BP(Back Propagation)表示反向传播。BP网络能学习和存贮大量的输入-输出模式映射关系,而无需事前揭示描述这种映射关系的数学方程。它的学习规则是使用最速下降法,通过反向传播来不断调整网络的权值和阈值,使网络的误差平方和最小。BP神经网络模型拓扑结构包括输入层(input)、隐层(hidden layer)和输出层(output layer)。
图1 三层BP网
如图所示,最下面一层为输入层,中间为隐藏层,最上面为输出层。其中X={x1,x2.......xn},Y={y1,y2,.......ym},O={o1,o2,.......ol}为向量,W、V为权值矩阵,V的行的数目跟Y的长度相等,V的列的数目跟X的长度相等。W的行的数目跟O的长度相等,W的列的数目跟Y的长度相等。
对于低层到高层的每一个节点,做如下的运算:
图2 sigmoid阈值单元
x1,x2....xn表示该层的输入,比如在输入层到隐藏层中,它们表示图1中的x0,x1.....xn;在隐藏层到输出层,它们表示y0,y1.....ym。w1,w2...wn表示该层的权值,并不只对应图1中的W。
之所以用sigmoid函数,原因如上图所示。它的导数可以用它的输出表示,这样在求梯度的时候很容易计算,而且这个函数与感知器相似。
BP神经网络的原理就是不断的训练,不停地去改变W和V的权值,然后把期望的结果可输出的O比较,当误差收敛到一定范围就可以终止训练。
图像需要进行一定的处理:灰度转化->二值化->图像锐化->去除噪声->归一化
灰度转化和二值化可参考:http://blog.csdn.net/hellousb2010/article/details/37939809
图像锐化和去除噪声可以通过滤波来解决,具体过程搜索一下。
归一化就是把图像调整到固定大小。我是用5X5的矩阵来存储归一化后的图像。比如5可以用
{0,1,1,1,1
0,1,0,0,0,
0,0,1,0,0,
0,0,0,1,0,
0,1,1,0,0}
表示。即:
输入为一定数量的5X5的矩阵,可以用一个长度为25的向量表示,所以输入层长度为25,隐藏层的节点数不一定,通常可以用(n+1)的1/2次方+a算出(n表示输入的向量的长度,a可以取0~输出向量的长度之间的数),我的隐藏层使用15个节点。
训练算法如下:
代码实现如下:
for (int j = 0; j < y.Count(); j++) { y[j] = sigmoid(net(j, v, x)); } for (int k = 0; k < o.Count(); k++) { o[k] = sigmoid(net(k, w, y)); } for (int k = 0; k < o.Count(); k++) { errorTermK[k] = o[k] * (1 - o[k]) * (d[k] - o[k]);//对于每个输出单元k,它的误差 } for (int h = 0; h < y.Count(); h++) { double sum = 0.0d; for (int k = 0; k < o.Count(); k++) { sum += w[k, h] * errorTermK[k];//对于每个隐藏单元h,它的误差 } errorTermH[h] = y[h] * (1 - y[h]) * sum; } for (int j = 0; j < w.GetLength(0); j++) { for (int i = 0; i < w.GetLength(1); i++) { w[j, i] -= rate * errorTermK[j] * y[i];//调整权值 } } for (int j = 0; j < v.GetLength(0); j++) { for (int i = 0; i < v.GetLength(1); i++) { v[j, i] -= rate * errorTermH[j] * x[i];//调整权值 } }
sigmoid函数和net函数定义如下:
private double sigmoid(double x) { return (1.0d / (1+Math.Pow(Math.E, 0-x))); } private double net(int j,double[,] v, double[] x) { double sum = 0; for (int i = 0; i < v.GetLength(1); i++) { sum += v[j, i] * x[i]; } return sum; }同样的样本也需要多次训练。
我用10个代表0~9的矩阵不停的训练,输出的O的值如下图所示:
可以看出,O[8]的值最大,接近1,接近期望输出的向量{0,0,0,0,0,0,0,0,1,0},代表该数字为8.
当然,训练的时候肯定不能用一个样本训练,需要输入很多样本,通常需要进行上千次训练,每个样本可以参与多次训练。
当输出与期望输出的误差收敛到一定范围,就可以停止训练。
把需要识别的图像处理成5X5的矩阵,输入到BP网络中,输出矩阵O,O中值最大的那个元素的位置即为识别出的数字。但是如果O中最大的值小于一定的阈值,可以判断为无法判断。
原文地址:http://blog.csdn.net/hellousb2010/article/details/39137551