——–本文中除了在图片下方标记了出处的图片,均为原创,转载请注明出处——–
上一篇文章《机器学习笔记06:神经网络的表示(Neural Networks-Representation)》 大概描述了神经网络的起源、结构、表示、工作方法及一些应用。今天这篇文章对应 Coursera 上的Stanford机器学习课程的week05。主要的内容是神经网络的学习,包括梯度下降、反向传播等。
1.误差函数(Cost Function)
线性回归和逻辑回归中都用到了误差函数来衡量模型的准确度,当然神经网络也不例外。先来看一个神经网络的图片,这里需要引入一些标记,以便于后面的描述。
本图片属于Stanford机器学习课程,转载请注明出处
对于神经网络,有如下几个记号:
Notation |
Representation |
{(x(1),y(1)),(x(2),y(2)),...,(x(m),y(m)),} |
training set (训练集) |
L |
total no. of layers in network (网络的层数) |
Sl |
no. of units(not counting bias unit) in layer l (第 l 层的单元数,不算偏置单元) |
对于二元分类问题, y=0 or 1 。输出单元也只有一个。即 SL=1 (最后一层只有一个单元);对于多类分类问题(类数大于2),若类数为 K ,则 y∈RK 。如上图的四类分类问题中,有
y=⎡⎣⎢⎢⎢⎢1000⎤⎦⎥⎥⎥⎥,⎡⎣⎢⎢⎢⎢0100⎤⎦⎥⎥⎥⎥,⎡⎣⎢⎢⎢⎢0010⎤⎦⎥⎥⎥⎥,⎡⎣⎢⎢⎢⎢0001⎤⎦⎥⎥⎥⎥
输出层(最后一层)的单元数量也为
K 。
现在来看误差函数(Cost Function)。先来回顾一下逻辑回归中的误差函数:
J(θ)=−1m∑i=1m[y(i)log(hθ(x(i)))+(1−y(i))log(1−hθ(x(i)))]+λ2m∑j=1nθ2j
其中第一项是原来的误差函数,第二项是惩罚项。
现在来看看神经网络的误差函数。首先需要知道 hΘ(x)∈RK , (hΘ(x))i=ithoutput 。神经网络的误差函数可以记为如下:
J(Θ)=−1m[∑i=1m∑k=1Ky(i)klog(hΘ(x(i)))k+(1−y(i)k)log(1−hΘ(x(i)))k]+λ2m∑l=1L−1∑i=1Sl∑j=1Sl+1(Θ(l)ji)2
其中
K 为输出层的单元数,即类数。在计算误差的时候,需要将每一类都计算进去。后面的惩罚项是整个神经网络中所有的参数
Θ 的值之和。注意
i 是从 1 开始,因为我们通常不处理偏差项,就如在逻辑回归中不处理
θ0 一样。以上就是神经网络中误差函数。
2.反向传播算法(Backpropagation Algorithm)
反向传播在神经网络中是一个非常重要的部分。它的主要作用是最小化误差函数,也就是提高神经网络的准确性。和在线性回归和逻辑回归中一样,我们采用梯度下降(Gradient descent)法来最优化误差函数。上面已经说明了误差函数为:
J(Θ)=−1m∑i=1m∑k=1K[y(i)klog(hΘ(x(i)))k+(1−y(i)k)log(1−hΘ(x(i)))k]+λ2m∑l=1L−1∑i=1Sl∑j=1Sl+1(Θ(l)ji)2
在梯度下降的过程中,需要计算每个
Θ 的偏导数,并用来更新
Θ 自身:
Θ(l)ji=Θ(l)ji−∂∂Θ(l)jiJ(Θ)
用一个样本来说明如何进行反向传播。假设神经网络如下图所示:
本图片属于Stanford机器学习课程,转载请注明出处
假如有一个样本
(x,y) 首先,我们需要进行前向传播,也就是计算预测值:
a(1)=x
z(2)=Θ(1)a(1)
a(2)=g(z(2))adda(2)0
z(3)=Θ(2)a(2)
a(3)=g(z(3))adda(3)0
z(4)=Θ(3)a(3)
a(4)=g(z(4))=hΘ(x)
以上的式子都是经过向量化的,具体请参考上一篇文章 《机器学习笔记06:神经网络的表示(Neural Networks-Representation)》 。接下来,为了使用梯度下降法来最小化误差函数,我们需要计算出每个参数
Θ 偏导数,我们就得使用反向传播算法。
首先引入一个标记 δ(l)j ,它表示 l 层上节点(单元) j 的误差。例如,假设有一个四层的神经网络( L=4 )。每一层的误差可以表示如下:
δ(4)=a(4)j−yj=hΘ(x)j−yj
δ(3)=(Θ(3))Tδ(4).∗g′(z(3))
δ(2)=(Θ(2))Tδ(3).∗g′(z(2))
其中
.∗ 是Matlab中的用法,即矩阵中对应位置相乘。需要注意的是,第一层没有误差,因为输入值本身是通过测量或者其他方式得到的。我们有如下的反向传播公式:
δ(l)=(Θ(l))Tδ(l+1).∗g′(z(l))
同时
g′(z(l)) 可写作:
g′(z(l))=a(l).∗(1−a(l))
所以
δ(l)=(Θ(l))Tδ(l+1).∗a(l).∗(1−a(l))
最后可以得到
∂∂Θ(l)ij=a(l)jδ(l+1)i
注意,上面的这几个式子都忽略了正则化,之后会添加上去。下面对反向传播进行详细的推导。
3.反向传播公式推导
上面的一节,乱七八糟看不懂没关系,下面来仔细推导一下反向传播。
最重要的一点是思维要清晰。我们需要清楚地知道,训练一个神经网络是为了达到好的预测效果,所以我们要最小化神经网络的误差函数。而最小化误差需要用到梯度下降法,我们又知道,使用梯度下降来最优化参数 Θlij 必须求误差函数 J(Θ) 关于 Θlij 的偏导数。而反向传播的重点即在求 Θlij 的偏导数上。
步骤一:进行前向传播,计算出输入 a(1) 对应的输出 a(L)
其中 L 表示神经网络的层数,前向传播请参考上一篇文章《机器学习笔记06:神经网络的表示(Neural Networks-Representation)》 。
步骤二:计算输出层的误差
假如有如下神经网络,其中黄色的线代表第二层的偏置单元 a(2)0 的参数 Θ(2)10 :
首先回顾一下神经网络的误差函数:
J(Θ)=−1m∑i=1m∑k=1K[y(i)klog(hΘ(x(i)))k+(1−y(i)k)log(1−hΘ(x(i)))k]+λ2m∑l=1L−1∑i=1Sl∑j=1Sl+1(Θ(l)ji)2
在这里,因为只把计算
Θ(2)10 关于 误差函数
J(Θ) 的偏导数作为例子,并且不考虑后面的惩罚项,所以函数
J(Θ) 可以简化为:
J(Θ)=−∑k=12[y(i)klog(hΘ(x(i)))k+(1−y(i)k)log(1−hΘ(x(i)))k]
其中上标
i 表示训练集的标签,即第几组样本,这里可以不予考虑,并且,我们只计算
Θ(2)10 的偏导数,只会用到输出节点
a(3)1 ,所以下标
k 也可以不予考虑,所以在这里我们可令:
Cost(Θ)=−[ylog(hΘ(x))+(1−y)log(1−hΘ(x))]
再回顾一下,
hΘ(x)=g(z) ,且这里有
z(3)1=Θ(2)10a(2)0+Θ(2)11a(2)1+Θ(2)12a(2)2 。所以我们对参数
Θ(2)10 求偏导如下(
注意:因为第一部分是对 Cost(Θ) 求关于 z(3)1 的偏导数,所以令函数 Cost(Θ) 中的 hΘ(x)=g(z) ):
∂∂Θ(2)10J(Θ)=∂Cost(Θ)∂z(3)1⋅∂z(3)1∂Θ(2)10
我们设
δlj 表示第
l 层上激励神经元节点
j 的误差,在这里设
δ31=∂Cost(Θ)∂z(3)1 。所以上面的式子可以继续推导如下:
∂∂Θ(2)10J(Θ)=δ31⋅∂z(3)1∂Θ(2)10=∂Cost(Θ)∂z(3)1⋅a(2)0=a(2)0[−y11g(z(3)1)g′(z(3)1)−(1−y1)11−g(z(3)1)(−g′(z(3)1))]=a(2)0[−y1g(z(3)1)+1−y11−g(z(3)1)]g′(z(3)1)=a(2)0−y1+y1g(z(3)1)+g(z(3)1)−y1g(z(3)1)g(z(3)1)(1−g(z(3)1))g′(z(3)1)=a(2)0g(z(3)1)−y1g(z(3)1)(1−g(z(3)1))g′(z(3)1)(3−1)
好了,下面我们来计算一下
g′(z(3)1) 。首先,我们先来计算一下
g′(z) ,随后将
g′(z(3)1) 代入即可:
g′(z)=−(1+e−z)−2⋅∂∂z(1+e−z)=−(11+e−z)2⋅e−z⋅(−1)=(11+e−z)(11+e−z)⋅e−z=(11+e−z)(e−z1+e−z)=(11+e−z)(1+e−z1+e−z−11+e−z)=g(z)(1−g(z))=a(3)1(1−a(3)1)
所以由上式可知
g′(z(3)1)=g(z(3)1)(1−g(z(3)1)) ,将此式代入 (3-1) 得:
∂∂Θ(2)10J(Θ)=a(2)0g(z(3)1)−y1g(z(3)1)(1−g(z(3)1))g′(z(3)1)=a(2)0g(z(3)1)−y1g(z(3)1)(1−g(z(3)1))g(z(3)1)(1−g(z(3)1))=a(2)0(g(z(3)1)−y1)=(g(z(3)1)−y1)a(2)0=δ(3)1a(2)0
上面的结果 δ(3)1a(2)0 即是误差函数 J(Θ) 关于参数 Θ(2)10 的偏导数。所以,最后一层(输出层)的节点(或称激励单元)
a(3)1 的误差为:
δ(3)1=∂Cost(Θ)∂z(3)1=g(z(3)1)−y1=a(3)1−y1
其他输出层中激励单元的误差也同理可得:
δ(3)2=∂Cost(Θ)∂z(3)2=g(z(3)2)−y2=a(3)2−y2
所以对于输出层有
K 个激励单元的
L 层神经网络,其输出层的误差为:
δ(L)=∑j=1Kδ(L)j=a(L)−y
好了,输出层的误差就讲到这里,下面我们要利用输出层的误差,进行反向传播,以求得每个参数
Θ(l)ij 的偏导数。
步骤三:将输出层的误差反向传播,计算每个参数 Θ(l)ij 的偏导数
这部分是最麻烦的地方,也是计算量最大的地方,但也是神经网络的精髓所在。我们以一个最简单的三层神经网络来做例子,其可推广到具有任意层数,且每层有任意个激励单元的神经网络。
假设有如下的神经网络:
我们以求参数
Θ(1)11 的偏导数为例,来说明神经网络的反向传播。
由神经网络的前向传播可知:
a(2)1=g(z(2)1)=g(a(1)1Θ(1)11)
a(3)1=g(z(3)1)=g(a(2)1Θ(2)11)
所以:
a(3)1=g(g(a(1)1Θ(1)11)⋅Θ(2)11)=g(g(z(2)1)⋅Θ(2)11)
通过链式求导,我们可知:
∂∂Θ(1)11J(Θ)=∂J(Θ)∂z(3)1⋅∂z(3)1∂z(2)1⋅∂z(2)1∂Θ(1)11
由
步骤二可知
∂J(Θ)∂z(3)1=δ(3)1 ,又因为
∂z(2)1∂Θ(1)11=a(1)1 ,所以有:
∂∂Θ(1)11J(Θ)=δ(3)1⋅∂z(3)1∂z(2)1⋅a(1)1
即形象地来看,如下图所示:
所以:
∂∂Θ(1)11J(Θ)=δ(3)1⋅∂z(3)1∂z(2)1⋅a(1)1=δ(3)1⋅a(1)1⋅∂(g(z(2)1)⋅Θ(2)11)∂z(2)1=δ(3)1⋅a(1)1⋅g′(z(2)1)⋅Θ(2)11=[δ(3)1⋅Θ(2)11⋅g′(z(2)1)]⋅a(1)1=δ(2)1a(1)1
故有:
δ(2)1=δ(3)1⋅Θ(2)11⋅g′(z(2)1)=δ(3)1⋅Θ(2)11⋅g(z(2)1)(1−g(z(2)1))
所以,推广到多层、每层多节点的神经网络,我们得到了反向传播的最重要的公式:
δ(l)=((Θ(l))Tδ(l+1)).∗g′(z(l))=((Θ(l))Tδ(l+1)).∗g(z(l)).∗(1−g(z(l)))=((Θ(l))Tδ(l+1)).∗a(l).∗(1−a(l))
上面这个公式即是反向传播中的最重要的公式,其中
Θ(l) 是一个和前向传播中一样的矩阵,
δ(l+1) 是一个列向量。至于上面的公式中为什么要转置矩阵,请读者自己画一个三层网络图来模拟一下反向传播便一目了然了。另外需要注意的是,在反向传播过程中,每层中的偏置单元是没有误差的,因为它们始终为1。
结合神经网络的误差公式:
J(Θ)=−1m[∑i=1m∑k=1Ky(i)klog(hΘ(x(i)))k+(1−y(i)k)log(1−hΘ(x(i)))k]+λ2m∑l=1L−1∑i=1Sl∑j=1Sl+1(Θ(l)ji)2
即可得到求任意参数
Θ(l)ij 的偏导数的公式:
∂∂Θ(l)ijJ(Θ)=1m∑t=1mδ(t)(l+1)ia(t)(l)j+λm∑l=1L−1∑i=1Sl∑j=1Sl+1(Θ(l)ji)
其中
m 表示训练集的大小,
L 表示网络的层数,
SL 表示第
L 层网络中激励单元的数量。通过上式,我们就能对神经网络执行梯度下降法来训练网络了。
附:Coursera机器学习week6“神经网络的学习”编程作业代码
上面就是神经网络的反向传播,希望能帮助到大家。
如有错误,期望您能纠正,留言或者是e-mail:
[email protected]
——–转载请注明出处——–