Pytorch: Fügen Sie in der Dokumentation einen Hinweis zur Impulsformulierung hinzu, die in optim . verwendet wird

Erstellt am 25. März 2017  ·  3Kommentare  ·  Quelle: pytorch/pytorch

Ich habe mir die Implementierung von SGD + Momentum in PyTorch angesehen und etwas anderes festgestellt als in anderen Paketen (und Papieren) beschrieben. Konzentrieren wir uns im Moment ausschließlich auf das (klassische) Momentum und nicht auf Nesterovs Version.

Zum Zeitpunkt des Schreibens lautet die Implementierung:

```
wenn Impuls != 0:
param_state = self.state[p]
if 'momentum_buffer' nicht in param_state:
buf = param_state['momentum_buffer'] = d_p.clone()
anders:
buf = param_state['momentum_buffer']
buf.mul_(Momentum).add_(1 - Dämpfung, d_p)
wenn nesterov:
d_p = d_p.add(Impuls, buf)
anders:
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

```
Stimmt der Unterschied oder übersehe ich etwas Wichtiges?

Der Unterschied zwischen den beiden Implementierungen ist nicht unerheblich, insbesondere wenn lr auf dem Weg reduziert wird. Wenn meine Behauptung wahr ist, könnten wir vielleicht die Referenz aktualisieren (ich bin mir nicht sicher, was das wäre) oder die obige Version in den SGD-Code aufnehmen (ich kann dies bei Bedarf aufnehmen)?

medium priority (this tag is deprecated)

Hilfreichster Kommentar

Für eine feste Lernrate sind die beiden Formulierungen äquivalent. Die Fackelformulierung wird gewählt, weil die Schrittweite direkt proportional zur Lernrate ist. Dies bedeutet, dass die Schrittgröße sofort abnimmt, wenn Sie die Lernrate verringern, und nicht nach einer bestimmten Anzahl von Iterationen, was im Allgemeinen gewünscht ist.

Alle 3 Kommentare

Für eine feste Lernrate sind die beiden Formulierungen äquivalent. Die Fackelformulierung wird gewählt, weil die Schrittweite direkt proportional zur Lernrate ist. Dies bedeutet, dass die Schrittgröße sofort abnimmt, wenn Sie die Lernrate verringern, und nicht nach einer bestimmten Anzahl von Iterationen, was im Allgemeinen gewünscht ist.

Ich stimme zu. Meine einzige Sorge war, dass die aktuelle Implementierung angesichts der Tatsache, dass die Referenz für die Methode das Sutskever-Papier ist und es keine Dokumentation gibt, um den Unterschied zu erklären, ein potenzielles _"Gotcha"_ für Leute sein könnte, die von anderen Frameworks zu PyTorch wechseln.

@keskarnitish Wenn Sie eine PR mit einer Notiz zu den Dokumenten senden,

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

szagoruyko picture szagoruyko  ·  3Kommentare

eliabruni picture eliabruni  ·  3Kommentare

SeparateReality picture SeparateReality  ·  3Kommentare

ikostrikov picture ikostrikov  ·  3Kommentare

miguelvr picture miguelvr  ·  3Kommentare