рдореИрдВ PyTorch рдореЗрдВ SGD + Momentum рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рджреЗрдЦ рд░рд╣рд╛ рдерд╛ рдФрд░ рдЕрдиреНрдп рдкреИрдХреЗрдЬреЛрдВ (рдФрд░ рдХрд╛рдЧрдЬрд╛рдд) рджреНрд╡рд╛рд░рд╛ рдЗрд╕рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рд╕реЗ рдХреБрдЫ рдЕрд▓рдЧ рджреЗрдЦрд╛ред рдлрд┐рд▓рд╣рд╛рд▓, рдЖрдЗрдП рдХреЗрд╡рд▓ (рд╢рд╛рд╕реНрддреНрд░реАрдп) рдЧрддрд┐ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ, рди рдХрд┐ рдиреЗрд╕реНрдЯрд░реЛрд╡ рдХреЗ рд╕рдВрд╕реНрдХрд░рдг рдкрд░ред
рд▓реЗрдЦрди рдХреЗ рд╕рдордп, рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрдврд╝рддрд╛ рд╣реИ:
```
рдпрджрд┐ рд╕рдВрд╡реЗрдЧ != 0:
рдкрд░рдо_рд░рд╛рдЬреНрдп = рд╕реНрд╡рд░рд╛рдЬреНрдп [рдкреА]
рдЕрдЧрд░ 'рдореЛрдореЗрдВрдЯрдо_рдмрдлрд░' param_state рдореЗрдВ рдирд╣реАрдВ рд╣реИ:
buf = param_state ['рдореЛрдореЗрдВрдЯрдо_рдмрдлрд╝рд░'] = d_p.clone ()
рдЕрдиреНрдпрдерд╛:
рдмрдл = рдкрд░рдо_рд╕реНрдЯреЗрдЯ ['рдореЛрдореЗрдВрдЯрдо_рдмрдлрд░']
buf.mul_(рдЧрддрд┐)ред рдЬреЛрдбрд╝реЗрдВ_(1 - рднреАрдЧрдирд╛, d_p)
рдЕрдЧрд░ рдиреЗрд╕реНрдЯрд░реЛрд╡:
d_p = d_p.add (рдЧрддрд┐, buf)
рдЕрдиреНрдпрдерд╛:
d_p = рдмрдл
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
```
рдХреНрдпрд╛ рдЕрд╕рдорд╛рдирддрд╛ рд╕рдЪ рд╣реИ рдпрд╛ рдХреНрдпрд╛ рдореБрдЭреЗ рдХреБрдЫ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдпрд╛рдж рдЖ рд░рд╣рд╛ рд╣реИ?
рджреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдиреЛрдВ рдХреЗ рдмреАрдЪ рдХрд╛ рдЕрдВрддрд░ рдорд╣рддреНрд╡рд╣реАрди рдирд╣реАрдВ рд╣реИ рдФрд░ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рддрдм рдЬрдм lr
рд░рд╛рд╕реНрддреЗ рдореЗрдВ рдХрдо рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдЕрдЧрд░ рдореЗрд░рд╛ рджрд╛рд╡рд╛ рд╕рд╣реА рд╣реИ, рддреЛ рд╢рд╛рдпрдж рд╣рдо рд╕рдВрджрд░реНрдн рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╡рд╣ рдХреНрдпрд╛ рд╣реЛрдЧрд╛) рдпрд╛ рдЙрдкрд░реЛрдХреНрдд рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдПрд╕рдЬреАрдбреА рдХреЛрдб рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рддреЛ рдореИрдВ рдЗрд╕реЗ рд▓реЗ рд╕рдХрддрд╛ рд╣реВрдВ)?
рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕реАрдЦрдиреЗ рдХреА рджрд░ рдХреЗ рд▓рд┐рдП, рджреЛ рд╕реВрддреНрд░ рд╕рдорд╛рди рд╣реИрдВред рдорд╢рд╛рд▓ рд╕реВрддреНрд░реАрдХрд░рдг рдЪреБрдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЪрд░рдг рдХрд╛ рдЖрдХрд╛рд░ рд╕реАрдЦрдиреЗ рдХреА рджрд░ рдХреЗ рд╕реАрдзреЗ рдЖрдиреБрдкрд╛рддрд┐рдХ рд╣реЛрддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдк рд╕реАрдЦрдиреЗ рдХреА рджрд░ рдХреЛ рдХрдо рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЪрд░рдг рдХрд╛ рдЖрдХрд╛рд░ рддреБрд░рдВрдд рдХрдо рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рди рдХрд┐ рдХреБрдЫ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреЗ рдмрд╛рдж, рдЬреЛ рдЖрдорддреМрд░ рдкрд░ рдЖрдк рдЪрд╛рд╣рддреЗ рд╣реИрдВред
рдореИрдВ рд╕рд╣рдордд рд╣реВрдБред рдореЗрд░реА рдПрдХрдорд╛рддреНрд░ рдЪрд┐рдВрддрд╛ рдпрд╣ рдереА рдХрд┐, рдпрд╣ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рд╕рдВрджрд░реНрдн рд╕рдЯрд╕реНрдХреЗрд╡рд░ рдкреЗрдкрд░ рд╣реИ рдФрд░ рдЕрдВрддрд░ рдХреЛ рд╕рдордЭрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рджрд╕реНрддрд╛рд╡реЗрдЬ рдирд╣реАрдВ рд╣реИ, рд╡рд░реНрддрдорд╛рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЕрдиреНрдп рдврд╛рдВрдЪреЗ рд╕реЗ PyTorch рдореЗрдВ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдВрднрд╛рд╡рд┐рдд _"рдЧреЛрдЪрд╛"_ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред
@keskarnitish рдпрджрд┐ рдЖрдк рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдореЗрдВ рдПрдХ рдиреЛрдЯ рдЬреЛрдбрд╝рдХрд░ рдкреАрдЖрд░ рднреЗрдЬрддреЗ рд╣реИрдВ, рддреЛ рдореБрдЭреЗ рд╡рд┐рд▓рдп рдХрд░рдиреЗ рдореЗрдВ рдЦреБрд╢реА рд╣реЛрддреА рд╣реИред
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕реАрдЦрдиреЗ рдХреА рджрд░ рдХреЗ рд▓рд┐рдП, рджреЛ рд╕реВрддреНрд░ рд╕рдорд╛рди рд╣реИрдВред рдорд╢рд╛рд▓ рд╕реВрддреНрд░реАрдХрд░рдг рдЪреБрдирд╛ рдЬрд╛рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЪрд░рдг рдХрд╛ рдЖрдХрд╛рд░ рд╕реАрдЦрдиреЗ рдХреА рджрд░ рдХреЗ рд╕реАрдзреЗ рдЖрдиреБрдкрд╛рддрд┐рдХ рд╣реЛрддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдк рд╕реАрдЦрдиреЗ рдХреА рджрд░ рдХреЛ рдХрдо рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЪрд░рдг рдХрд╛ рдЖрдХрд╛рд░ рддреБрд░рдВрдд рдХрдо рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рди рдХрд┐ рдХреБрдЫ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреЗ рдмрд╛рдж, рдЬреЛ рдЖрдорддреМрд░ рдкрд░ рдЖрдк рдЪрд╛рд╣рддреЗ рд╣реИрдВред