为啥要合适的初始化
- 【不放大缩小,方差稳定性】过大或者过小的初始化:过大,梯度爆炸,使得网络不收敛,参数更新的幅度也会很大,这就导致loss function的值在其最小值附近震荡;过小,梯度消失,更新的幅度也很小,着就会导致loss的收敛很缓慢,或者在收敛到最小值前在某个局部的极小值收敛了
- 【破坏对称性(差异性)】《速通》里面认为:初始化如果没有差异,那么梯度过程和结果也没有差异,冗余(多通道只是一个通道,多头attention只是一头,FC只是一个神经元),因此要破坏"对称性"(《花书》(&8.4,P184)也有提及)
- 【权重不宜全大于0;小于0】在特殊场景下,输入 x x x 有特殊性,比如x表示价格,此时 x > 0 x\gt0 x>0 ,如果参数全部大于0,则通过relu,均大于0,起不到非线性作用
首先说一下主体思路
常量
略
随机
略
Xavier初始化(Glorot初始化)
Xavier初始化,由Xavier Glorot 在2010年的论文 Understanding the difficulty of training deep feedforward neural networks提出
推导过程中的三个假设:
- 权值矩阵w是独立同分布的,且其均值为0
- 每一层的输入a是独立同分布的,且均值也为0
- w和a是相互独立的
对于权值的初始化,Glorot提出两个准则:
- 各个层激活值的方差保持不变(正向传播)
- 各个层的梯度值的方差保持不变(反向传播)
Glorot初始化推导过程是基于tanh激活函数(或softsign)的,所以这里隐含了两个条件:
- 激活函数关于0对称。
- 激活函数在0值处梯度为1。
基本结论:
- 均匀分布 W ∼ U [ − 3 F ′ , + 3 F ′ ] W \sim U\left[-\sqrt{\frac{3}{F'}}, + \sqrt{\frac{3}{F'}}\right] W∼U[−F′3,+F′3]
- 正态分布 W ∼ N ( 0 , 1 F ′ ) W \sim N(0,\sqrt{\frac{1}{F'}}) W∼N(0,F′1)
-
F
′
F'
F′的选取,论文推导时采用均值:
F ′ = F i n + F o u t 2 F'= {\frac{F_{in} +F_{out}}2} F′=2Fin+Fout
这里说明一下:
- 每个Xavier初始化有两个分布:均匀,正态,但他们的均值方差一致。
- 严格意义上来说,Xavier初始化和激活无关(但是有很强的假设条件)。
- 以上结论,有很强的条件,严格上只有tanh(或softsign)符合
- Xavier初始化的推导过程中,不考虑正向和反向的差异,所以在论文中采用 F ′ = F i n + F o u t 2 F'={\frac{F_{in} +F_{out}}2} F′=2Fin+Fout,其实原论文中, F i n F_{in} Fin是正向推导使用的, F o u t F_{out} Fout是反向推导使用的,论文中做了平均,可以参见论文内公式(8)~(12).
- tensorflow实现了以上结论,不加修正(不考虑激活函数的假设问题)。参考:tensorflow源码
- pytorch加了修正,但我不完全理解这个修正
- 修正策略:以sigmoid为基准,实现 U ( − a , a ) , a = gain × 6 fan_in + fan_out \mathcal{U}(-a, a),a = \text{gain} \times \sqrt{\frac{6}{\text{fan\_in} + \text{fan\_out}}} U(−a,a),a=gain×fan_in+fan_out6和 N ( 0 , σ 2 ) , σ = gain × 2 fan_in + fan_out \mathcal{N}(0, \sigma^2),\sigma = \text{gain} \times \sqrt{\frac{2}{\text{fan\_in} + \text{fan\_out}}} N(0,σ2),σ=gain×fan_in+fan_out2),其中gain在下图所示。参考:pytorch源码
- 我不理解之处是:应该以tanh为基准,构建gain,但是是以sigmoid为基准
- 但是我贴出一个链接,这是pytorch的讨论《
Calculate_gain(‘tanh’)》,里面满满的实验试一下的味道,实验的理论是正向传播的方差不变性.
nonlinearity | gain |
---|---|
Linear / Identity | 1 1 1 |
Conv{1,2,3}D | 1 1 1 |
Sigmoid | 1 1 1 |
Tanh | 5 3 \frac{5}{3} 35 |
ReLU | 2 \sqrt{2} 2 |
Leaky Relu | 2 1 + negative_slope 2 \sqrt{\frac{2}{1 + \text{negative\_slope}^2}} 1+negative_slope22 |
SELU | 3 4 \frac{3}{4} 43 |
有些文章,特别关注各个层激活值的梯度的方差保持不变(反向传播)(《速通》(&9.2,P137)沿用了这个思路),比如考虑sigmoid在0处的梯度是tanh的0.25倍,所以使用96参数,而不是6。但是F的选取仍然是采用均值。比如如下文章:Xavier Initialization以及其中文csdn-blog [ 注 ∗ ] [注^*] [注∗],理论性和效果存疑。
激活函数 | U ( − a , a ) \mathcal{U}(-a, a) U(−a,a) | N ( 0 , σ 2 ) \mathcal{N}(0, \sigma^2) N(0,σ2) |
---|---|---|
Sigmoid | a = 96 fan_in + fan_out a = \sqrt{\frac{96}{\text{fan\_in} + \text{fan\_out}}} a=fan_in+fan_out96 | σ = 32 fan_in + fan_out \sigma = \sqrt{\frac{32}{\text{fan\_in} + \text{fan\_out}}} σ=fan_in+fan_out32 |
Tanh | a = 6 fan_in + fan_out a = \sqrt{\frac{6}{\text{fan\_in} + \text{fan\_out}}} a=fan_in+fan_out6 | σ = 2 fan_in + fan_out \sigma = \sqrt{\frac{2}{\text{fan\_in} + \text{fan\_out}}} σ=fan_in+fan_out2 |
ReLU【类似he初始化】 | a = 12 fan_in + fan_out a = \sqrt{\frac{12}{\text{fan\_in} + \text{fan\_out}}} a=fan_in+fan_out12 |
σ
=
4
fan_in
+
fan_out
\sigma = \sqrt{\frac{4}{\text{fan\_in} + \text{fan\_out}}}
σ=fan_in+fan_out4
[
注
∗
]
[注^*]
[注∗] |
[ 注 ∗ ] [注^*] [注∗]:这俩博客的relu部分的公式有问题,不满足每行俩的方差一致,上表已经修正
He初始化
He初始化,2015年何凯明的论文 Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification提出
你可以这么简单理解HE:就是在relu函数下,并不满足关于0对称,以及0点处的导数为1,所以按照Xavier的思路重新推导了
基本结论:
- 均匀分布 W ∼ U [ − 6 F ′ , + 6 F ′ ] W \sim U\left[-\sqrt{\frac{6}{F'}}, + \sqrt{\frac{6}{F'}}\right] W∼U[−F′6,+F′6]
- 正态分布 W ∼ N ( 0 , 2 F ′ ) W \sim N(0,\sqrt{\frac{2}{F'}}) W∼N(0,F′2)
-
F
′
F'
F′的选取,我们以pytorch为例,即:
F ′ = { F i n (default) , preserves the magnitude of the variance of the weights in the forward pass F o u t , preserves the magnitudes in the backwards pass F'= \begin{cases} F_{in} \text{ (default)} &,\text{preserves the magnitude of the variance of the weights in the forward pass} \\ F_{out} &,\text{preserves the magnitudes in the backwards pass} \end{cases} F′={Fin (default)Fout,preserves the magnitude of the variance of the weights in the forward pass,preserves the magnitudes in the backwards pass
在这里要说明一下
- Xavier初始化,不考虑激活函数的差异(部分框架实现可能有修正),也不考虑正向和反向的差异,所以在xavier的论文中统一采用 F ′ = F i n + F o u t 2 F'= {\frac{F_{in} +F_{out}}2} F′=2Fin+Fout
- 在He初始化中,激活函数差异肯定被考虑到了.
- 在He初始化中,正向和反向的差异,论文中是说两种策略,通过 F ′ F' F′的选取去实现,用户可以选择。参见he论文的公式(10)和(14)
- tensorflow实现了以上部分结论,严格限定为fan_in。参考:tensorflow源码
- pytorch加了参数,可以选择使用fan_in或fan_out。参考:pytorch源码
BN
其实有了BN,对于初始化,我们只要关注有差异,就OK了,大大降低了权重初始化的门槛。后面会写一个BN&LN详细讲。
Pre-Train
那说啥,你懂的~