梯度
神经网络的梯度
- 考虑如下有d层的神经网络
h t = f t ( h t − 1 ) a n d y = ℓ ∗ f d ∗ . . . ∗ f 1 ( x ) \mathbf{h}^t=f_t(\mathbf{h}^{t-1})\ and\ y=\ell*f_d*...*f_1(\mathbf{x}) ht=ft(ht−1) and y=ℓ∗fd∗...∗f1(x) - 计算损失
ℓ
\ell
ℓ关于参数
W
t
\mathbf{W}_t
Wt的梯度
∂ ℓ ∂ W t = ∂ ℓ ∂ h d ∂ h d ∂ h d − 1 . . . ∂ h t + 1 ∂ h t ∂ h t ∂ W t \frac{\partial\ell}{\partial\mathbf{W}^t}=\frac{\partial\ell}{\partial\mathbf{h}^d}\frac{\partial\mathbf{h}^d}{\partial\mathbf{h}^{d-1}}...\frac{\partial\mathbf{h}^{t+1}}{\partial\mathbf{h}^{t}}\frac{\partial\mathbf{h}^t}{\partial\mathbf{W}^{t}} ∂Wt∂ℓ=∂hd∂ℓ∂hd−1∂hd...∂ht∂ht+1∂Wt∂ht
可以看到中间有 d − t d-t d−t次矩阵乘法,每项求导之后都是一个雅可比矩阵,因此对于这么多的矩阵乘法,将带来: - 梯度爆炸 1. 5 100 ≈ 4 ∗ 1 0 17 1.5^{100}\approx4*10^{17} 1.5100≈4∗1017,梯度特别大,可能会超过表示的上限
- 梯度消失 0. 8 100 ≈ 2 ∗ 1 0 − 10 0.8^{100}\approx2*10^{-10} 0.8100≈2∗10−10,数字非常非常小,梯度不见
举例:MLP
- 加入如下MLP(为了简单省略偏移)
f t ( h t − 1 ) = σ ( W t h t − 1 ) f_t(\mathbf{h}^{t-1})=\sigma(\mathbf{W^t h^{t-1}}) ft(ht−1)=σ(Wtht−1)
t是指层数, σ \sigma σ是激活函数
对于两层之间的求导可得:
∂ h t ∂ h t − 1 = d i a g ( σ ‘ ( W t h t − 1 ) ) ( W t ) ⊤ \frac{\partial\mathbf{h}^t}{\partial\mathbf{h}^{t-1}}=diag(\sigma^`(\mathbf{W^t h^{t-1}}))(\mathbf{W}^t)^\top ∂ht−1∂ht=diag(σ‘(Wtht−1))(Wt)⊤
而对于整个神经网络:
∏ i = t d − 1 ∂ h i + 1 ∂ h i = ∏ i = t d − 1 d i a g ( σ ‘ ( W i h i − 1 ) ) ( W i ) ⊤ \prod_{i=t}^{d-1}\frac{\partial\mathbf{h}^{i+1}}{\partial\mathbf{h}^{i}}=\prod_{i=t}^{d-1}diag(\sigma^`(\mathbf{W^i h^{i-1}}))(\mathbf{W}^i)^\top i=t∏d−1∂hi∂hi+1=i=t∏d−1diag(σ‘(Wihi−1))(Wi)⊤
其中,需要知道的是,由于激活函数是对输入参数的每个元素的操作,因此
d i a g ( σ ‘ ( W i h i − 1 ) ) diag(\sigma^`(\mathbf{W^i h^{i-1}})) diag(σ‘(Wihi−1))
这部分应该是一个对角矩阵,即对角线之外的元素都是0,只有对角线上是可能非零的
梯度爆炸
- 使用ReLU作为激活函数
σ ( x ) = max ( 0 , x ) a n d σ ‘ = { 1 i f x > 0 0 o t h e r w i s e \sigma(x)=\max(0,x)\ and\ \sigma^`=\left\{ \begin{aligned} 1 \quad if\ x>0\\ 0 \quad otherwise\\ \end{aligned} \right . σ(x)=max(0,x) and σ‘={1if x>00otherwise
∏ i = t d − 1 ∂ h i + 1 ∂ h i = ∏ i = t d − 1 d i a g ( σ ‘ ( W i h i − 1 ) ) ( W i ) ⊤ \prod_{i=t}^{d-1}\frac{\partial\mathbf{h}^{i+1}}{\partial\mathbf{h}^{i}}=\prod_{i=t}^{d-1}diag(\sigma^`(\mathbf{W^i h^{i-1}}))(\mathbf{W}^i)^\top i=t∏d−1∂hi∂hi+1=i=t∏d−1diag(σ‘(Wihi−1))(Wi)⊤
中的一些元素会来自于 ∏ i = t d − 1 ( W i ) ⊤ \prod_{i=t}^{d-1}(\mathbf{W}^i)^\top ∏i=td−1(Wi)⊤ - 如果d-t很大,值就会很大
梯度爆炸的问题
- 值超出值域(infinity)
- 对于16位浮点数尤为严重(6e-5 - 6e4),16位运算快,比较常用
- 对学习率敏感
- 如果学习率太大 -> 大参数值 -> 更大的梯度
- 学习率太小 -> 训练无进展
- 我们可能需要在训练过程中不断调整学习率
梯度消失
- 使用sigmoid作为激活函数
σ ( x ) = 1 1 + e − x \sigma(x)=\frac{1}{1+e^{-x}} σ(x)=1+e−x1 - 对这个激活函数求导:
σ ‘ ( x ) = σ ( x ) ( 1 − σ ( x ) ) \sigma^`(x)=\sigma(x)(1-\sigma(x)) σ‘(x)=σ(x)(1−σ(x))
得到的图像是:
可以发现,当输入稍微大一些时,导数会变为很小,趋近于0,根据原来计算的多层神经网络梯度计算的公式:
∏
i
=
t
d
−
1
∂
h
i
+
1
∂
h
i
=
∏
i
=
t
d
−
1
d
i
a
g
(
σ
‘
(
W
i
h
i
−
1
)
)
(
W
i
)
⊤
\prod_{i=t}^{d-1}\frac{\partial\mathbf{h}^{i+1}}{\partial\mathbf{h}^i}=\prod_{i=t}^{d-1}diag(\sigma^`(\mathbf{W^i h^{i-1}}))(\mathbf{W}^i)^\top
i=t∏d−1∂hi∂hi+1=i=t∏d−1diag(σ‘(Wihi−1))(Wi)⊤
其中
d
i
a
g
(
σ
‘
(
W
i
h
i
−
1
)
)
diag(\sigma^`(\mathbf{W^i h^{i-1}}))
diag(σ‘(Wihi−1))这个部分会很小
梯度消失的问题
- 梯度值变成0
- 对16位浮点数尤为严重
- 训练没有进展
- 不管如何选学习率
- 对于底部层尤为严重
- 仅仅顶部层训练较好
- 无法让神经网络更深
- 因为当层数越深的时候,梯度越小,最后梯度消失,导致较深的层次得到为0的梯度值,训练没有进展,而对于较浅的层则没有这样的问题
总结
- 数值过大或过小会导致数值问题
- 常发生在深度模型中,因为其会对n个数类乘
数值稳定
- 目标:让梯度值在合理范围内
- 例如[1e-6, 1e3]
- 将乘法变加法
- ResNet(很多层的时候,加入加法,使一些乘法变为加法),LSTM(时序的,时序序列很长,原始的时序神经网络太长了,太多乘法,也将乘法变为加法)
- 归一化
- 梯度归一化(比如把梯度变为均值为0,方差为1的数),梯度裁剪(强行把梯度控制在一个范围内,比如说大于5的都是5,小于-5的都设置为-5)
- 合理的权重初始和激活函数(这是这节的重点)
让每层的方差是一个常数
- 将每层的输出和梯度都看做随机变量
- 让他们的均值和方差都保持一致
怎么能达到这样的要求呢?
权重初始化
- 在合理值区间里随机初始参数
- 训练开始的时候更容易有数值不稳定
- 远离最优解的地方损失函数表面可能很复杂
- 最优解附近表面会比较平
- 使用 N ( 0 , 0.01 ) N(0,0.01) N(0,0.01)来初始化对小网络没问题,但是不能保证深度神经网络
例子:MLP
- 我们假设
- w i , j t w_{i,j}^t wi,jt是独立同分布,那么 E [ w i , j t ] = 0 , V a r [ w i , j t ] = γ t E[w_{i,j}^t]=0, Var[w_{i,j}^t]=\gamma_t E[wi,jt]=0,Var[wi,jt]=γt
- h i t − 1 h_i^{t-1} hit−1独立于 w i , j t w_{i,j}^t wi,jt
- 假设没有激活函数,即 h t = W t h t − 1 \mathbf{h}^t=\mathbf{W}^t \mathbf{h}^{t-1} ht=Wtht−1,这里 W t ∈ R n t ∗ n t − 1 \mathbf{W}^t\in R^{n_t*n_{t-1}} Wt∈Rnt∗nt−1
- 这里的乘法顺序与写代码的顺序相反,在代码中一般是 h t − 1 W t \mathbf{h}^{t-1}\mathbf{W}^t ht−1Wt,由于公式顺序相反,因此对于 h t − 1 \mathbf{h}^{t-1} ht−1,它的维度应该是: dim ( h t − 1 ) = n t − 1 ∗ m \dim({\mathbf{h}^{t-1}})=n_{t-1}*m dim(ht−1)=nt−1∗m,也就是行数为特征数,列数为样本数
正向均值
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
E[h_i^t]=E[\sum_jw_{i,j}^th_j^{t-1}]=\sum_jE[w_{i,j}^t]E[h_j^{t-1}]=0
E[hit]=E[j∑wi,jthjt−1]=j∑E[wi,jt]E[hjt−1]=0
我们假设,输入的样本数只有一个,那么对于
h
t
−
1
\mathbf{h^{t-1}}
ht−1来说,应该是一个
n
t
−
1
∗
1
n_{t-1}*1
nt−1∗1维度的向量(列数为样本量),那么,在
W
t
h
t
−
1
\mathbf{W}^t \mathbf{h}^{t-1}
Wtht−1计算之后得到的
h
t
\mathbf{h}^t
ht应该是一个
n
t
∗
1
n_{t}*1
nt∗1维度的向量。那么,我们选取第
i
i
i行时,
h
i
t
h_i^t
hit就是一个张量了,而该张量怎么计算的呢?根据矩阵的定义,就是
∑
j
w
i
,
j
t
h
j
t
−
1
\sum_jw_{i,j}^th_j^{t-1}
∑jwi,jthjt−1,也就是将
W
t
\mathbf{W^t}
Wt的第
i
i
i行拿出来,和向量
h
t
−
1
\mathbf{h^{t-1}}
ht−1做矩阵运算,得到如上的结果
正向方差
V
a
r
[
h
i
t
]
=
E
[
(
h
i
t
)
2
]
−
E
[
h
i
t
]
2
=
E
[
(
∑
j
w
i
,
j
t
h
j
t
−
1
)
2
]
Var[h_i^t]=E[(h_i^t)^2]-E[h_i^t]^2=E[(\sum_jw_{i,j}^th_j^{t-1})^2]
Var[hit]=E[(hit)2]−E[hit]2=E[(j∑wi,jthjt−1)2]
然后根据平方的运算定义,可以计算为每个项的平方加上交叉项
=
E
[
∑
j
(
w
i
,
j
t
)
2
(
h
j
t
−
1
)
2
+
∑
j
≠
k
w
i
,
j
t
w
i
,
k
t
h
j
t
−
1
h
k
t
−
1
]
=E[\sum_j(w_{i,j}^t)^2(h_j^{t-1})^2+\sum_{j\neq k}w_{i,j}^t w_{i,k}^t h_j^{t-1} h_k^{t-1}]
=E[j∑(wi,jt)2(hjt−1)2+j=k∑wi,jtwi,kthjt−1hkt−1]
由于都是独立同分布的,所有式子的右边为0
= E [ ∑ j ( w i , j t ) 2 ( h j t − 1 ) 2 ] = ∑ j E [ ( w i , j t ) 2 ] E [ ( h j t − 1 ) 2 ] =E[\sum_j(w_{i,j}^t)^2(h_j^{t-1})^2]=\sum_jE[(w_{i,j}^t)^2]E[(h_j^{t-1})^2] =E[j∑(wi,jt)2(hjt−1)2]=j∑E[(wi,jt)2]E[(hjt−1)2]
对于上面的结果,因为:
E
[
w
i
,
j
t
]
=
0
E[w_{i,j}^t]=0
E[wi,jt]=0
V
a
r
[
w
i
,
j
t
]
=
E
[
(
w
i
,
j
t
)
2
]
−
E
[
w
i
,
j
t
]
2
=
E
[
(
w
i
,
j
t
)
2
]
=
γ
t
Var[w_{i,j}^t]=E[(w_{i,j}^t)^2]-E[w_{i,j}^t]^2=E[(w_{i,j}^t)^2]=\gamma_t
Var[wi,jt]=E[(wi,jt)2]−E[wi,jt]2=E[(wi,jt)2]=γt
所以:
= ∑ j V a r [ w i , j t ] V a r [ h j t − 1 ] = n t − 1 γ t V a r [ h j t − 1 ] =\sum_jVar[w_{i,j}^t]Var[h_j^{t-1}]=n_{t-1}\gamma_tVar[h_j^{t-1}] =j∑Var[wi,jt]Var[hjt−1]=nt−1γtVar[hjt−1]
综上:
V
a
r
[
h
i
t
]
=
n
t
−
1
γ
t
V
a
r
[
h
j
t
−
1
]
Var[h_i^t]=n_{t-1}\gamma_tVar[h_j^{t-1}]
Var[hit]=nt−1γtVar[hjt−1]
如果要保证输入和输出的方差保持一致,则要求
n
t
−
1
γ
t
=
1
n_{t-1}\gamma_t=1
nt−1γt=1
反向均值和方差
- 和正向类似,因为在假设中是没有激活函数的,所以根据链式法则,我们可以得到:
∂ ℓ ∂ h t − 1 = ∂ ℓ ∂ h t ∂ h t ∂ h t − 1 = ∂ ℓ ∂ h t W t \frac{\partial\ell}{\partial\mathbf{h}^{t-1}}=\frac{\partial\ell}{\partial\mathbf {h}^t}\frac{\partial\mathbf{h}^t}{\partial\mathbf{h}^{t-1}}=\frac{\partial\ell}{\partial\mathbf {h}^t}\mathbf{W}^t ∂ht−1∂ℓ=∂ht∂ℓ∂ht−1∂ht=∂ht∂ℓWt
在式子中 ∂ h t ∂ h t − 1 \frac{\partial\mathbf{h}^t}{\partial\mathbf{h}^{t-1}} ∂ht−1∂ht相当于对 y = a x y=ax y=ax计算 ∂ y ∂ x \frac{\partial y}{\partial x} ∂x∂y,得到的结果是变量 a a a,即 W t \mathbf{W}^t Wt
E
[
∂
ℓ
∂
h
i
t
−
1
]
=
0
E[\frac{\partial\ell}{\partial h_i^{t-1}}]=0
E[∂hit−1∂ℓ]=0
V
a
r
[
∂
ℓ
∂
h
i
t
−
1
]
=
∑
j
V
a
r
[
∂
ℓ
∂
h
j
t
]
V
a
r
[
w
i
,
j
t
]
=
n
t
γ
t
V
a
r
[
∂
ℓ
∂
h
j
t
]
Var[\frac{\partial\ell}{\partial h_i^{t-1}}]=\sum_jVar[\frac{\partial\ell}{\partial h_j^{t}}]Var[w_{i,j}^t]=n_{t}\gamma_tVar[\frac{\partial\ell}{\partial h_j^{t}}]
Var[∂hit−1∂ℓ]=j∑Var[∂hjt∂ℓ]Var[wi,jt]=ntγtVar[∂hjt∂ℓ]
(这里的j可以是任意的)
所以:
n
t
γ
t
=
1
n_{t}\gamma_t=1
ntγt=1
计算方法和正向是类似的,可以直接带入正向的式子中尝试,其中差异就是正向是
t
−
1
t-1
t−1到
t
t
t层,其中
j
j
j的数量是
n
t
−
1
n_{t-1}
nt−1,而这是方向的,是
t
t
t层到
t
−
1
t-1
t−1层,其中
j
j
j的数量是
n
t
n_{t}
nt
Xavier初始
- 难以需要满足 n t − 1 γ t = 1 n_{t-1}\gamma_t=1 nt−1γt=1和 n t γ t = 1 n_{t}\gamma_t=1 ntγt=1,因为 n t − 1 n_{t-1} nt−1和 n t n_t nt是我们无法控制的,除非输入刚好等于输出
- Xavier使得
γ
t
(
n
t
−
1
+
n
t
)
/
2
=
1
→
γ
t
=
2
/
(
n
t
−
1
+
n
t
)
\gamma_t(n_{t-1}+n_t)/2=1\rightarrow \gamma_t=2/(n_{t-1}+n_t)
γt(nt−1+nt)/2=1→γt=2/(nt−1+nt),也就是说给定
t
t
t输出和
t
−
1
t-1
t−1层输出,可以计算
t
t
t层的方差,决定了第
t
t
t层初始化的时候采用什么样的随机分布
- 正态分布 N ( 0 , 2 / ( n t − 1 + n t ) ) N(0,\sqrt{2/(n_{t-1}+n_t)}) N(0,2/(nt−1+nt))
- 均匀分布 u ( − 6 / ( n t − 1 + n t ) , 6 / ( n t − 1 + n t ) ) u(-\sqrt{6/(n_{t-1}+n_t)},\sqrt{6/(n_{t-1}+n_t)}) u(−6/(nt−1+nt),6/(nt−1+nt))
- 根据输入输出来适配权重形状
假设线性的激活函数
- 假设
σ
(
x
)
=
a
x
+
b
\sigma(x)=ax+b
σ(x)=ax+b
h ‘ = W t h t − 1 a n d h t = σ ( h ‘ ) \mathbf{h}^`=\mathbf{W}^t\mathbf{h}^{t-1}\ and\ \mathbf{h}^t=\sigma(\mathbf{h}^`) h‘=Wtht−1 and ht=σ(h‘)
E [ h i t ] = E [ a h i ‘ + b ] = b → b = 0 E[h_i^t]=E[ah_i^`+b]=b\ \rightarrow\ b=0 E[hit]=E[ahi‘+b]=b → b=0
V a r [ h i t ] = E [ ( h i t ) 2 ] − E [ h i t ] 2 = E [ ( a h i ‘ + b ) 2 ] − b 2 = E [ ( a h i ‘ ) 2 + b 2 + 2 a b h i ‘ ] − b 2 = E [ a 2 ( h i ‘ ) 2 ] = a 2 V a r [ h i ‘ ] → a = 1 \begin{aligned} Var[h_i^t]&=E[(h_i^t)^2]-E[h_i^t]^2\\ & =E[(ah_i^`+b)^2]-b^2 \\ &=E[(ah_i^`)^2+b^2+2abh_i^`]-b^2 \\ & =E[a^2(h_i^`)^2]\\ &=a^2Var[h_i^`] \rightarrow a=1 \end{aligned} Var[hit]=E[(hit)2]−E[hit]2=E[(ahi‘+b)2]−b2=E[(ahi‘)2+b2+2abhi‘]−b2=E[a2(hi‘)2]=a2Var[hi‘]→a=1
对于反向,也差不多,得到一样的结论
∂ ℓ ∂ h ‘ = ∂ ℓ ∂ h t ( W t ) ⊤ a n d ∂ ℓ ∂ h t − 1 = a ∂ ℓ ∂ h ‘ \frac{\partial\ell}{\partial\mathbf{h}^`}=\frac{\partial\ell}{\partial\mathbf{h}^t}(\mathbf{W}^t)^\top \ and\ \frac{\partial\ell}{\partial\mathbf{h}^{t-1}}=a\frac{\partial\ell}{\partial\mathbf{h}^`} ∂h‘∂ℓ=∂ht∂ℓ(Wt)⊤ and ∂ht−1∂ℓ=a∂h‘∂ℓ
(and后的式子应该是错误的)
E
[
∂
ℓ
∂
h
i
t
−
1
]
=
0
→
b
=
0
E[\frac{\partial\ell}{\partial h_i^{t-1}}]=0\ \rightarrow\ b=0
E[∂hit−1∂ℓ]=0 → b=0
V
a
r
[
∂
ℓ
∂
h
i
t
−
1
]
=
a
2
V
a
r
[
∂
ℓ
∂
h
j
‘
]
→
a
=
1
Var[\frac{\partial\ell}{\partial h_i^{t-1}}]=a^2Var[\frac{\partial\ell}{\partial h_j^{`}}]\ \rightarrow\ a=1
Var[∂hit−1∂ℓ]=a2Var[∂hj‘∂ℓ] → a=1
综上,意味着激活函数必须是 f ( x ) = x f(x)=x f(x)=x
检查常用激活函数
- 使用泰勒展开
s i g m o i d ( x ) = 1 2 + x 4 − x 3 48 + O ( x 5 ) sigmoid(x)=\frac{1}{2}+\frac{x}{4}-\frac{x^3}{48}+O(x^5) sigmoid(x)=21+4x−48x3+O(x5)
t a n h ( x ) = 0 + x − x 3 3 + O ( x 5 ) tanh(x)=0+x-\frac{x^3}{3}+O(x^5) tanh(x)=0+x−3x3+O(x5)
r e l u ( x ) = 0 + x f o r x ≥ 0 relu(x)=0+x\ for\ x\ge0 relu(x)=0+x for x≥0
可以发现,对于tanh和relu,在零点附近是近似于 f ( x ) = x f(x)=x f(x)=x,而且神经网络通常值是在零点附近的比较小的数,因此tanh和relu满足要求
对于sigmoid需要调整: 4 ∗ s i g m o i d ( x ) − 2 4*sigmoid(x)-2 4∗sigmoid(x)−2
总结
- 合理的权重初始值和激活函数的选取可以提升数值稳定性