原文写于个人博客,欢迎关注www.xiaolewei.com
前言
所谓神经网络是一组连接的输入/输出单元,类似于人脑中的神经细胞,其中每个连接都与一个权重相关联。学习阶段通过输入元组,不断的调整权重参数,使得它能够预测输入元组的正确类标号。
所谓类标号,是某种类别的标号。
多层前馈神经网络
后向传播算法是在前馈神经网络上进行学习。多层前馈神经网络由一个输入层,一个或者多个隐藏层以及一个输出层组成。
图中每个圆即为一个神经单元
其中每一层都包含多个单元。输入层的每个单元对应于用于训练的元组的每个观测属性,输入会提供给输入层的单元,经过加权后,再提供给隐藏层的单元。而隐藏层的输出可以是另一个隐藏层,也可以是输出层。实践中隐藏层通常只有一层。
之所以称该网络为前馈的,是因为权重不回送到输入层或前一层的输出单元。
这里先说明一下几个关键字:
权重
对于一个单元而言,可能同时具有多个输入,显然所有的输入并不是同等重要的,可以形象地理解为造成某一结果的原因占不同的比重,例如对于LungCancer
,Smoker
和Drinker
显然前者更容易导致肺癌的产生。这里就会倾向于给予Smoker
更大的权重。
偏倚
计算各个输入的权重和时,人为的为这个和加上一个参数,这个参数就是偏倚。
输入处理
对于连续型变量,通常采用一些规范化的方法,将其映射到0-1之间,如最小-最大化规范
等。
而对于离散化的数据,则常常重新编码,使每个域值都有一个输入单元。如属性A的所有可能取值为{a0, a1, a2}
,则为其分配3个输入单元,使用I0
,I1
,I2
表示,对于某一实例,若A=a1,则将输入单元I1置为1,其余置为0。
单元计算
对于单个单元,其处理过程如下:
图中yi为上一层单元的输出值,即本单元的输入值,wij为该输入值的权重,θj为偏倚,挤压函数可以简单的理解为一个将输入值映射到较小区间0-1之间。
对于各个输入值,首先计算权重和,再加上偏倚获得净输入,即:
净输入Ij = ∑ yi * Wij + θj
将该结果作用于挤压函数,得到输出结果。对于挤压函数一般使用Logistic函数,如:
Oj = 1/(1 + e^(-Ij) )
误差计算
神经网络经过一次学习,学习到了什么?或者说经过一次学习,神经网络该如何自我调整,来接近真理?这就是误差计算的作用。误差计算通过计算更新权重与偏倚,来使得预测结果更接近真相。
误差
对于输出层:
Errj = Oj * (1-Oj) * (Tj-Oj)
Oj 即为该单元的实际输出,而Tj就是该训练样本的已知目标值。
对于隐藏层:
Errj = Oj * (1-Oj) * ∑ Errk * Wjk
由该单元的输出单元的误差权重和,和本身输出组成。
Oj * (1-Oj) 实际上时
Logistic函数
的导数
权重与偏倚
计算出误差后,即可对权重进行更新。这里先引入另一个名词 学习率
,用l
表示,通常取0-1之间的数,一般将l设为 1/t,这里的t为已迭代次数。
权重使用如下公式进行更新:
Wij = Wij + l * Errj * Oj
对于偏倚使用如下公式更新:
θj = θj + l * Errj
更新策略
关于更新策略,有两种方式,一种是每学习一次,就更新一次,称为实例更新
,另一种是将计算出来的增量累计到变量中,等训练完所有元组后再更新,称为周期更新
。由于实例更新
通常带来更准确的效果,所以该方式更为常见。
基本流程
这里先讲一个大概流程,后面使用实际的训练例子,可以得到更直观的感受。
首先是对网络的一个初始化工作,包括建立结构,将权重和偏倚初始化为随机小数(通常为-1-1之间),输入训练元组,根据计算结果对权重和偏倚进行更新,输入下一个训练元组,重复上述过程,直到:
- 前一周期所有ΔW均小于某一阈值
- 前一周琦误分类元组小于某一阈值
- 超过指定周期数
中一个条件满足。
样例详解
输入值以及各项初始值如下:
x1 | x2 | x3 | w14 | w15 | w24 | w25 | w34 | w35 | w46 | w56 | θ4 | θ5 | θ6 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 0 | 1 | 0.2 | -0.3 | 0.4 | 0.1 | -0.5 | 0.2 | -0.3 | -0.2 | -0.4 | 0.2 | 0.1 |
以下计算中,部分相似的过程省略,直接给出结果。
计算净输入以及输出值:
单元J | 净输入Ij | 输出Oj |
---|---|---|
4 | 0.2+0-0.5-0.4=-0.7 | 1/(1+e^(0.7))=0.332 |
5 | -0.3+0+0.2+0.2=0.1 | 0.525 |
6 | -0.3*0.332-(-0.2) * 0.525+0.1)=-0.105 | 0.474 |
计算误差:
单元j | Errj |
---|---|
6 | 0.474 * (1-0.474) * (1-0.474) = 0.1311 |
5 | 0.525 * (1-0.525) * 0.1311 * (-0.2) = -0.0065 |
4 | 0.332 * (1-0.332) * 0.1311 * (-0.3) = -0.02087 |
更新权重和偏倚:
权重/偏倚 | 新值 |
---|---|
w46 | -0.3 + 0.9 * 0.1311 * 0.332 = -0.261 |
w56 | -0.138 |
w14 | 0.2 + 0.9 * (-0.087)* 1 = 0.192 |
w15 | -0.306 |
w24 | 0.4 |
w25 | 0.1 |
w34 | -0.508 |
θ6 | 0.1 + 0.9 * 0.1311 = 0.218 |
θ5 | 0.2 + 0.9 * (-0.0065) = 0.194 |
θ4 | -0.408 |
至此便完成了一个训练元组的迭代。