BP神经网络基本原理:
误差逆传播(back propagation, BP)算法是一种计算单个权值变化引起网络性能变化的较为简单的方法。由于BP算法过程包含从输出节点开始,反向地向第一隐含层(即最接近输入层的隐含层)传播由总误差引起的权值修正,所以称为“反向传播”。BP神经网络是有教师指导训练方式的多层前馈网络,其基本思想是:从网络输入节点输入的样本信号向前传播,经隐含层节点和输出层节点处的非线性函数作用后,从输出节点获得输出。若在输出节点得不到样本的期望输出,则建立样本的网络输出与其期望输出的误差信号,并将此误差信号沿原连接路径逆向传播,去逐层修改网络的权值和节点处阈值,这种信号正向传播与误差信号逆向传播修改权值和阈值的过程反复进行,直训练样本集的网络输出误差满足一定精度要求为止。
以下是使用C/C++(大多数是C语言代码,只有数据读取部分是C++)完成的一个实际案例。
要求:
将Iris(鸢尾花)数据集分为训练集(Iris-train.txt)和测试集(Iris-test.txt),分别含75个样本,每个集合中每种花各有25个样本。为了方便训练,将3类花分别编号为1,2,3 。使用这些数据训练一个4输入(分别对应4个特征)、隐含层(10个神经元)、3输出(分别对应该样本属于某一品种的可能性大小)的神经网络(4*10*3)。
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 9 #define innode 4//输入层结点数 10 #define hidenode 10//隐层结点数 11 #define outnode 3//输出层结点数 12 #define trainsample 75//训练样本数 13 #define testsample 75//测试样本数 14 15 double trainData[trainsample][innode];//输入样本 16 double outData[trainsample][outnode];//输出样本 17 18 double testData[testsample][innode];//测试样本 19 20 double w[innode][hidenode];//输入层到隐层的权值 21 double w1[hidenode][outnode];//隐层到输出层的权值 22 double b1[hidenode];//隐层阈值 23 double b2[outnode];//输出层阈值 24 25 double e=0.0;//误差计算 26 double error=1.0;//允许的最大误差 27 28 double rate_w=0.9;//输入层到隐层的学习率 29 double rate_w1=0.9;//隐层到输出层的学习率 30 double rate_b1=0.9;//隐层阈值学习率 31 double rate_b2=0.9;//输出层阈值学习率 32 33 double result[outnode];//bp输出 34 35 //初始化函数 36 void init(double w[], int n); 37 //Bp训练函数 38 void train(double trainData[trainsample][innode], double label[trainsample][outnode]); 39 //Bp识别 40 double *recognize(double *p); 41 //从文件夹读取数据 42 void readData(std::string filename, double data[][innode], int x); 43 //数据归一化处理 44 void changeData(double data[][innode], int x); 45 46 int main() 47 { 48 int i,j; 49 int trainNum=0;//样本训练次数 50 double *r; //测试结果 51 int count=0;//正确测试结果数 52 double maxRate = 1.0;//输出结果中的最大概率 53 //对权值和阈值进行初始化 54 init((double*)w, innode*hidenode); 55 init((double*)w1, hidenode*outnode); 56 init(b1, hidenode); 57 init(b2, outnode); 58 59 //读取训练数据 60 readData("./Iris-train.txt", trainData, trainsample); 61 //对训练数据进行归一化处理 62 changeData(trainData, trainsample); 63 64 /*for(i=0; i r[1] && r[0]>r[2])116 count++;117 if(i>=25 && i<50 && r[1]>r[0] && r[1]>r[2])118 count++;119 if(i>=50 && r[2]>r[0] && r[2]>r[1])120 count++;121 }122 123 printf("\n\n共有%d个检测样本, 正确检测出%d个, 准确率: %7.4lf\n\n",testsample, count, (double)count/testsample);124 system("pause");125 return 0;126 }127 128 //初始化函数(0到1之间的数)129 void init(double w[], int n)130 {131 int i;132 srand((unsigned int)time(NULL));133 for(i=0; i >data[i][j];280 }281 inData >>dataLabel;282 }283 inData.close();284 }285 286 //数据归一化处理287 void changeData(double data[][innode], int x)288 {289 //归一化公式:(x-min)/(max-min)290 double minNum,maxNum;291 int i,j;292 minNum = data[0][0];293 maxNum = data[0][0];294 //找最大最小值295 for(i=0; i data[i][j])300 minNum = data[i][j];301 if(maxNum < data[i][j])302 maxNum = data[i][j];303 }304 }305 //归一化306 for(i=0; i
5.1 3.5 1.4 0.2 0
4.9 3.0 1.4 0.2 0 4.7 3.2 1.3 0.2 0 4.6 3.1 1.5 0.2 0 5.0 3.6 1.4 0.2 0 5.4 3.9 1.7 0.4 0 4.6 3.4 1.4 0.3 0 5.0 3.4 1.5 0.2 0 4.4 2.9 1.4 0.2 0 4.9 3.1 1.5 0.1 0 5.4 3.7 1.5 0.2 0 4.8 3.4 1.6 0.2 0 4.8 3.0 1.4 0.1 0 4.3 3.0 1.1 0.1 0 5.8 4.0 1.2 0.2 0 5.7 4.4 1.5 0.4 0 5.4 3.9 1.3 0.4 0 5.1 3.5 1.4 0.3 0 5.7 3.8 1.7 0.3 0 5.1 3.8 1.5 0.3 0 5.4 3.4 1.7 0.2 0 5.1 3.7 1.5 0.4 0 4.6 3.6 1.0 0.2 0 5.1 3.3 1.7 0.5 0 4.8 3.4 1.9 0.2 0 7.0 3.2 4.7 1.4 1 6.4 3.2 4.5 1.5 1 6.9 3.1 4.9 1.5 1 5.5 2.3 4.0 1.3 1 6.5 2.8 4.6 1.5 1 5.7 2.8 4.5 1.3 1 6.3 3.3 4.7 1.6 1 4.9 2.4 3.3 1.0 1 6.6 2.9 4.6 1.3 1 5.2 2.7 3.9 1.4 1 5.0 2.0 3.5 1.0 1 5.9 3.0 4.2 1.5 1 6.0 2.2 4.0 1.0 1 6.1 2.9 4.7 1.4 1 5.6 2.9 3.6 1.3 1 6.7 3.1 4.4 1.4 1 5.6 3.0 4.5 1.5 1 5.8 2.7 4.1 1.0 1 6.2 2.2 4.5 1.5 1 5.6 2.5 3.9 1.1 1 5.9 3.2 4.8 1.8 1 6.1 2.8 4.0 1.3 1 6.3 2.5 4.9 1.5 1 6.1 2.8 4.7 1.2 1 6.4 2.9 4.3 1.3 1 6.3 3.3 6.0 2.5 2 5.8 2.7 5.1 1.9 2 7.1 3.0 5.9 2.1 2 6.3 2.9 5.6 1.8 2 6.5 3.0 5.8 2.2 2 7.6 3.0 6.6 2.1 2 4.9 2.5 4.5 1.7 2 7.3 2.9 6.3 1.8 2 6.7 2.5 5.8 1.8 2 7.2 3.6 6.1 2.5 2 6.5 3.2 5.1 2.0 2 6.4 2.7 5.3 1.9 2 6.8 3.0 5.5 2.1 2 5.7 2.5 5.0 2.0 2 5.8 2.8 5.1 2.4 2 6.4 3.2 5.3 2.3 2 6.5 3.0 5.5 1.8 2 7.7 3.8 6.7 2.2 2 7.7 2.6 6.9 2.3 2 6.0 2.2 5.0 1.5 2 6.9 3.2 5.7 2.3 2 5.6 2.8 4.9 2.0 2 7.7 2.8 6.7 2.0 2 6.3 2.7 4.9 1.8 2 6.7 3.3 5.7 2.1 2
测试数据:
5.0 3.0 1.6 0.2 0
5.0 3.4 1.6 0.4 0 5.2 3.5 1.5 0.2 0 5.2 3.4 1.4 0.2 0 4.7 3.2 1.6 0.2 0 4.8 3.1 1.6 0.2 0 5.4 3.4 1.5 0.4 0 5.2 4.1 1.5 0.1 0 5.5 4.2 1.4 0.2 0 4.9 3.1 1.5 0.1 0 5.0 3.2 1.2 0.2 0 5.5 3.5 1.3 0.2 0 4.9 3.1 1.5 0.1 0 4.4 3.0 1.3 0.2 0 5.1 3.4 1.5 0.2 0 5.0 3.5 1.3 0.3 0 4.5 2.3 1.3 0.3 0 4.4 3.2 1.3 0.2 0 5.0 3.5 1.6 0.6 0 5.1 3.8 1.9 0.4 0 4.8 3.0 1.4 0.3 0 5.1 3.8 1.6 0.2 0 4.6 3.2 1.4 0.2 0 5.3 3.7 1.5 0.2 0 5.0 3.3 1.4 0.2 0 6.6 3.0 4.4 1.4 1 6.8 2.8 4.8 1.4 1 6.7 3.0 5.0 1.7 1 6.0 2.9 4.5 1.5 1 5.7 2.6 3.5 1.0 1 5.5 2.4 3.8 1.1 1 5.5 2.4 3.7 1.0 1 5.8 2.7 3.9 1.2 1 6.0 2.7 5.1 1.6 1 5.4 3.0 4.5 1.5 1 6.0 3.4 4.5 1.6 1 6.7 3.1 4.7 1.5 1 6.3 2.3 4.4 1.3 1 5.6 3.0 4.1 1.3 1 5.5 2.5 4.0 1.3 1 5.5 2.6 4.4 1.2 1 6.1 3.0 4.6 1.4 1 5.8 2.6 4.0 1.2 1 5.0 2.3 3.3 1.0 1 5.6 2.7 4.2 1.3 1 5.7 3.0 4.2 1.2 1 5.7 2.9 4.2 1.3 1 6.2 2.9 4.3 1.3 1 5.1 2.5 3.0 1.1 1 5.7 2.8 4.1 1.3 1 7.2 3.2 6.0 1.8 2 6.2 2.8 4.8 1.8 2 6.1 3.0 4.9 1.8 2 6.4 2.8 5.6 2.1 2 7.2 3.0 5.8 1.6 2 7.4 2.8 6.1 1.9 2 7.9 3.8 6.4 2.0 2 6.4 2.8 5.6 2.2 2 6.3 2.8 5.1 1.5 2 6.1 2.6 5.6 1.4 2 7.7 3.0 6.1 2.3 2 6.3 3.4 5.6 2.4 2 6.4 3.1 5.5 1.8 2 6.0 3.0 4.8 1.8 2 6.9 3.1 5.4 2.1 2 6.7 3.1 5.6 2.4 2 6.9 3.1 5.1 2.3 2 5.8 2.7 5.1 1.9 2 6.8 3.2 5.9 2.3 2 6.7 3.3 5.7 2.5 2 6.7 3.0 5.2 2.3 2 6.3 2.5 5.0 1.9 2 6.5 3.0 5.2 2.0 2 6.2 3.4 5.4 2.3 2 5.9 3.0 5.1 1.8 2