我正在复制神经网络。我试图了解标准图层类型的工作方式。特别是,我在任何地方都找不到关于跨 channel 归一化层如何在反向传递上表现的描述的麻烦。
由于规范化层没有参数,因此我可以猜测两个可能的选项:
我想不出您为什么会基于任何直觉而在另一个上做一个理由,因此我想在这方面寻求帮助。
编辑1:
该层是caffe中的标准层,如此处http://caffe.berkeleyvision.org/tutorial/layers.html所述(请参见“本地响应规范化(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
请熟悉或不熟悉这两种方法的人将后向通过阶段的方法转换为简单的英语吗?
最佳答案
它使用链式规则通过本地响应归一化层向后传播梯度。从某种意义上说,它有点类似于非线性层(它本身也没有可训练的参数,但确实会影响向后的渐变)。
从您链接到的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
),然后计算sum
的i = 0
,然后为每个连续的i
添加addend[i + n/2]
减去addend[i - n/2 - 1]
,它将在恒定时间内为您提供i
的新值的总和值。 关于machine-learning - 通过跨 channel 本地响应归一化(LRN)层的反向传播算法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33782870/