美文网首页
PyTorch中"诡异"的动量SGD实现

PyTorch中"诡异"的动量SGD实现

作者: Yanring_ | 来源:发表于2019-04-30 19:55 被阅读0次

    pytorch中SGD的动量实现是如下这个样子的

                if momentum != 0:
                       param_state = self.state[p]
                       if 'momentum_buffer' not in param_state:
                           buf = param_state['momentum_buffer'] = d_p.clone()
                       else:
                           buf = param_state['momentum_buffer']
                           buf.mul_(momentum).add_(1 - dampening, d_p)
                       if nesterov:
                           d_p = d_p.add(momentum, buf)
                       else:
                           d_p = buf
    
                   p.data.add_(-group['lr'], d_p)
    

    将pytorch的实现翻译为公式,就是如下这个样子:
    \begin{aligned} v_{t+1} &= \mu v_{t}- \nabla f\left(\theta_{t}\right) \\ \theta_{t+1} &=\theta_{t}+\varepsilon v_{t+1} \end{aligned}
    为什么说它诡异呢?因为它与Polyak, Sutskever等人的论文中的表达方式是不同的:
    \begin{aligned} v_{t+1} &=\mu v_{t}-\varepsilon \nabla f\left(\theta_{t}\right) \\ \theta_{t+1} &=\theta_{t}+v_{t+1} \end{aligned}
    \varepsilon是学习率,\mu是动量因子。

    对一下,其实就是\varepsilon换了个位置,从传统的\nabla f\left(\theta_{t}\right)换到了v_{t+1}。 但是其实通过展开,可以发现,在学习率保持不变的的情况下,这两种实现方式是等价的。而在学习率变化的情况下,直观的来说,前一种方法学习率会立马作用在动量上:
    \varepsilon v_{t+1}
    使得学习率的更改立马产生效果,而使用原始的方法往往要好几个batch之后学习率才生效(因为动量太大了)。
    因此,一般来说使用pytorch采用的实现方法会适用一些。
    [1]https://zhuanlan.zhihu.com/p/43016574
    [2]https://github.com/pytorch/pytorch/issues/1099

    相关文章

      网友评论

          本文标题:PyTorch中"诡异"的动量SGD实现

          本文链接:https://www.haomeiwen.com/subject/xscbnqtx.html