我试图了解在使用miinibatch SGD时如何计算渐变。我已经在CS231在线课程中实现了它,但只是意识到在中间层中,梯度基本上是针对每个样本计算的所有梯度的总和(对于Caffe或Tensorflow中的实现相同)。仅在最后一层(损失)中,它们通过样本数来平均。 它是否正确?如果是这样,是否意味着因为在最后一层它们是平均的,所以在做backprop时,所有的渐变都会自动平均? 谢谢!
答案 0 :(得分:4)
最好先了解SGD为何先行。
通常,神经网络究竟是什么,输入向量x,标签y(或目标变量,根据问题是分类还是回归而变化)和一些参数向量w的非常复杂的复合函数。假设我们正在进行分类。实际上,对于变量向量w,我们实际上正在尝试进行最大似然估计(实际上MAP估计,因为我们肯定会使用L2或L1正则化,但这对于现在来说太过于技术性)。假设样本是独立的;那么我们有以下成本函数:
p(y1|w,x1)p(y2|w,x2) ... p(yN|w,xN)
将这个wrt优化为w是一个混乱,因为所有这些概率都是多重的(这将产生一个非常复杂的衍生物)。我们使用对数概率(取日志不会改变极值点,我们除以N,所以我们可以将训练集视为经验概率分布,p(x))
J(X,Y,w)=-(1/N)(log p(y1|w,x1) + log p(y2|w,x2) + ... + log p(yN|w,xN))
这是我们的实际成本函数。神经网络实际上做的是对概率函数p(yi | w,xi)进行建模。这可能是一个非常复杂的1000+分层ResNet或只是一个简单的感知器。
现在w的衍生物很容易说明,因为我们现在有一个补充:
dJ(X,Y,w)/dw = -(1/N)(dlog p(y1|w,x1)/dw + dlog p(y2|w,x2)/dw + ... + dlog p(yN|w,xN)/dw)
理想情况下,上面是实际的渐变。但是这种批量计算并不容易计算。如果我们正在处理包含1M训练样本的数据集,该怎么办?更糟糕的是,训练集可以是样本x的流,其具有无限大小。
SGD的随机部分在这里发挥作用。选择m个样本,其中m <&lt;&lt; N从训练集中随机均匀地计算并使用它们计算导数:
dJ(X,Y,w)/dw =(approx) dJ'/dw = -(1/m)(dlog p(y1|w,x1)/dw + dlog p(y2|w,x2)/dw + ... + dlog p(ym|w,xm)/dw)
请记住,我们有一个经验(或在无限训练集的情况下是实际的)数据分布p(x)。从p(x)中抽取m个样本并对它们求平均值的上述操作实际上产生了实际导数dJ(X,Y,w)/ dw的无偏估计量dJ'/ dw。那是什么意思?取很多这样的m个样本并计算不同的dJ'/ dw估计值,对它们求平均值,你得到dJ(X,Y,w)/ dw非常接近,甚至是无限采样的极限。可以证明,这些嘈杂但无偏的梯度估计在长期运行中表现得像原始梯度。平均而言,SGD将遵循实际梯度的路径(但它可能会陷入不同的局部最小值,所有这些都取决于学习率的选择)。小批量大小m与噪声估计dJ'/ dw中的固有误差直接相关。如果m很大,则获得具有低方差的梯度估计,您可以使用更大的学习率。如果m很小或m = 1(在线学习),估计量dJ'/ dw的方差非常高,你应该使用较小的学习率,否则算法很容易失控。
现在足够的理论,你的实际问题是
仅在最后一层(损失)中,它们按样本数平均。它是否正确?如果是这样,是否意味着因为在最后一层它们是平均的,所以在做backprop时,所有的渐变都会自动平均?谢谢!
是的,在最后一层中除以m就足够了,因为一旦最下层乘以它,链规则会将因子(1 / m)传播到所有参数。您无需为每个参数单独执行操作,这将无效。
答案 1 :(得分:2)
在最后一层中,它们被平均,并且在之前的总和中。先前层中的总和梯度在下一层的不同节点上求和,而不是通过示例。这种平均化只是为了在更改批量大小时使学习过程的行为相似 - 如果对所有层进行求和,则一切都应该相同,但要适当降低学习率。