【深度学习基础】系列博客为学习Coursera上吴恩达深度学习课程所做的课程笔记。

1.梯度消失和梯度爆炸

假设我们正在训练一个极深的神经网络(为了简化理解,每层只有两个神经元):

该网络的每一层的参数为: w [ 1 ] , w [ 2 ] , w [ 3 ] , . . . . . . , w [ L ] w^{[1]},w^{[2]},w^{[3]},......,w^{[L]} w[1],w[2],w[3],......,w[L]。为了简化问题,假设激活函数为: g ( z ) = z g(z)=z g(z)=z,为线性激活函数。同时忽略b,假设 b [ l ] = 0 , l ∈ [ 1 , L ] b^{[l]}=0,l\in [1,L] b[l]=0,l[1,L]

因此有:

  • a [ 1 ] = z [ 1 ] = w [ 1 ] X a^{[1]}=z^{[1]}=w^{[1]}X a[1]=z[1]=w[1]X
  • a [ 2 ] = z [ 2 ] = w [ 2 ] a [ 1 ] = w [ 2 ] w [ 1 ] X a^{[2]}=z^{[2]}=w^{[2]}a^{[1]}=w^{[2]}w^{[1]}X a[2]=z[2]=w[2]a[1]=w[2]w[1]X
  • a [ 3 ] = z [ 3 ] = w [ 3 ] w [ 2 ] w [ 1 ] X a^{[3]}=z^{[3]}=w^{[3]}w^{[2]}w^{[1]}X a[3]=z[3]=w[3]w[2]w[1]X
  • y ^ = w [ L ] w [ L − 1 ] w [ L − 2 ] . . . . . . w [ 3 ] w [ 2 ] w [ 1 ] X \hat y=w^{[L]}w^{[L-1]}w^{[L-2]}......w^{[3]}w^{[2]}w^{[1]}X y^=w[L]w[L1]w[L2]......w[3]w[2]w[1]X

假设每一个

w [ l ] = [ 1.5 0 0 1.5 ] w^{[l]}=\begin{bmatrix} 1.5 & 0 \\ 0 & 1.5 \\ \end{bmatrix} w[l]=[1.5001.5]

(注意 w [ L ] w^{[L]} w[L]的维度可能和其他的不一样,这里可以忽略这个问题)。最终可得到:

y ^ = w [ L ] [ 1. 5 L − 1 0 0 1. 5 L − 1 ] X \hat y = w^{[L]} \begin{bmatrix} 1.5^{L-1} & 0 \\ 0 & 1.5^{L-1} \\ \end{bmatrix} X y^=w[L][1.5L1001.5L1]X

此时 y ^ \hat y y^和激活函数的值会呈指数级增长。相反的,如果每一个

w [ l ] = [ 0.5 0 0 0.5 ] w^{[l]}=\begin{bmatrix} 0.5 & 0 \\ 0 & 0.5 \\ \end{bmatrix} w[l]=[0.5000.5]

,则:

y ^ = w [ L ] [ 0. 5 L − 1 0 0 0. 5 L − 1 ] X \hat y = w^{[L]} \begin{bmatrix} 0.5^{L-1} & 0 \\ 0 & 0.5^{L-1} \\ \end{bmatrix} X y^=w[L][0.5L1000.5L1]X

此时 y ^ \hat y y^和激活函数的值会呈指数级下降。

那么上述情况下对应的梯度也会呈指数级的上升或者下降,这就会导致训练的时间大大加长。这就是所谓的梯度消失和梯度爆炸

⚠️是否会出现梯度消失、梯度爆炸问题和激活函数的类型密切相关。并且梯度消失、梯度爆炸问题一般会随着网络层数的增加而变得越来越明显。

2.权重初始化

梯度消失和梯度爆炸的解决办法之一就是更谨慎的选择随机初始化参数。

当激活函数为ReLU函数时,可随机初始化参数( n [ l ] n^{[l]} n[l]表示第l层的神经元数):

w [ l ] = n p . r a n d o m . r a n d n ( n [ l ] , n [ l − 1 ] ) ∗ n p . s q r t ( 2 n [ l − 1 ] ) w^{[l]}=np.random.randn(n^{[l]},n^{[l-1]}) * np.sqrt(\frac{2}{n^{[l-1]}}) w[l]=np.random.randn(n[l],n[l1])np.sqrt(n[l1]2)

当激活函数为tanh函数时,可随机初始化参数:

w [ l ] = n p . r a n d o m . r a n d n ( n [ l ] , n [ l − 1 ] ) ∗ n p . s q r t ( 1 n [ l − 1 ] ) w^{[l]}=np.random.randn(n^{[l]},n^{[l-1]}) * np.sqrt(\frac{1}{n^{[l-1]}}) w[l]=np.random.randn(n[l],n[l1])np.sqrt(n[l1]1)

这种方式称为Xavier初始化。或者也可以:

w [ l ] = n p . r a n d o m . r a n d n ( n [ l ] , n [ l − 1 ] ) ∗ n p . s q r t ( 2 n [ l − 1 ] + n [ l ] ) w^{[l]}=np.random.randn(n^{[l]},n^{[l-1]}) * np.sqrt(\frac{2}{n^{[l-1]}+n^{[l]}}) w[l]=np.random.randn(n[l],n[l1])np.sqrt(n[l1]+n[l]2)

❗️上述公式中通过高斯分布随机初始化参数后又乘上了一个数值,比如 n p . s q r t ( 2 n [ l − 1 ] ) np.sqrt(\frac{2}{n^{[l-1]}}) np.sqrt(n[l1]2)等,这个数值也可作为神经网络的一个超参数。但通常并不作为调优时的首选,其优先级一般较低。


想要获取最新文章推送或者私聊谈人生,请关注我的个人微信公众号:⬇️x-jeff的AI工坊⬇️

个人博客网站:https://shichaoxin.com

GitHub:https://github.com/x-jeff


Logo

脑启社区是一个专注类脑智能领域的开发者社区。欢迎加入社区,共建类脑智能生态。社区为开发者提供了丰富的开源类脑工具软件、类脑算法模型及数据集、类脑知识库、类脑技术培训课程以及类脑应用案例等资源。

更多推荐