在进行批处理时,反向传播如何通过 Max Pooling 层工作?

数据挖掘 神经网络 深度学习 反向传播
2021-09-26 05:22:01

假设我们使用 100 个样本的批大小进行学习。

因此,在每批中,每个神经元(和偏差等)的权重都通过添加学习率的负值 * 我们使用 100 个样本找到的平均误差值 * 误差函数相对于当前正在更新的神经元权重。

现在,当我们使用 Max Pool 层时,我们如何计算该层的导数?在我们前馈的每个样本中,选择一个不同的像素(比方说)作为最大值,所以当我们反向传播超过 100 个样本时,每次选择不同的路径时,我们该怎么做呢?我想到的一个解决方案是记住每个被选为最大值的像素,然后可能将导数拆分到所有最大像素上。这是正在做的事情吗?

2个回答

当神经网络处理一个批次时,会为每个示例计算每个层的所有激活值(如果库和硬件支持,可能每个示例并行)。存储这些值以供以后使用 - 即批次中每个示例每次激活一个值,它们不会以任何方式聚合

在反向传播期间,这些激活值被用作计算梯度的数值来源之一,以及到目前为止计算的梯度和连接权重。与前向传播一样,每个示例都应用反向传播,它不适用于平均值或求和值。只有在处理完所有示例后,您才能使用批次的总和或平均梯度。

这同样适用于最大池层。您不仅知道批处理中每个示例的池化层的输出是什么,而且您可以查看前一层并确定池中的哪个输入是最大值。

在数学上,避免需要为 NN 层和神经元定义索引,该规则可以这样表示

  • 前向函数是 m=max(a,b)

  • 我们知道 Jm 对于一些目标函数 J(在神经网络中,这将是我们想要最小化的损失函数,并且我们假设我们已经反向传播到这一点)

  • 我们想知道 JaJb

  • 如果 a>b

    • 本地,*m=a. 所以Ja=Jm

    • 本地,*m 不依赖于 b. 所以Jb=0

  • 所以 Ja=Jm 如果 a>b, 别的 Ja=0

  • Jb=Jm 如果 b>a, 别的 Jb=0

当反向传播穿过最大池化层时,梯度会按示例进行处理,并仅分配给前一层的最大输入。其他输入获得零梯度。当它被批处理时,它没有什么不同,它只是按示例处理,可能是并行处理的。在整个批次中,这可能意味着最大池的多个输入激活(可能是全部)获得梯度的一部分——每个来自批次中不同的示例子集。


* 本地 -> 当只对m.

** 从技术上讲,如果a=b正是这样我们就有了不连续性,但在实践中,我们可以在训练神经网络时忽略它而不会出现问题。

我有同样的问题,但我可能通过查看 Caffe 的源代码想通了。

请看 Caffe 的源代码:

line 620 & 631这段代码

它通过添加每个输入的(该参数的)导数来计算每个参数的导数,然后将其除以批量大小。

此外,请参阅line 137代码,它只是将导数缩放为1/iter_size,与平均值相同。

我们可以看到在进行反向传播时对 Max Pooling 层没有特殊处理。

至于Max Pooling的导数,我们再来看看Caffe的源码:

line 272这段代码显然,只有最大元素的导数是1*top_diff,其他元素的导数是0*top_diff