前馈网络及反向传播
2014-03-22 20:32
148 查看
本文主要介绍多层感知器模型(MLP),它也可以看成是一种logister回归,输入层通过非线性转换,即通过隐含层把输入投影到线性可分的空间中。
如果我们在中间加一层神经元作为隐含层,则它的结构如下图所示
![](http://images.cnitblog.com/blog/587426/201402/112051578922075.png)
单隐层的MLP定义了一个映射:
![](http://images.cnitblog.com/blog/587426/201402/112051583126904.png)
,其中 D和L为输入向量和输出向量f(x)的大小。
隐含层与输出层神经元的值通过激活函数计算出来,例如下图:如果我们选用sigmoid作为激活函数,输入设为x,要求出隐含层的激活值a,公式如下。其中
![](http://images.cnitblog.com/blog/587426/201402/112051588003517.png)
。
![](http://images.cnitblog.com/blog/587426/201402/112051590204519.png)
![](http://images.cnitblog.com/blog/587426/201402/112052004345520.png)
同理输出的h(x)可以用同样的公式得到,上述过程就是向前传导,因为这种联接图没有闭环或回路。
我们可以用反向传播法(backpropagation)来训练上面这个神经网络。下面主要介绍backpropation算法。
假设对于单个样例(x,y),它的代价函数(cost function)为
![](http://images.cnitblog.com/blog/587426/201402/112052009696147.png)
对于一个样本集
![](http://images.cnitblog.com/blog/587426/201402/112052012912948.png)
,定义它的cost
function为:
![](http://images.cnitblog.com/blog/587426/201402/112052015931505.png)
我们要做的就是最小化上述式子,类似于最小二乘,不同的是加上了第二项的权重衰减,它是用来防止过拟合,可以把它看成是一个约束项,而整个式子就是求解最值的拉格朗日公式。我们的目标是针对参数
![](http://images.cnitblog.com/blog/587426/201402/112052017834263.png)
和
![](http://images.cnitblog.com/blog/587426/201402/112052020009562.png)
来求其函数
![](http://images.cnitblog.com/blog/587426/201402/112052021883321.png)
的最小值。为了求解神经网络,我们需要将每一个参数
![](http://images.cnitblog.com/blog/587426/201402/112052023811378.png)
和
![](http://images.cnitblog.com/blog/587426/201402/112052025512663.png)
初始化为一个很小的、接近零的随机值(比如说,使用正态分布
![](http://images.cnitblog.com/blog/587426/201402/112052027173949.png)
生成的随机值,其中
![](http://images.cnitblog.com/blog/587426/201402/112052028602693.png)
设置为
![](http://images.cnitblog.com/blog/587426/201402/112052030857992.png)
),之后对目标函数使用诸如批量梯度下降法的最优化算法。关于w和b的初值,我根据这篇论文(Understanding
the difficulty of training deep feedforward neuralnetworks)得出的结论:如果激活函数为tanh,我们设置为
![](http://images.cnitblog.com/blog/587426/201402/112052034333036.png)
之间的值,如果激活函数是sigmoid,则是
![](http://images.cnitblog.com/blog/587426/201402/112052037688836.png)
。
关于反向传播算法的推导,UFLDL 中介绍的很清楚,我直接粘帖过来了。
既然是用梯度下降法,我们先对代价函数J求关于w和b 的偏导数,直接写出结果:
![](http://images.cnitblog.com/blog/587426/201402/112052039981907.png)
反向传播算法的思路如下:给定一个样例
![](http://images.cnitblog.com/blog/587426/201402/112052041991436.png)
,我们首先进行"前向传导"运算,计算出网络中所有的激活值,包括
![](http://images.cnitblog.com/blog/587426/201402/112052044584979.png)
的输出值。之后,针对第
![](http://images.cnitblog.com/blog/587426/201402/112052046942752.png)
层的每一个节点
![](http://images.cnitblog.com/blog/587426/201402/112052049483065.png)
,我们计算出其"残差"
![](http://images.cnitblog.com/blog/587426/201402/112052052561623.png)
,该残差表明了该节点对最终输出值的残差产生了多少影响。对于最终的输出节点,我们可以直接算出网络产生的激活值与实际值之间的差距,我们将这个差距定义为
![](http://images.cnitblog.com/blog/587426/201402/112052054756922.png)
(第
![](http://images.cnitblog.com/blog/587426/201402/112052058447736.png)
层表示输出层)。对于隐藏单元我们如何处理呢?我们将基于节点(译者注:第
![](http://images.cnitblog.com/blog/587426/201402/112052060892280.png)
层节点)残差的加权平均值计算
![](http://images.cnitblog.com/blog/587426/201402/112052062678267.png)
,这些节点以
![](http://images.cnitblog.com/blog/587426/201402/112052064178080.png)
作为输入。下面将给出反向传导算法的细节:
进行前馈传导计算,利用前向传导公式,得到
![](http://images.cnitblog.com/blog/587426/201402/112052066864096.png)
直到输出层
![](http://images.cnitblog.com/blog/587426/201402/112052070048423.png)
的激活值。
对于第
![](http://images.cnitblog.com/blog/587426/201402/112052073325224.png)
层(输出层)的每个输出单元
![](http://images.cnitblog.com/blog/587426/201402/112052076435254.png)
,我们根据以下公式计算残差:
![](http://images.cnitblog.com/blog/587426/201402/112052079676352.png)
[译者注:
![](http://images.cnitblog.com/blog/587426/201402/112052083815410.png)
]
对
![](http://images.cnitblog.com/blog/587426/201402/112052088152712.png)
的各个层,第
![](http://images.cnitblog.com/blog/587426/201402/112052091161269.png)
层的第
![](http://images.cnitblog.com/blog/587426/201402/112052093433339.png)
个节点的残差计算方法如下:
![](http://images.cnitblog.com/blog/587426/201402/112052097204154.png)
{译者注:
![](http://images.cnitblog.com/blog/587426/201402/112052108416597.png)
将上式中的
![](http://images.cnitblog.com/blog/587426/201402/112052112207412.png)
与
![](http://images.cnitblog.com/blog/587426/201402/112052117725214.png)
的关系替换为
![](http://images.cnitblog.com/blog/587426/201402/112052122441828.png)
与
![](http://images.cnitblog.com/blog/587426/201402/112052156935645.png)
的关系,就可以得到:
![](http://images.cnitblog.com/blog/587426/201402/112052160909001.png)
以上逐次从后向前求导的过程即为"反向传导"的本意所在。 ]
计算我们需要的偏导数,计算方法如下:
![](http://images.cnitblog.com/blog/587426/201402/112052165028059.png)
最后,我们用矩阵-向量表示法重写以上算法。我们使用"
![](http://images.cnitblog.com/blog/587426/201402/112052167714075.png)
" 表示向量乘积运算符(在Matlab或Octave里用".*"表示,也称作阿达马乘积)。若
![](http://images.cnitblog.com/blog/587426/201402/112052172192445.png)
,则
![](http://images.cnitblog.com/blog/587426/201402/112052174303447.png)
。在上一个教程中我们扩展了
![](http://images.cnitblog.com/blog/587426/201402/112052176084732.png)
的定义,使其包含向量运算,这里我们也对偏导数
![](http://images.cnitblog.com/blog/587426/201402/112052178456802.png)
也做了同样的处理(于是又有
![](http://images.cnitblog.com/blog/587426/201402/112052181713603.png)
)。
那么,反向传播算法可表示为以下几个步骤:
进行前馈传导计算,利用前向传导公式,得到
![](http://images.cnitblog.com/blog/587426/201402/112052246174937.png)
直到输出层
![](http://images.cnitblog.com/blog/587426/201402/112052248678480.png)
的激活值。
对输出层(第
![](http://images.cnitblog.com/blog/587426/201402/112052251218794.png)
层),计算:
![](http://images.cnitblog.com/blog/587426/201402/112052253485094.png)
对于
![](http://images.cnitblog.com/blog/587426/201402/112052286809883.png)
的各层,计算:
![](http://images.cnitblog.com/blog/587426/201402/112052290884240.png)
计算最终需要的偏导数值:
![](http://images.cnitblog.com/blog/587426/201402/112052292953769.png)
实现中应注意:在以上的第2步和第3步中,我们需要为每一个
![](http://images.cnitblog.com/blog/587426/201402/112052296482042.png)
值计算其
![](http://images.cnitblog.com/blog/587426/201402/112052298093327.png)
。假设
![](http://images.cnitblog.com/blog/587426/201402/112052299804613.png)
是sigmoid函数,并且我们已经在前向传导运算中得到了
![](http://images.cnitblog.com/blog/587426/201402/112052302408155.png)
。那么,使用我们早先推导出的
![](http://images.cnitblog.com/blog/587426/201402/112052304681227.png)
表达式,就可以计算得到
![](http://images.cnitblog.com/blog/587426/201402/112052306573985.png)
。
最后,我们将对梯度下降算法做个全面总结。在下面的伪代码中,
![](http://images.cnitblog.com/blog/587426/201402/112052308971757.png)
是一个与矩阵
![](http://images.cnitblog.com/blog/587426/201402/112052312692572.png)
维度相同的矩阵,
![](http://images.cnitblog.com/blog/587426/201402/112052314202385.png)
是一个与
![](http://images.cnitblog.com/blog/587426/201402/112052315716899.png)
维度相同的向量。注意这里"
![](http://images.cnitblog.com/blog/587426/201402/112052319441943.png)
"是一个矩阵,而不是"
![](http://images.cnitblog.com/blog/587426/201402/112052321173229.png)
与
![](http://images.cnitblog.com/blog/587426/201402/112052353069274.png)
相乘"。下面,我们实现批量梯度下降法中的一次迭代:
对于所有
![](http://images.cnitblog.com/blog/587426/201402/112052355819587.png)
,令
![](http://images.cnitblog.com/blog/587426/201402/112052358469901.png)
,
![](http://images.cnitblog.com/blog/587426/201402/112052359995416.png)
(设置为全零矩阵或全零向量)
对于
![](http://images.cnitblog.com/blog/587426/201402/112052362024945.png)
到
![](http://images.cnitblog.com/blog/587426/201402/112052367678518.png)
,
使用反向传播算法计算
![](http://images.cnitblog.com/blog/587426/201402/112052369486574.png)
和
![](http://images.cnitblog.com/blog/587426/201402/112052371682875.png)
。
计算
![](http://images.cnitblog.com/blog/587426/201402/112052374852904.png)
。
计算
![](http://images.cnitblog.com/blog/587426/201402/112052379472747.png)
。
更新权重参数:
![](http://images.cnitblog.com/blog/587426/201402/112052383687575.png)
注意:为了使代价函数更快的收敛,首先要对输入数据进行归一化。
上面忘了讲tanh激活函数,
![](http://images.cnitblog.com/blog/587426/201402/112052386242119.png)
,非线性数据围绕原点对称更容易很好的收敛代价函数,因为它们倾向于产生零均值输入到下一层,一般讲,tanh有更好的收敛性能。
本文转自:http://www.cnblogs.com/loujiayu/p/3545026.html
如果我们在中间加一层神经元作为隐含层,则它的结构如下图所示
![](http://images.cnitblog.com/blog/587426/201402/112051578922075.png)
单隐层的MLP定义了一个映射:
![](http://images.cnitblog.com/blog/587426/201402/112051583126904.png)
,其中 D和L为输入向量和输出向量f(x)的大小。
隐含层与输出层神经元的值通过激活函数计算出来,例如下图:如果我们选用sigmoid作为激活函数,输入设为x,要求出隐含层的激活值a,公式如下。其中
![](http://images.cnitblog.com/blog/587426/201402/112051588003517.png)
。
![](http://images.cnitblog.com/blog/587426/201402/112051590204519.png)
![](http://images.cnitblog.com/blog/587426/201402/112052004345520.png)
同理输出的h(x)可以用同样的公式得到,上述过程就是向前传导,因为这种联接图没有闭环或回路。
我们可以用反向传播法(backpropagation)来训练上面这个神经网络。下面主要介绍backpropation算法。
假设对于单个样例(x,y),它的代价函数(cost function)为
![](http://images.cnitblog.com/blog/587426/201402/112052009696147.png)
对于一个样本集
![](http://images.cnitblog.com/blog/587426/201402/112052012912948.png)
,定义它的cost
function为:
![](http://images.cnitblog.com/blog/587426/201402/112052015931505.png)
我们要做的就是最小化上述式子,类似于最小二乘,不同的是加上了第二项的权重衰减,它是用来防止过拟合,可以把它看成是一个约束项,而整个式子就是求解最值的拉格朗日公式。我们的目标是针对参数
![](http://images.cnitblog.com/blog/587426/201402/112052017834263.png)
和
![](http://images.cnitblog.com/blog/587426/201402/112052020009562.png)
来求其函数
![](http://images.cnitblog.com/blog/587426/201402/112052021883321.png)
的最小值。为了求解神经网络,我们需要将每一个参数
![](http://images.cnitblog.com/blog/587426/201402/112052023811378.png)
和
![](http://images.cnitblog.com/blog/587426/201402/112052025512663.png)
初始化为一个很小的、接近零的随机值(比如说,使用正态分布
![](http://images.cnitblog.com/blog/587426/201402/112052027173949.png)
生成的随机值,其中
![](http://images.cnitblog.com/blog/587426/201402/112052028602693.png)
设置为
![](http://images.cnitblog.com/blog/587426/201402/112052030857992.png)
),之后对目标函数使用诸如批量梯度下降法的最优化算法。关于w和b的初值,我根据这篇论文(Understanding
the difficulty of training deep feedforward neuralnetworks)得出的结论:如果激活函数为tanh,我们设置为
![](http://images.cnitblog.com/blog/587426/201402/112052034333036.png)
之间的值,如果激活函数是sigmoid,则是
![](http://images.cnitblog.com/blog/587426/201402/112052037688836.png)
。
关于反向传播算法的推导,UFLDL 中介绍的很清楚,我直接粘帖过来了。
既然是用梯度下降法,我们先对代价函数J求关于w和b 的偏导数,直接写出结果:
![](http://images.cnitblog.com/blog/587426/201402/112052039981907.png)
反向传播算法的思路如下:给定一个样例
![](http://images.cnitblog.com/blog/587426/201402/112052041991436.png)
,我们首先进行"前向传导"运算,计算出网络中所有的激活值,包括
![](http://images.cnitblog.com/blog/587426/201402/112052044584979.png)
的输出值。之后,针对第
![](http://images.cnitblog.com/blog/587426/201402/112052046942752.png)
层的每一个节点
![](http://images.cnitblog.com/blog/587426/201402/112052049483065.png)
,我们计算出其"残差"
![](http://images.cnitblog.com/blog/587426/201402/112052052561623.png)
,该残差表明了该节点对最终输出值的残差产生了多少影响。对于最终的输出节点,我们可以直接算出网络产生的激活值与实际值之间的差距,我们将这个差距定义为
![](http://images.cnitblog.com/blog/587426/201402/112052054756922.png)
(第
![](http://images.cnitblog.com/blog/587426/201402/112052058447736.png)
层表示输出层)。对于隐藏单元我们如何处理呢?我们将基于节点(译者注:第
![](http://images.cnitblog.com/blog/587426/201402/112052060892280.png)
层节点)残差的加权平均值计算
![](http://images.cnitblog.com/blog/587426/201402/112052062678267.png)
,这些节点以
![](http://images.cnitblog.com/blog/587426/201402/112052064178080.png)
作为输入。下面将给出反向传导算法的细节:
进行前馈传导计算,利用前向传导公式,得到
![](http://images.cnitblog.com/blog/587426/201402/112052066864096.png)
直到输出层
![](http://images.cnitblog.com/blog/587426/201402/112052070048423.png)
的激活值。
对于第
![](http://images.cnitblog.com/blog/587426/201402/112052073325224.png)
层(输出层)的每个输出单元
![](http://images.cnitblog.com/blog/587426/201402/112052076435254.png)
,我们根据以下公式计算残差:
![](http://images.cnitblog.com/blog/587426/201402/112052079676352.png)
[译者注:
![](http://images.cnitblog.com/blog/587426/201402/112052083815410.png)
]
对
![](http://images.cnitblog.com/blog/587426/201402/112052088152712.png)
的各个层,第
![](http://images.cnitblog.com/blog/587426/201402/112052091161269.png)
层的第
![](http://images.cnitblog.com/blog/587426/201402/112052093433339.png)
个节点的残差计算方法如下:
![](http://images.cnitblog.com/blog/587426/201402/112052097204154.png)
{译者注:
![](http://images.cnitblog.com/blog/587426/201402/112052108416597.png)
将上式中的
![](http://images.cnitblog.com/blog/587426/201402/112052112207412.png)
与
![](http://images.cnitblog.com/blog/587426/201402/112052117725214.png)
的关系替换为
![](http://images.cnitblog.com/blog/587426/201402/112052122441828.png)
与
![](http://images.cnitblog.com/blog/587426/201402/112052156935645.png)
的关系,就可以得到:
![](http://images.cnitblog.com/blog/587426/201402/112052160909001.png)
以上逐次从后向前求导的过程即为"反向传导"的本意所在。 ]
计算我们需要的偏导数,计算方法如下:
![](http://images.cnitblog.com/blog/587426/201402/112052165028059.png)
最后,我们用矩阵-向量表示法重写以上算法。我们使用"
![](http://images.cnitblog.com/blog/587426/201402/112052167714075.png)
" 表示向量乘积运算符(在Matlab或Octave里用".*"表示,也称作阿达马乘积)。若
![](http://images.cnitblog.com/blog/587426/201402/112052172192445.png)
,则
![](http://images.cnitblog.com/blog/587426/201402/112052174303447.png)
。在上一个教程中我们扩展了
![](http://images.cnitblog.com/blog/587426/201402/112052176084732.png)
的定义,使其包含向量运算,这里我们也对偏导数
![](http://images.cnitblog.com/blog/587426/201402/112052178456802.png)
也做了同样的处理(于是又有
![](http://images.cnitblog.com/blog/587426/201402/112052181713603.png)
)。
那么,反向传播算法可表示为以下几个步骤:
进行前馈传导计算,利用前向传导公式,得到
![](http://images.cnitblog.com/blog/587426/201402/112052246174937.png)
直到输出层
![](http://images.cnitblog.com/blog/587426/201402/112052248678480.png)
的激活值。
对输出层(第
![](http://images.cnitblog.com/blog/587426/201402/112052251218794.png)
层),计算:
![](http://images.cnitblog.com/blog/587426/201402/112052253485094.png)
对于
![](http://images.cnitblog.com/blog/587426/201402/112052286809883.png)
的各层,计算:
![](http://images.cnitblog.com/blog/587426/201402/112052290884240.png)
计算最终需要的偏导数值:
![](http://images.cnitblog.com/blog/587426/201402/112052292953769.png)
实现中应注意:在以上的第2步和第3步中,我们需要为每一个
![](http://images.cnitblog.com/blog/587426/201402/112052296482042.png)
值计算其
![](http://images.cnitblog.com/blog/587426/201402/112052298093327.png)
。假设
![](http://images.cnitblog.com/blog/587426/201402/112052299804613.png)
是sigmoid函数,并且我们已经在前向传导运算中得到了
![](http://images.cnitblog.com/blog/587426/201402/112052302408155.png)
。那么,使用我们早先推导出的
![](http://images.cnitblog.com/blog/587426/201402/112052304681227.png)
表达式,就可以计算得到
![](http://images.cnitblog.com/blog/587426/201402/112052306573985.png)
。
最后,我们将对梯度下降算法做个全面总结。在下面的伪代码中,
![](http://images.cnitblog.com/blog/587426/201402/112052308971757.png)
是一个与矩阵
![](http://images.cnitblog.com/blog/587426/201402/112052312692572.png)
维度相同的矩阵,
![](http://images.cnitblog.com/blog/587426/201402/112052314202385.png)
是一个与
![](http://images.cnitblog.com/blog/587426/201402/112052315716899.png)
维度相同的向量。注意这里"
![](http://images.cnitblog.com/blog/587426/201402/112052319441943.png)
"是一个矩阵,而不是"
![](http://images.cnitblog.com/blog/587426/201402/112052321173229.png)
与
![](http://images.cnitblog.com/blog/587426/201402/112052353069274.png)
相乘"。下面,我们实现批量梯度下降法中的一次迭代:
对于所有
![](http://images.cnitblog.com/blog/587426/201402/112052355819587.png)
,令
![](http://images.cnitblog.com/blog/587426/201402/112052358469901.png)
,
![](http://images.cnitblog.com/blog/587426/201402/112052359995416.png)
(设置为全零矩阵或全零向量)
对于
![](http://images.cnitblog.com/blog/587426/201402/112052362024945.png)
到
![](http://images.cnitblog.com/blog/587426/201402/112052367678518.png)
,
使用反向传播算法计算
![](http://images.cnitblog.com/blog/587426/201402/112052369486574.png)
和
![](http://images.cnitblog.com/blog/587426/201402/112052371682875.png)
。
计算
![](http://images.cnitblog.com/blog/587426/201402/112052374852904.png)
。
计算
![](http://images.cnitblog.com/blog/587426/201402/112052379472747.png)
。
更新权重参数:
![](http://images.cnitblog.com/blog/587426/201402/112052383687575.png)
注意:为了使代价函数更快的收敛,首先要对输入数据进行归一化。
上面忘了讲tanh激活函数,
![](http://images.cnitblog.com/blog/587426/201402/112052386242119.png)
,非线性数据围绕原点对称更容易很好的收敛代价函数,因为它们倾向于产生零均值输入到下一层,一般讲,tanh有更好的收敛性能。
本文转自:http://www.cnblogs.com/loujiayu/p/3545026.html
相关文章推荐
- 前馈网络及反向传播
- 神经网络中的反向传播----Back Propagation
- TensorFlow 深度学习框架 (2)-- 反向传播优化神经网络
- 神经网络误差反向传播
- 反向传播神经网络极简入门
- 神经网络学习(三)反向(BP)传播算法(1)
- TensorFlow 深度学习框架 (2)-- 反向传播优化神经网络
- 详解神经网络中的反向传播
- 反向传播神经网络极简入门
- C++从零实现深度神经网络之二——前向传播和反向传播
- 一文弄懂神经网络中的反向传播——BackPropagation
- 神经网络反向传播梯度计算数学原理
- 神经网络反向传播
- 依赖反向传播改进神经网络数据处理的精确度
- 深度网络中softmax_loss、Smooth L1 loss计算以及反向传播推导
- TensorFlow 深度学习框架 (2)-- 反向传播优化神经网络
- 神经网络的前向传播和误差反向传播(NN,RNN,LSTM)(一)
- BP反向传播一文弄懂神经网络中的反向传播法
- 反向传播神经网络 BPNN
- 【模式识别】反向传播神经网络 BPNN