首先是一些概念与定义。
明确深度网络的定义:包含多层结构-----两层或更多隐藏层的-----的网络被称为深度网络。那么针对深度网络的学习任务,就是深度学习了。
反向传播算法:一种计算代价函数梯度的快速算法。
1.热身:神经网络中使用矩阵快速计算输出的方法
我们使用
(下面有些时候为了在csdn编辑方便,写作W^l----jk)表示从第(l-1)层(同前,下写作(l-1)^th)的第k个神经元(同前,下记作k^th)到第l层的第j个神经元(下记作j^th)的链接上的权重。示意如下图:
w^3----24代表的是第2层的第4个神经元到第3层的第2个神经元的链接的权重。之所以要k---->j,是为了后面计算的时候与偏置的一起使用表示方便。
同理,我们对网络的偏置与激活值也做类似的表达。使用
表示第l层的第j个神经元的偏置。使用
表示第l层的第j个神经元的输出。示意如下图:
又因为第l-1层的输出a^(l-1)----j实际上就是下一层的某个神经元的输入,根据上一节的公式,我们可以得到下面的这个公式:
为了用矩阵和向量的形式重写上式,我们对每一层l,定义一个权重矩阵w^l,权重矩阵w^l的元素正是链接到第l层的神经元的权重,更具体的来说,第j行第k列的元素代表的就是l-1层的第k个神经元到第l层的第j个神经元链接的权重,即上面的w^l-----jk。类似的,对于每一层l,定义偏置向量,b^l,其元素是偏置值b^l---j。对于每一层l,定义
激活向量a^l,其元素是激活值a^l--j。
然后我们引入向量化函数
sigma(
激活函数),其作用矩阵或者向量即把每一个元素进行函数操作。示例如下,作用函数是f(x)=x^2,那么向量化函数f(x)当x为矩阵时:
那么(23)式可以改写为:
在使用上式进行a^l的过程中,用到了一个中间变量
我们称为
带权输入。
z^l的每个元素都是
。z^l--j就是第l层的第j个神经元的激活函数的带权输入。
2.关于代价函数的两个假设:
假设1:代价函数可以被写成一个在每个样本x上的代价函数Cx的均值:
假设2:代价函数可以写成关于神经网络的输出a^L的函数。示意:
例如二次代价函数满足这个要求,因为对于一个单独的训练样本x,其二次代价函数可以写作:
为什么不看成关于y的函数是因为,y的值并不会随着权重和偏置的改变而改变,在训练样本定下来之后,y也就定下来不变化了,并不属于需要学习的对象。
3.Hadamard(哈达曼)乘积![](https://img-blog.csdn.net/20160802145639281)
很好理解吧……就是每个元素分别做乘积(跟普通矩阵乘法不一样!)
也叫Schur乘积
4.反向传播的四个基本方程
反向传播是对权重和偏置调整影响代价函数的理解。
引入中间量
(下记为deltalj),成为在第l层上的第j个神经元上的
误差。反向传播将计算误差的流程,然后将其关联到
和
上。
为了理解误差是如何定义的,假设神经网络上有个小鬼(demon)。
这个小鬼假设在l层的第j个神经元上,先他调皮捣蛋,对神经元的带权输入产生了一点扰动
,是神经元的输出由
变成
,最后会导致整个代价会产生
的改变。
假设现在他现在变好了,想帮你优化代价,它试着来找到让代价更小的
,假设
有一个较大的值(或正或负),那么为了使代价更小,他必须找到一个异号的
。相反,如果这个
接近于0,那么这个小鬼并不能通过改变扰动来改善代价,他则认为现在是接近最优(前提是小鬼能调整的
很小)。所以,这里有一种启发式的认识,
是神经元误差的度量。
按照上面诉说的这段话,我们定义l层上的第j个神经元的误差
为:
输出层误差方程:
重写为矩阵形式:
则可以写作:
使用下一层的误差来表示当前层的误差:
通过BP1和BP2,我们就可以先计算L层误差,再用BP2计算L-1层误差,一步步地反向传播完整个网络。
代价函数关于偏置的改变率:
代价函数关于任何一个权重的改变率:
示意图是:
,ain是表示该权重链接的输入神经元的激活值,out表示的该权重链接的输出神经元的误差。
如果ain很小,那么这个值也会趋于很小,我们就说该权重
缓慢学习,表示梯度下降的时候,这个权重不会改变太多。换句话说,BP4告诉我们,低激活值的神经元的权重学习会非常缓慢。
四个方程的证明 ,在此略过,书上有一节单独来讲,可选即可看可不看。
总结下四个方程为:
反向传播代码用算法描述如下:
1.
输入x:为输入层设置对应的激活值
2.
前向传播:对每个1,2,3……L,计算
3.
输出误差
:计算向量
4.
反向传播误差:对每个l=L-1,L-2……2,计算
5.
输出:代价函数函数的梯度由
给出