Pytorch: Ajouter une note dans la documentation sur la formulation de l'élan utilisée dans optim

Créé le 25 mars 2017  ·  3Commentaires  ·  Source: pytorch/pytorch

J'ai examiné la mise en œuvre de SGD + Momentum dans PyTorch et j'ai remarqué quelque chose d'un peu différent de la façon dont les autres packages (et articles) le décrivent. Pour le moment, concentrons-nous uniquement sur la dynamique (classique) et non sur la version de Nesterov.

Au moment de la rédaction, la mise en œuvre se lit comme suit :

```
si élan != 0 :
param_state = self.state[p]
si 'momentum_buffer' n'est pas dans param_state :
buf = param_state['momentum_buffer'] = d_p.clone()
autre:
buf = param_state['momentum_buffer']
buf.mul_(momentum).add_(1 - amortissement, d_p)
si nesterov :
d_p = d_p.add(momentum, buf)
autre:
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

```
La disparité est-elle vraie ou est-ce que je manque quelque chose d'important ?

La différence entre les deux implémentations n'est pas négligeable et surtout lorsque lr est réduit en cours de route. Si mon affirmation est vraie, nous pourrions peut-être mettre à jour la référence (je ne sais pas ce que ce serait) ou inclure la version ci-dessus dans le code SGD (je peux la reprendre si nécessaire) ?

medium priority (this tag is deprecated)

Commentaire le plus utile

Pour un taux d'apprentissage fixe, les deux formulations sont équivalentes. La formulation Torch est choisie car la taille du pas est directement proportionnelle au taux d'apprentissage. Cela signifie que si vous diminuez le taux d'apprentissage, la taille du pas diminue immédiatement, et non après un certain nombre d'itérations, ce qui est généralement ce que vous voulez.

Tous les 3 commentaires

Pour un taux d'apprentissage fixe, les deux formulations sont équivalentes. La formulation Torch est choisie car la taille du pas est directement proportionnelle au taux d'apprentissage. Cela signifie que si vous diminuez le taux d'apprentissage, la taille du pas diminue immédiatement, et non après un certain nombre d'itérations, ce qui est généralement ce que vous voulez.

Je suis d'accord. Ma seule préoccupation était que, étant donné que la référence de la méthode est l'article de Sutskever et qu'il n'y a pas de documentation pour expliquer la différence, l'implémentation actuelle pourrait être un _"attrape"_ potentiel pour les personnes qui passent à PyTorch à partir d'autres frameworks.

@keskarnitish si vous envoyez un PR en ajoutant une note aux documents, je suis heureux de fusionner.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

bartvm picture bartvm  ·  3Commentaires

bartolsthoorn picture bartolsthoorn  ·  3Commentaires

SeparateReality picture SeparateReality  ·  3Commentaires

rajarshd picture rajarshd  ·  3Commentaires

dablyo picture dablyo  ·  3Commentaires