BackPropagation Neuron NetWok

  BP神经网络学习算法可以说是目前最成功的神经网络学习算法。显示任务中使用神经网络时,大多数是使用BP算法进行训练.
  在我看来BP神经网络就是一个”万能的模型+误差修正函数“,每次根据训练得到的结果与预想结果进行误差分析,进而修改权值和阈值,一步一步得到能输出和预想结果一致的模型。举一个例子:比如某厂商生产一种产品,投放到市场之后得到了消费者的反馈,根据消费者的反馈,厂商对产品进一步升级,优化,从而生产出让消费者更满意的产品。这就是BP神经网络的核心
  下面就让我们来看看BP算法到底是什么东西。BP网络由输入层、隐藏层、输出层组成。给定训练集D={(x1,y1),(x2,y2…(xn,yn)},其中xnϵRd,ynϵRl,表示输入示例由d个属性组成,输出l维实值变量。现在,我们看看如何求得输出值,以及怎么由输出值调整权值和阈值。
       详解BP神经网络
   神经元是以生物研究及大脑的响应机制而建立的拓扑结构网络,模拟神经冲突的过程,多个树突的末端接受外部信号,并传输给神经元处理融合,最后通过轴突将神经传给其它神经元或者效应器。神经元的拓扑结构如图:
             详解BP神经网络

  对于第i个神经元,X1、X2、…、Xj为神经元的输入,输入常为对系统模型关键影响的自变量,W1、W2、…、Wj为连接权值调节各个输入量的占重比。将信号结合输入到神经元有多种方式,选取最便捷的线性加权求和可得neti神经元净输入:

Netin=i=1nwixi

  θi表示该神经元的阈值,根据生物学中的知识,只有当神经元接收到的信息达到阈值是才会被**。因此,我们将Netinθj进行比较,然后通过**函数处理以产生神经元的输出。
  **函数:**函数这里我们不多重述。如果输出值有一定的范围约束,比如用来分类,一般我们用的最多的是Sigmod函数,它可以把输入从负无穷大到正无穷大的信号变换成0到1之间输出。如果没有约束的话,我们可以使用线性**函数(即权值相乘之和)。这样我们得到的输出为:
yj=f(Netinθj)

  我们可以将公式化简一下,设第一个输入永远值为θ,权值为-1,则我们可以得到公式:
yj=f(i=0nwixi)

  其中w0=-1,x0=θj,其中f为选择的**函数。
  已经知道在BP神经网络模型中,我们有三层结构,输入层、隐藏层、输出层,因此输入层到隐藏层的权值,设为vih,隐藏层第h个神经元的阈值我们设为γh。隐藏层到输出层的权值,设为whj,输出层第j个神经元的阈值我们用θj表示。在下面这张图里,有d输入神经元,q个隐藏神经元,隐藏有q个隐藏神经元阈值,l个输出神经元,因此有l个输出神经元阈值。
详解BP神经网络
  其中βj中的bh=f(αhθh)。隐藏层和输出层的**函数,在这里我们暂时全部用Sigmod函数。
  在某个训练示例(xk,yk)中,假设神经网络的训练输出为yk,=(y1k,,y2k,,,ylk,),输出为l维向量,其中
yik,=f(βiθi)

  那么这次预测结果的误差我们可以用最小二乘法表示:
Ek=12j=1l(yjk,yjk)2

  而我们现在要做的就是根据这个误差去调整d+l+1q+l个参数的值,一步一步缩小Ek。那么从现在开始,我们就要进入数学的世界了。这里我们使用最常用的算法:梯度下降法来更新参数。函数永远是沿着梯度的方向变化最快,那么我们对每一个需要调整的参数求偏导数,如果偏导数>0,则要按照偏导数相反的方向变化;如果偏导数<0,则按照此方向变化即可。于是我们使用-1*偏导数则可以得到参数需要变化的值。同时我们设定一个学习速率η,这个学习速率不能太快,也不能太慢。太快可能会导致越过最优解;太慢可能会降低算法的效率。(具体设多少就属于玄学调参的领域了)。因此我们可以得到一个参数调整公式:
Param+=ηEkParam

  首先我们看看隐藏层到输出层的权值调整值:
Δwhj=ηEkwhj

  好,我们从上到下缕一缕这个偏导该怎么求,我们把每一个公式都罗列出来:

  1.输出层到隐藏层:

αh=i=1dvihxi(1)

|x1x2x3xd||v11v12v13v1qv21v22v23w2qvd1wd2wd3wdq|

  2.经过隐藏层的**函数:

bh=f(αhγh)(2)

  3.隐藏层到输出层:

βj=h=1qwhjbh(3)

  用矩阵表示

|b1b2b3bq||w11w12w13w1lw21w22w23w2lwq1wq2wq3wql|

  4.经过输出层的**函数:

yjk,=f(βjθj)(4))

  5.误差:

Ek=12j=1l(yjk,yjk)2(5)

  综上我们可以得知whj先影响βj,再影响yjk,,最后影响Ek,(一个w权值只会影响一个β)所以我们可得:
Δwhj=ηEkwhj=ηEkyjk,yjk,βjβjwhj(6)

其中βjwhj=bh,前面提到过,bh是第h个隐藏神经元的输出。
gj=Ekyjk,yjk,βj=(yjk,yjk)f(βjθj)(7)

  而我们选择的**函数是Sigmod函数,该函数具有一个很好的性质
f(x)=11+exf(x)=f(x)(1f(x))(8)

  所以我们有:
f(βjθj)=f(βjθj)(1f(βjθj))=yjk(1yjk)(9)

  综合formula(6)(7)(9)我们可得:
Δwhj=ηEkwhj=ηgibh=η(yjkyjk)yjk(1yjk)bh(10)

  同理:

Δθj=ηEkθj=ηEkyjkyjkθj=ηgj(11)

  我们再看看Δvih的值怎么求,还是由formula(1),(2),(3),(4),(5)推导,一个v权值会影响所有的β
Δvih=ηehxi(12)

Δγh=ηeh (13)

  其中
eh=j=1lEkβjβjbjf(αhγh)=(j=1l(yjk,yjk)f(βjθj)whj)f(αhγh)(14)

  至此,我们所有得公式都推导完毕了,剩下做的就是设定一个迭代终止条件,可以是误差小于一定值时终止递归,也可以是设定迭代次数。这样一个BP神经网络模型就算是设计结束。

  java实现代码和实验数据在我的github上面

相关文章: