我正在使用pycaffe的向后功能来实现反卷积过程。我首先运行正向过程并获取网络的输出数据blob,然后将数据blob分配给顶层的diff blob,然后运行反向过程。但是,底层的差异不会被后向过程改变,它们全为零。我不知道为什么差异不通过向后转移。

def backward(fcn_net, im, name_list_, target_blob):
    start=name_list_[len(name_list_)-1]; end=name_list_[0]
    print(start, end)
    fcn_net.blobs[start].diff[...]=im[...]
    fcn_net.backward(start=start, end=end)
    return fcn_net.blobs[target_blob].diff


在上面的代码中,name_list_有序地包含所有conv层和池化层,而向后从最后一个conv层开始。谢谢!

最佳答案

使用pycaffe使用start =和end =参数推断网络的一部分是困难的,但是可能的。如果可以推论所有图层,那将更加简单-如Shai所建议,只需设置“ force_backward:true”即可。

以下两个问题可能导致net.backward(...)之后起始层的差异为零:


Caffe(它的C ++部分)对Backward()调用进行了优化,以优化其认为不必要的某些层。它优化了达到可学习参数(只是没有可学习参数或所有参数上的lr_mult = 0)所不需要的反向传播。最常见的结果是优化反向传播到数据层,因为它通常不需要渐变。

如果您需要在数据层上进行区分(例如,对于Gatys型样式传输),请将“ force_backward:true”放入包含您的网络层的原型中-这会取消此优化。
另一个问题是自动拆分图层。加载网络时,只要在其他图层的2个或多个底部(输入)中使用了某个图层的顶部(输出),Caffe就会自动插入拆分图层。您可以检查Caffe日志文件中名称中包含“ _split_”子字符串的图层。

例:

原始网络(节点是图层):

数据---> conv1-> conv2-> ...
      \-> somelayer-> ...


加载后:

数据->拆分---> conv1-> conv2-> ...
               \-> somelayer-> ...


插入自动拆分图层后,图层“数据”的顶部(输出)保留其名称,但“ conv1”和“ somelayer”的底部重新命名为某些生成的名称。结果,当您对从“ conv1”层开始的网络部分进行向后(...)运行时,.diff仅在自动生成的Blob中进行更新。要使用原始的Blob名称,请转移“ start =“ arg值”以包括自动拆分层(用于forward()和backward()调用)。

关于python - pycaffe无法从上到下传递差异,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44895846/

10-12 18:03