zoukankan      html  css  js  c++  java
  • 深度学习权重初始化

    深度学习其本质是优化所有权重的值,使其达到一个最优解的状态,这其中,需要更新权重的层包括卷积层、BN层和FC层等。在最优化中,权重的初始化是得到最优解的重要步骤。如果权重初始化不恰当,则可能会导致模型陷入局部最优解,导致模型预测效果不理想,甚至使损失函数震荡,模型不收敛。而且,使用不同的权重初始化方式,模型最终达到的效果也是很不一样的。因此,掌握权重的初始化方式是炼丹师必备的炼丹术之一。在这里,我介绍一下深度学习中,我们常用的几种权重初始化的方式。


    Xavier初始化

    Xavier初始化方法提出于2010年的《Understanding the difficulty of training deep feedforward neural networks》中。Xavier初始化的方式其基本思想是“方差一致性”,即保持激活值的方差一致或者梯度的方差一致,这样有利于优化。基于该基本思想,作者假设每层的输入位于激活函数的线性区域,且具备零点对称的分布。

    • 保持激活值的方差一致

    首先,对于每个卷积层,其响应结果为:

    $$Y_l=W_lX_l+b_l ag{1}$$

    其中,$X_l$是每层的输入参数,其shape为$(k imes k imes c)$,$k$为特征图的尺寸,$c$是通道数;$W_l$是该层的卷积核参数,其shape为$(d imes k imes k imes c)$,$d$表示卷积核的数量;$b_l$是偏差,我们通常让其为0。从公式(1)中,可以得知,$X_l=f(Y_{l-1})$和$c_l=d_{l-1}$,其中$f()$表示激活函数。

    假设每层的$W_l$是相互独立的,且同分布;每层的$X_l$是相互独立的,且同分布;$W_l$和$X_l$是相互独立的。因此,令$b_l=0$,可以得到:

    $$Var[y_l]=n_lVar[w_lx_l]  ag{2}$$

    其中,$y_l$,$w_l$和$x_l$表示$Y_l$,$W_l$和$X_l$的每个随机变量,$n_l=k^2c$表示神经元个数。令$w_l$具有零均值,且关于零点对称分布;$x_l$也具有零均值,且位于激活函数的线性区域,$x_l=f(y_{l-1})=y_{l-1}$,所以:

    egin{align*}
    Var[y_l]&=n_lVar[w_lx_l] \
    &=n_lVar[w_l]Var[x_l] \
    &=n_lVar[w_l]Var[y_{l-1}] ag{3}
    end{align*}

    因此,对于L层的输出,有:

    $Var[y_L]=Var[y_1]left ( prod _{l=2}^L n_lVar[w_l] ight ) ag{4}$

    所以,公式(4)是初始化设计的关键,如果每层的$n_lVar[w_l]$过大或者过小,都会导致最后输出的值会指数型的增加或减少。因此,对于所有层,都需要满足:

    $$n_lVar[w_l]=1 ag{5}$$

    所以,每层权重的初始化服从零均值,方差为$frac{1}{n_l}$的分布。

    • 保持梯度的方差一致

    对于后向梯度传播而言,每个卷积层的的梯度为:

    $$ riangle X_l=hat{W_l} riangle Y_l ag{6}$$

    其中,$ riangle X_l$和$ riangle Y_l$分别表示梯度;$ riangle Y$的shape为$(k imes k imes d)$;$hat{W}$的shape为$(c imes k imes k imes d)$,这里的$hat{W}$和$W$可以变换形状进行转换。同样,这里假设$w_l$和$ riangle y_l$相互独立,$ riangle x_l$具有零均值,$w_l$关于零点对称分布。在公式(6)中,可以得到:

    $$ riangle y_l=f'(y_l) riangle x_{l+1} ag{7}$$

    由于假设位于线性激活区域,$f'(y_l)=1$,所以:

    egin{align*}
    Var[ riangle x_l]&=hat{n_l}Var[hat{w_l} riangle y_l] \
    &=hat{n_l}Var[hat{w_l}]Var[ riangle y_l] \
    &=hat{n_l}Var[hat{w_l}]Var[ riangle x_{l+1}] ag{8}
    end{align*}

    其中,$hat{n_l}=k^2d$,与上述的$n_l=k^2c$不一样,但都表示神经元个数。

    将L层结果堆积起来,得到

    $$Var[ riangle x_2]=Var[ riangle x_{L+1}](prod _{l=2}^Lhat{n_l}Var[w_l]) ag{9}$$

    同样,为了使公式(8)不会过大或者过小(过大或者过小会导致梯度爆炸或者梯度弥散),让每层梯度均满足:

    $$hat{n_l}Var[w_l]=1 ag{10}$$

    所以,每层权重的初始化服从零均值,方差为$frac{1}{hat{n_l}}$的分布。

    上面从激活值的方差和梯度的方差进行了推导,对比公式(5)和公式(10),发现两者存在差异,但使用哪种方式进行权重初始化,都是可以接受的。假设我们使用使用公式(10)进行权重初始化,那么公式(9)中$prod _{l=2}^Lhat{n_l}Var[w_l]=1$,代入公式(4)中,有$prod _{l=2}^Ln_lVar[w_l]=prod _{l=2}^Lfrac{n_l}{hat{n_l}}=frac{c_2}{d_L}$,这样同样不会使输出的值过大或者过小。

    作者为了同时满足公式(5)和公式(10),对两者进行取均值,因此,对所有层,权重初始化需要满足:

    $$Var(w_l)=frac{2}{n_l+hat{n_l}} ag{11}$$

    其中,对于第$l$层而言,$n_l=k^2c$和$hat{n_l}=k^2d$表示第$l$层与第$l-1$层的神经元数量关系,差异是输入通道$c$和输出通道$d$的区别。

    因此,Xavier初始化方式需要服从零均值,方差为$frac{2}{n_l+hat{n_l}}$。在论文中,使用的是均匀分布,零点对称的均匀分布的方差为$frac{a^2}{3}$,因此,Xavier初始化方式服从$Wsim Uleft [-sqrt{frac{6}{n_l+hat{n_l}}},sqrt{frac{6}{n_l+hat{n_l}}}  ight ]$的均匀分布。

    He初始化

    He初始化是由何凯明大神与2015年在《Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification》中提出的。其基本思想和Xavier一致,保持方差的一致性,且推导也是在Xavier初始化方式类似。

    Xavier初始化方式中,其假设激活函数是线性的。但随着深度学习的发展,ReLU已经是常见的激活函数了,其不是线性的,所以Xavier初始化会对ReLU系列的激活函数失效。因此,何凯明在基于激活函数是ReLU的基础上,推导出He初始化方式。

    • 保持激活值的方差一致

    假设$w_l$具有零均值,$w_l$与$x_l$相互独立,所以$Var[w_l]=E[w_l^2]-E^2[w_l]=E[w_l^2]$。而激活函数是ReLU,有$x_l=max(0,y_{l-1})$,所以$x_l$不具备零均值,且$E[x_l^2]=frac{1}{2}Var[y_{l-1}]$。因此,公式(2)可以得到

    egin{align*}
    Var[y_l]&=n_lVar[w_lx_l] \
    &=n_l(E[(w_lx_l)^2]-E^2[w_lx_l]) \
    &=n_l(E[w_l^2]E[x_l^2]-E^2[w_l]E^2[x_l]) \
    &=n_lE[w_l^2]E[x_l^2] \
    &=n_lVar[w_l]E(x_l^2) \
    &=frac{1}{2}n_lVar[w_l]Var[y_{l-1}] ag{12}
    end{align*}

    对比公式(3)和公式(12),可以发现,两者相差了$frac{1}{2}$的系数,这个系数是由ReLU引起的。因此,将L层输出堆积在一起,可以得到

    $$Var[y_L]=Var[y_1]left ( prod _{l=2}^L frac{1}{2} n_lVar[w_l] ight ) ag{13}$$

    因此,对于每一层都需要满足:

    $$frac{1}{2}n_lVar[w_l]=1 ag{14}$$

    所以,每层权重的初始化服从零均值,方差为$frac{2}{n_l}$的分布。

    • 保持梯度的方差一致

    由公式(7)可以得知,对于ReLU而言,$f'(y_l)$等于$0$或者$1$,两者的概率是相同的。而又假设$ riangle x_l$具有零均值,$f'(y_l)$与$ riangle x_{l+1}$是相互独立的,可以得到$E[ riangle y]=frac{E[ riangle x_{l+1}]}{2}=0$和$E[( riangle y)^2]=Var[ riangle y]=frac{1}{2}Var[ riangle x_{l+1}]$。结合这些条件,可以从公式(7)导出:

    egin{align*}
    Var[ riangle x_l]&=hat{n_l}Var[w_l]Var[ riangle y_l] \
    &=hat{n_l}Var[w_l](E[ riangle ^2y_l]-E^2[ riangle y_l]) \
    &=frac{1}{2}hat{n_l}Var[w_l]Var[ riangle x_{l+1}]  ag{15}
    end{align*}

    公式(10)和公式(15)主要的差别也是$frac{1}{2}$的系数,同样是由于ReLU引起的。因此将L层堆积起来,可以得到

    $$Var[ riangle x_2]=Var[ riangle x_{L+1}](prod _{l=2}^Lfrac{1}{2}hat{n_l}Var[w_l])  ag{16}$$

    因此,对于每一层都需要满足:

    $$frac{1}{2}hat{n_l}Var[w_l]=1 ag{17}$$

    所以,每层权重的初始化服从零均值,方差为$frac{2}{hat{n_l}}$的分布。

    同样,使用公式(14)或者公式(17)对网络权重进行初始化都可以,服从零均值、方差为$frac{2}{n_l}$或者$frac{2}{hat{n_l}}$的分布。在论文中,作者选择使用了高斯分布,即服从$Wsim Gleft [0,sqrt{frac{2}{n}}  ight ]$的高斯分布。

    预训练初始化

    在实际中,我们大部分是在已有的网络上进行修改,得到预期结果后,再对网络进行裁剪等操作。而预训练模型是别人已经在特定的数据集(如ImageNet)上进行大量迭代训练的,可以认为是比较好的权重初始化。加载预训练模型进行初始化,能使我们进行更高频率的工程迭代,更快得到结果。而且,通常加载预训练模型会得到较好的结果。

    但是要注意几个问题:

    1. 许多文章指出,当源场景与目标场景差异过大时,加载预训练模型可能不是一种很好的方式,会导致领域失配;
    2. 何凯明在2019年的《Rethinking ImageNet Pre-training》中指出,加载预训练模型并不能使准确率提高,只要迭代步数够多,随机初始化也能产生相同的效果。但实际中,我们无法得知得迭代多少次,模型才饱和;而且迭代步数越多,时间成本也就越大。

    总体来说,如果初始版本的模型存在预训练模型的话,我们可以通过加载预训练模型来进行初始化,快速得到结果;然后再根据需求,对初始版本的网络进行修改。


    综上所示,如果模型存在预训练模型,尽可能使用预训练进行初始化;而对于没有预训练模型或者新加了部分层,可以使用He初始化方式来进行初始化。

    参考材料

    1. https://blog.csdn.net/weixin_35479108/article/details/90694800
    2. https://www.zhihu.com/question/291032522/answer/605843215
  • 相关阅读:
    后台管理导航栏时间提醒代码。
    关于XML(一)。
    MySQL存储过程之细节
    MySQL存储过程之函数及元数据
    MySQL存储过程之安全策略
    MySQL存储过程之游标
    MySQL存储过程之异常处理
    MySQL存储过程之流程控制
    MySQL存储过程之新sql语句--变量
    MySQL存储过程之参数和复合语句
  • 原文地址:https://www.cnblogs.com/dengshunge/p/12380829.html
Copyright © 2011-2022 走看看