以下是链接我个人关于深度学习的所有见解,其后会对深度学习思想,正反向传播,损失函数,正则惩罚,梯度下降,矩阵求导,网络搭建,等等都进行详细的讲解!只有你想不到的,没有我讲不到的。让我用最通俗的语言,为你留下最深刻的印象,后来的年轻人以及我徒弟,好好加油! 深度解剖(0):最通俗易懂,详细无死角的深度学习讲解(目录) 如果有说得不对的地方,欢迎大家指出,我会第一时间进行更正,有兴趣可以加微信a944284742一起讨论技术,如果觉得喜欢,一定要点赞,因为这是对我最大的鼓励。
损失函数先来看看我们上小节辛苦推导出来的公式: a ( i , L ) = σ ( z L ) = σ ( a ( i , L − 1 ) ⋅ w ( i , L ) + b ( L ) ) a^{(i,L)} =\sigma (z^{L}) = \sigma(a^{(i,L-1)}·w^{(i,L)} + b^{(L)}) a(i,L)=σ(zL)=σ(a(i,L−1)⋅w(i,L)+b(L))通过这个公式,我们可以进行前向传播,简单的说,给定一个输入,通过前向传播就能获得一个预测值,这里说到预测值,我们肯定会联想到 l o s s loss loss,其代表的是损失,前面为了方便理解,我给大家说: l o s s = 预测值 − 真实值 loss = 预测值 - 真实值 loss=预测值−真实值,通过链式法则反向传播更新参数 w , b w,b w,b之后,通过多次迭代,loss会减少。在实际中,我们的损失函数是这样定义的: 单个样本: l o s s ( L ) ( x , w , b , y ) = 1 2 ∣ ∣ a L − y ∣ ∣ 2 2 单个样本:loss^{(L)}(x,w,b,y) = \frac{1}{2}||a^L-y||_2^2 单个样本:loss(L)(x,w,b,y)=21∣∣aL−y∣∣22
多个样本: l o s s ( n , L ) ( x , w , b , y ) = 1 n ∑ i = 0 n 1 2 ∣ ∣ a L − y ∣ ∣ 2 2 多个样本:loss^{(n,L)}(x,w,b,y) = \frac{1}{n}∑ _{i=0}^n \frac{1}{2}||a^L-y||_2^2 多个样本:loss(n,L)(x,w,b,y)=n1i=0∑n21∣∣aL−y∣∣22 大家不要觉得这个 1 2 \frac{1}{2} 21很奇怪,其是为了后面反向求导的方便,为了容易理解,假设我们使用单个样本进行训练,即使用下面的推导 l o s s ( L ) ( x , w , b , y ) = 1 2 ∣ ∣ a L − y ∣ ∣ 2 2 loss^{(L)}(x,w,b,y) = \frac{1}{2}||a^L-y||_2^2 loss(L)(x,w,b,y)=21∣∣aL−y∣∣22大家需要注意的是, ∣ ∣ a L − y ∣ ∣ 2 ||a^L-y||_2 ∣∣aL−y∣∣2,表示是L2范数,因为我们的输出 a L a^L aL虽然是一个样本训练的结果,但是这个结果可能是多列的,即不单单是一维的。但是计算得到 l o s s loss loss,一般都是一个数值。并且也请大家注意到 l o s s ( L ) ( x , w , b , y ) loss^{(L)}(x,w,b,y) loss(L)(x,w,b,y),其大小只与 x , w , b , y x,w,b,y x,w,b,y相关,同时,这里的 w , b w,b w,b是没有上标的,其代表的并不是某一层的 w w w,而是所有网络结构 w w w的综合,当然 b b b也是一样。
bp算法单层公式推导上面我们通过前向传播,得到 a L a^L aL,然后计算得到损失 l o s s loss loss,并且告诉大家其 l o s s loss loss只和参数 ( x , w , b , y ) (x,w,b,y) (x,w,b,y)相关,为了直接的体现出来我在这里把公式代入展开: l o s s ( L ) ( x , w , b , y ) = 1 2 ∣ ∣ σ ( z L ) − y ∣ ∣ 2 2 = 1 2 ∣ ∣ σ ( a L − 1 ⋅ w L + b L ) − y ∣ ∣ 2 2 loss^{(L)}(x,w,b,y) = \frac{1}{2}||\sigma (z^L)-y||_2^2=\frac{1}{2}|| \sigma(a^{L-1}·w^{L} + b^{L}) -y||_2^2 loss(L)(x,w,b,y)=21∣∣σ(zL)−y∣∣22=21∣∣σ(aL−1⋅wL+bL)−y∣∣22这个样子展开之后,大家应该和能感受到, l o s s loss loss是直接受到 x , w , b , y x,w,b,y x,w,b,y参数的影响的,但是我们要更新的只有 w , b w,b w,b。通过前面的小节我们知道 σ \sigma σ表示的是激活函数,但是激活函数有很多种类,如sigmod,rule,softmax,prule等等。在这里不做详细的讲解,后续有专门的章节,进行详细解说。
好了,现在正式进入反向传播,根据上面的公式,我们要对 w w w进行更新,那么我们就需要知道更新多大的值才比较合适。前面提到,我们训练网络就是为了让 l o s s loss loss接近0,也就是现在我们要想办法改变 w , b w,b w,b让 l o s s loss loss变得更加小。也就是说,我们需要对 w , b w,b w,b求偏导,
∂ [ l o s s ( L ) ( x , w , b , y ) ] ∂ w L = [ ( a L − y ) ⊙ σ ′ ( z L ) ] ( a L − 1 ) T \frac {\partial [loss^{(L)}(x,w,b,y)]}{\partial w^L} =[(a^L-y) ⊙\sigma'(z^L)](a^{L-1})^{T} ∂wL∂[loss(L)(x,w,b,y)]=[(aL−y)⊙σ′(zL)](aL−1)T 注意上式中有一个符号⊙⊙,它代表Hadamard积,对于两个维度相同的向量 A ( a 1 , a 2 , . . . a n ) T A(a_1,a_2,...a_n)^{T} A(a1,a2,...an)T和 B ( b 1 , b 2 , . . . b n ) T B(b_1,b_2,...bn)^{T} B(b1,b2,...bn)T ,则 A ⊙ B = ( a 1 b 1 , a 2 b 2 , . . . a n b n ) T A⊙B=(a_1b_1,a_2b_2,...a_nb_n)^T A⊙B=(a1b1,a2b2,...anbn)T。直白的说就是对应的相乘就可以了。因为上述公式中的 a L , y , σ ′ ( z L ) a^L,y,\sigma'(z^L) aL,y,σ′(zL)表示的不是一个数,而是一个多维的数组,但是 σ ′ ( z L ) \sigma'(z^L) σ′(zL)与 a L , y a^L,y aL,y维度都是相同的,单个样本的时候,一般为1*n维的数组。那么为什么乘以 ( a L − 1 ) T (a^{L-1})^{T} (aL−1)T的时候,需要进行转置(符号T,表示行列互换,可以百度一下矩阵转置)呢?,首先注意, a L − 1 与 a L a^{L-1}与a^{L} aL−1与aL的维度不一定相同的,[(a^L-y) ⊙\sigma’(zL)]与(a{L-1})^{T}表示的也不是矩阵相乘。而是普通的数组相乘。如下面两个矩阵相乘: { [ a 11 L − 1 a 12 L − 1 a 13 L − 1 ] } ⋅ { [ w 11 L w 12 L ] [ w 21 L w 22 L ] [ w 31 L w 32 L ] } = { [ a 11 L a 12 L ] } \left\{ \begin{matrix} [a_{11}^{L-1} & a_{12}^{L-1}& a_{13}^{L-1}]\\ \end{matrix} \right\}· \left\{ \begin{matrix} [w_{11}^L& w_{12}^L ]\\ \\ [w_{21}^L & w_{22}^L]\\ \\ [w_{31}^L & w_{32}^L]\\ \end{matrix} \right\} = \left\{ \begin{matrix} [a_{11}^{L} & a_{12}^{L}]\\ \end{matrix} \right\} {[a11L−1a12L−1a13L−1]}⋅⎩ ⎨ ⎧[w11L[w21L[w31Lw12L]w22L]w32L]⎭ ⎬ ⎫={[a11La12L]} 那么计算的过程: a 11 L = a 11 L − 1 w 11 + a 12 L − 1 w 21 + a 13 L − 1 w 31 a_{11}^{L} = a_{11}^{L-1}w_{11} + a_{12}^{L-1}w_{21} + a_{13}^{L-1}w_{31} a11L=a11L−1w11+a12L−1w21+a13L−1w31 a 12 L = a 11 L − 1 w 12 + a 12 L − 1 w 22 + a 13 L − 1 w 32 \\a_{12}^{L} = a_{11}^{L-1}w_{12} + a_{12}^{L-1}w_{22} + a_{13}^{L-1}w_{32} a12L=a11L−1w12+a12L−1w22+a13L−1w32 这是正向传播的过程,我们反向传播是为了求 { [ ∂ a 11 L ∂ w 11 L ∂ a 12 L ∂ w 12 L [ ∂ a 11 L ∂ w 21 L ∂ a 12 L ∂ w 22 L [ ∂ a 11 L ∂ w 31 L ∂ a 12 L ∂ w 32 L } = { [ a 11 L − 1 a 12 L − 1 ] [ a 11 L − 1 a 12 L − 1 ] [ a 11 L − 1 a 12 L − 1 ] } \left\{ \begin{matrix} [\frac{\partial a_{11}^L}{\partial w_{11}^L} & \frac{\partial a_{12}^L}{\partial w_{12}^L} \\ \\ [\frac{\partial a_{11}^L}{\partial w_{21}^L} & \frac{\partial a_{12}^L}{\partial w_{22}^L} \\ \\ [\frac{\partial a_{11}^L}{\partial w_{31}^L} & \frac{\partial a_{12}^L}{\partial w_{32}^L} \\ \end{matrix} \right\} = \left\{ \begin{matrix} [a_{11}^{L-1}& a_{12}^{L-1}]\\ \\ [a_{11}^{L-1} & a_{12}^{L-1}]\\ \\ [a_{11}^{L-1} & a_{12}^{L-1}]\\ \end{matrix} \right\} ⎩ ⎨ ⎧[∂w11L∂a11L[∂w21L∂a11L[∂w31L∂a11L∂w12L∂a12L∂w22L∂a12L∂w32L∂a12L⎭ ⎬ ⎫=⎩ ⎨ ⎧[a11L−1[a11L−1[a11L−1a12L−1]a12L−1]a12L−1]⎭ ⎬ ⎫,那么如何才能得到这个呢,那就是使用数组乘法, [ ( a L − y ) ⊙ σ ′ ( z L ) ] [(a^L-y) ⊙\sigma'(z^L)] [(aL−y)⊙σ′(zL)]与 ( a L − 1 ) T (a^{L-1})^{T} (aL−1)T相乘,如下面是使用np一个简单的例子:
import numpy as np
A = [[1,2]]
A = np.array(A)
B = [[1,2,3]]
B = np.array(B)
print(np.multiply(A,B.T))
输出结果:
[[1 2]
[2 4]
[3 6]]
上面是对 w w w数组求偏导的过程,现在我们对 b b b求偏导: ∂ [ l o s s ( L ) ( x , w , b , y ) ] ∂ b L = [ ( a L − y ) ⊙ σ ′ ( z L ) ] \frac {\partial [loss^{(L)}(x,w,b,y)]}{\partial b^L} =[(a^L-y) ⊙\sigma'(z^L)] ∂bL∂[loss(L)(x,w,b,y)]=[(aL−y)⊙σ′(zL)] 这里的由来,就不再进行解释了,因为按照前面求 w w w的思路就可以了。
bp算法多层公式推导经过上面我们得到两个公式:
∂ [ l o s s ( L ) ( x , w , b , y ) ] ∂ w L = [ ( a L − y ) ⊙ σ ′ ( z L ) ] ( a L − 1 ) T \frac {\partial [loss^{(L)}(x,w,b,y)]}{\partial w^L} =[(a^L-y) ⊙\sigma'(z^L)](a^{L-1})^{T} ∂wL∂[loss(L)(x,w,b,y)]=[(aL−y)⊙σ′(zL)](aL−1)T ∂ [ l o s s ( L ) ( x , w , b , y ) ] ∂ b L = [ ( a L − y ) ⊙ σ ′ ( z L ) ] \frac {\partial [loss^{(L)}(x,w,b,y)]}{\partial b^L} =[(a^L-y) ⊙\sigma'(z^L)] ∂bL∂[loss(L)(x,w,b,y)]=[(aL−y)⊙σ′(zL)] 但是上面这个公式有个缺陷,其反向传播过程,只传递了一层,即从L层传到了L-1,假设我们的网络结构现在一共有L,我们就要把 l o s s loss loss从第L层传递到第一层,即要传递给网络中所有的 w w w与 b b b。
其上公式我们可以注意到,在求解输出层的
w
,
b
w,b
w,b,有中间依赖部分
∂
[
l
o
s
s
(
L
)
(
x
,
w
,
b
,
y
)
]
∂
z
L
\frac {\partial [loss^{(L)}(x,w,b,y)]}{\partial z^L}
∂zL∂[loss(L)(x,w,b,y)],我们可以先把对
z
L
z^L
zL的偏导求出来:
δ
L
=
∂
[
l
o
s
s
(
L
)
(
x
,
w
,
b
,
y
)
]
∂
z
L
=
(
a
L
−
y
)
⊙
σ
′
(
z
L
)
\delta^L = \frac {\partial [loss^{(L)}(x,w,b,y)]}{\partial z^L}=(a^L-y) ⊙\sigma'(z^L)
δL=∂zL∂[loss(L)(x,w,b,y)]=(aL−y)⊙σ′(zL) 首先这里要明确一个东西,求输出层L中
w
,
b
w,b
w,b的梯度,是为了更新L层的
w
,
b
w,b
w,b,上面求
δ
L
\delta^L
δL得梯度,是为了传递给前面得网络层,所以这三个都是有必要的,如下图标记:
三种颜色分别表示要求的3种梯度。现在我们终于把梯度
δ
L
\delta^L
δL求出来了,根据链式法则,有如下公式:
δ l = ∂ [ l o s s ( L ) ( x , w , b , y ) ] ∂ z l = ( ∂ z L ∂ z L − 1 ∂ z L − 1 ∂ z L − 2 ⋅ ⋅ ⋅ ⋅ ∂ z l + 1 ∂ z l ) T ∂ [ l o s s ( L ) ( x , w , b , y ) ] ∂ z L \delta^l = \frac {\partial [loss^{(L)}(x,w,b,y)]}{\partial z^l}= (\frac {\partial z^L}{\partial z^{L-1}} \frac {\partial z^{L-1}}{\partial z^{L-2}}····\frac {\partial z^{l+1}}{\partial z^{l}})^T\frac {\partial [loss^{(L)}(x,w,b,y)]}{\partial z^L} δl=∂zl∂[loss(L)(x,w,b,y)]=(∂zL−1∂zL∂zL−2∂zL−1⋅⋅⋅⋅∂zl∂zl+1)T∂zL∂[loss(L)(x,w,b,y)]看到上面的公式,大家要注意下大L和小 l l l的区分,大L表示的输出层,小 l l l表示的是中间层次。也就是说通过上面的公式,我们就能求出中间任意层次的梯度的(通过链式法则)。我们求出了中间任意层次的梯度,但是还是不够的,因为我们最终是为了作用于 w , b w,b w,b,也就是说,求出之前层数 z l z^l zl(此时没有经过激活函数)的梯度,然后还要传递给对应层数的 w , b w,b w,b,其实传递的方式是很简单的,因为: z l = w a l − 1 + b l z^l = wa^{l-1}+b^l zl=wal−1+bl 所以根据链式法则: ∂ [ l o s s ( x , w , b , y ) ] ∂ w l = δ l ( a l − 1 ) T \frac {\partial [loss(x,w,b,y)]}{\partial w^l}= \delta^l(a^{l-1})^T ∂wl∂[loss(x,w,b,y)]=δl(al−1)T ∂ [ l o s s ( x , w , b , y ) ] ∂ b l = δ l \frac {\partial [loss(x,w,b,y)]}{\partial b^l}= \delta^l ∂bl∂[loss(x,w,b,y)]=δl那么和明显的感觉到,我们要更新某一层的 w , b w,b w,b,就要求出该层的 δ l \delta^l δl,现在我们对前面的公式: δ l = ∂ [ l o s s ( L ) ( x , w , b , y ) ] ∂ z l = ( ∂ z L ∂ z L − 1 ∂ z L − 1 ∂ z L − 2 ⋅ ⋅ ⋅ ⋅ ∂ z l + 1 ∂ z l ) T ∂ [ l o s s ( L ) ( x , w , b , y ) ] ∂ z L \delta^l = \frac {\partial [loss^{(L)}(x,w,b,y)]}{\partial z^l}= (\frac {\partial z^L}{\partial z^{L-1}} \frac {\partial z^{L-1}}{\partial z^{L-2}}····\frac {\partial z^{l+1}}{\partial z^{l}})^T\frac {\partial [loss^{(L)}(x,w,b,y)]}{\partial z^L} δl=∂zl∂[loss(L)(x,w,b,y)]=(∂zL−1∂zL∂zL−2∂zL−1⋅⋅⋅⋅∂zl∂zl+1)T∂zL∂[loss(L)(x,w,b,y)] 进行简化得到: δ l = ∂ [ l o s s ( x , w , b , y ) ] ∂ z l = ( ∂ z l + 1 ∂ z l ) T ∂ [ l o s s ( x , w , b , y ) ] ∂ z l + 1 = ( ∂ z l + 1 ∂ z l ) T δ l + 1 \delta^l = \frac {\partial [loss^{}(x,w,b,y)]}{\partial z^l}= (\frac {\partial z^{l+1}}{\partial z^l})^T\frac {\partial [loss(x,w,b,y)]}{\partial z^{l+1}}=(\frac {\partial z^{l+1}}{\partial z^l})^T\delta^{l+1} δl=∂zl∂[loss(x,w,b,y)]=(∂zl∂zl+1)T∂zl+1∂[loss(x,w,b,y)]=(∂zl∂zl+1)Tδl+1 简介如下: δ l = ( ∂ z l + 1 ∂ z l ) T δ l + 1 \delta^l =(\frac {\partial z^{l+1}}{\partial z^l})^T\delta^{l+1} δl=(∂zl∂zl+1)Tδl+1 这样就变成了一个递推模型,即重点在于求解 ( ∂ z l + 1 ∂ z l ) (\frac {\partial z^{l+1}}{\partial z^l}) (∂zl∂zl+1),其求解又非常的简单
z l + 1 = w l + 1 a l + b l + 1 = w l + 1 σ ( z l ) + b l + 1 z^{l+1} = w^{l+1}a^l+b^{l+1} = w^{l+1}\sigma(z^l) +b^{l+1} zl+1=wl+1al+bl+1=wl+1σ(zl)+bl+1所以: ( ∂ z l + 1 ∂ z l ) = w l + 1 d i a g ( σ ′ ( z l ) ) (\frac {\partial z^{l+1}}{\partial z^l}) = w^{l+1}diag(\sigma'( z^l)) (∂zl∂zl+1)=wl+1diag(σ′(zl)) 前面为大家简介了很多次矩阵的运算,这里的diag表示处对角线之外,其余都为0,至于为什么要这样,大家可以去推导一下,如果没有先明白,可以看文章开头,添加我的微信一起探讨。现在我们带入前面的式子 δ l = ∂ [ l o s s ( x , w , b , y ) ] ∂ z l = ( ∂ z l + 1 ∂ z l ) T ∂ [ l o s s ( x , w , b , y ) ] ∂ z l + 1 = ( w l + 1 d i a g ( σ ′ ( z l ) ) ) T δ l + 1 = ( w l + 1 ) T δ l + 1 ⊙ σ ′ ( z l ) \delta^l = \frac {\partial [loss^{}(x,w,b,y)]}{\partial z^l}= (\frac {\partial z^{l+1}}{\partial z^l})^T\frac {\partial [loss(x,w,b,y)]}{\partial z^{l+1}}=(w^{l+1}diag(\sigma'( z^l)))^T\delta^{l+1}= (w^{l+1})^T\delta^{l+1}⊙\sigma'(z^l) δl=∂zl∂[loss(x,w,b,y)]=(∂zl∂zl+1)T∂zl+1∂[loss(x,w,b,y)]=(wl+1diag(σ′(zl)))Tδl+1=(wl+1)Tδl+1⊙σ′(zl) 到这里,反向传播算是推导完成了,也就是说,我们只要知道了某一层的 δ l \delta^l δl,我们就能得到其对应需要更新$ Δ \Delta Δw, Δ \Delta Δb$。
反向传播已经简介完成,暂时还没有想到接下来讲解什么内容,敬请期待!