神经网络的参数学习是一个非凸优化问题.当使用梯度下降法来进行优化网络参数时,参数初始值的选取十分关键,关系到网络的优化效率和泛化能力。参数初始化的方式通常有以下三种:
-
预训练初始化:不同的参数初始值会收敛到不同的局部最优解。虽然这些局部最优解在训练集上的损失比较接近,但是它们的泛化能力差异很大。一个好的初始值会使得网络收敛到一个泛化能力高的局部最优解。通常情况下,一个已经在大规模数据上训练过的模型可以提供一个好的参数初始值,这种初始化方法称为预训练初始化。
预训练任务可以为监督学习或无监督学习任务.由于无监督学习任务更容易获取大规模的训练数据,因此被广泛采用。预训练模型在目标任务上的学习过程也称为精调。
-
随机初始化:在线性模型的训练(比如感知器和Logistic 回归)中,我们一般将参数全部初始化为 0 0 0。但是这在神经网络的训练中会存在一些问题。因为如果参数都为0,在第一遍前向计算时,所有的隐藏层神经元的激活值都相同;在反向传播时,所有权重的更新也都相同,这样会导致隐藏层神经元没有区分性.这种现象也称为对称权重现象。为了打破这个平衡,比较好的方式是对每个参数都随机初始化,使得不同神经元之间的区分性更好。
-
固定值初始化:对于一些特殊的参数,我们可以根据经验用一个特殊的固定值来进行初始化。比如偏置(Bias)通常用 0 0 0 来初始化,但是有时可以设置某些经验值以提高优化效率。在LSTM网络的遗忘门中,偏置通常初始化为 1 1 1或 2 2 2,使得时序上的梯度变大。对于使用 R e L U ReLU ReLU 的神经元,有时也可以将偏置设为 0.01 0.01 0.01,使得 R e L U ReLU ReLU 神经元在训练初期更容易激活,从而获得一定的梯度来进行误差反向传播。
虽然预训练初始化通常具有更好的收敛性和泛化性,但是灵活性不够,不能在目标任务上任意地调整网络结构。因此,好的随机初始化方法对训练神经网络模型来说依然十分重要。随机初始化通常只应用在神经网络的权重矩阵上。
这里我们介绍三类常用的随机初始化方法:基于固定方差的参数初始化、基于方差缩放的参数初始化和正交初始化方法。
1. 基于固定方差的参数初始化
该方法中“固定”的含义是方差 σ 2 \sigma^2 σ2 为一个预设值,和神经元的输入、激活函数以及所在层数无关。一种最简单的随机初始化方法是从一个固定均值(通常为0)和方差 σ 2 \sigma^2 σ2 的分布中采样来生成参数的初始值。基于固定方差的参数初始化方法主要有以下两种:
-
高斯分布初始化:使用一个高斯分布 N ( 0 , σ 2 ) N(0, \sigma^2) N(0,σ2) 对每个参数进行随机初始化。
该方法在pytorch中的实现方法为
torch.nn.init.normal(tensor, mean=0, std=1)
其中参数
mean
为正态分布的均值,默认为 0 0 0,参数std
为正态分布的标准差,默认为 1 1 1。 -
均匀分布初始化:在一个给定的区间 [ − 𝑟 , 𝑟 ] [−𝑟, 𝑟] [−r,r] 内采用均匀分布来初始化参数。假设随机变量 𝑥 𝑥 x 在区间 [ 𝑎 , 𝑏 ] [𝑎, 𝑏] [a,b] 内均匀分布,则其方差为
v a r ( x ) = ( a − b ) 2 12 var(x)=\frac{(a-b)^2}{12} var(x)=12(a−b)2因此,若使用区间为 [ − 𝑟 , 𝑟 ] [−𝑟, 𝑟] [−r,r] 的均匀分布来采样,并满足 v a r ( 𝑥 ) = σ 2 var(𝑥) = \sigma^2 var(x)=σ2 时,则 𝑟 𝑟 r 的取值为
r = 3 σ 2 r=\sqrt{3\sigma^2} r=3σ2为了降低固定方差对网络性能以及优化效率的影响,基于固定方差的随机初始化方法一般需要配合逐层归一化来使用。该方法在pytorch中的实现方法为
torch.nn.init.uniform(tensor, a=0, b=1)
其中参数
a
为均匀分布的下界,参数b
为参数分布的上界。
2. 基于方差缩放的参数初始化
要高效地训练神经网络,给参数选取一个合适的随机初始化区间是非常重要的。一般而言,参数初始化的区间应该根据神经元的性质进行差异化的设置。如果一个神经元的输入连接很多,它的每个输入连接上的权重就应该小一些,以避免神经元的输出过大(当激活函数为 R e L U ReLU ReLU 时)或过饱和(当激活函数为 S i g m o i d Sigmoid Sigmoid 函数时)。
初始化一个深度网络时,为了缓解梯度消失或爆炸问题,我们尽可能保持每个神经元的输入和输出的方差一致,根据神经元的连接数量来自适应地调整初始化分布的方差,这类方法称为方差缩放。
2.1 Xavier 初始化
假设在一个神经网络中,第
𝑙
𝑙
l 层的一个神经元
𝑎
(
𝑙
)
𝑎^{(𝑙)}
a(l),其接收前一层的
𝑀
𝑙
−
1
𝑀_{𝑙−1}
Ml−1 个
神经元的输出
a
i
(
𝑙
−
1
)
a^{(𝑙−1)}_i
ai(l−1),且
1
≤
𝑖
≤
𝑀
𝑙
−
1
1 \le 𝑖 ≤ 𝑀_{𝑙−1}
1≤i≤Ml−1,
𝑎
(
𝑙
)
=
f
(
∑
i
=
1
M
l
−
1
w
i
l
a
i
(
𝑙
−
1
)
)
𝑎^{(𝑙)}=f(\sum_{i=1}^{M_{l-1}}w_i^{l}a^{(𝑙−1)}_i)
a(l)=f(i=1∑Ml−1wilai(l−1))其中
𝑓
(
⋅
)
𝑓(⋅)
f(⋅) 为激活函数,
w
i
l
w_i^{l}
wil 为赋给前面每一个神经元的权重参数,
𝑀
𝑙
−
1
𝑀_{𝑙−1}
Ml−1 是第
𝑙
−
1
𝑙 − 1
l−1 层神经元个数。为简单起见,这里令激活函数
𝑓
(
⋅
)
𝑓(⋅)
f(⋅) 为恒等函数,即
𝑓
(
𝑥
)
=
𝑥
𝑓(𝑥) = 𝑥
f(x)=x。
假设
w
i
l
w_i^{l}
wil 和
a
i
(
𝑙
−
1
)
a^{(𝑙−1)}_i
ai(l−1) 均值都为0,且相互独立,则
𝑎
(
𝑙
)
𝑎^{(𝑙)}
a(l) 的均值为
E
(
𝑎
(
𝑙
)
)
=
E
(
∑
i
=
1
M
l
−
1
w
i
l
a
i
(
𝑙
−
1
)
)
=
∑
i
=
1
M
l
−
1
E
(
w
i
l
)
E
(
a
i
(
𝑙
−
1
)
)
=
0
\begin{aligned} E(𝑎^{(𝑙)})&=E(\sum_{i=1}^{M_{l-1}}w_i^{l}a^{(𝑙−1)}_i) \\ &=\sum_{i=1}^{M_{l-1}}E(w_i^{l})E(a^{(𝑙−1)}_i) \\ &=0 \end{aligned}
E(a(l))=E(i=1∑Ml−1wilai(l−1))=i=1∑Ml−1E(wil)E(ai(l−1))=0
𝑎
(
𝑙
)
𝑎^{(𝑙)}
a(l) 的方差为
v
a
r
(
𝑎
(
𝑙
)
)
=
v
a
r
(
∑
i
=
1
M
l
−
1
w
i
l
a
i
(
𝑙
−
1
)
)
=
∑
i
=
1
M
l
−
1
v
a
r
(
w
i
l
)
v
a
r
(
a
i
(
𝑙
−
1
)
)
=
M
l
−
1
v
a
r
(
w
i
l
)
v
a
r
(
a
i
(
𝑙
−
1
)
)
\begin{aligned} var(𝑎^{(𝑙)})&=var(\sum_{i=1}^{M_{l-1}}w_i^{l}a^{(𝑙−1)}_i) \\ &=\sum_{i=1}^{M_{l-1}}var(w_i^{l})var(a^{(𝑙−1)}_i) \\ &= {M_{l-1}}var(w_i^{l})var(a^{(𝑙−1)}_i) \end{aligned}
var(a(l))=var(i=1∑Ml−1wilai(l−1))=i=1∑Ml−1var(wil)var(ai(l−1))=Ml−1var(wil)var(ai(l−1))也就是说,输入信号的方差在经过该神经元后被放大或缩小了
𝑀
𝑙
−
1
v
a
r
(
𝑤
𝑖
(
𝑙
)
)
𝑀_{𝑙−1} var(𝑤^{(𝑙)}_𝑖 )
Ml−1var(wi(l))倍。为了使得在经过多层网络后,信号不被过分放大或过分减弱,我们尽可能保持每个神经元的输入和输出的方差一致.这样
𝑀
𝑙
−
1
v
a
r
(
𝑤
𝑖
(
𝑙
)
)
𝑀_{𝑙−1} var(𝑤^{(𝑙)}_𝑖 )
Ml−1var(wi(l)) 设为
1
1
1 比较合理,即
v
a
r
(
𝑤
𝑖
(
𝑙
)
)
=
1
M
t
−
1
var(𝑤^{(𝑙)}_𝑖 )=\frac{1}{M_{t-1}}
var(wi(l))=Mt−11同理,为了使得在反向传播中,误差信号也不被放大或缩小,需要将
𝑤
𝑖
(
𝑙
)
𝑤^{(𝑙)}_𝑖
wi(l) 的方差保持为
v
a
r
(
𝑤
𝑖
(
𝑙
)
)
=
1
M
t
var(𝑤^{(𝑙)}_𝑖 )=\frac{1}{M_{t}}
var(wi(l))=Mt1作为折中,同时考虑信号在前向和反向传播中都不被放大或缩小,可以设置
v
a
r
(
𝑤
𝑖
(
𝑙
)
)
=
2
M
t
+
M
t
−
1
var(𝑤^{(𝑙)}_𝑖 )=\frac{2}{M_{t}+M_{t-1}}
var(wi(l))=Mt+Mt−12在计算出参数的理想方差后,可以通过高斯分布或均匀分布来随机初始化参数。这种根据每层的神经元数量来自动计算初始化参数方差的方法称为
X
a
v
i
e
r
Xavier
Xavier 初始化。
-
若采用区间为 [ − 𝑟 , 𝑟 ] [−𝑟, 𝑟] [−r,r] 的均匀分布来初始化 𝑤 𝑖 ( 𝑙 ) 𝑤^{(𝑙)}_𝑖 wi(l) ,则𝑟 的取值为 6 M t + M t − 1 \sqrt{\frac{6}{M_{t}+M_{t-1}}} Mt+Mt−16 。该方法在 t a n h tanh tanh 中表现的很好, 在 r e l u relu relu 中表现很差。
nn.init.xavier_uniform(tensor, gain=1)
其中参数
gain
为可选的缩放因子的缩放倍数。 -
若采用高斯分布来随机初始化参数,连接权重 𝑤 𝑖 ( 𝑙 ) 𝑤^{(𝑙)}_𝑖 wi(l) 可以按 N ( 0 , 2 M t + M t − 1 ) N(0, \frac{2}{M_{t}+M_{t-1}}) N(0,Mt+Mt−12) 的高斯分布进行初始化。针对Xavier在relu表现不佳可采用该方法,在Relu网络中, 假设每一层有一半的神经元被激活,另一半为0。一般在使用Relu的网络中推荐使用这种初始化方式。
pytorch 中的 X a v i e r Xavier Xavier 使用高斯分布初始化方法如下所示:
nn.init.xavier_normal(tensor, gain=1)
其中参数
gain
为可选的缩放因子的缩放倍数。
2.2 Kaiming初始化
K
a
i
m
i
n
g
Kaiming
Kaiming 初始化也被称作
H
e
He
He 初始化。当第
𝑙
𝑙
l 层神经元使用
R
e
L
U
ReLU
ReLU 激活函数时,通常有一半的神经元输出为
0
0
0,因此其分布的方差也近似为使用恒等函数时的一半。这样,只考虑前向传播时,参数
𝑤
𝑖
(
𝑙
)
𝑤^{(𝑙)}_𝑖
wi(l) 的理想方差为
v
a
r
(
𝑤
𝑖
(
𝑙
)
)
=
2
M
t
−
1
var(𝑤^{(𝑙)}_𝑖 )=\frac{2}{M_{t-1}}
var(wi(l))=Mt−12其中
𝑀
𝑙
−
1
𝑀_{𝑙−1}
Ml−1 是第
𝑙
−
1
𝑙 − 1
l−1 层神经元个数。
当使用ReLU 激活函数时,若采用高斯分布来初始化参数 𝑤 𝑖 ( 𝑙 ) 𝑤^{(𝑙)}_𝑖 wi(l) ,其方差为 2 M t − 1 \frac{2}{M_{t-1}} Mt−12;若采用区间为 [ − 𝑟 , 𝑟 ] [−𝑟, 𝑟] [−r,r] 的均匀分布来初始化参数 𝑤 𝑖 ( 𝑙 ) 𝑤^{(𝑙)}_𝑖 wi(l) ,则 r = 6 M t + M t − 1 r=\sqrt{\frac{6}{M_{t}+M_{t-1}}} r=Mt+Mt−16 这种初始化方法称为 K a i m i n g Kaiming Kaiming 初始化。
pytorch中的两种实现如下所示:
torch.nn.init.kaiming_uniform(tensor, a=0, mode='fan_in',nonlinearity='leaky_relu')
torch.nn.init.kaiming_normal(tensor, a=0, mode='fan_in')
3. 正交初始化
上面介绍的两种基于方差的初始化方法都是对权重矩阵中的每个参数进行独立采样。由于采样的随机性,采样出来的权重矩阵依然可能存在梯度消失或梯度爆炸问题。
假设一个𝐿 层的等宽线性网络(激活函数为恒等函数)为
y
=
W
L
W
L
−
1
⋯
W
1
x
y=W^{L}W^{L-1}\cdots W^{1}x
y=WLWL−1⋯W1x其中
W
L
∈
R
𝑀
×
𝑀
(
1
≤
𝑙
≤
𝐿
)
W^{L}∈ ℝ^{𝑀×𝑀} (1 ≤ 𝑙 ≤ 𝐿)
WL∈RM×M(1≤l≤L) 为神经网络的第
𝑙
𝑙
l 层权重矩阵。在反向传播中,误差项
δ
\delta
δ 的反向传播公式为
δ
l
−
1
=
(
W
l
)
T
δ
l
\delta^{l-1}=(W^{l})^T \delta^{l}
δl−1=(Wl)Tδl 。为了避免梯度消失或梯度爆炸问题,我们希望误差项在反向传播中具有范数保持性,即
∥
δ
l
−
1
∥
2
=
∥
δ
l
−
1
∥
2
=
∥
(
W
l
)
T
δ
l
∥
2
\Vert \delta^{l-1} \Vert^2 =\Vert \delta^{l-1} \Vert^2 =\Vert (W^{l})^T \delta^{l} \Vert^2
∥δl−1∥2=∥δl−1∥2=∥(Wl)Tδl∥2。如果我们以均值为
0
0
0、方差为
1
M
\frac{1}{M}
M1的高斯分布来随机生成权重矩阵
W
L
W^{L}
WL中每个元素的初始值,那么当
M
→
∞
M \rightarrow \infty
M→∞ 时,范数保持性成立。但是当
𝑀
𝑀
M 不足够大时,这种对每个参数进行独立采样的初始化方式难以保证范数保持性。
因此,一种更加直接的方式是将 W L W^{L} WL 初始化为正交矩阵,即 W L ( W l ) T = I W^{L}(W^{l})^T=I WL(Wl)T=I,这种方法称为正交初始化。正交初始化的具体实现过程可以分为两步:
- 用均值为 0 0 0、方差为 1 1 1 的高斯分布初始化一个矩阵;
- 将这个矩阵用奇异值分解得到两个正交矩阵,并使用其中之一作为权重矩阵.
根据正交矩阵的性质,这个线性网络在信息的前向传播过程和误差的反向
传播过程中都具有范数保持性,从而可以避免在训练开始时就出现梯度消失或
梯度爆炸现象。
正交初始化通常用在循环神经网络中循环边上的权重矩阵上。
当在非线性神经网络中应用正交初始化时,通常需要将正交矩阵乘一个缩放系数 ρ \rho ρ。比如当激活函数为 R e L U ReLU ReLU 时,激活函数在 0 0 0 附近的平均梯度可以近似为 0.5 0.5 0.5。为了保持范数不变,缩放系数 ρ \rho ρ 可以设置为 2 \sqrt{2} 2。
pytorch 中实现正交初始化的API如下所示
torch.nn.init.orthogonal(tensor, gain=1)
参数 gain
为缩放因子。