【问题标题】:Adam optimizer with warmup on PyTorch在 PyTorch 上进行预热的 Adam 优化器
【发布时间】:2021-03-28 07:13:51
【问题描述】:

在论文Attention is all you need 的第 5.3 节中,作者建议线性增加学习率,然后与步长的平方根成反比。

我们如何在 PyTorch 中使用 Adam 优化器实现这一点?最好不要额外的包。

【问题讨论】:

  • 只需要使用 Adadelta。根据我的经验,到目前为止,它的最终性能比 Adam 更好

标签: python machine-learning pytorch


【解决方案1】:

PyTorch 提供了learning-rate-scheduler,用于在训练过程中实现各种调整学习率的方法。 一些简单的 LR 调度器已经实现,可以在这里找到:https://pytorch.org/docs/stable/optim.html#how-to-adjust-learning-rate

在您的特殊情况下,您可以 - 就像其他 LR 调度程序一样 - 子类 _LRScheduler 以实现基于时期数的可变调度。对于基本方法,您只需要实现 __init__()get_lr() 方法。

请注意,这些调度程序中的许多都希望您在每个 epoch 调用一次 .step()。但您也可以更频繁地更新它,甚至传递自定义参数,就像在余弦退火 LR 调度器中一样:https://pytorch.org/docs/stable/_modules/torch/optim/lr_scheduler.html#CosineAnnealingLR

【讨论】:

    【解决方案2】:
    class NoamOpt:
    "Optim wrapper that implements rate."
    def __init__(self, model_size, factor, warmup, optimizer):
        self.optimizer = optimizer
        self._step = 0
        self.warmup = warmup
        self.factor = factor
        self.model_size = model_size
        self._rate = 0
        
    def step(self):
        "Update parameters and rate"
        self._step += 1
        rate = self.rate()
        for p in self.optimizer.param_groups:
            p['lr'] = rate
        self._rate = rate
        self.optimizer.step()
        
    def rate(self, step = None):
        "Implement `lrate` above"
        if step is None:
            step = self._step
        return self.factor * \
            (self.model_size ** (-0.5) *
            min(step ** (-0.5), step * self.warmup ** (-1.5)))
        
    def get_std_opt(model):
        return NoamOpt(model.src_embed[0].d_model, 2, 4000,torch.optim.Adam(model.parameters(), lr=0, betas=(0.9, 0.98), eps=1e-9))
    

    如:https://nlp.seas.harvard.edu/2018/04/03/attention.html#optimizer

    【讨论】:

      【解决方案3】:

      正如上一条评论所建议的,我们可以使用https://nlp.seas.harvard.edu/2018/04/03/attention.html#optimizer 引入的类。但是这个答案会报错,除非我们定义一个函数来更新 state_dict。

      这是完整的调度程序:

      class NoamOpt:
          "Optim wrapper that implements rate."
          def __init__(self, model_size, warmup, optimizer):
              self.optimizer = optimizer
              self._step = 0
              self.warmup = warmup
              self.model_size = model_size
              self._rate = 0
          
          def state_dict(self):
              """Returns the state of the warmup scheduler as a :class:`dict`.
              It contains an entry for every variable in self.__dict__ which
              is not the optimizer.
              """
              return {key: value for key, value in self.__dict__.items() if key != 'optimizer'}
          
          def load_state_dict(self, state_dict):
              """Loads the warmup scheduler's state.
              Arguments:
                  state_dict (dict): warmup scheduler state. Should be an object returned
                      from a call to :meth:`state_dict`.
              """
              self.__dict__.update(state_dict) 
              
          def step(self):
              "Update parameters and rate"
              self._step += 1
              rate = self.rate()
              for p in self.optimizer.param_groups:
                  p['lr'] = rate
              self._rate = rate
              self.optimizer.step()
              
          def rate(self, step = None):
              "Implement `lrate` above"
              if step is None:
                  step = self._step
              return (self.model_size ** (-0.5) *
                  min(step ** (-0.5), step * self.warmup ** (-1.5))) 
      

      稍后,在训练循环中使用它:

      optimizer = NoamOpt(input_opts['d_model'], 500,
                  torch.optim.Adam(model.parameters(), lr=0, betas=(0.9, 0.98), eps=1e-9))
      

      。 . .

      optimizer.step()
      

      【讨论】:

        猜你喜欢
        • 2019-05-07
        • 1970-01-01
        • 2018-10-02
        • 1970-01-01
        • 2017-10-14
        • 1970-01-01
        • 2016-02-20
        • 2018-06-04
        • 1970-01-01
        相关资源
        最近更新 更多