深度学习笔记[续]——数值稳定性、模型初始化与激活函数
- 引言
-
- 回顾:没有激活函数参与,输入输出分布的变化情况
-
- Xavier \text{Xavier} Xavier方法
- 存在激活函数的情况
-
- 总结
引言
继续上一节介绍激活函数在神经网络前馈/反向传播中的作用。
回顾:没有激活函数参与,输入输出分布的变化情况
在神经网络前馈/反向传播过程中没有激活函数的参与,各隐藏层之间的均值和方差变化情况表示如下:
依然描述
t t t层神经元输出
h i ( t ) h_i^{(t)} hi(t)与
t − 1 t-1 t−1层神经元输入
h j ( t − 1 ) h_{j}^{(t-1)} hj(t−1)之间的关系。
已知:
各权重在该该层内的权重空间内是‘独立同分布’;
各层输入/输出特征在对应特征空间中同分布,但是否独立未知。
权重和特征分布属于不同的空间(权重空间/特征空间),它们必然相互独立。
- t t t层各神经元内权重 W i ⇔ j ( t ) ( i = 1 , 2 , ⋯ , j = 1 , 2 , ⋯ ) \mathcal W_{i \Leftrightarrow j}^{(t)}(i=1,2,\cdots,j=1,2,\cdots) Wi⇔j(t)(i=1,2,⋯,j=1,2,⋯)均独立同分布,且分布均值为 0 0 0,方差为 γ t \gamma_t γt:
E [ W i ⇔ j ( t ) ] = 0 Var [ W i ⇔ j ( t ) ] = γ t \mathbb E[\mathcal W_{i \Leftrightarrow j}^{(t)}] = 0 \quad \text{Var} [\mathcal W_{i \Leftrightarrow j}^{(t)}] = \gamma_t E[Wi⇔j(t)]=0Var[Wi⇔j(t)]=γt
- t t t层神经元输入 h j ( t − 1 ) ( j = 1 , 2 , ⋯ ) h_j^{(t-1)}(j=1,2,\cdots) hj(t−1)(j=1,2,⋯)以及输出 h i ( t ) ( t = 1 , 2 , ⋯ ) h_i^{(t)}(t=1,2,\cdots) hi(t)(t=1,2,⋯)均服从各自分布。这里以 t t t层输出为例:
E [ h i ( t ) ] = 0 Var [ h i ( t ) ] = a \mathbb E[h_i^{(t)}] = 0 \quad \text{Var}[h_i^{(t)}] = a E[hi(t)]=0Var[hi(t)]=a
同理,对应反向传播过程中 h i ( t ) h_i^{(t)} hi(t)梯度的均值和方差表示为:
E [ ∂ L ∂ h i ( t ) ] = 0 Var [ ∂ L ∂ h i ( t ) ] = b \mathbb E \left[\frac{\partial \mathcal L}{\partial h_i^{(t)}}\right] = 0 \quad \text{Var} \left[\frac{\partial \mathcal L}{\partial h_i^{(t)}}\right] = b E[∂hi(t)∂L]=0Var[∂hi(t)∂L]=b
前馈计算过程: h j ( t − 1 ) ⇒ h i ( t ) h_j^{(t-1)} \Rightarrow h_i^{(t)} hj(t−1)⇒hi(t):
- 均值结果:
输入与输出的均值结果无变化:
⇒ E [ h i ( t ) ] = E [ h j ( t − 1 ) ] = 0 \Rightarrow \mathbb E[h_i^{(t)}] = \mathbb E [h_{j}^{(t-1)}] = 0 ⇒E[hi(t)]=E[hj(t−1)]=0
E [ h i ( t ) ] = E [ ∑ j W i ⇔ j ( t ) ⋅ h j ( t − 1 ) ] = ∑ j E [ W i ⇔ j ( t ) ] ⋅ E [ h j ( t − 1 ) ] = 0 \mathbb E[h_i^{(t)}] = \mathbb E \left[\sum_{j} \mathcal W_{i \Leftrightarrow j}^{(t)} \cdot h_j^{(t-1)}\right] = \sum_j \mathbb E [\mathcal W_{i \Leftrightarrow j}^{(t)}] \cdot \mathbb E [h_j^{(t-1)}] = 0 E[hi(t)]=E[j∑Wi⇔j(t)⋅hj(t−1)]=j∑E[Wi⇔j(t)]⋅E[hj(t−1)]=0
- 方差结果:
输入与输出的方差结果存在偏差,其中
n t − 1 n_{t-1} nt−1表示
t t t层输入神经元数量。
Var [ h i ( t ) ] = n t − 1 ⋅ γ t ⋅ Var [ h j ( t − 1 ) ] \text{Var} [h_i^{(t)}] = n_{t-1} \cdot \gamma_t \cdot \text{Var}[h_j^{(t-1)}] Var[hi(t)]=nt−1⋅γt⋅Var[hj(t−1)]
反向传播过程: ∂ L ∂ h i ( t ) ⇒ ∂ L ∂ h j ( t − 1 ) \begin{aligned}\frac{\partial \mathcal L}{\partial h_i^{(t)}} \Rightarrow \frac{\partial \mathcal L}{\partial h_j^{(t-1)}}\end{aligned} ∂hi(t)∂L⇒∂hj(t−1)∂L:
- 均值结果:
同上,依然没有变化:
⇒ E [ ∂ L ∂ h j ( t − 1 ) ] = E [ ∂ L ∂ h i ( t ) ] = 0 \Rightarrow \begin{aligned}\mathbb E \left[\frac{\partial \mathcal L}{\partial h_j^{(t-1)}}\right] = \mathbb E \left[\frac{\partial \mathcal L}{\partial h_i^{(t)}}\right] = 0\end{aligned} ⇒E[∂hj(t−1)∂L]=E[∂hi(t)∂L]=0
E [ ∂ L ∂ h j ( t − 1 ) ] = E [ ∂ L ∂ h i ( t ) ⋅ ∂ h i ( t ) ∂ h j ( t − 1 ) ] = E [ ∂ L ∂ h i ( t ) ] ⋅ E [ W i ⇐ j ( t ) ] ⏟ 0 = 0 \begin{aligned}\mathbb E \left[\frac{\partial \mathcal L}{\partial h_j^{(t-1)}}\right]\end{aligned} = \mathbb E \left[\frac{\partial \mathcal L}{\partial h_i^{(t)}} \cdot \frac{\partial h_i^{(t)}}{\partial h_j^{(t-1)}}\right] = \mathbb E \left[\frac{\partial \mathcal L}{\partial h_i^{(t)}}\right] \cdot \underbrace{\mathbb E \left[\mathcal W_{i \Leftarrow j}^{(t)}\right]}_{0} = 0 E[∂hj(t−1)∂L]=E[∂hi(t)∂L⋅∂hj(t−1)∂hi(t)]=E[∂hi(t)∂L]⋅0 E[Wi⇐j(t)]=0
- 方差结果:
和前馈计算相似。
n t n_t nt表示
t t t层神经元的数量。
Var [ ∂ L ∂ h j ( t − 1 ) ] = n t ⋅ γ t ⋅ Var [ ∂ L ∂ h i ( t ) ] \text{Var} \left[\frac{\partial \mathcal L}{\partial h_j^{(t-1)}}\right] = n_t \cdot \gamma_t \cdot \text{Var} \left[\frac{\partial \mathcal L}{\partial h_i^{(t)}}\right] Var[∂hj(t−1)∂L]=nt⋅γt⋅Var[∂hi(t)∂L]
至此,可以发现,在没有激活函数,也就是纯粹的线性计算过程中,无论是前馈/反向传播过程,每一层分布的方差均在发生偏移。如果我们希望在传播过程中满足分布不变,则需要同时满足两个等式:
{ n t − 1 ⋅ γ t = 1 n t ⋅ γ t = 1 \begin{cases} n_{t-1} \cdot \gamma_t = 1 \\ n_{t} \cdot \gamma_t = 1 \end{cases} {nt−1⋅γt=1nt⋅γt=1
Xavier \text{Xavier} Xavier方法
很明显,上述两个等式在神经网络中很难同时满足——该层的输入和输出神经元数量必须相同。
Xavier \text{Xavier} Xavier方法给出一个折中的方式:令 γ t ⋅ n t − 1 + n t 2 = 1 ⇒ γ t = 2 n t − 1 + n t \begin{aligned}\gamma_t \cdot \frac{n_{t-1} + n_t}{2} = 1 \Rightarrow \gamma_t = \frac{2}{n_{t-1} + n_{t}}\end{aligned} γt⋅2nt−1+nt=1⇒γt=nt−1+nt2从而通过折中方式选择第 t t t层权重的方差 γ t \gamma_t γt。
也就是说,当前网络层的输入、输出神经元数量确定后,使用其确定参数 γ t \gamma_t γt,并使用该参数来构建随机分布作为初始化分布:
也就是关于权重
W ( t ) \mathcal W^{(t)} W(t)的先验分布。
- 如果使用高斯分布,有:
W ( t ) ∼ N [ 0 , 2 n t − 1 + n t ] \begin{aligned}\mathcal W^{(t)} \sim \mathcal N \left[0,\sqrt{\frac{2}{n_{t-1} + n_t}} \right]\end{aligned} W(t)∼N[0,nt−1+nt2 ]
- 如果使用均匀分布,有:
均匀分布的方差表示为
( b − a ) 2 12 \begin{aligned}\frac{(b - a)^2}{12}\end{aligned} 12(b−a)2,其中
a , b a,b a,b表示均匀分布范围。
W ( t ) ∼ U [ − 6 n t − 1 + n t , 6 t − 1 + n t ] \mathcal W^{(t)} \sim \mathcal U \left[- \sqrt{\frac{6}{n_{t-1} + n_t}},\sqrt{\frac{6}{_{t-1} + n_t}}\right] W(t)∼U[−nt−1+nt6 ,t−1+nt6 ]
从而通过这种权重初始化的方式尽量使各层的输入、输出分布的方差信息保持一致。
存在激活函数的情况
假设激活函数是线性函数
从上帝视角观察,自然不会使用线性函数作为激活函数。因为它无法学习到非线性信息。这里仅讨论如果线性函数作为激活函数,它会产生什么样的影响。
假设激活函数 σ ( x ) = α ⋅ x + β \sigma(x) = \alpha \cdot x + \beta σ(x)=α⋅x+β,并且有:
{ Z ( t ) = W ( t ) ⋅ h ( t − 1 ) h ( t ) = σ ( Z ( t ) ) \begin{cases} \mathcal Z^{(t)} = \mathcal W^{(t)} \cdot h^{(t-1)} \\ h^{(t)} = \sigma(\mathcal Z^{(t)}) \end{cases} {Z(t)=W(t)⋅h(t−1)h(t)=σ(Z(t))
- 此时,计算前馈传播过程中 h i ( t ) h_i^{(t)} hi(t)的期望结果 E [ h i ( t ) ] \mathbb E [h_i^{(t)}] E[hi(t)]:
其中
Z i ( t ) \mathcal Z_i^{(t)} Zi(t)表示线性计算过程中第
i i i个神经元的输出结果。
{ Z i ( t ) = ∑ j W i ⇔ j ( t ) ⋅ h j ( t − 1 ) E [ h i ( t ) ] = E [ α ⋅ Z i ( t ) + β ] = α ⋅ E [ ∑ j W i ⇔ j ( t ) ⋅ h j ( t − 1 ) ] + β = α ⋅ ∑ j E [ W i ⇔ j ( t ) ] ⋅ E [ h j ( t − 1 ) ] ⏟ = 0 + β = β \begin{cases} \begin{aligned} \mathcal Z_i^{(t)} & = \sum_j \mathcal W_{i \Leftrightarrow j}^{(t)} \cdot h_j^{(t-1)}\\ \mathbb E [h_i^{(t)}] & = \mathbb E [\alpha \cdot \mathcal Z_i^{(t)} + \beta] \\ & = \alpha \cdot \mathbb E \left[\sum_j \mathcal W_{i \Leftrightarrow j}^{(t)} \cdot h_j^{(t-1)}\right] + \beta \\ & = \alpha \cdot \underbrace{\sum_j \mathbb E [\mathcal W_{i \Leftrightarrow j}^{(t)}] \cdot \mathbb E[h_j^{(t-1)}]}_{=0} + \beta \\ & = \beta \end{aligned} \end{cases} ⎩ ⎨ ⎧Zi(t)E[hi(t)]=j∑Wi⇔j(t)⋅hj(t−1)=E[α⋅Zi(t)+β]=α⋅E[j∑Wi⇔j(t)⋅hj(t−1)]+β=α⋅=0 j∑E[Wi⇔j(t)]⋅E[hj(t−1)]+β=β
可以看出,激活后的结果与激活前存在 β \beta β的偏差。但由于我们希望 E [ h i ( t ) ] = E [ Z i ( t ) ] = 0 \mathbb E [h_i^{(t)}] = \mathbb E [\mathcal Z_i^{(t)}] = 0 E[hi(t)]=E[Zi(t)]=0,因而有: β = 0 \beta = 0 β=0。
也就是激活前与激活后的均值相同。
- 计算前馈传播过程中 h i ( t ) h_i^{(t)} hi(t)的方差结果 Var [ h i ( t ) ] \text{Var}[h_i^{(t)}] Var[hi(t)]:
将
β = 0 \beta=0 β=0代入。
Var [ h i ( t ) ] = E [ ( h i ( t ) ) 2 ] − [ E ( h i ( t ) ) ] 2 ⏟ β 2 = E [ ( α ⋅ Z i ( t ) + β ) 2 ] − β 2 = α 2 ⋅ { E [ ( Z i ( t ) ) 2 ] − [ E ( Z i ( t ) ) ] 2 ⏟ = 0 } ⏟ = Var ( Z i ( t ) ) + 2 α β E ( Z i ( t ) ) ⏟ = 0 + E ( β 2 ) − β 2 ⏟ = 0 = α 2 ⋅ Var ( Z i ( t ) ) \begin{aligned} \text{Var}[h_i^{(t)}] & = \mathbb E \left[(h_i^{(t)})^2\right] - \underbrace{\left[\mathbb E(h_i^{(t)})\right]^2}_{\beta^2} \\ & = \mathbb E \left[(\alpha \cdot \mathcal Z_i^{(t)} + \beta)^2\right] - \beta^2 \\ & = \alpha^2 \cdot \underbrace{\left\{\mathbb E \left[(\mathcal Z_i^{(t)})^2\right] - \underbrace{\left[\mathbb E(\mathcal Z_i^{(t)})\right]^2}_{=0}\right\}}_{=\text{Var}(\mathcal Z_i^{(t)})} + 2 \alpha\beta \underbrace{\mathbb E (\mathcal Z_i^{(t)})}_{=0} + \underbrace{\mathbb E(\beta^2)- \beta^2}_{=0} \\ & = \alpha^2 \cdot \text{Var}(\mathcal Z_i^{(t)}) \end{aligned} Var[hi(t)]=E[(hi(t))2]−β2 [E(hi(t))]2=E[(α⋅Zi(t)+β)2]−β2=α2⋅=Var(Zi(t)) ⎩ ⎨ ⎧E[(Zi(t))2]−=0 [E(Zi(t))]2⎭ ⎬ ⎫+2αβ=0 E(Zi(t))+=0 E(β2)−β2=α2⋅Var(Zi(t))
可以看做是激活后的结果相较于激活前结果扩大了 α 2 \alpha^2 α2倍。同理,我们同样希望激活前与激活后的方差相同:
α 2 ⋅ Var ( Z i ( t ) ) = Var ( Z i ( t ) ) ⇒ α = 1 \alpha^2 \cdot \text{Var}(\mathcal Z_i^{(t)}) = \text{Var}(\mathcal Z_i^{(t)}) \Rightarrow \alpha = 1 α2⋅Var(Zi(t))=Var(Zi(t))⇒α=1
综上,可以看出,如果要维持输出分布 均值为 0 0 0,方差为某常数 的情况,我们的线性激活函数只能是:
好像做了一些什么,又好像什么都没做~就是一个恒等映射,当然
α \alpha α取
− 1 -1 −1,相当于将输出向量的方向完全倒置。
σ ( x ) = x \sigma(x) = x σ(x)=x
关于它的反向传播过程,与正向结果相同,这里就不赘述了。
激活函数的底层逻辑
从上面的逻辑,我们会发现:如果激活函数是线性的,那么为了输入、输出维持在一个相对稳定的条件下,它只能选择恒等函数 ( Identity Function ) (\text{Identity Function}) (Identity Function)。
但恒等函数它的作用很明显。它能够让输入、输出分布之间保持稳定。但我们也希望能够通过前馈计算产生出一些非线性信息,从而通过反向传播,使模型参数拟合更加复杂的函数。
这里的意思是可理解为:恒等函数和非线性信息两者是矛盾的。但是它们的优点我们都想要。
关于一些常见的激活函数,使用泰勒公式进行展开:
其中
O \mathcal O O表示函数的复杂程度。其中
O \mathcal O O内
x x x指数越大,函数的‘非线性程度’越复杂。
{ Sigmoid ( x ) = 1 2 + 1 4 x − 1 48 x 3 + O ( x 5 ) Tanh ( x ) = 0 + x − 1 3 x 3 + O ( x 5 ) ReLU ( x ) = 0 + x x ≥ 0 \begin{cases} \begin{aligned} \text{Sigmoid}(x) & = \frac{1}{2} + \frac{1}{4}x - \frac{1}{48}x^3 + \mathcal O(x^5) \\ \text{Tanh}(x) & = 0 + x - \frac{1}{3}x^3 + \mathcal O(x^5) \\ \text{ReLU}(x) & = 0 + x \quad x \geq 0 \end{aligned} \end{cases} ⎩ ⎨ ⎧Sigmoid(x)Tanh(x)ReLU(x)=21+41x−481x3+O(x5)=0+x−31x3+O(x5)=0+xx≥0
它们的函数图像表示如下:
![深度学习笔记(续)——数值稳定性、模型初始化与激活函数_第1张图片](http://img.e-com-net.com/image/info8/c5bd4cbd16d04110b272f82eadd44cb0.jpg)
对比泰勒展开式与函数图像,可以发现:
-
Tanh \text{Tanh} Tanh激活函数和 ReLU \text{ReLU} ReLU激活函数的一次项系数均是 1 1 1,这导致在函数图像中存在一个小区间(红色椭圆标注的位置),这个小区间几乎支持恒等映射。
对应的负值区间同理,只不过
ReLU \text{ReLU} ReLU函数在负值范围内失活。
-
在神经网络计算隐藏层输出的分布时,相当大一部分的结果聚集在 0 0 0点附近。也就是说,神经网络所拟合的非线性结果是基于线性结果的基础上,增加函数的复杂度(变量的高次项)得到的结果。因此,我们希望在尽可能满足低次项分布稳定的基础上,去学习高次项特征(距离 0 0 0点远的结果)的非线性信息,最终得到拟合的复杂函数。
不否认的是, Sigmoid \text{Sigmoid} Sigmoid函数作为激活函数并没有 ReLU,Tanh \text{ReLU,Tanh} ReLU,Tanh函数优秀,核心原因在于在 0 0 0附近它没有实现恒等映射。
-
尝试最 Sigmoid \text{Sigmoid} Sigmoid函数做一些修改:
ScaledSigmoid ( x ) = 4 × Sigmoid ( x ) − 2 \text{ScaledSigmoid}(x) = 4 \times \text{Sigmoid}(x) - 2 ScaledSigmoid(x)=4×Sigmoid(x)−2
其对应函数图像表示如下:
经过这样的修改后,其泰勒展开式的一次项是 1 1 1,该函数也存在了在 0 0 0附近恒等映射的条件。
总结
这里和深度学习笔记——数值稳定性、模型初始化与激活函数一同总结:
-
通过权重初始化和激活函数的调整来维持输出分布数值的稳定性。
需要强调的点:这里说的‘数值稳定性’是指各隐藏层输出分布的‘数值稳定性’。
-
(核心)这个稳定性这里使用隐藏层输入、输出分布之间的差异表示。主要通过参数:均值和方差进行描述。
获取非线性信息和维持数值稳定性这两件事情是矛盾的:
个人理解及延伸:权重自身能够直接影响稳定性————只要该值
≠ 1 \neq 1 =1,本层的输出分布和输入分布就会存在差异。也就是说,‘线性激活函数’本身就可以看作是一个‘线性计算层’;相反,每个‘线性计算层’都可以看作是一个‘线性激活函数’。那么‘线性计算层’中的权重
W ≠ 1 \mathcal W \neq 1 W=1本身就是
破坏数值稳定性的。
而
激活函数的作用针对
W \mathcal W W线性计算的输出结果:如果该结果较小,依然在
0 0 0附近徘徊,那么依然希望该结果‘维持现状’——恒等映射;而距离
0 0 0较远的数值结果,希望它‘不脱离这个分布’——非线性的方式将该结果‘拖拽回来’。
Sigmoid,Tanh \text{Sigmoid,Tanh} Sigmoid,Tanh的构建思路都可以解释。
而
ReLU \text{ReLU} ReLU和上述两个函数显得格格不入——它的非线性仅体现在
0 0 0处的映射上。这可能要归属于‘稀疏特征’的强大之处了。和
Dropout \text{Dropout} Dropout思想相同。
- 如果过于强调稳定性:最终的结果相当于激活函数是一个恒等映射——反向传播中,学不到描述复杂函数的有效的梯度信息;
这个结果导致函数‘过于简单’————欠拟合
( UnderFitting \text{UnderFitting} UnderFitting)。
- 如果过于强调非线性:前馈计算过程中,经过每一层的输出分布差异是较大的。这种情况,更容易出现梯度消失/梯度爆炸,并且
泰勒展开式
高次项的权重系数过高,导致模型结果过拟合 ( OverFitting ) (\text{OverFitting}) (OverFitting)。
-
而优秀的激活函数就是既要维持分布稳定,又要能够使模型学习到非线性特征的非线性函数。