1.梯度消失与爆炸
H 2 = H 1 ∗ W 2 \mathrm{H}_{2}=\mathrm{H}_{1} * \mathrm{W}_{2} H2=H1∗W2
Δ W 2 = ∂ L o s s ∂ W 2 = ∂ L o s s ∂ o u t × ∂ o u t ∂ H 2 × ∂ H 2 ∂ w 2 = ∂ L o s s ∂ o u t × ∂ o u t ∂ H 2 × H 1 \begin{aligned} \Delta W_{2} &=\frac{\partial L o s s}{\partial W_{2}}=\frac{\partial L o s s}{\partial o u t} \times \frac{\partial o u t}{\partial H_{2}} \times \frac{\partial H_{2}}{\partial w_{2}} \\ &=\frac{\partial L o s s}{\partial o u t} \times \frac{\partial o u t}{\partial H_{2}} \times H_{1} \end{aligned} ΔW2=∂W2∂Loss=∂out∂Loss×∂H2∂out×∂w2∂H2=∂out∂Loss×∂H2∂out×H1
这里我们用损失函数针对权重的求导作为例子进行分析(对输出的求导可以参考另一篇博文):
梯度消失: H 1 → 0 ⇒ Δ W 2 → 0 \mathrm{H}_{1} \rightarrow \mathbf{0} \Rightarrow \Delta \mathrm{W}_{2} \rightarrow \mathbf{0} H1→0⇒ΔW2→0
梯度爆炸: H 1 → ∞ ⇒ Δ W 2 → ∞ \mathrm{H}_{1} \rightarrow \infty \quad \Rightarrow \Delta \mathrm{W}_{2} \rightarrow \infty H1→∞⇒ΔW2→∞
可见,如果某一层的输出值接近于0或者接近无穷,就会产生梯度消失或者梯度爆炸
在统计学总我们有:
E
(
X
×
Y
)
=
E
(
X
)
×
E
(
Y
)
D
(
X
)
=
E
(
X
2
)
−
[
E
(
X
)
]
2
D
(
X
+
Y
)
=
D
(
X
)
+
D
(
Y
)
⇒
D
(
X
×
Y
)
=
D
(
X
)
×
D
(
Y
)
+
D
(
X
)
×
[
E
(
Y
)
]
2
+
D
(
Y
)
×
[
E
(
X
)
]
2
\begin{aligned} E(X \times Y)&=E(X) \times E(Y)\\ D(X)&=E\left(X^{2}\right)-[E(X)]^{2}\\ D(X+Y)&=D(X)+D(Y)\\ \Rightarrow D(X \times Y)&=D(X) \times D(Y)+D(X) \times [E(Y)]^{2}+D(Y) \times [E(X)]^{2} \end{aligned}
E(X×Y)D(X)D(X+Y)⇒D(X×Y)=E(X)×E(Y)=E(X2)−[E(X)]2=D(X)+D(Y)=D(X)×D(Y)+D(X)×[E(Y)]2+D(Y)×[E(X)]2
if
E
(
X
)
=
0
,
E
(
Y
)
=
0
E(X)=0, E(Y)=0
E(X)=0,E(Y)=0,
D
(
X
×
Y
)
=
D
(
X
)
×
D
(
Y
)
D(X \times Y)=D(X) \times D(Y)
D(X×Y)=D(X)×D(Y)
把第一层隐藏层的第一个神经元作为例子,我们有: H 11 = ∑ i = 0 n X i × W 1 i \mathrm{H}_{11}=\sum_{i=0}^{n} X_{i} \times W_{1 i} H11=∑i=0nXi×W1i
如果我们让X和W的分布是标准正态分布,输入数据方差是1:
D
(
H
11
)
=
∑
i
=
0
n
D
(
X
i
)
×
D
(
W
1
i
)
=
n
×
(
1
×
1
)
=
n
⇒
std
(
H
11
)
=
D
(
H
11
)
=
n
\begin{aligned} D\left(H_{11}\right) &=\sum_{i=0}^{n} D\left(X_{i}\right) \times D\left(W_{1 i}\right) \\ &=\mathrm{n} \times(1 \times 1) \\ &=\mathrm{n}\\ \Rightarrow &\operatorname{std}\left(H_{11}\right)=\sqrt{D\left(H_{11}\right)}=\sqrt{n} \end{aligned}
D(H11)⇒=i=0∑nD(Xi)×D(W1i)=n×(1×1)=nstd(H11)=D(H11)=n
也就是说,在经过第一层神经网络的处理后,一个隐藏层神经元的输出的数值范围就扩大了
n
\sqrt{n}
n倍!这里的
n
n
n是网络层输入的维度。
因此,为了保持层与层之间的输出方差维持在一个常数范围,最好的办法就是让节点输出的方差为1,因为方差为1,无论多少层变换后,方差仍为1。为了让一层网络层输出节点的方差为常数1,我们应该让W的标准差是
1
/
n
\sqrt{1/n}
1/n,即:
D
(
H
1
)
=
n
×
D
(
X
)
×
D
(
W
)
=
1
D
(
W
)
=
1
n
⇒
std
(
W
)
=
1
n
D\left(H_{1}\right)=n \times D(X) \times D(W)=1\\ D(W)=\frac{1}{n} \Rightarrow \operatorname{std}(\mathrm{W})=\sqrt{\frac{1}{n}}
D(H1)=n×D(X)×D(W)=1D(W)=n1⇒std(W)=n1
也就是让W的方差等于
1
/
n
1/n
1/n
方差一致性:保持数据尺度维持在恰当范围内,通常方差为1
激活函数:
- 饱和函数,如sigmoid,tanh。综合考虑前向后向传播,针对某一隐藏层,假设输入节点数是 n i n_i ni,输出结点数是 n i + 1 n_{i+1} ni+1, 应该有
n i × D ( W ) = 1 n i + 1 × D ( W ) = 1 ⇒ D ( W ) = 2 n i + n i + 1 \begin{array}{l} n_{i} \times D(W)=1 \\ n_{i+1} \times D(W)=1 \\ \Rightarrow D(W)=\dfrac{2}{n_{i}+n_{i+1}} \end{array} ni×D(W)=1ni+1×D(W)=1⇒D(W)=ni+ni+12
假设W的分布满足
W
∼
U
[
−
a
,
a
]
W \sim U[-\boldsymbol{a}, \boldsymbol{a}]
W∼U[−a,a], 我们有:
W
∼
U
[
−
a
,
a
]
D
(
W
)
=
(
−
a
−
a
)
2
12
=
(
2
a
)
2
12
=
a
2
3
2
n
i
+
n
i
+
1
=
a
2
3
⇒
a
=
6
n
i
+
n
i
+
1
⇒
W
∼
U
[
−
6
n
i
+
n
i
+
1
,
6
n
i
+
n
i
+
1
]
\begin{aligned} &W \sim \boldsymbol{U}[-\boldsymbol{a}, \boldsymbol{a}]\\ &D(W)=\dfrac{(-a-a)^{2}}{12}=\dfrac{(2 a)^{2}}{12}=\dfrac{a^{2}}{3}\\ &\frac{2}{n_{i}+n_{i+1}}=\dfrac{a^{2}}{3} \Rightarrow a=\dfrac{\sqrt{6}}{\sqrt{n_{i}+n_{i+1}}}\\ &\Rightarrow \quad W \sim U\left[-\dfrac{\sqrt{6}}{\sqrt{n_{i}+n_{i+1}}}, \dfrac{\sqrt{6}}{\sqrt{n_{i}+n_{i+1}}}\right] \end{aligned}
W∼U[−a,a]D(W)=12(−a−a)2=12(2a)2=3a2ni+ni+12=3a2⇒a=ni+ni+16⇒W∼U[−ni+ni+16,ni+ni+16]
- ReLu及其变种。针对relu及其变种函数,可以把负半轴的斜率设定为 a a a
D ( W ) = 2 n i D ( W ) = 2 ( 1 + a 2 ) ∗ n i std ( W ) = 2 ( 1 + a 2 ) ∗ n i \begin{array}{l} D(W)=\dfrac{2}{n_{i}} \\ D(W)=\dfrac{2}{\left(1+a^{2}\right) * n_{i}} \\ \operatorname{std}(W)=\sqrt{\dfrac{2}{\left(1+a^{2}\right) * n_{i}}} \end{array} D(W)=ni2D(W)=(1+a2)∗ni2std(W)=(1+a2)∗ni2
2. 十种初始化方法
- Xavier均匀分布
- Xavier正态分布
- Kaiming均匀分布
- Kaiming正态分布
- 均匀分布
- 正态分布
- 常数分布
- 正交矩阵初始化
- 单位矩阵初始化
- 稀疏矩阵初始化
nn.init.calculate_gain
主要功能:计算激活函数的方差变化尺度
主要参数
- nonlinearity: 激活函数名称
- param: 激活函数的参数,如Leaky ReLU 的negative_slop