【NumPy】MNIST上深度学习计算过程理解:二、大权重初始化问题
一、背景
基于对应链接示例上的深度学习过程,对每一步进行详细的说明,方便数据和实例的结合理解深度学习的过程。
示例的简单介绍:提供0-9的数字灰度照片进行深度学习训练,数据包括6万张训练图像和1万张测试图像以及对应的标签(即0-9的标签)。图像的像素为28*28,大小为784。
续:为什么选择小权重进行初始化
二、梯度
梯度概念
梯度 是一个向量,指向函数值变化最快的方向。神经网络中,使用梯度下降法优化损失函数,沿着梯度反方向更新权重,使损失函数值减小。
"""
比喻1:爬山
- 你站在山上,想知道哪条路下山最快
- 梯度就是指向最陡峭下山方向的箭头
- 箭头长度表示坡度的陡峭程度
比喻2:导航系统
- 你在城市中,想找到去目的地的最近路线
- 梯度就是告诉你"往东走100米,再往北走50米"
- 梯度方向:最佳前进方向
- 梯度大小:需要前进的距离
"""
数学定义(求偏导):
对于多元函数 f ( w ) , 其中 w = ( w 1 , w 2 , . . . , w n ) ,梯度定义为 : 对于多元函数f(w),其中 w=(w_1,w_2,...,w_n),梯度定义为: 对于多元函数f(w),其中w=(w1,w2,...,wn),梯度定义为:
∇ f ( w ) = ( ∂ f ∂ w 1 , ∂ f ∂ w 2 , . . . , ∂ f ∂ w n ) ∇f(w)=(\frac{\partial f}{\partial w_1},\frac{\partial f}{\partial w_2},...,\frac{\partial f}{\partial w_n}) ∇f(w)=(∂w1∂f,∂w2∂f,...,∂wn∂f)
更新权重公式:
w ← w − η ∗ ∇ f w ) w←w−η*∇fw) w←w−η∗∇fw)
其中 η 是学习率。
在神经网络中,梯度表示:当权重发生微小变化时,损失函数的变化率。如果梯度很大,说明权重的微小变化会导致损失函数大幅变化;如果梯度很小,说明权重的变化对损失函数影响很小。
梯度消失
是什么? 在神经网络中,反向传播过程中,传递从输出层向输入层传递时,梯度值越来越小,前面几层的权重更新非常缓慢,甚至停止更新。
三、大随机数初始化导致梯度消失
以sigmoid激活函数为例
sigmoid函数及其导数如下:
σ ( x ) = 1 1 + e − x , σ ′ ( x ) = σ ( x ) ( 1 − σ ( x ) ) σ(x) = {1\over 1+e^{-x}}, σ'(x)=σ(x)(1−σ(x)) σ(x)=1+e−x1,σ′(x)=σ(x)(1−σ(x))
sigmoid函数的导数图像为钟形曲线,最大值在x=0处,为0.25。当|x|较大时,导数趋近于0。
如果我们使用大随机数初始化权重,比如权重值在[-1, 1]之间,那么对于隐藏层的每个神经元,其输入加权和可能很大(因为权重和输入值的乘积累加)。例如,如果输入值在[0,1]之间,权重在[-1,1]之间,那么加权和可能远大于1或远小于-1。
当加权和的绝对值很大时,sigmoid函数的输出会接近0或1,此时导数接近0。在反向传播时,梯度需要乘以这些导数值,因此梯度会迅速减小。
具体示例
考虑一个简单的三层网络(输入层、隐藏层、输出层),使用sigmoid激活函数。
前向传播:
- 隐藏层输入: z h = W 1 x + b 1 z_h=W_1x+b_1 zh=W1x+b1
- 隐藏层输出: a h = σ ( z h ) a_h=σ(z_h) ah=σ(zh)
- 输出层输入: z o = W 2 a h + b 2 z_o=W_2a_h+b_2 zo=W2ah+b2
- 输出层输出: a o = σ ( z o ) a_o=σ(z_o) ao=σ(zo)
反向传播:
- 输出层误差: δ o = ( a o − y ) ⋅ σ ′ ( z o ) δ_o=(a_o−y)⋅σ'(z_o) δo=(ao−y)⋅σ′(zo)
- 隐藏层误差: δ h = ( W 2 T δ o ) ⋅ σ ′ ( z h ) δ_h=(W_2^Tδ_o)⋅σ'(z_h) δh=(W2Tδo)⋅σ′(zh)
如果权重初始化过大,导致 z h z_h zh和 z o z_o zo的绝对值很大,那么 σ ′ ( z h ) σ'(z_h) σ′(zh)和 σ ′ ( z o ) σ'(z_o) σ′(zo)就会很小。根据链式法则,隐藏层的误差 δ h δ_h δh会非常小,进而导致梯度消失。
梯度消失的影响
梯度消失会导致网络的前面几层权重更新非常缓慢,因为这些层的梯度几乎为零。这意味着前面几层无法有效地学习,整个网络的性能会下降。
四、数值示例
通过一个具体的数值计算来展示大权重如何导致梯度消失。
假设:
- 输入 x = [ 0.5 , 0.5 ] x = [0.5, 0.5] x=[0.5,0.5]
- 权重 W 1 W_1 W1(2x2)初始化为大值: [ [ 2.0 , − 2.0 ] , [ 2.0 , − 2.0 ] ] [[2.0, -2.0], [2.0, -2.0]] [[2.0,−2.0],[2.0,−2.0]]
- 偏置 b 1 b_1 b1 = [ 0.0 , 0.0 ] [0.0, 0.0] [0.0,0.0]
- 权重 W 2 W_2 W2(2x1)初始化为大值: [ [ 2.0 ] , [ 2.0 ] ] [[2.0], [2.0]] [[2.0],[2.0]]
- 偏置 b 2 b_2 b2 = [ 0.0 ] [0.0] [0.0]
- 目标输出 y = 0.5 y = 0.5 y=0.5
使用sigmoid激活函数。
前向传播:
- 隐藏层输入: z 1 = x ∗ W 1 = [ 0.5 ∗ 2.0 + 0.5 ∗ 2.0 , 0.5 ∗ ( − 2.0 ) + 0.5 ∗ ( − 2.0 ) ] = [ 2.0 , − 2.0 ] z_1 = x * W_1 = [0.5*2.0+0.5*2.0, 0.5*(-2.0)+0.5*(-2.0)] = [2.0, -2.0] z1=x∗W1=[0.5∗2.0+0.5∗2.0,0.5∗(−2.0)+0.5∗(−2.0)]=[2.0,−2.0]
- 隐藏层输出: a 1 = s i g m o i d ( z 1 ) = [ s i g m o i d ( 2.0 ) , s i g m o i d ( − 2.0 ) ] ≈ [ 0.8808 , 0.1192 ] a_1 = sigmoid(z_1) = [sigmoid(2.0), sigmoid(-2.0)] ≈ [0.8808, 0.1192] a1=sigmoid(z1)=[sigmoid(2.0),sigmoid(−2.0)]≈[0.8808,0.1192]
- 输出层输入: z 2 = a 1 ∗ W 2 = 0.8808 ∗ 2.0 + 0.1192 ∗ 2.0 = 2.0 z_2 = a_1 * W_2 = 0.8808*2.0 + 0.1192*2.0 = 2.0 z2=a1∗W2=0.8808∗2.0+0.1192∗2.0=2.0
- 输出层输出: a 2 = s i g m o i d ( 2.0 ) ≈ 0.8808 a_2 = sigmoid(2.0) ≈ 0.8808 a2=sigmoid(2.0)≈0.8808
计算损失(使用均方误差):
损失 L = 0.5 ∗ ( a 2 − y ) 2 = 0.5 ∗ ( 0.8808 − 0.5 ) 2 ≈ 0.0725 L = 0.5 * (a_2 - y)^2 = 0.5 * (0.8808 - 0.5)^2 ≈ 0.0725 L=0.5∗(a2−y)2=0.5∗(0.8808−0.5)2≈0.0725
反向传播:
- 输出层梯度:
- ∂ L / ∂ a 2 = a 2 − y = 0.8808 − 0.5 = 0.3808 ∂L/∂a_2 = a_2 - y = 0.8808 - 0.5 = 0.3808 ∂L/∂a2=a2−y=0.8808−0.5=0.3808
- ∂ a 2 / ∂ z 2 = s i g m o i d ′ ( z 2 ) = a 2 ∗ ( 1 − a 2 ) = 0.8808 ∗ ( 1 − 0.8808 ) ≈ 0.1045 ∂a_2/∂z_2 = sigmoid'(z_2) = a_2 * (1 - a_2 ) = 0.8808 * (1-0.8808) ≈ 0.1045 ∂a2/∂z2=sigmoid′(z2)=a2∗(1−a2)=0.8808∗(1−0.8808)≈0.1045
- 所以 δ 2 = ∂ L / ∂ z 2 = ∂ L / ∂ a 2 ∗ ∂ a 2 / ∂ z 2 = 0.3808 ∗ 0.1045 ≈ 0.0398 δ_2 = ∂L/∂z_2 = ∂L/∂a_2 * ∂a_2/∂z_2 = 0.3808 * 0.1045 ≈ 0.0398 δ2=∂L/∂z2=∂L/∂a2∗∂a2/∂z2=0.3808∗0.1045≈0.0398
- 隐藏层梯度:
- 首先, ∂ L / ∂ a 1 = δ 2 ∗ W 2 T = 0.0398 ∗ [ 2.0 , 2.0 ] = [ 0.0796 , 0.0796 ] ∂L/∂a_1 = δ_2 * W_2^T = 0.0398 * [2.0, 2.0] = [0.0796, 0.0796] ∂L/∂a1=δ2∗W2T=0.0398∗[2.0,2.0]=[0.0796,0.0796]
- 然后, ∂ a 1 / ∂ z 1 = a 1 ∗ ( 1 − a 1 ) = [ 0.8808 ∗ ( 1 − 0.8808 ) , 0.1192 ∗ ( 1 − 0.1192 ) ] ≈ [ 0.1045 , 0.1050 ] ∂a_1/∂z_1 = a_1 * (1 - a_1) = [0.8808*(1-0.8808), 0.1192*(1-0.1192)] ≈ [0.1045, 0.1050] ∂a1/∂z1=a1∗(1−a1)=[0.8808∗(1−0.8808),0.1192∗(1−0.1192)]≈[0.1045,0.1050]
- 所以 δ 1 = ∂ L / ∂ z 1 = ∂ L / ∂ a 1 ∗ ∂ a 1 / ∂ z 1 = [ 0.0796 ∗ 0.1045 , 0.0796 ∗ 0.1050 ] ≈ [ 0.00832 , 0.00836 ] δ_1 = ∂L/∂z_1 = ∂L/∂a_1 * ∂a_1/∂z_1 = [0.0796*0.1045, 0.0796*0.1050] ≈ [0.00832, 0.00836] δ1=∂L/∂z1=∂L/∂a1∗∂a1/∂z1=[0.0796∗0.1045,0.0796∗0.1050]≈[0.00832,0.00836]
可以看到,隐藏层的梯度( δ 1 δ_1 δ1)大约是0.008,而输出层的梯度( δ 2 δ_2 δ2)大约是0.04。如果网络更深,梯度会进一步缩小。
权重初始化得更小,比如在[-0.1, 0.1]之间,重新计算:
假设:
- W 1 = [ [ 0.1 , − 0.1 ] , [ 0.1 , − 0.1 ] ] W_1 = [[0.1, -0.1], [0.1, -0.1]] W1=[[0.1,−0.1],[0.1,−0.1]]
- W 2 = [ [ 0.1 ] , [ 0.1 ] ] W_2 = [[0.1], [0.1]] W2=[[0.1],[0.1]]
前向传播:
- z 1 = [ 0.5 ∗ 0.1 + 0.5 ∗ 0.1 , 0.5 ∗ ( − 0.1 ) + 0.5 ∗ ( − 0.1 ) ] = [ 0.1 , − 0.1 ] z_1 = [0.5*0.1+0.5*0.1, 0.5*(-0.1)+0.5*(-0.1)] = [0.1, -0.1] z1=[0.5∗0.1+0.5∗0.1,0.5∗(−0.1)+0.5∗(−0.1)]=[0.1,−0.1]
- a 1 = [ s i g m o i d ( 0.1 ) , s i g m o i d ( − 0.1 ) ] ≈ [ 0.5249 , 0.4751 ] a_1 = [sigmoid(0.1), sigmoid(-0.1)] ≈ [0.5249, 0.4751] a1=[sigmoid(0.1),sigmoid(−0.1)]≈[0.5249,0.4751]
- z 2 = 0.5249 ∗ 0.1 + 0.4751 ∗ 0.1 = 0.1 z_2 = 0.5249*0.1 + 0.4751*0.1 = 0.1 z2=0.5249∗0.1+0.4751∗0.1=0.1
- a 2 = s i g m o i d ( 0.1 ) ≈ 0.5249 a_2 = sigmoid(0.1) ≈ 0.5249 a2=sigmoid(0.1)≈0.5249
反向传播:
- 输出层梯度:
- ∂ L / ∂ a 2 = 0.5249 − 0.5 = 0.0249 ∂L/∂a_2 = 0.5249 - 0.5 = 0.0249 ∂L/∂a2=0.5249−0.5=0.0249
- ∂ a 2 / ∂ z 2 = 0.5249 ∗ ( 1 − 0.5249 ) ≈ 0.249 ∂a2/∂z_2 = 0.5249*(1-0.5249) ≈ 0.249 ∂a2/∂z2=0.5249∗(1−0.5249)≈0.249
- δ 2 = 0.0249 ∗ 0.249 ≈ 0.0062 δ_2 = 0.0249 * 0.249 ≈ 0.0062 δ2=0.0249∗0.249≈0.0062
- 隐藏层梯度:
- ∂ L / ∂ a 1 = 0.0062 ∗ [ 0.1 , 0.1 ] = [ 0.00062 , 0.00062 ] ∂L/∂a_1 = 0.0062 * [0.1, 0.1] = [0.00062, 0.00062] ∂L/∂a1=0.0062∗[0.1,0.1]=[0.00062,0.00062]
- ∂ a 1 / ∂ z 1 = [ 0.5249 ∗ ( 1 − 0.5249 ) , 0.4751 ∗ ( 1 − 0.4751 ) ] ≈ [ 0.249 , 0.249 ] ∂a_1/∂z_1 = [0.5249*(1-0.5249), 0.4751*(1-0.4751)] ≈ [0.249, 0.249] ∂a1/∂z1=[0.5249∗(1−0.5249),0.4751∗(1−0.4751)]≈[0.249,0.249]
- δ 1 = [ 0.00062 ∗ 0.249 , 0.00062 ∗ 0.249 ] ≈ [ 0.000154 , 0.000154 ] δ_1 = [0.00062*0.249, 0.00062*0.249] ≈ [0.000154, 0.000154] δ1=[0.00062∗0.249,0.00062∗0.249]≈[0.000154,0.000154]
在这个例子中,虽然梯度仍然很小,但这是因为我们的网络很浅,而且损失本身很小。但我们可以看出,当权重较小时,sigmoid函数的导数在0.25左右,而权重较大时,sigmoid函数的导数会很小(如第一个例子中输出层的导数约为0.1045,隐藏层的导数约为0.105)。如果网络更深,大权重导致的梯度消失会更明显。
更多推荐
所有评论(0)