网络结构:2个输入神经元,5个隐层,1个输出神经元
输入和输出:一共6组数据,input1和input2为输入,output1为输出
学习率:0.5
精度控制:0.00001
最大循环次数:1000000
代码如下:
#include <stdlib.h> #include <math.h> #include <stdio.h> #include <time.h> #include <windows.h> #define COUT 6 //样本数量 #define IN_COUT 2 //输入层数量 #define Hid_COUT 5 //隐层数量 #define OUT_COUT 1 //输出层数量 //int Hid_COUT=Hid_COUT; //隐层节点数 float weight_hidden[IN_COUT*Hid_COUT]; //隐藏层权矩阵,隐层节点最大数量为50 float weight_output[Hid_COUT*OUT_COUT]; //输出层权矩阵 float learnRate=0.5; //学习率 float accuracy=0.00001; //精度控制参数 int maxLoopCout=1000000; //最大循环次数 float ChgH[Hid_COUT], ChgO[OUT_COUT]; //修改量矩阵 float O1[Hid_COUT], O2[OUT_COUT]; //隐层和输出层输出量 int i, j, k; float temp; float e=0; int n; float fnet(float net) //Sigmoid函数,神经网络激活函数 { return 1/(1+exp(-net)); } int InitBp() //初始化bp网络 { int i, j; srand((unsigned)time(NULL)); //获得随机数,赋值给各层权值 for (i = 0; i < IN_COUT; i++) //IN_COUT--输入维数(3) for (j = 0; j < Hid_COUT; j++) weight_hidden[j+10*i] = rand() / (float)(RAND_MAX); for (i = 0; i < Hid_COUT; i++) for (j = 0; j < OUT_COUT; j++) //OUT_COUT--输出维数(2) weight_output[j+i*10] = rand() / (float)(RAND_MAX); return 1; } void TrainBp( float input0,float input1, float output0) //训练bp网络,样本为x,理想输出为y。COUNT-样本数量 { for (k= 0; k < Hid_COUT; k++) //计算隐层输出向量 { temp = 0; //for (j = 0; j < IN_COUT; j++) //第i组个样本中的第j个 // temp += x[j] * weight_hidden[k+10*j]; temp += input0 * weight_hidden[k+10*0] + input1 * weight_hidden[k+10*1]; O1[k] = fnet(temp); //经过传递函数计算后的隐层输出向量 } for (k = 0; k < OUT_COUT; k++) //计算输出层输出向量 { temp = 0; for (j = 0; j < Hid_COUT; j++) temp += O1[j] * weight_output[k+j*10]; O2[k] = fnet(temp); //经过传递函数计算后的出层输出向量 } for (j = 0; j < OUT_COUT; j++) //计算输出层的权修改量 ChgO[j] = O2[j] * (1 - O2[j]) * (output0 - O2[j]); for (j = 0; j < OUT_COUT ; j++) //计算输出误差 // e += (y[j] - O2[j]) * (y[j] - O2[j]); e += (output0 - O2[j]) * (output0 - O2[j]); for (j = 0; j < Hid_COUT; j++) //计算隐层权修改量 { temp = 0; for (k = 0; k < OUT_COUT; k++) temp += weight_output[k+j*10] * ChgO[k]; ChgH[j] = temp * O1[j] * (1 - O1[j]); } for (j = 0; j < Hid_COUT; j++) //修改输出层权矩阵 for (k = 0; k < OUT_COUT; k++) weight_output[k+j*10] += learnRate * O1[j] * ChgO[k]; //输出层权矩阵 for (k = 0; k < Hid_COUT; k++) { //for (j = 0; j < IN_COUT; j++) // weight_hidden[k+10*j] += learnRate * x[j] * ChgH[k]; //隐藏层权矩阵 weight_hidden[k+10*0] += learnRate * input0 * ChgH[k]; weight_hidden[k+10*1] += learnRate * input1 * ChgH[k]; } } int UseBp() //使用bp网络 { float Input[IN_COUT]; float O1[50]; //隐层输出 float O2[OUT_COUT]; //输出层输出 while (1) //持续执行,除非中断程序 { printf("请输入%d个数:\n",IN_COUT); int i, j; for (i = 0; i < IN_COUT; i++) scanf("%f", &Input[i]); float temp; for (i = 0; i < Hid_COUT; i++) { temp = 0; for (j = 0; j < IN_COUT; j++) temp += Input[j] * weight_hidden[i+10*j]; O1[i] = fnet(temp); } for (i = 0; i < OUT_COUT; i++) { temp = 0; for (j = 0; j < Hid_COUT; j++) temp += O1[j] * weight_output[i+j*10]; O2[i] = fnet(temp); } printf("结果: "); for (i = 0; i < OUT_COUT; i++) printf("%.3f ", O2[i]); printf("\n"); } return 1; } int main() { float input1[6]= {0.1,0.5,0.9,0.7, 0,0.3}; float input2[6]= {0.2,0.3,0.6,0.8,0.1,0.2}; float output1[6]={ 0, 1, 1, 1, 0, 1}; /*float input1[6]= {0.1,0.8,0.3}; float input2[6]= {0.2,0.5,0.8}; float output1[6]={ 0, 1, 1};*/ DWORD start,end; InitBp(); /****TrainBp******/ e=accuracy + 1; //目的是为了让e大于f,能进行下面的循环,并无算法上的意义 start= GetTickCount(); for (n = 0; e > accuracy && n < maxLoopCout; n++) //对每个样本训练网络,当精度符合要求并且n小于最大循环次数时停止 { e = 0; for(int ms=0;ms<COUT;ms++) TrainBp(input1[ms],input2[ms],output1[ms]); if (n % 10 == 0) printf("误差 : %f\n", e); //每训练10次输出一次误差结果 } end= GetTickCount(); printf("训练时间:%d\n",end-start); printf("总共循环次数:%d\n", n); printf("bp网络训练结束!\n"); UseBp(); return 1; /****TrainBp******/ }
时间: 2024-10-03 19:02:42