zoukankan      html  css  js  c++  java
  • 比较Adam 和Adamw

    引用自: https://www.lizenghai.com/archives/64931.html

    AdamW

    AdamW是在Adam+L2正则化的基础上进行改进的算法。
    使用Adam优化带L2正则的损失并不有效。如果引入L2正则项,在计算梯度的时候会加上对正则项求梯度的结果。

    那么如果本身比较大的一些权重对应的梯度也会比较大,由于Adam计算步骤中减去项会有除以梯度平方的累积,使得减去项偏小。按常理说,越大的权重应该惩罚越大,但是在Adam并不是这样。

    而权重衰减对所有的权重都是采用相同的系数进行更新,越大的权重显然惩罚越大。

    在常见的深度学习库中只提供了L2正则,并没有提供权重衰减的实现。


    Adam+L2 VS AdamW

    图片中红色是传统的Adam+L2 regularization的方式,绿色是Adam+weightdecay的方式。可以看出两个方法的区别仅在于“系数乘以上一步参数值“这一项的位置。

    再结合代码来看一下AdamW的具体实现。

    以下代码来自https://github.com/macanv/BERT-BiLSTM-CRF-NER/blob/master/bert_base/bert/optimization.py中的AdamWeightDecayOptimizer中的apply_gradients函数中,BERT中的优化器就是使用这个方法。

    在代码中也做了一些注释用于对应之前给出的Adam简化版公式,方便理解。可以看出update += self.weight_decay_rate * param这一句是Adam中没有的,也就是Adam中绿色的部分对应的代码,weightdecay这一步是是发生在Adam中需要被更新的参数update计算之后,并且在乘以学习率learning_rate之前,这和图片中的伪代码的计算顺序是完全一致的。总之一句话,如果使用了weightdecay就不必再使用L2正则化了。

       # m = beta1*m + (1-beta1)*dx
          next_m = (tf.multiply(self.beta_1, m) + tf.multiply(1.0 - self.beta_1, grad))
          # v = beta2*v + (1-beta2)*(dx**2)
          next_v = (tf.multiply(self.beta_2, v) + tf.multiply(1.0 - self.beta_2, tf.square(grad)))
          # m / (np.sqrt(v) + eps)
          update = next_m / (tf.sqrt(next_v) + self.epsilon)
          # Just adding the square of the weights to the loss function is *not*
          # the correct way of using L2 regularization/weight decay with Adam,
          # since that will interact with the m and v parameters in strange ways.
          #
          # Instead we want ot decay the weights in a manner that doesn't interact
          # with the m/v parameters. This is equivalent to adding the square
          # of the weights to the loss with plain (non-momentum) SGD.
          if self._do_use_weight_decay(param_name):
            update += self.weight_decay_rate * param
          update_with_lr = self.learning_rate * update
          # x += - learning_rate * m / (np.sqrt(v) + eps)
          next_param = param - update_with_lr
    

    原有的英文注释中也解释了Adam和传统Adam+L2正则化的差异,好了到这里应该能理解Adam了,并且也能理解AdamW在Adam上的改进了。

  • 相关阅读:
    操作datetable 里面查出来的某个字段
    C# 字符串去重 还有 去除最后一位逗号。
    C# .net 调用ERP接口
    视图下拉列表接收控制器传来的值,并选中下拉类表中该值相对应的选项(新手笔记,请各位大神指教)
    MVC5控制器传值的三种方式(ViewData,ViewBag,TempData),刚刚学习MVC5的新手,希望各位大神多多指教
    c++模板之SFINAE
    c++头文件包含问题
    成员函数指针有多态的效果吗?
    emacs基本操作
    在c++中用function与bind实现委托
  • 原文地址:https://www.cnblogs.com/tfknight/p/13425532.html
Copyright © 2011-2022 走看看