Pytorch: optimで使用される運動量の定式化に関するメモをドキュメントに追加します

作成日 2017年03月25日  ·  3コメント  ·  ソース: pytorch/pytorch

私はPyTorchでのSGD + Momentumの実装を見てきましたが、他のパッケージ(および論文)がそれを説明する方法とは少し異なることに気づきました。 とりあえず、ネステロフのバージョンではなく、(古典的な)勢いだけに焦点を当てましょう。

これを書いている時点で、実装は次のようになっています。

`` `
勢いの場合!= 0:
param_state = self.state [p]
'momentum_buffer'がparam_stateにない場合:
buf = param_state ['momentum_buffer'] = d_p.clone()
それ以外:
buf = param_state ['momentum_buffer']
buf.mul_(momentum).add_(1-減衰、d_p)
nesterovの場合:
d_p = d_p.add(momentum、buf)
それ以外:
d_p = buf

            p.data.add_(-group['lr'], d_p)
Mathematically, if we denote the momentum buffer by `v` and assume that `dampening=0`, at every iteration, the buffer is updated as `v = m*v + g` and the step is `∆x = lr * v`. Notice that the learning rate `lr` hits the momentum term `v` as well as the gradient. To me, this is different from what classical momentum is, and also differs from how other packages implement SGD+M.

Let us contrast this with the Sutskever et. al. paper and other commonly used pacakges such as Lasagne, Keras, Neon, etc.

## [Sutskever et. al.](http://www.jmlr.org/proceedings/papers/v28/sutskever13.pdf)
The snippet of the relevant section is pasted below. 
![Sutskever et. al.](http://i.imgur.com/QJelodE.png)

Retaining the syntax from above, the algorithm updates `v` as `v = m*v - lr * g` with the step `∆x = v`. So, the learning rate `lr` only hits the gradient. It does not (explicitly) influence the effect of the momentum term which is in contrast with PyTorch's implementation. 

# [Lasagne](https://github.com/Lasagne/Lasagne/blob/master/lasagne/updates.py#L217)

Lasagne employs the same rule as suggested in Sutskever for momentum. 

for param in params:
    value = param.get_value(borrow=True)
    velocity = theano.shared(np.zeros(value.shape, dtype=value.dtype),
                             broadcastable=param.broadcastable)
    x = momentum * velocity + updates[param]
    updates[velocity] = x - param
# [Keras](https://github.com/fchollet/keras/blob/master/keras/optimizers.py#L141)

Same for Keras:
   for p, g, m in zip(params, grads, moments):
        v = self.momentum * m - lr * g  # velocity
        self.updates.append(K.update(m, v))

        if self.nesterov:
            new_p = p + self.momentum * v - lr * g
        else:
            new_p = p + v
# [Neon](https://github.com/NervanaSystems/neon/blob/master/neon/optimizers/optimizer.py#L520)

and Neon.
            velocity[:] = self.momentum_coef * velocity - lrate * grad

            # Nesterov accelerated gradient (NAG) is implemented the same
            # as in torch's "sgd.lua". It's a reformulation of Sutskever's
            # NAG equation found in "On the importance of initialization
            # and momentum in deep learning".
            if self.nesterov:
                param[:] = param + self.momentum_coef * velocity -\
                           lrate * grad
            else:
                param[:] = param + velocity

`` `
格差は本当ですか、それとも私は何か重要なものを見逃していますか?

2つの実装の違いは重要ではなく、特にlrが途中で削減された場合は重要です。 私の主張が真実である場合、参照を更新するか(それが何であるかはわかりません)、SGDコードに上記のバージョンを含めることができますか(必要に応じてこれを取り上げることができます)?

medium priority (this tag is deprecated)

最も参考になるコメント

学習率が固定されている場合、2つの定式化は同等です。 ステップサイズが学習率に正比例するため、トーチの定式化が選択されます。 これは、学習率を下げると、ステップサイズがすぐに減少することを意味します。これは、一般的に必要な反復回数の後ではありません。

全てのコメント3件

学習率が固定されている場合、2つの定式化は同等です。 ステップサイズが学習率に正比例するため、トーチの定式化が選択されます。 これは、学習率を下げると、ステップサイズがすぐに減少することを意味します。これは、一般的に必要な反復回数の後ではありません。

同意します。 私の唯一の懸念は、メソッドのリファレンスがSutskeverの論文であり、違いを説明するドキュメントがないことを考えると、現在の実装は、他のフレームワークからPyTorchに移行する人々にとって潜在的な「落とし穴」になる可能性があるということでした。

@keskarnitishドキュメントにメモを追加するPRを送信する場合は、マージできてうれしいです。

このページは役に立ちましたか?
0 / 5 - 0 評価