Neural Networks and Deep Learning中How the bp algorithm works的一些记录与总结

本章的链接:http://neuralnetworksanddeeplearning.com/chap2.html

1. 梯度下降的理解

在神经网络的输出层(output layer)可以定义一个loss function,例如C,我们使用梯度下降法的目的就是使得C的值降低到最小。

梯度的定义如下,

而C是关于权重矩阵W以及偏置b的函数,因此可以求出其梯度,在梯度的负方向上C的值下降最快,又因为梯度其实就是偏导数组成的向量,所以根据求出的偏导数来更新权重W和偏置b(也即在梯度的方向更新向量W和b)可以达到使C降低速度最快的目的。而当方向定了之后,一次更新多少?这个问题就要由学习率α来决定,所以在求梯度下降算法的更新公式里通常会带有学习率α。

2. 权重矩阵的元素下标为什么是后一层的在前,而前一层的在后?

l层的下标在前而l-1层的下标在后

简单地理解,当这样表示权重矩阵的元素时,权重矩阵第i行的所有元素便代表着第l-1层的所有节点到第l层的第i个节点的权重值,这样便可以简化向量形式的公式写法,

而如果反过来,l层的下标在后,l-1层的下标在前(也就是按照层的顺序排列),那么上述公式就需要对w进行一次转置,让表达式变得有些annoying了。

 

3. 神经网络每一层的输入输出

以上面这个图为例,假设layer1的输入是向量X,且layer1到layer2的权重矩阵为W12,那么有

z_{2}=W_{12}X+b1

这个z2叫做weighted input,代表着layer1对layer2的输入,也就是对layer1的输出做了一定处理,变成了layer2的输入,

然后到了layer2之后,会在layer2中对z2做一次处理,记做

a_{2}=\sigma (z_{2})

a代表activation,也就是layer2的激活值,也代表着layer2的输出值,然后再经过上述同样的步骤传递到layer3,以此类推。

 

4. demon的故事

当这个demon对其中的z_{j}^{l}施以一个微小的变化\Delta z_{j}^{l}时,最终的output的cost会改变一个相应的值,即

从这个故事中得到了一些启发,即微小的改变对最终的cost会有影响,那么现在细化到每一层来看,定义layerl的误差

个人理解这里的定义只是为了方便求解,先求出\delta _{j}^{l},然后再求\delta _{j}^{l}对w或者b的偏导,即可求得C对w或b的偏导数。

这里也强调了此处的误差\delta _{j}^{l}并不是我们通常意义上的离正确值的偏差,而是一个为了方便计算的定义

 

5. 一些推导与说明

  

    a_{j}^{L}=\sigma (z_{j}^{L})

  

而由于最终的cost并不是完全取决于某一特定的神经元j,所以这里\delta _{j}^{L}的值会较小,这也正是我们所期望的;同时,也反映了sigma(激活函数)相应于z_{j}^{L}的变化速度。且上式中的每一项都非常好进行计算。

最后,上式可写作

其中

也可写作

而上述公式又可以写成如下形式

这个公式看起来就像是l+1层的误差反向传播到了第l层上,因此我们通过联合下下面两个公式,就可以求出一个神经网络中的所有层的误差了

 

1)BP3:

最初,我们有前向传播公式

z^{l}=w^{l}a^{l-1}+b^{l},其中a^{l-1}是l-1层的激活值(也就是输出值),w^{l}b^{l}分别是权重矩阵和偏置向量

那么向量化求导可得

\frac{\partial C}{\partial b^{l}}=\frac{\partial C}{\partial z^{l}}\frac{\partial z^{l}}{\partial b^{l}}=\frac{\partial C}{\partial z^{l}}\bigodot ones\_like(b^{l})=\frac{\partial C}{\partial z^{l}}=\delta^{l},其中\bigodot代表元素相乘积。

同理可推导BP4,

2) BP4:

最初有

z^{l}=w^{l}a^{l-1}+b^{l}

由于w是个矩阵,所以先对元素求偏导,计算每个元素的值,有:

\frac{\partial C}{\partial w^{l}_{jk}}=\frac{\partial C}{\partial z^{l}_{j}}\frac{\partial z^{l}_{j}}{\partial w^{l}_{jk}}=\frac{\partial C}{\partial z^{l}_{j}}\frac{\partial (w^{l}a^{l-1}+b^{l})}{\partial w^{l}_{jk}}=\frac{\partial C}{\partial z^{l}_{j}}a_{k}^{l-1}=a_{k}^{l-1}\delta_{j}^{l}

然后再写成向量化的形式,

\frac{\partial C}{\partial w^{l}}=\delta^{l}a^{l-1},因为w的行代表l+1层的神经元,列代表l层的神经元,故写为\delta^{l}a^{l-1}(j*k)

 

6. 总结

当一个权重所连接的两端神经元中,输入神经元的激活值较低或者输出神经元的值已接近饱和,那么这个权重学习的速度就会降低,这也是由这些偏导公式决定的。

bp算法的公式总结,也是反向传播的计算公式:

 

7. 写代码时遇到的一些困惑点

首先,神经网络的输出层的z和a是相同的(就目前学习到的神经网络来看)(z和a分别代表一个神经元的输入和输出,一般有a=\sigma (z)),而在输出层会定义一个loss function,这个loss function是a的函数,也就是z的函数,例如平方误差或者softmax等。

那么loss function会对a有一个偏导数,此偏导代表了a的变化对loss func的影响,记做\frac{\partial L}{\partial a},而a对z也会有一个偏导\frac{\partial a}{\partial z},又因为a通常和z在输出层是相等的,即a=z,故\frac{\partial a}{\partial z}=1,所以在BP算法的公式BP1中有\delta^L = \bigtriangledown _aC,即输出层的误差\delta^L,然后就可以通过这个误差进行权重矩阵的求解和反向传播了。

示例代码的loss func是softmax函数,即

L=-s_y_i+ln\frac{e^{s_y_i}}{\Sigma{e^{s_j}}}

那么可求得\frac{\partial L}{\partial s_{y_i}} = -1+\frac{e^{s_{y_i}}}{\Sigma{e^{s_j}}}

即代码中4/5/6行所代表的意思,这里的s_j实际上就是a_j,即输出层的输出值。

        # 先求出输出层softmax型的loss func对输出层的偏导数,作为反向传播的起点,此处与SVM相同
        # softmax公式为L=-s[yi]+ln(∑e^s[j]),可以求得L对s[yi]的偏导数为-1+e^s[yi]/∑e^s[j],也就是下面代码中的-1+prob
        # 由于输出层的z和a是相同的值(即a==z),所以此处delta(L)/delta(a) == delta(L)/delta(z)
        output = np.zeros_like(scores)
        output[range(N), y] = -1
        output += prob
        # 先根据反向传播的上层梯度乘以本地变量求出W2的梯度
        grads['W2'] = (a2.T).dot(output) # 公式BP4
        grads['W2'] = grads['W2'] / N + reg * W2
        # 求取b2的梯度,方法同上
        grads['b2'] = np.ones(N).dot(output) / N
        # 将最后一层节点的误差反向传播至隐藏层
        hidden = output.dot(W2.T)
        # 考虑到ReLU函数的作用,可以知道只有在z2矩阵中大于零的部分才会被传递至后面的层中,这里求的就是ReLU函数的偏导矩阵
        mask = np.zeros_like(z2)
        mask[z2 > 0] = 1
        hidden = hidden * mask # N*H,这里相当于求解出了how bp algorithm works那一章中的公式BP2
        # 再从隐藏层反向传播至W1
        grads['W1'] = (X.T).dot(hidden) # 公式BP4
        grads['W1'] = grads['W1'] / N + reg * W1
        # W1同理
        grads['b1'] = np.ones(N).dot(hidden) / N
        pass

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值