以上逐次从后向前求导的过程即为“反向传导”的本意所在。 计算我们需要的偏导数,计算方法如下:
最后,我们用矩阵-向量表示法重写以上算法。我们使用“” 表示向量乘积运算符(在Matlab或Octave里用“.*”表示,也称作阿达马乘积)。若 则
。
,
那么,反向传播算法可表示为以下几个步骤:
1 进行前馈传导计算,利用前向传导公式,得到 的激活值。
2 对输出层(第
层),计算:
3 对于
4 计算最终需要的偏导数值:
的各层,计算:
直到输出层
实现中应注意:在以上的第2步和第3步中,我们需要为每一个 值计算其
。假设
是sigmoid函数,并且我们已经在前向传导运算中得到了
表达式,就可以计算得到
。那么,使用我们早先推导出的
。
最后,我们将对梯度下降算法做个全面总结。在下面的伪代码中,一个与矩阵
维度相同的矩阵,
是一个与
是
维度相同的向量。注
意这里“”是一个矩阵,而不是“ 与 相乘”。下面,我们实现批量
梯度下降法中的一次迭代:
对于所有 ,令 1 对于
到 。
2 计算 3 计算
更新权重参数:
。
。
,
(设置为全零矩阵或全零向量)
和
, 使用反向传播算法计算
现在,我们可以重复梯度下降法的迭代步骤来减小代价函数 值,进而求解我们的神经网络。
的
三 实验仿真
3.1 利用autoencoder提取特征
从给定的很多张自然图片中截取出大小为8*8的小patches图片共10000张,现在需要用sparse autoencoder的方法训练出一个隐含层网络所学习到的特征。该网络共有3层,输入层是64个节点,隐含层是25个节点,输出层当然也是64个节点了。
其实实现该功能的主要步骤还是需要计算出网络的损失函数以及其偏导数。下面用简单的语言大概介绍下这个步骤,方便理清算法的流程。
1. 计算出网络每个节点的输入值(即程序中的z值)和输出值(即程序中的a值,a是z的sigmoid函数值)。
2. 利用z值和a值计算出网络每个节点的误差值(即程序中的delta值)。 3. 这样可以利用上面计算出的每个节点的a,z,delta来表达出系统的损失函数以及损失函数的偏导数了,当然这些都是一些数学推导。
其实步骤1是前向进行的,也就是说按照输入层——隐含层——输出层的方向进行计算。而步骤2是方向进行的(这也是该算法叫做BP算法的来源),即每个节点的误差值是按照输出层——隐含层——输入层方向进行的。 下面看一下实验流程:
首先运行主程序train.m中的步骤1,即随机采样出10000个小的patch,并且显示出其中的204个patch图像,图像显示如下所示:
然后运行train.m中的步骤2和步骤3,进行损失函数和梯度函数的计算并验证。进行gradient checking的时间可能会太长,我这里大概用了1个半小时以上,当用gradient checking时,发现误差只有6.5101e-11,远小于1e-9,所以说明前面的损失函数和偏导函数程序是对的。后面就可以接着用优化算法来求参数了,本程序给的是优化算法是L-BFGS。经过几分钟的优化,就出结果了。
最后的W1的权值如下所示:
3.2 Self-taught learning
Self-taught learning是用的无监督学习来学习到特征提取的参数,然后用有监督学习来训练分类器。这里分别是用的sparse autoencoder和softmax regression,实验的数据依旧是手写数字数据库MNIST Dataset。
采用数字5~9的样本来进行无监督训练,采用的方法是sparse autoencoder,可以提取出这些数据的权值,权值转换成图片显示如下:
但是本次实验主要是进行0~4这5个数字的分类,虽然进行无监督训练用的是数字5~9的训练样本,这依然不会影响后面的结果。只是后面的分类器设计是用的softmax regression,所以是有监督的。最后的结果精度是98%,而直接用原始的像素点进行分类器的设计不仅效果要差(才96%),而且训练的速度也会变慢不少。
3.3 convolution与 pooling
在全局连接网络中,如果我们的图像很大,比如说为96*96,隐含层有要学习100个特征,则这时候把输入层的所有点都与隐含层节点连接,则需要学习10^6个参数,这样的话在使用BP算法时速度就明显慢了很多。
所以后面就发展到了局部连接网络,也就是说每个隐含层的节点只与一部分连续的输入点连接。这样的好处是模拟了人大脑皮层中视觉皮层不同位置只对局部区域有响应。局部连接网络在神经网络中的实现使用convolution的方法。它在神经网络中的理论基础是对于自然图像来说,因为它们具有稳定性,即图像中某个部分的统计特征和其它部位的相似,因此我们学习到的某个部位的特征也同样适用于其它部位。
下面具体看一个例子是怎样实现convolution的,假如对一张大图片的数据集,r*c大小,则首先需要对这个数据集随机采样大小为a*b的小图片,然后用这