【问题标题】:Neural network with batch training algorithm, when to apply momentum and weight decay具有批量训练算法的神经网络,何时应用动量和权重衰减
【发布时间】:2015-01-12 19:14:54
【问题描述】:

我构建了一个神经网络,并通过使用带有随机梯度下降的反向传播成功地对其进行了训练。现在我正在切换到批量训练,但我对何时应用动量和重量衰减有点困惑。 我很清楚反向传播在理论上是如何工作的,我只是停留在实现细节上。 使用随机方法,我所要做的就是在计算梯度后立即将更新应用于权重,就像在这个伪 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) 相同,但重量衰减

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

【问题讨论】:

  • 三个都应该在积累的时候进行。
  • @mp85: 你得到你要找的东西了吗?哪一个是正确的答案?
  • 最后,我只是不断累积每个模式的“原始”梯度(未缩放),并在更新结束时应用学习率、动量、权重衰减和所有其他技巧循环遍历每个模式。它奏效了。

标签: algorithm machine-learning neural-network backpropagation


【解决方案1】:

对此进行一些快速评论。随机梯度下降在大多数情况下会导致非平滑优化,并且需要不适合当前技术进步(例如并行计算)的顺序优化。

因此,小批量方法试图通过批量优化(并行计算)的优势来获得随机优化的优势。在这里,您要做的是创建小的训练块,您以并行方式将其提供给学习算法。最后,每个工人应该告诉你他们训练样本的错误,你可以将其平均并用作正常的随机梯度下降。

这种方法可以实现更平滑的优化,如果使用并行计算,优化速度可能会更快。

【讨论】:

    【解决方案2】:

    似乎第一个问题都可以。但是如果你想结合动量,你最好在你的实现中检查原始公式。我会说你不应该在积累过程中缩放梯度。在计算动量时,使用公式:

    v_{t+1} = \mu v_t - \alpha * g_t
    

    其中 g_t 是梯度。 alpha 是学习率。

    我还建议使用 AdaGrad 和 mini-batch 而不是 full-batch。

    参考:http://firstprayer.github.io/stochastic-gradient-descent-tricks/

    【讨论】:

      猜你喜欢
      • 2012-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-11
      • 1970-01-01
      • 2018-11-26
      • 1970-01-01
      相关资源
      最近更新 更多