我建立了一个神经网络,并通过使用具有随机梯度下降的反向传播成功地训练了它。现在我正在转向批量训练,但我对于何时应用动量和重量衰减感到有点困惑。 我非常清楚反向传播在理论上如何运作,我只是坚持实施细节。 使用随机方法,我所要做的就是在计算渐变之后立即对权重应用更新,如此伪python代码中所示:
for epoch in epochs:
for p in patterns:
outputs = net.feedforward(p.inputs)
# output_layer_errors is needed to plot the error
output_layer_errors = net.backpropagate(outputs, p.targets)
net.update_weights()
其中update_weights方法定义如下:
def update_weights(self):
for h in self.hidden_neurons:
for o in self.output_neurons:
gradient = h.output * o.error
self.weights[h.index][o.index] += self.learning_rate * gradient + \
self.momentum * self.prev_gradient
self.weights[h.index][o.index] -= self.decay * self.weights[h.index][o.index]
for i in self.input_neurons:
for h in self.hidden_neurons:
gradient = i.output * h.error
self.weights[i.index][h.index] += self.learning_rate * gradient + \
self.momentum * self.prev_gradient
self.weights[i.index][h.index] -= self.decay * self.weights[i.index][h.index]
这就像一个魅力(注意可能有错误,因为我只是使用python,因为它更容易理解,实际网络用C编码。这段代码只是为了显示我为计算更新所做的步骤) 。 现在,切换到批量更新,主要算法应该是这样的:
for epoch in epochs:
for p in patterns:
outputs = net.feedforward(p.inputs)
# output_layer_errors is needed to plot the error
output_layer_errors = net.backpropagate(outputs, p.targets)
net.accumulate_updates()
net.update_weights()
累积方法如下:
def accumulate_weights(self):
for h in self.hidden_neurons:
for o in self.output_neurons:
gradient = h.output * o.error
self.accumulator[h.index][o.index] += self.learning_rate * gradient
# should I compute momentum here?
for i in self.input_neurons:
for h in self.hidden_neurons:
gradient = i.output * h.error
# should I just accumulate the gradient without scaling it by the learning rate here?
self.accumulator[i.index][h.index] = self.learning_rate * gradient
# should I compute momentum here?
并且update_weights是这样的:
def update_weights(self):
for h in self.hidden_neurons:
for o in self.output_neurons:
# what to do here? apply momentum? apply weight decay?
self.weights[h.index][o.index] += self.accumulator[h.index][o.index]
self.accumulator[h.index][o.index] = 0.0
for i in self.input_neurons:
for h in self.hidden_neurons:
# what to do here? apply momentum? apply weight decay?
self.weights[i.index][h.index] += self.accumulator[i.index][h.index]
self.accumulator[i.index][h.index] = 0.0
我不确定是否必须:
1)使用累积时或更新时的学习率来缩放渐变
2)在更新时的累积时间应用动量
3)与2相同但是对于体重衰减
有人可以帮我解决这个问题吗? 对于这个冗长的问题,我很抱歉,但我想我会更详细地解释我的疑虑。
答案 0 :(得分:3)
对此有一些快速评论。随机梯度下降在大多数情况下导致非平滑优化,并且需要不适合当前技术进步的顺序优化,例如并行计算。
因此,小批量方法试图利用批量优化(并行计算)的优势获得随机优化的优势。在这里,您要创建的是小型训练块,您可以以与学习算法并行的方式提供这些块。最后,每个工作人员都应该告诉你他们的训练样本的错误,你可以将其平均并用作正常的随机梯度后代。
这种方法可以实现更顺畅的优化,如果您使用并行计算,可能会更快地进行优化。
答案 1 :(得分:0)
似乎第一个问题要么没问题。但是如果你想结合动量,你最好检查你的实现中的原始公式。我会说你不应该在积累过程中缩放渐变。在计算动量时,使用公式:
v_{t+1} = \mu v_t - \alpha * g_t
其中g_t是渐变。 alpha是学习率。
我还建议使用AdaGrad和mini-batch代替完整批次。
参考:http://firstprayer.github.io/stochastic-gradient-descent-tricks/