#对反向传播算法的理解
求梯度用反向传播算法,核心是“链式求导”法则,又如何具体实现呢?这里,主要参考Michael Nielsen的Neural Networks and Deep Learning里的第二章。
介绍反向传播算法之前,我们需要知道以下几点:
- 确定Cost function CCC,即损失函数
- 根据CCC得出CxC_xCx,即一个训练样本的损失函数。需要CxC_xCx的原因是,我们接下来的反向传播算法是对一个训练样本进行的。重复这个操作,最终对所有训练样本进行完反向传播。这些我们后面会细说。
符号定义
对于一个训练样本,我们记做xxx
对于神经网络里每一层的权值,我们记做wlw^lwl
对于神经网络里每一层的偏差,我们记做blb^lbl
对于神经网络里每一层的输入,我们记做zlz^lzl
对于神经网络里每一层的输出,我们记做ala^lal
定义激活函数为fff
那么 al=f(zl)a^l = f(z^l)al=f(zl)
神经网络的前向传播过程即:
$a^0 = x $
z1=w1a0+b1z^1 = w^1a^0+b^1z1=w1a0+b1
a1=f(z1)a^1 = f(z^1)a1=f(z1)
z2=w2a1+b2z^2 = w^2a^1+b^2z2=w2a1+b2
a2=f(z2)a^2 = f(z^2)a2=f(z2)
…
这样依次进行下去,即 al=f(wlal−1+bl)a^l=f(w^la^{l-1}+b^l)al=f(wlal−1+bl)
前面提到我们需要求得一个训练样本的损失函数CxC_xCx,这是很容易求出的。
例如:损失函数
下面为了方便,我们把CxC_xCx记做CCC,这里是把下标xxx省略掉。
反向传播算法
定义神经网络里每一层的误差:
δl=∂C∂zl\delta^l =\frac {\partial C}{\partial z^l}δl=∂zl∂C
下面介绍的四个公式会给我们计算δl\delta^lδl和损失函数梯度的方法。这四个公式都是链式法则的推论。
公式1:
δl=∂C∂al⋅f′(zl)\delta^l = \frac{\partial C}{\partial a^l} \cdot f'(z^l)δl=∂al∂C⋅f′(zl)
我们使用公式1,求得神经网络里最后一层的误差,最后一层通常不使用激活函数,因此在最后一层里 aL=zLa^L=z^LaL=zL, 我们的重点就是放在计算$ \frac{\partial C}{\partial a^L}$上。
公式2:
δl=((wl+1)Tδl+1)⋅f′(zl)\delta^l = ((w^{l+1})^\mathrm{T}\delta^{l+1})\cdot f'(z^l)δl=((wl+1)Tδl+1)⋅f′(zl)
这个公式是让我们通过递推的方式求得每一层的δl\delta^lδl。上面我们提到我们使用公式1求得神经网络最后一层的 δl\delta^lδl,那么δl−1,δl−2.....\delta^{l-1} ,\delta^{l-2}.....δl−1,δl−2.....我们便可以通过公式2求出,注意!!!公式2里面的点乘!!!!!!
公式3:
∂C∂bl=δl\frac{\partial C}{\partial b^l} = \delta^l∂bl∂C=δl
求得偏差blb^lbl的梯度
公式4:
∂C∂wl=δl(al−1)T\frac{\partial C}{\partial w^l} = \delta^l(a^{l-1})^\mathrm{T}∂wl∂C=δl(al−1)T
以上是对一个训练样本的损失函数进行梯度计算,最后只需要我们把所有训练样本的梯度累加,然后除以样本数目,作为最终的梯度。(如有正则化,需要再加上正则化部分的梯度,而这个是最好求的,略讲)。
如果我们直接从所有训练样本出发,又该如何呢?注意!!下面在使用上述4个公式的时候,都是在使用整个训练样本,之前的x(Dx(Dx(Dx1)1)1),在下面都是X(DX(DX(DxN)N)N),相应的zl,al,δlz^l,a^l,\delta^lzl,al,δl的列数变成NNN。大家这里仔细分析一下就可以得出。
公式3表明了一个训练样本的 blb^{l}bl的梯度是δl\delta^lδl,我们又知道所有训练样本对blb^lbl 的梯度的影响是累加的,即 bl=(b1,l+b2,l+b3,l+....+bN,l)/Nb^l = (b^{1,l}+b^{2,l}+b^{3,l}+....+b^{N,l})/Nbl=(b1,l+b2,l+b3,l+....+bN,l)/N,假设训练样本总数是N,我们用[δ1,l,δ2,l.....δN,l][\delta^{1,l},\delta^{2,l}.....\delta^{N,l}][δ1,l,δ2,l.....δN,l]表示所有样本计算的梯度,只需要sum一下,然后除以N,便可以求得最终的blb^lbl的梯度。
最后一层的δL\delta^LδL,同样是δl=[δ1,l,δ2,l,δ3,l,....δN,l]\delta^l = [\delta^{1,l},\delta^{2,l},\delta^{3,l},....\delta^{N,l}]δl=[δ1,l,δ2,l,δ3,l,....δN,l]。运用公式2,递推求得前一层的δl−1\delta^{l-1}δl−1。
运用公式4,即可求得所有训练样本的wlw^lwl的累积梯度,我们只需再除以N 即可(尚未考虑正则化,如果有正则化,加上相应梯度即可,此步简单)。
通过所有上面讲述的,我们可以意识到,关键点和难点是如何求出最后一层的δL\delta^LδL, 得出它后,其他的计算都可以由公式递推得到。因此,在求δL\delta^LδL上,我们需要多一些耐心和认真。我个人的求解方式是 通过对单个 ∂C∂zjl\frac{\partial C}{\partial z^l_j}∂zjl∂C计算,总结出整个 ∂C∂zl\frac{\partial C}{\partial z^l}∂zl∂C的计算过程。