在 python 中构建自定义 Caffe 层

Building custom Caffe layer in python

在 Python 中解析了许多有关构建 Caffe 层的链接后,我仍然难以理解一些概念。可以请人澄清一下吗?

我还缺少的是:

  1. setup()方法:我应该在这里做什么?为什么在示例中我应该将 'bottom' 参数的长度与“2”进行比较?为什么应该是2?它似乎不是批量大小,因为它是任意的?而我理解的bottom是blob,然后第一个维度是batch size?
  2. reshape()方法:据我了解'bottom'输入参数是下层的blob,'top'参数是上层的blob,我需要根据reshape top layer我的前向传播计算的输出形状。但是,如果这些形状在每次传球时都没有变化,只有权重发生变化,为什么我需要在每次前向传球时都这样做?
  3. reshapeforward 方法使用的 'top' 输入参数的索引为 0。为什么我需要使用 top[0].data=...top[0].input=... 而不是 top.data=...top.input=...?这个指数是关于什么的?如果我们不使用这个顶级列表的其他部分,为什么它会以这种方式暴露出来?我可以怀疑它或 C++ backbone 的巧合,但最好能准确知道。
  4. reshape()方法,符合:

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

    我在这里做什么?为什么它的维度又是2?我在这里数什么?为什么 blob 的两个部分(0 和 1)在某些成员(count)的数量上应该相等?

  5. forward()方法,我这一行定义的是:

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

    如果我定义它,当它在前向路径之后使用?我们可以只使用

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

    而不是稍后在此方法中计算损失,而不分配给 self,或者它是出于某种目的完成的?

  6. backward() 方法:这是关于什么的:for i in range(2):?为什么范围又是 2?

  7. backward()方法,propagate_down参数:为什么定义?我的意思是,如果它是 True,梯度应该被分配给 bottom[X].diff,正如我所看到的,但是为什么有人会调用对 propagate_down = False 什么都不做的方法,如果它什么也不做并且还在里面循环?

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

你在这里问了很多问题,我给你一些要点和建议,希望能为你澄清问题。我不会明确回答你所有的问题。

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

top 斑点也是如此:事实上,在大多数情况下,每一层都有一个 top,但情况并非总是如此(参见 AccuracyLayer ).因此,top 也是 4-D 斑点的 向量 ,层的每个 top 一个。大多数时候该向量中只有一个元素,但有时您可能会发现多个元素。

我相信这涵盖了您的问题 1、3、4 和 6。

reshape() (Q.2) 开始,这个函数不会在每次前向传递时调用,它仅在网络设置为 space 分配 inputs/outputs 和参数时调用。
有时,您可能想要更改网络的输入大小(例如,对于检测网络),然后您需要为网络的所有层调用 reshape() 以适应新的输入大小。

至于propagate_down参数(Q.7):由于一层可能有多个bottom,原则上你需要将渐变传递给all bottoms 在反向传播期间。但是,损失层底部 label 的梯度是什么意思?有些情况下您不想传播到 all bottoms:这就是这个标志的用途。 (这里有一个 ,损失层有三个 bottom,期望所有层都有梯度)。

有关详细信息,请参阅

为什么应该是2?

那个具体的要点是在谈论欧几里得损失层。欧几里德损失是 2 向量之间的均方误差。因此,该层的输入 blob 中必须有 2 个向量。每个向量的长度必须相同,因为它是逐元素的差异。您可以在 reshape 方法中看到此检查。

谢谢。