神经网络--误差反传

来源:互联网 发布:计算机编程天才 编辑:程序博客网 时间:2024/06/04 19:56

什么是神经网络

一般的,典型的三层神经网络的基本构成如下,Layer L1是输入层,Layer L2是隐含层,Layer L3是隐含层。

我们现在手里有一堆数据{x1,x2,x3,...,xn},输出也是一堆数据{y1,y2,y3,...,yn},现在要他们在隐含层做某种变换,让你把数据灌进去后得到你期望的输出。

计算过程

假设,现在我们手里有这样一个网络层:

第一层是输入层,包含两个神经元i1,i2,和截距项b1;第二层是隐含层,包含两个神经元h1,h2和截距项b2,第三层是输出o1,o2,每条线上标的wi是层与层之间连接的权重,激活函数我们默认为sigmoid函数。现在对他们赋上初值,如下图:

其中,

:  :  :  i1=0.05i2=0.10;o1=0.01,o2=0.99;w1=0.15,w2=0.20,w3=0.25,w4=0.30;w5=0.40,w6=0.45,w7=0.50,w8=0.55

目标:

i1,i2(0.050.10)使o1,o2(0.010.99)

也就是说要通过调整阈值让输入数据通过整个网络后,输出尽量跟上给定的数据,这里涉及到输入怎么通过网络得到输出(前向信号传播)以及怎样调整网络权值(反向误差传递)两个问题。

前向计算

1、输入层 隐含层

1)首先,计算神经元h1的输入加权和:

neth1=w1×i1+w2×i2+b1×1=0.15×0.05+0.2×0.1+0.35×1=0.3775

2)神经元h1的真正的输出o1(也就是这个加权和到底激不激活,值是多少?一般采用sigmoid函数作为激活函数):
outh1=11+eneth1=11+e0.3775=0.5932

同样的,可以计算神经元h2的真正输出outh2=0.5969

2、隐含层 输出层

计算输出层神经元o1和o2的值(真正得输出):

neto1outo1outo2=w5×outh1+w6×outh2+b2×1=0.4×0.5932+0.45×0.5969+0.6×1=1.1059=11+eneto1=11+e1.1059=0.7514=0.7729

到此,前向传播也就结束了,我们得到输出值为[0.75136079,0.772928465],与给定值[0.01,0.99]相差还很远,那么怎样来缩小这个差距呢?这就涉及到网络权值得调整,其关键在于如何调整,实际上是通过梯度下降来进行调整的,也就是误差反传。

误差反传

1、总误差

Eall=in12(targetioutputi)2

总的误差就是样本所有的期望输出与实际输出误差平方和,值得注意的是这里的12只是为了后面在求导的时候好计算。

这里写图片描述

于是乎,这里的总的误差就可以写成如下形式:

Etotal=i=0112(targetioutputi)2=Eo1+Eo2=12(target0output0)2+12(target1output1)2=12(0.010.7514)2+12(0.990.7729)2=0.2984

2、误差反传(权值更新)

注意,我们这里要做的事情是要通过权值调整来缩小上面的误差,一般的方法就是用负梯度来更新权值就可以了,也就是说我们需要知道误差对每个权值的梯度是多少,也就是要求Etotalw

这里,我们以权重参数w5为例加以说明,如何求取这个梯度的(也就是链式求导法则):

Etotalw5=Etotalouto1×outo1neto1×neto1w5

针对上面的式子,分别看下每一项求导。

1、Etotalouto1

我们知道Etotal实际上是多个样本的误差平方和,它写作下面的样儿:

Etotal=i=0112(targetioutputi)2=Eo1+Eo2=12(target0output0)2+12(target1output1)2

上面的式子对outo1求偏导时,很明显只有一项可以求导数,其他的项都不是它的函数,偏导直接为0:
Etotalouto1=2×12(targeto1outputo1)21×(1)+0=(targeto1outputo1)=(0.010.7514)=0.7414

上述式子对平方项进行求导刚好就多出一个2,与12刚好就抵消了方便计算。

2、outo1neto1

这一步实际上是对激活函数进行求导,我们这里激活函数选取的是 sigmoid函数,于是

outo1outo1neto1=11+eneto1=outo1(1outo1)=0.7514(10.7514)=0.1868

3、neto1w5

我们知道neto1实际上是前面的神经元通过连接权值加权得到的,也就是:

neto1neto1w5=w5×outh1+w6×outh2+b2×1=outh1=0.5932

因此,根据上面三项的计算结果,总的误差对w5的偏导为:

Etotalw5=Etotalouto1×outo1neto1×neto1w5=0.082167

加深一点印象

回过头来,我们再看看上面求导的式子,发现:

Etotalw5=(targeto1outo1)×outo1(1outo1)×outh1

为了方便表达,用δo1表示输出层的误差:
δo1=Etotalouto1×outo1neto1=Etotalneto1=(targeto1outo1)×outo1(1outo1)

于是乎
Etotalw5=δo1×outh1

对于上面这个式子,什么意思?也就是说我只要求出一个神经元的层误差,那么连接我这个神经元的他的权值的梯度实际上就是层误差在乘上一个连接的神经元的输出即可,这样可以快速计算出连接到我这个神经元上的权值偏导。

上面梯度我们已经算到了,最后我们用负梯度来更新这个权值w5

w5=w5η×Etotalw5=0.40.5×0.082167

其中,η为学习率,这里取了0.5。紧接着,我们可以同样的方式更新权值w6,w7,w8

隐含层 隐含层权值更新

方法其实与上面说的差不多,但是有个地方需要变一下,在上文计算总误差对w5的偏导时,是从out(o1)—->net(o1)—->w5,但是在隐含层之间的权值更新时,是out(h1)—->net(h1)—->w1,而out(h1)会接受E(o1)和E(o2)两个地方传来的误差,所以这个地方两个都要计算。

Etotalouth1=Eo1outh1+Eo2outh1

先看Eo1outh1

Eo1outh1=Eo1neto1×neto1outh1

Eo1neto1=Eo1outo1×outo1neto1

neto1outh1=w5

为了简化公式,可以用δh1表示隐含层单元h1的误差:
Etotalw1=(oEtotalouto×outoneto×netoouth1)×outh1neth1×neth1w1=(oδo×who)×outh1(1outh1)×i1=δh1i1

计算到梯度后,同样可以使用负梯度对w1进行权值更新,这一层其他权值也可以通过相应的方式进行更新了。值得注意的是,上述式子当中汇聚到h1的误差是上一层误差加权和,误差反传就是这个意思(通过逐层求导进行反向传播)。

总结

前向是信号传播,后向则是误差传递。人类对正向问题比较擅长,对于逆向问题就很显得捉襟见肘了,对于后向传递有如下几点需要理解:

  • 误差
    对应于前向的信号,反向传递主要是以误差的形式在网络中流动,也是一个一个的数值。

  • 层误差
    针对每个神经元的的误差是多少?以上述的h1为例,

    δh1=(oδo×who)×outh1(1outh1)

    1)oδo×who:后面每一层的误差通过连接加权汇总到h1。
    2)outh1(1outh1):前向是使用了激活函数,所以这里误差反传的时候是不是应该在乘上激活函数的导数呢,这就是所谓的逆向。

  • 权值梯度
    网络的学习是负梯度来更新的,有了层误差梯度如何计算。以w1为例,
    Etotalw1=δh1i1

    也就是,梯度 = 层误差 × 连接线的另一端的输出。

参考

一文弄懂神经网络
在线神经网络演示地址

原创粉丝点击