内容发布更新时间 : 2024/12/22 11:18:03星期一 下面是文章的全部内容请认真阅读。
#include
#define OUT_COUT 2 //输出向量维数 #define IN_COUT 3 //输入向量维数 #define COUT 6 //样本数量
typedef struct { //bp人工神经网络结构 int h; //实际使用隐层数量
double v[IN_COUT][50]; //隐藏层权矩阵i,隐层节点最大数量为50 double w[50][OUT_COUT]; //输出层权矩阵 double a; //学习率
double b; //精度控制参数 int LoopCout; //最大循环次数 } bp_nn;
double fnet(double net) { //Sigmoid函数,神经网络激活函数 return 1/(1+exp(-net)); }
int InitBp(bp_nn *bp) { //初始化bp网络 int i,j;
printf(\请输入隐层节点数,最大数为100:\\n\ scanf(\ printf(\请输入学习率:\\n\
scanf(\ //(*bp).a为double型数据,所以必须是lf printf(\请输入精度控制参数:\\n\ scanf(\
printf(\请输入最大循环次数:\\n\ scanf(\ srand((unsigned)time(NULL)); for (i = 0; i < IN_COUT; i++) for (j = 0; j < (*bp).h; j++)
(*bp).v[i][j] = rand() / (double)(RAND_MAX); for (i = 0; i < (*bp).h; i++) for (j = 0; j < OUT_COUT; j++)
(*bp).w[i][j] = rand() / (double)(RAND_MAX); return 1; }
int TrainBp(bp_nn *bp, float x[COUT][IN_COUT], int y[COUT][OUT_COUT]) {
//训练bp网络,样本为x,理想输
出为y
double f = (*bp).b; //精度控制参数 double a = (*bp).a; //学习率 int h = (*bp).h; //隐层节点数 double v[IN_COUT][50], w[50][OUT_COUT]; //权矩阵
double ChgH[50], ChgO[OUT_COUT]; //修改量矩阵
double O1[50], O2[OUT_COUT]; //隐层和输出层输出量 int LoopCout = (*bp).LoopCout; //最大循环次数 int i, j, k, n,d; double temp; double e = f + 1; double c; double Ep[10000];
for (i = 0; i < IN_COUT; i++) // 复制结构体中的权矩阵 for (j = 0; j < h; j++)
v[i][j] = (*bp).v[i][j]; for (i = 0; i < h; i++)
for (j = 0; j < OUT_COUT; j++) w[i][j] = (*bp).w[i][j];
for (n = 0; e > f && n < LoopCout; n++) { //对每个样本训练网络 e = 0;
for (i= 0; i < COUT; i++) {
for (k= 0; k < h; k++) { //计算隐层输出向量 temp = 0;
for (j = 0; j < IN_COUT; j++)
temp = temp + x[i][j] * v[j][k]; O1[k] = fnet(temp); }
for (k = 0; k < OUT_COUT; k++) { //计算输出层输出向量 temp = 0;
for (j = 0; j < h; j++)
temp = temp + O1[j] * w[j][k]; O2[k] = fnet(temp); }
for (j = 0; j < OUT_COUT; j++) //计算输出层的权修改量 ChgO[j] = O2[j] * (1 - O2[j]) * (y[i][j] - O2[j]); for (j = 0; j < OUT_COUT ; j++) //计算输出误差 e = e + (y[i][j] - O2[j]) * (y[i][j] - O2[j]); Ep[n]=e;
for (j = 0; j < h; j++) { //计算隐层权修改量 temp = 0;
for (k = 0; k < OUT_COUT; k++)
temp = temp + w[j][k] * ChgO[k]; ChgH[j] = temp * O1[j] * (1 - O1[j]); }
for (j = 0; j < h; j++) //修改输出层权矩阵 for (k = 0; k < OUT_COUT; k++)
w[j][k] = w[j][k] + a * O1[j] * ChgO[k]; for (j = 0; j < IN_COUT; j++) for (k = 0; k < h; k++)
v[j][k] = v[j][k] + a * x[i][j] * ChgH[k]; }
if (n % 10 == 0)
printf(\误差 : %f\\n\
}
printf(\总共循环次数:%d\\n\ printf(\调整后的隐层权矩阵:\\n\ for (i = 0; i < IN_COUT; i++) { for (j = 0; j < h; j++)
printf(\ \ printf(\ }
printf(\调整后的输出层权矩阵:\\n\ for (i = 0; i < h; i++) {
for (j = 0; j < OUT_COUT; j++) printf(\ \ printf(\ }
for (i = 0; i < IN_COUT; i++) //把结果复制回结构体 for (j = 0; j < h; j++)
(*bp).v[i][j] = v[i][j]; for (i = 0; i < h; i++)
for (j = 0; j < OUT_COUT; j++) (*bp).w[i][j] = w[i][j]; initgraph(640, 480); //画误差曲线 for(d=100;d