使用Python构建自定义Caffe层

18

在阅读了许多有关用Python构建Caffe层的链接后,我仍然难以理解一些概念。能否有人澄清一下?

我还需要了解以下内容:

  1. setup()方法:我应该在这里做什么?为什么在示例中,我应该将'bottom'参数的长度与'2'进行比较?为什么它应该是2?因为它是任意的,所以它似乎不是批次大小吗?而且,如果我理解正确,'bottom'就是Blob,那么第一个维度就是批次大小吗?
  2. reshape()方法:按照我的理解,'bottom'输入参数是下一层的Blob,而'top'参数是上一层的Blob,并且我需要根据前向传递的计算输出形状来重新调整上一层。但是,如果这些形状从传递到传递不发生变化,为什么我需要每个前向传递都这样做,只有权重会改变?
  3. reshapeforward方法在使用“top”输入参数时具有0索引。为什么我需要使用top[0].data=...top[0].input=...而不是top.data=...top.input=...?这个索引是什么意思?如果我们不使用这个top列表的其他部分,为什么要以这种方式公开它?我可以怀疑它是C++底层的巧合,但最好确切地知道。
  4. reshape()方法中的一行:

    if bottom[0].count != bottom[1].count
    

    我在这里做什么?为什么它的维度再次是2?而我在这里正在计数什么?为什么blob的两个部分(0和1)都应该有相同数量的某些成员(count)?

  5. forward()方法,我通过这行代码定义了什么:

    self.diff[...] = bottom[0].data - bottom[1].data
    

    如果我定义了forward path后,什么时候使用它?我们能直接使用吗?

    diff = bottom[0].data - bottom[1].data 
    

    这种方法中是否是出于某种目的,而不将损失分配给self?

  6. backward() 方法中,for i in range(2): 是什么意思?为什么范围又是2?

  7. backward() 方法中,propagate_down 参数:为什么要定义它?我的意思是,如果它是 True,那么梯度应该被分配给 bottom[X].diff,但如果它什么也不做,只是循环内部,为什么有人会调用这个方法呢?

如果这些问题太基础了,我很抱歉,我只是找不到一个好的指南来理解它们,并在这里寻求帮助。


1
不要忘记使用 WITH_PYTHON_LAYERS=1 标志来制作 pycaffe,参见这里 - iamprem
2个回答

17

您在这里提出了很多问题,我会为您提供一些要点和指引,希望能为您澄清一些事情。我不会明确回答您所有的问题。

看起来您最困惑的是blob和层输入/输出之间的区别。实际上大多数层只有一个blob作为输入和一个blob作为输出,但并非总是如此。考虑一个损失层:它有两个输入:预测和实际标签。因此,在这种情况下,bottom是一个长度为2(!)的向量,其中bottom[0]是表示预测的(4-D) blob,而bottom[1]是另一个带有标签的blob。因此,在构建这样的层时,您必须确定您有恰好(硬编码)2个输入blob(请参见AccuracyLayer定义中的ExactNumBottomBlobs())。

同样,top块也是如此:大多数情况下,每个层只有一个top,但并非总是如此(例如,参见AccuracyLayer)。因此,top也是一个4-D块的向量,每个层的top都有一个。大多数情况下,该向量中只有一个元素,但有时您可能会发现不止一个。
我相信这回答了你的问题1、3、4和6。
至于reshape()(问题2),此函数并非在每次前向传递时都会被调用,它仅在设置网络以分配输入/输出和参数空间时才会被调用。
偶尔,您可能希望更改网络的输入大小(例如,对于检测网络),然后您需要为网络的所有层调用reshape()以适应新的输入大小。
关于propagate_down参数(问题7):由于一层可能有多个bottom,在反向传播期间你需要原则上将梯度传递到所有bottom。但是,对于损失层的label bottom,梯度的含义是什么?有些情况下,你不想传递给所有bottom:这就是该标志的作用。(这里有一个带有三个bottom的损失层的示例,它们都希望获得梯度)。
了解更多信息,请参见"Python"层教程

1
谢谢,Shai,现在更有意义了。 - loknar

0

为什么应该是2?

这个特定的代码片段是关于欧几里得损失层的。欧几里得损失是2个向量之间的均方误差。因此,这个层的输入blob中必须有2个向量。每个向量的长度必须相同,因为它是逐元素的差异。您可以在reshape方法中看到这个检查。

谢谢。


1
这应该是注释 - ketan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接