Rog*_*llo 2 machine-learning deep-learning caffe tensorflow
我试图了解使用 minibatch SGD 时如何计算梯度。我已经在 CS231 在线课程中实现了它,但才意识到在中间层中,梯度基本上是为每个样本计算的所有梯度的总和(在 Caffe 或 Tensorflow 中的实现相同)。只有在最后一层(损失),它们才被样本数量平均。这样对吗?如果是这样,是否意味着因为在最后一层它们被平均,所以在进行反向传播时,所有梯度也会自动平均?谢谢!
最好理解为什么 SGD 首先起作用。
通常,神经网络实际上是一个非常复杂的复合函数,由输入向量 x、标签 y(或目标变量,根据问题是分类还是回归而变化)和一些参数向量 w 组成。假设我们正在研究分类。我们实际上是在尝试对变量向量 w 进行最大似然估计(实际上是 MAP 估计,因为我们肯定会使用 L2 或 L1 正则化,但现在这太技术性了)。假设样本是独立的;那么我们有以下成本函数:
p(y1|w,x1)p(y2|w,x2) ... p(yN|w,xN)
Run Code Online (Sandbox Code Playgroud)
将这个 wrt 优化为 w 是一团糟,因为所有这些概率都是相乘的(这将产生一个非常复杂的导数 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))
Run Code Online (Sandbox Code Playgroud)
这是我们拥有的实际成本函数。神经网络实际上做的是对概率函数 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)
Run Code Online (Sandbox Code Playgroud)
理想情况下,上面是实际的梯度。但是这种批量计算并不容易计算。如果我们正在处理具有 100 万个训练样本的数据集怎么办?更糟糕的是,训练集可能是一个样本流 x,其大小是无限的。
SGD 的随机部分在这里发挥作用。从训练集中随机均匀地选取 m 个具有 m << 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)
Run Code Online (Sandbox Code Playgroud)
请记住,我们有一个经验(或在无限训练集的情况下是实际的)数据分布 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的方差很大,应该使用较小的学习率,否则算法很容易发散失控。
现在足够的理论,你的实际问题是
只有在最后一层(损失),它们才被样本数量平均。这样对吗?如果是这样,是否意味着因为在最后一层它们被平均,所以在进行反向传播时,所有梯度也会自动平均?谢谢!
是的,在最后一层除以 m 就足够了,因为一旦最下层乘以它,链式法则会将因子 (1/m) 传播到所有参数。不需要对每个参数单独做,这样会失效。