神经网络采用批量训练算法,何时应用动量和重量衰减

时间:2014-11-15 13:14:50

标签: algorithm machine-learning neural-network backpropagation

我建立了一个神经网络,并通过使用具有随机梯度下降的反向传播成功地训练了它。现在我正在转向批量训练,但我对于何时应用动量和重量衰减感到有点困惑。 我非常清楚反向传播在理论上如何运作,我只是坚持实施细节。 使用随机方法,我所要做的就是在计算渐变之后立即对权重应用更新,如此伪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相同但是对于体重衰减

有人可以帮我解决这个问题吗? 对于这个冗长的问题,我很抱歉,但我想我会更详细地解释我的疑虑。

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/