【CV知识点汇总与解析】| 参数初始化篇
【写在前面】
本系列文章适合Python已经入门、有一定的编程基础的学生或人士,以及人工智能、算法、机器学习求职的学生或人士。系列文章包含了深度学习、机器学习、计算机视觉、特征工程等。相信能够帮助初学者快速入门深度学习,帮助求职者全面了解算法知识点。
1、什么是参数初始化?
初始化参数指的是在网络模型训练之前,对各个节点的权重和偏置进行初始化赋值的过程。
在深度学习中,神经网络的权重初始化方法(weight initialization)对模型的收敛速度和性能有着至关重要的影响。模型的训练,简而言之,就是对权重参数W的不停迭代更新,以期达到更好的性能。而随着网络深度(层数)的增加,训练中极易出现梯度消失或者梯度爆炸等问题。因此,对权重W的初始化显得至关重要,一个好的权重初始化虽然不能完全解决梯度消失或梯度爆炸的问题,但是对于处理这两个问题是有很大帮助的,并且十分有利于提升模型的收敛速度和性能表现。
2、模型参数更新的过程
在总结参数初始化的原则之前,先简单看一下网络模型运行的过程,参数初始化的目的是使网络模型能够更好地进行训练。现在大部分的网络训练依然采用误差的反向传播算法,误差反向传播分为正反两个过程,这里就不再赘述了,先引入几个概念。下面这幅图是一个神经网络的某一个层:
由图可知,每一个层内部的组成主要有:
输入X/hi:来自原始样本X的输入(i=0)或上一层(第i−1层)的输出hi。
权重W:网络模型训练的主体对象,第ii层的权重参数wi。
状态值z:作为每一层激活函数f的输入,处于网络层的内部,所以称之为状态值。
激活值h:状态值zi经过了激活函数f后的输出,也就是第i层的最终输出hi;
数据在网络模型中流动的时候,则会有(这里默认没有偏置项B):
z i = w i ⋅ h i − 1 h i = f ( z i ) \begin{aligned} z^{i} &=w^{i} \cdot h^{i-1} \\ h^{i} &=f\left(z^{i}\right) \end{aligned} zihi=wi⋅hi−1=f(zi)
然后在反向传播的过程中,由于是复合函数的求导,根据链式法则,会有两组导数,一个是损失函数Cost对z的导数,一个是损失函数Cost对W的导数。
3、参数初始化的几个基本条件
什么样的初始化参数才是最好的呢?
需要牢记参数初始化的目的是为了让神经网络在训练过程中学习到有用的信息,这意味着参数梯度不应该为0。而我们知道在全连接的神经网络中,参数梯度和反向传播得到的状态梯度以及入激活值有关——激活值饱和会导致该层状态梯度信息为0,然后导致下面所有层的参数梯度为0;入激活值为0会导致对应参数梯度为0。所以如果要保证参数梯度不等于0,那么参数初始化应该使得各层激活值不会出现饱和现象且激活值不为0。我们把这两个条件总结为参数初始化条件:
-
初始化必要条件一:各层激活值不会出现饱和现象。
-
初始化必要条件二:各层激活值不为0。
4、过大或者过小的初始化的危害
如果权值的初始值过大,则会导致梯度爆炸,使得网络不收敛;过小的权值初始值,则会导致梯度消失,会导致网络收敛缓慢或者收敛到局部极小值。
如果权值的初始值过大,则loss function相对于权值参数的梯度值很大,每次利用梯度下降更新参数的时,参数更新的幅度也会很大,这就导致loss function的值在其最小值附近震荡。
而过小的初值值则相反,loss关于权值参数的梯度很小,每次更新参数时,更新的幅度也很小,着就会导致loss的收敛很缓慢,或者在收敛到最小值前在某个局部的极小值收敛了。
5、常见初始化方法
1.全0初始化
就是将所有权重置0。当然是不能这样的,神经网络通过梯度更新参数,参数都是0,梯度也就是0,神经网络就停止学习了。
2.随机初始化
参数随机化,不过随机参数服从高斯分布或均匀分布,假设网络输入神经元个数为 n i n n_{in} nin,输出神经元个数为 n o u t n_{out} nout,则服从高斯分布的参数随机初始化为:
w = 0.001 ∗ randn ( n in , n out ) w=0.001 * \operatorname{randn}\left(n_{\text {in }}, n_{\text {out }}\right) w=0.001∗randn(nin ,nout )
其中高斯分布均值为0,方差为1。0.001为控制因子,这样使得参数期望尽量接近0。
3.Xavier
初始化方法由Bengio等人在2010年的论文《Understanding the difficulty of training deep feedforward neural networks》中提出。
它为了保证前向传播和反向传播时每一层的方差一致:在正向传播时,每层的激活值的方差保持不变;在反向传播时,每层的梯度值的方差保持不变。根据每层的输入个数和输出个数来决定参数随机初始化的分布范围,是一个通过该层的输入和输出参数个数得到的分布范围内的均匀分布。
4.He初始化
与Xavier方法一样,He初始化方法也希望初始化使得正向传播时,状态值的方差保持不变;反向传播时,关于激活值的梯度的方差保持不变。
其初始化方法为:
W ∼ N ( 0 , 2 n 1 ) \mathrm{W} \sim \mathrm{N}\left(0, \sqrt{\frac{2}{\mathrm{n}_{1}}}\right) W∼N(0,n12)
其中, n 1 \mathrm{n}_{1} n1为第 l 层神经元个数。
6、梯度消失的根本原因
我们神经网络中的初始权值也一般是小于 1 的数,所以相当于公式中是多个小于 1 的数在不断的相乘,导致乘积和还很小。这只是有两层的时候,如果层数不断增多,乘积和会越来越趋近于 0,以至于当层数过多的时候,最底层的梯度会趋近于 0,无法进行更新,并且 Sigmoid 函数也会因为初始权值过小而趋近于 0,导致斜率趋近于 0,也导致了无法更新。
7、怎么缓解梯度消失?
-
预训练加微调
-
梯度剪切
-
使用合理的参数初始化方案,如He初始化
-
使用 ReLU、LReLU、ELU、maxout 等激活函数
sigmoid函数的梯度随着x的增大或减小和消失,而ReLU不会。
-
使用批规范化BN
-
残差结构
【项目推荐】
面向小白的顶会论文核心代码库:https://github.com/xmu-xiaoma666/External-Attention-pytorch
面向小白的YOLO目标检测库:https://github.com/iscyy/yoloair
面向小白的顶刊顶会的论文解析:https://github.com/xmu-xiaoma666/FightingCV-Paper-Reading