草庐IT

python - 查找 Caffe 卷积滤波器相对于输入的梯度

coder 2023-05-02 原文

我需要找到关于卷积神经网络 (CNN) 中单个卷积滤波器的输入层的梯度,作为 visualize the filters 的一种方式。 .
给定 Caffe 的 Python 接口(interface)中经过训练的网络例如 this example 中的那个,然后我怎样才能找到卷积滤波器相对于输入层数据的梯度?

编辑:

基于 answer by cesans ,我在下面添加了代码。我的输入层的尺寸是 [8, 8, 7, 96]。我的第一个 conv 层 conv1 有 11 个大小为 1x5 的过滤器,得到尺寸 [8, 11, 7, 92].

net = solver.net
diffs = net.backward(diffs=['data', 'conv1'])
print diffs.keys() # >> ['conv1', 'data']
print diffs['data'].shape # >> (8, 8, 7, 96)
print diffs['conv1'].shape # >> (8, 11, 7, 92)

从输出中可以看出,net.backward() 返回的数组的维度等于我在 Caffe 中的层的维度。经过一些测试,我发现这个输出分别是 data 层和 conv1 层的损失梯度。

但是,我的问题是如何找到单个 conv-filter 相对于输入层中的数据的梯度,这是另一回事。我怎样才能做到这一点?

最佳答案

Caffe 网络处理两个数字“流”。
第一个是数据“流”:通过网络推送的图像和标签。随着这些输入在网络中前进,它们被转换为高级表示,并最终转换为类别概率 vector (在分类任务中)。
第二个“流”包含不同层的参数、卷积的权重、偏差等。这些数字/权重在网络的训练阶段会改变和学习。

尽管这两个“流”所扮演的角色根本不同,但 caffe 仍然使用相同的数据结构 blob 来存储和管理它们。
但是,对于每一层,每个流都有两个不同的 blob vector 。

这是一个我希望澄清的例子:

import caffe
solver = caffe.SGDSolver( PATH_TO_SOLVER_PROTOTXT )
net = solver.net

如果你现在看

net.blobs

您将看到一个字典,其中存储了网络中每一层的“caffe blob”对象。每个 blob 都有存储数据和梯度的空间

net.blobs['data'].data.shape    # >> (32, 3, 224, 224)
net.blobs['data'].diff.shape    # >> (32, 3, 224, 224)

对于卷积层:

net.blobs['conv1/7x7_s2'].data.shape    # >> (32, 64, 112, 112)
net.blobs['conv1/7x7_s2'].diff.shape    # >> (32, 64, 112, 112)

net.blobs 保存第一个数据流,它的形状与输入图像的形状匹配,直至生成的类概率 vector 。

另一方面,你可以看到 net

的另一个成员
net.layers

这是一个caffe vector ,存储了不同层的参数。
看第一层('data'层):

len(net.layers[0].blobs)    # >> 0

没有要为输入层存储的参数。
另一方面,对于第一个卷积层

len(net.layers[1].blobs)    # >> 2

网络存储一个 blob 用于过滤器权重,另一个用于恒定偏差。他们来了

net.layers[1].blobs[0].data.shape  # >> (64, 3, 7, 7)
net.layers[1].blobs[1].data.shape  # >> (64,)

如您所见,该层对 3 channel 输入图像执行 7x7 卷积,并有 64 个这样的过滤器。

现在,如何获得渐变?好吧,正如你所说的

diffs = net.backward(diffs=['data','conv1/7x7_s2'])

返回 data 流的梯度。我们可以通过

来验证这一点
np.all( diffs['data'] == net.blobs['data'].diff )  # >> True
np.all( diffs['conv1/7x7_s2'] == net.blobs['conv1/7x7_s2'].diff )  # >> True

(TL;DR) 你想要参数的梯度,这些参数存储在 net.layers 中:

net.layers[1].blobs[0].diff.shape # >> (64, 3, 7, 7)
net.layers[1].blobs[1].diff.shape # >> (64,)

为了帮助您将图层名称及其索引映射到 net.layers vector 中,您可以使用 net._layer_names


更新关于使用渐变来可视化过滤器响应:
梯度通常是为 标量 函数定义的。损失是一个标量,因此您可以说像素/滤波器权重相对于标量损失的梯度。此梯度是每个像素/过滤器权重的单个数字。
如果你想获得最大激活特定内部隐藏节点的输入,你需要一个“辅助”网络,它的损失正是你想要的特定隐藏节点激活的度量形象化。一旦你有了这个辅助网络,你就可以从任意输入开始,并根据输入层的辅助损失梯度改变这个输入:

update = prev_in + lr * net.blobs['data'].diff

关于python - 查找 Caffe 卷积滤波器相对于输入的梯度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31324739/

有关python - 查找 Caffe 卷积滤波器相对于输入的梯度的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

  3. ruby - 查找字符串中的内容类型(数字、日期、时间、字符串等) - 2

    我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s

  4. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  5. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  6. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  7. python - 如何读取 MIDI 文件、更改其乐器并将其写回? - 2

    我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的

  8. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  9. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  10. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

随机推荐