Ⅰ、反向模式求导
反向模式求导是从后向前,先求 y 对 z 的影响(h + m +n) ,再求 x 对 y 的影响(i+j+k) ,然后相乘(h + m +n)*(i+j+k):
前向模式求导追踪一个输入如何影响每一个节点,对每一个节点进行 ∂∂x\frac{\partial }{\partial x}∂x∂ 操作;反向求导模式追踪每一个节点如何影响一个输出,对每一个节点进行 ∂z∂\frac{\partial z}{\partial }∂∂z 操作。
下面我们再假设一个更一般的函数fθ(a,b,c)=(θ1a+θ2b)∗(θ3(c+1)+θ4b)f_\theta(a,b,c) =(\theta_1 a+ \theta_2 b)∗(\theta_3(c+1)+\theta_4 b)fθ(a,b,c)=(θ1a+θ2b)∗(θ3(c+1)+θ4b),其中θ1−θ4\theta_1-\theta_4θ1−θ4代表上篇最后定义的权重
,也就是系数,我们还是假设a = 5 , b = 3 , c = 1
,则可以得到下列图像:
注意:蓝色框部分是从下往上看,是求值的过程;红色框部分是从上往下看,是反向模式求导的过程。
从上图中可以看出反向模式求导可以一次性将所有的参数的导数求出来,我们选择b
看一下是怎么样进行反向模式求导的。
第一条路:f->g->b:
∂f∂f=1\frac{\partial f}{\partial f} = 1∂f∂f=1
∂f∂g=∂f∂f⋅∂f∂g=1⋅e=5θ1+3θ2\frac{\partial f}{\partial g} = \frac{\partial f}{\partial f}·\frac{\partial f}{\partial g} =1·e = 5\theta_1+3\theta_2∂g∂f=∂f∂f⋅∂g∂f=1⋅e=5θ1+3θ2
∂f∂b=∂f∂f⋅∂f∂g⋅∂f∂g=1⋅e⋅θ4=θ4⋅(5θ1+3θ2)\frac{\partial f}{\partial b} = \frac{\partial f}{\partial f}·\frac{\partial f}{\partial g}·\frac{\partial f}{\partial g} =1·e·\theta_4 = \theta_4·(5\theta_1+3\theta_2)∂b∂f=∂f∂f⋅∂g∂f⋅∂g∂f=1⋅e⋅θ4=θ4⋅(5θ1+3θ2)
第二条路:f->e->b:
∂f∂f=1\frac{\partial f}{\partial f} = 1∂f∂f=1
∂f∂e=∂f∂f⋅∂f∂b=1⋅g=2θ3+3θ4\frac{\partial f}{\partial e} = \frac{\partial f}{\partial f}·\frac{\partial f}{\partial b} =1·g = 2\theta_3+3\theta_4∂e∂f=∂f∂f⋅∂b∂f=1⋅g=2θ3+3θ4
∂f∂b=∂f∂f⋅∂f∂g⋅∂f∂g=1⋅g⋅θ4=θ2⋅(2θ3+3θ4)\frac{\partial f}{\partial b} = \frac{\partial f}{\partial f}·\frac{\partial f}{\partial g}·\frac{\partial f}{\partial g} =1·g·\theta_4 = \theta_2·(2\theta_3+3\theta_4)∂b∂f=∂f∂f⋅∂g∂f⋅∂g∂f=1⋅g⋅θ4=θ2⋅(2θ3+3θ4)
两条路合并后就是b
正确的导数:
∂f∂b=θ4⋅(5θ1+3θ2)+θ2⋅(2θ3+3θ4)\frac{\partial f}{\partial b} = \theta_4·(5\theta_1+3\theta_2)+\theta_2·(2\theta_3+3\theta_4)∂b∂f=θ4⋅(5θ1+3θ2)+θ2⋅(2θ3+3θ4)
可以看到是连续偏导求出的b
的导数,我们假设:
δ0L=∂f∂f=1\delta^L_0 = \frac{\partial f}{\partial f} = 1δ0L=∂f∂f=1
δ0L−1=∂f∂e=∂f∂f⋅∂f∂e=δ0L⋅∂f∂e\delta^{L-1}_0=\frac{\partial f}{\partial e} = \frac{\partial f}{\partial f}·\frac{\partial f}{\partial e}=\delta^L_0·\frac{\partial f}{\partial e}δ0L−1=∂e∂f=∂f∂f⋅∂e∂f=δ0L⋅∂e∂f
δ1L−1=∂f∂g=∂f∂f⋅∂f∂g=δ0L⋅∂f∂g\delta^{L-1}_1=\frac{\partial f}{\partial g}= \frac{\partial f}{\partial f}·\frac{\partial f}{\partial g}=\delta^L_0·\frac{\partial f}{\partial g}δ1L−1=∂g∂f=∂f∂f⋅∂g∂f=δ0L⋅∂g∂f
δ0L−2=∂f∂g=∂f∂f⋅∂f∂e⋅∂e∂b+∂f∂f⋅∂f∂g⋅∂g∂b=δ0L−1⋅∂e∂b+δ1L−1⋅∂g∂b\delta^{L-2}_0=\frac{\partial f}{\partial g}= \frac{\partial f}{\partial f}·\frac{\partial f}{\partial e}·\frac{\partial e}{\partial b}+ \frac{\partial f}{\partial f}·\frac{\partial f}{\partial g}·\frac{\partial g}{\partial b}=\delta^{L-1}_0·\frac{\partial e}{\partial b}+\delta^{L-1}_1·\frac{\partial g}{\partial b}δ0L−2=∂g∂f=∂f∂f⋅∂e∂f⋅∂b∂e+∂f∂f⋅∂g∂f⋅∂b∂g=δ0L−1⋅∂b∂e+δ1L−1⋅∂b∂g
其中上述中的LLL代表层数,LLL代表最上层导数,L−1L-1L−1层代表第二层导数,…,下标代表第LLL层的第iii个元素,可以看出,每层的偏导数是用上一层的偏导数值乘上层对本层的参数的偏导数。
理解上述反向模式求导,下面我们就可以推导反向求导:
下面是一个四层的神经网络:
上面是一个五层网络,我们先推导反向传播公式,然后选取上面几个点进行代入计算推导:
我们先来回顾一下神经网络的代价函数与梯度计算:
J(θ)=−1m(∑i=1m∑k=1K(yk(i)ln(hθ(x(i)))k+(1−yk(i))ln(1−hθ(x(i)))k))+λm∑l=1L∑i=1sl∑j=1sl+1(θji(l))J(\theta) = -\frac{1}{m}(\sum_{i=1}^{m}\sum_{k=1}^{K}(y^{(i)}_kln(h_\theta(x^{(i)}))_k+(1-y_k^{(i)})ln(1-h_\theta(x^{(i)}))_k))+\frac{\lambda}{m}\sum_{l=1}^{L}\sum_{i=1}^{s_l}\sum_{j=1}^{s_{l+1}}(\theta_{ji}^{(l)})J(θ)=−m1(i=1∑mk=1∑K(yk(i)ln(hθ(x(i)))k+(1−yk(i))ln(1−hθ(x(i)))k))+mλl=1∑Li=1∑slj=1∑sl+1(θji(l))
其中的第二项为正则化项,是网络中所有权值的平方和。第一项与逻辑回归中的代价函数类似,但这里我们需要累加所有输出神经元的误差。
梯度计算:
为了能够使用梯度下降算法训练网络,我们需要计算代价函数的梯度。一种很直观的方法就是使用数值计算,对于某个Θij\Theta_{ij}Θij,给它加上减去一个很小的量 ϵ\epsilonϵ来计算梯度:
∂J(θ)∂θj≈J(θ1,⋯ ,θj+ϵ,⋯ ,θn)−J(θ1,⋯ ,θj−ϵ,⋯ ,θn)2ϵ\frac{\partial J(\theta)}{\partial \theta_j} \approx \frac{J(\theta_1,\cdots,\theta_j+\epsilon,\cdots,\theta_n)-J(\theta_1,\cdots,\theta_j-\epsilon,\cdots,\theta_n)}{2\epsilon}∂θj∂J(θ)≈2ϵJ(θ1,⋯,θj+ϵ,⋯,θn)−J(θ1,⋯,θj−ϵ,⋯,θn)
上式可以计算θj\theta_jθj的梯度,但是如果每个都用这种方式来计算,那么算法时间与空间复杂度会导致很大,影响算法的效率,所以这种方式是不可取的,但是,这种方式往往前期用来验证梯度的计算是否正确,如果不正确则需要更改梯度算法。,注意:一旦我们确定梯度下降的算法正确,需要立即注销掉关于上述上述方式计算梯度的代码,否则会导致程序执行过慢。
那么,如果上述的方式不可以计算梯度,那么梯度该如何计算呢?我们利用与反向模式求导的对比的方式进行推导反向求导的公式:
我们继续选用上面的五层神经网络:
开始推导之前,先定义一个变量 δi(l)\delta_i^{(l)}δi(l),代表下列:
δi(l)=∂J(θ)∂zi(l)\delta_i^{(l)} = \frac{\partial J(\theta)}{\partial z_i^{(l)}}δi(l)=∂zi(l)∂J(θ)
其中zj(l)=Θji(l)ai(l−1)z_j^{(l)}=\Theta_{ji}^{(l)}a_i^{(l-1)}zj(l)=Θji(l)ai(l−1),注意:此处的j
与上式的i
的含义是一样的,此处只不过与刚开始所定义的i
与j
代表的第几层的第几个所相符。具体看上一篇的神经网络的符号的说明。
还要注意:ai(l)=g(zi(l))a_i^{(l)} = g(z_i^{(l)})ai(l)=g(zi(l))
结合反向模式求导,某个参数偏导数是各个路径上偏导数的之和,则我们可以定义出来:
δi(l)=∑j=1s(l+1)∂J(θ)∂ak(l)∂ak(l)∂zi(l)(1)\delta_i^{(l)} =\sum_{j=1}^{s_{(l+1)}} \frac{\partial J(\theta)}{\partial a_k^{(l)}}\frac{\partial a_k^{(l)}}{\partial z_i^{(l)}}\tag{1}δi(l)=j=1∑s(l+1)∂ak(l)∂J(θ)∂zi(l)∂ak(l)(1)
我们看到最后一层,没有其它输入,所以我们可以得到s(l+1)=i=1s_{(l+1)}=i=1s(l+1)=i=1
则我们可以直接得到:
δi(l)=∂J(θ)∂ai(l)g′(zi(l))=aj(l)−yj(l)(2)\delta_i^{(l)} =\frac{\partial J(\theta)}{\partial a_i^{(l)}}g'(z_i^{(l)})=a_j^{(l)}-y_j^{(l)}\tag{2}δi(l)=∂ai(l)∂J(θ)g′(zi(l))=aj(l)−yj(l)(2)
上述就是最后一层的误差,对于其它层的误差如下:
δi(l)=∂J(θ)∂zi(l)\delta_i^{(l)} = \frac{\partial J(\theta)}{\partial z_i^{(l)}}δi(l)=∂zi(l)∂J(θ)
根据链式法则可得:
δi(l)=∑j=1s(l+1)∂J(θ)∂zj(l+1)∂zj(l+1)∂ai(l)∂ai(l)∂zi(l)(3)\delta_i^{(l)} =\sum_{j=1}^{s_{(l+1)}} \frac{\partial J(\theta)}{\partial z_j^{(l+1)}} \frac{\partial z_j^{(l+1)}}{\partial a_i^{(l)}}\frac{\partial a_i^{(l)}}{\partial z_i^{(l)}}\tag{3}δi(l)=j=1∑s(l+1)∂zj(l+1)∂J(θ)∂ai(l)∂zj(l+1)∂zi(l)∂ai(l)(3)
可以简化写成:
δi(l)=∑j=1s(l+1)∂J(θ)∂zj(l+1)∂zj(l+1)∂zi(l)=∑j=1s(l+1)δj(l+1)∂zj(l+1)∂zi(l)(3)\delta_i^{(l)} =\sum_{j=1}^{s_{(l+1)}} \frac{\partial J(\theta)}{\partial z_j^{(l+1)}} \frac{\partial z_j^{(l+1)}}{\partial z_i^{(l)}}=\sum_{j=1}^{s_{(l+1)}}\delta_j^{(l+1)}\frac{\partial z_j^{(l+1)}}{\partial z_i^{(l)}}\tag{3}δi(l)=j=1∑s(l+1)∂zj(l+1)∂J(θ)∂zi(l)∂zj(l+1)=j=1∑s(l+1)δj(l+1)∂zi(l)∂zj(l+1)(3)
其中∂zj(l+1)∂zi(l)=∑i=1slΘji(l)g′(zi(l))+bj(l)∂zi(l)=Θji(l)g′(zi(l))\frac{\partial z_j^{(l+1)}}{\partial z_i^{(l)}} = \frac{\sum_{i=1}^{s_l}\Theta_{ji}^{(l)}g'(z_i^{(l)})+b_j^{(l)}}{\partial z_i^{(l)}}=\Theta_{ji}^{(l)}g'(z_i^{(l)})∂zi(l)∂zj(l+1)=∂zi(l)∑i=1slΘji(l)g′(zi(l))+bj(l)=Θji(l)g′(zi(l))
所以代入(3)式可得:
δi(l)=∑j=1s(l+1)δj(l+1)Θji(l)g′(zi(l))=∑j=1s(l+1)δj(l+1)Θji(l)ai(l)(1−ai(l))(4)\delta_i^{(l)} =\sum_{j=1}^{s_{(l+1)}} \delta_j^{(l+1)}\Theta_{ji}^{(l)}g'(z_i^{(l)})=\sum_{j=1}^{s_{(l+1)}}\delta_j^{(l+1)}\Theta_{ji}^{(l)}a_i^{(l)}(1-a_i^{(l)})\tag{4}δi(l)=j=1∑s(l+1)δj(l+1)Θji(l)g′(zi(l))=j=1∑s(l+1)δj(l+1)Θji(l)ai(l)(1−ai(l))(4)
上面是δi(l)\delta_i^{(l)}δi(l)的一般形式
同样我们可以利用和上述一样的链式求导来求∂J(θ)∂θji(l)\frac{\partial J(\theta)}{\partial \theta_{ji}^{(l)}}∂θji(l)∂J(θ)
∂J(θ)∂θji(l)=∑j=1sl+1∂J(θ)∂zj(l+1)∂zj(l+1)∂zi(l)∂zi(l)∂θji(l)=∑j=1s(l+1)δj(l+1)∂zj(l+1)∂θji(l)(5)\frac{\partial J(\theta)}{\partial \theta_{ji}^{(l)}}=\sum_{j=1}^{s_{l+1}}\frac{\partial J(\theta)}{\partial z_j^{(l+1)}} \frac{\partial z_j^{(l+1)}}{\partial z_i^{(l)}}\frac{\partial z_i^{(l)}}{\partial \theta_{ji}^{(l)}}=\sum_{j=1}^{s_{(l+1)}}\delta_j^{(l+1)}\frac{\partial z_j^{(l+1)}}{\partial \theta_{ji}^{(l)}}\tag{5}∂θji(l)∂J(θ)=j=1∑sl+1∂zj(l+1)∂J(θ)∂zi(l)∂zj(l+1)∂θji(l)∂zi(l)=j=1∑s(l+1)δj(l+1)∂θji(l)∂zj(l+1)(5)
其中zj(l+1)=∑i=1slΘji(l)g′(zi(l))+bj(l)z_j^{(l+1)}= \sum_{i=1}^{s_l}\Theta_{ji}^{(l)}g'(z_i^{(l)})+b_j^{(l)}zj(l+1)=∑i=1slΘji(l)g′(zi(l))+bj(l)
我们会发现∂zj(l+1)∂θji(l)=∑p=1slΘji(l)g′(zi(l))+bj(l)∂θji(l)=∑p=1slΘji(l)ai(l)+bj(l)∂θji(l)=ai(l)(6)\frac{\partial z_j^{(l+1)}}{\partial\theta_{ji}^{(l)}} = \frac{\sum_{p=1}^{s_l}\Theta_{ji}^{(l)}g'(z_i^{(l)})+b_j^{(l)}}{\partial \theta_{ji}^{(l)}}=\frac{\sum_{p=1}^{s_l}\Theta_{ji}^{(l)}a_i^{(l)}+b_j^{(l)}}{\partial \theta_{ji}^{(l)}}=a_i^{(l)}\tag{6}∂θji(l)∂zj(l+1)=∂θji(l)∑p=1slΘji(l)g′(zi(l))+bj(l)=∂θji(l)∑p=1slΘji(l)ai(l)+bj(l)=ai(l)(6)
注意:我们前面定义过 ai(l)=g′(zi(l))a_i^{(l)} = g'(z_i^{(l)})ai(l)=g′(zi(l))
将(6)式代入(5)式,可以得到:
∂J(θ)∂θji(l)=δj(l+1)ai(l)(7)\frac{\partial J(\theta)}{\partial \theta_{ji}^{(l)}}=\delta_j^{(l+1)}a_i^{(l)}\tag{7}∂θji(l)∂J(θ)=δj(l+1)ai(l)(7)
(7)式就是我们得到的梯度计算式。
我们再继续使用上图中的例子来说明:
δ1(5)=a1(5)−y1(5)\delta_1^{(5)}=a_1^{(5)}-y_1^{(5)}δ1(5)=a1(5)−y1(5)
δ1(4)=δ1(5)θ11(4)a1(4)(1−a1(4))\delta_1^{(4)}=\delta_1^{(5)}\theta_{11}^{(4)}a_1^{(4)}(1-a_1^{(4)})δ1(4)=δ1(5)θ11(4)a1(4)(1−a1(4))
δ3(4)=δ1(5)θ13(4)a3(4)(1−a3(4))\delta_3^{(4)}=\delta_1^{(5)}\theta_{13}^{(4)}a_3^{(4)}(1-a_3^{(4)})δ3(4)=δ1(5)θ13(4)a3(4)(1−a3(4))
δ1(3)=δ1(4)θ11(3)a1(3)(1−a1(3))\delta_1^{(3)}=\delta_1^{(4)}\theta_{11}^{(3)}a_1^{(3)}(1-a_1^{(3)})δ1(3)=δ1(4)θ11(3)a1(3)(1−a1(3))
δ4(3)=δ3(4)θ34(3)a4(3)(1−a4(3))\delta_4^{(3)}=\delta_3^{(4)}\theta_{34}^{(3)}a_4^{(3)}(1-a_4^{(3)})δ4(3)=δ3(4)θ34(3)a4(3)(1−a4(3))
∂J(θ)∂θ11(4)=δ1(5)a1(4)\frac{\partial J(\theta)}{\partial \theta_{11}^{(4)}}=\delta_1^{(5)}a_1^{(4)}∂θ11(4)∂J(θ)=δ1(5)a1(4)
∂J(θ)∂θ13(4)=δ1(5)a3(4)\frac{\partial J(\theta)}{\partial \theta_{13}^{(4)}}=\delta_1^{(5)}a_3^{(4)}∂θ13(4)∂J(θ)=δ1(5)a3(4)
∂J(θ)∂θ11(3)=δ1(4)a1(3)\frac{\partial J(\theta)}{\partial \theta_{11}^{(3)}}=\delta_1^{(4)}a_1^{(3)}∂θ11(3)∂J(θ)=δ1(4)a1(3)
∂J(θ)∂θ34(3)=δ3(4)a4(3)\frac{\partial J(\theta)}{\partial \theta_{34}^{(3)}}=\delta_3^{(4)}a_4^{(3)}∂θ34(3)∂J(θ)=δ3(4)a4(3)
从上面其实也看出来,反向传播实际也是表达出θji(l)\theta_{ji}^{(l)}θji(l)对最终误差J(θ)J(\theta)J(θ)的影响程度,通过J(θ)J(\theta)J(θ)来调整θji(l)\theta_{ji}^{(l)}θji(l)产生的影响,这种影响的计算与模式求导很像,是各个路径上对θji(l)\theta_{ji}^{(l)}θji(l)产生的影响的总和。
看到这里,我们的反向传播算法就结束了,下面是一个神经网络的过程总结:
- 对于所有的l,i,jl,i,jl,i,j初始化Δji(l)=0\Delta_{ji}^{(l)}=0Δji(l)=0
- 对于mmm组训练数据,kkk从1取到mmm:
(Ⅰ)令a(1)=x(k)a^{(1)}=x^{(k)}a(1)=x(k)
(Ⅱ)前向传播,计算各层激活向量a(l)a^{(l)}a(l)
(Ⅲ)利用(2)式,计算输出层误差δ(L)\delta^{(L)}δ(L)
(Ⅳ)利用(4)式,计算其它层误差δ(L−1)、δ(L−2),⋯,δ(2)\delta^{(L-1)}、\delta^{(L-2)},\cdots,\delta^{(2)}δ(L−1)、δ(L−2),⋯,δ(2)
(Ⅴ)利用(7)式,累加Δji(l)\Delta_{ji}^{(l)}Δji(l):Δji(l):=Δji(l)+ai(l)δj(l+1)\Delta_{ji}^{(l)}:=\Delta_{ji}^{(l)}+a_i^{(l)}\delta_j^{(l+1)}Δji(l):=Δji(l)+ai(l)δj(l+1) - 计算梯度矩阵:
Dji(l)={1mΔji(l)+λmΘji(l)if i≠01mΔji(l)if i=0D^{(l)}_{ji} = \begin{cases} \dfrac{1}{m}\Delta^{(l)}_{ji} + \dfrac{\lambda}{m}\Theta^{(l)}_{ji} &if \ i \neq 0 \\ \dfrac{1}{m}\Delta_{ji}^{(l)} &if \ i=0\end{cases}Dji(l)=⎩⎨⎧m1Δji(l)+mλΘji(l)m1Δji(l)if i=0if i=0 - 更新权值 Θ(l):=Θ(l)+αD(l)\Theta^{(l)} := \Theta^{(l)}+ \alpha D^{(l)}Θ(l):=Θ(l)+αD(l)
权值初始化
权值的初始化。对于神经网络,不能像之前那样使用相同的 0 值来初始化,这会导致每层的 逻辑单元 都相同。因此我们使用随机化的初始化方法,使得 −δ≤Θijl≤δ-\delta \leq \Theta_{ij}^{l} \leq \delta−δ≤Θijl≤δ 。
神经网络的基础知识整理完毕,欢迎指出问题。