通过跨通道局部响应归一化 (LRN) 层的反向传播算法
Backpropagation algorithm through cross-channel local response normalization (LRN) layer
我正在研究复制神经网络。我试图了解标准图层类型的工作原理。特别是,我在任何地方都找不到关于跨通道归一化层在反向传播中的行为的描述。
由于归一化层没有参数,我猜到了两个可能的选项:
来自下一层(即后面)的误差梯度在不对它们做任何处理的情况下向后传递。
误差梯度的归一化方式与正向传播中跨通道的激活归一化的方式相同。
我想不出为什么你会根据任何直觉做一个而不是另一个的原因,因此我需要这方面的帮助。
编辑 1:
该层是caffe中的标准层,如此处所述http://caffe.berkeleyvision.org/tutorial/layers.html(参见'Local Response Normalization (LRN)')。
alexNet 论文第 3.3 节描述了前向传递中的层实现:http://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf
编辑 2:
我相信前向和后向传递算法在 Torch 库中都有描述:https://github.com/soumith/cudnn.torch/blob/master/SpatialCrossMapLRN.lua
在此处的 Caffe 库中:https://github.com/BVLC/caffe/blob/master/src/caffe/layers/lrn_layer.cpp
请熟悉其中 either/both 的人能否将后向传播阶段的方法翻译成通俗易懂的英语?
当然,您可以打印变量来观察它们的变化,或者使用调试模型来查看通过网络时错误如何变化。
它使用链式法则通过局部响应归一化层向后传播梯度。在这个意义上它有点类似于非线性层(它本身也没有可训练的参数,但确实会影响向后的梯度)。
从您链接到的 Caffe 中的代码,我看到他们将每个神经元中的误差作为参数,并通过执行以下操作来计算上一层的误差:
首先,在正向传递中,他们缓存了一个所谓的比例,计算(根据 AlexNet 论文,参见第 3.3 节中的公式)为:
scale_i = k + alpha / n * sum(a_j ^ 2)
这里和下面的 sum
是由 j
索引的总和,从 max(0, i - n/2)
到 min(N, i + n/2)
(请注意,在论文中,它们没有通过 n
进行归一化,所以我认为这是 Caffe 与 AlexNet 不同的做法)。然后将前向传播计算为 b_i = a_i + scale_i ^ -beta
.
为了向后传播误差,假设来自下一层的误差是be_i
,我们需要计算的误差是ae_i
。然后 ae_i
计算为:
ae_i = scale_i ^ -b * be_i - (2 * alpha * beta / n) * a_i * sum(be_j * b_j / scale_j)
既然你打算手动实现它,我也将分享 Caffe 在他们的代码中使用的两个技巧,使实现更简单:
当您计算总和的加数时,分配一个大小为 N + n - 1
的数组,并在其两端填充 n/2
个零。这样你就可以计算从 i - n/2
到 i + n/2
的总和,而不用关心低于零和超过 N
.
您不需要在每次迭代时重新计算 sum
,而是提前计算加数(a_j^2
用于前端,be_j * b_j / scale_j
对于反向传递),然后计算 i = 0
的 sum
,然后对于每个连续的 i
,只需添加 addend[i + n/2]
并减去 addend[i - n/2 - 1]
,它会给你在常数时间内 i
的新值的总和值。
我有一个backward的替代公式,我不知道它是否等同于caffe的:
所以咖啡是:
ae_i = scale_i ^ -b * be_i - (2 * alpha * beta / n) * a_i * sum(be_j * b_j / scale_j)
通过对原表达式进行微分
b_i = a_i/(scale_i^-b)
我明白了
ae_i = scale_i ^ -b * be_i - (2 * alpha * beta / n) * a_i * be_i*sum(ae_j)/scale_i^(-b-1)
我正在研究复制神经网络。我试图了解标准图层类型的工作原理。特别是,我在任何地方都找不到关于跨通道归一化层在反向传播中的行为的描述。
由于归一化层没有参数,我猜到了两个可能的选项:
来自下一层(即后面)的误差梯度在不对它们做任何处理的情况下向后传递。
误差梯度的归一化方式与正向传播中跨通道的激活归一化的方式相同。
我想不出为什么你会根据任何直觉做一个而不是另一个的原因,因此我需要这方面的帮助。
编辑 1:
该层是caffe中的标准层,如此处所述http://caffe.berkeleyvision.org/tutorial/layers.html(参见'Local Response Normalization (LRN)')。
alexNet 论文第 3.3 节描述了前向传递中的层实现:http://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf
编辑 2:
我相信前向和后向传递算法在 Torch 库中都有描述:https://github.com/soumith/cudnn.torch/blob/master/SpatialCrossMapLRN.lua
在此处的 Caffe 库中:https://github.com/BVLC/caffe/blob/master/src/caffe/layers/lrn_layer.cpp
请熟悉其中 either/both 的人能否将后向传播阶段的方法翻译成通俗易懂的英语?
当然,您可以打印变量来观察它们的变化,或者使用调试模型来查看通过网络时错误如何变化。
它使用链式法则通过局部响应归一化层向后传播梯度。在这个意义上它有点类似于非线性层(它本身也没有可训练的参数,但确实会影响向后的梯度)。
从您链接到的 Caffe 中的代码,我看到他们将每个神经元中的误差作为参数,并通过执行以下操作来计算上一层的误差:
首先,在正向传递中,他们缓存了一个所谓的比例,计算(根据 AlexNet 论文,参见第 3.3 节中的公式)为:
scale_i = k + alpha / n * sum(a_j ^ 2)
这里和下面的 sum
是由 j
索引的总和,从 max(0, i - n/2)
到 min(N, i + n/2)
(请注意,在论文中,它们没有通过 n
进行归一化,所以我认为这是 Caffe 与 AlexNet 不同的做法)。然后将前向传播计算为 b_i = a_i + scale_i ^ -beta
.
为了向后传播误差,假设来自下一层的误差是be_i
,我们需要计算的误差是ae_i
。然后 ae_i
计算为:
ae_i = scale_i ^ -b * be_i - (2 * alpha * beta / n) * a_i * sum(be_j * b_j / scale_j)
既然你打算手动实现它,我也将分享 Caffe 在他们的代码中使用的两个技巧,使实现更简单:
当您计算总和的加数时,分配一个大小为
N + n - 1
的数组,并在其两端填充n/2
个零。这样你就可以计算从i - n/2
到i + n/2
的总和,而不用关心低于零和超过N
.您不需要在每次迭代时重新计算
sum
,而是提前计算加数(a_j^2
用于前端,be_j * b_j / scale_j
对于反向传递),然后计算i = 0
的sum
,然后对于每个连续的i
,只需添加addend[i + n/2]
并减去addend[i - n/2 - 1]
,它会给你在常数时间内i
的新值的总和值。
我有一个backward的替代公式,我不知道它是否等同于caffe的:
所以咖啡是:
ae_i = scale_i ^ -b * be_i - (2 * alpha * beta / n) * a_i * sum(be_j * b_j / scale_j)
通过对原表达式进行微分
b_i = a_i/(scale_i^-b)
我明白了
ae_i = scale_i ^ -b * be_i - (2 * alpha * beta / n) * a_i * be_i*sum(ae_j)/scale_i^(-b-1)