网络结构: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******/
}
原文:http://blog.csdn.net/xiaoch1222/article/details/51332297