2015-11-21 13:05

# BP算法的C语言实现，代码个人测试正确， 但是wrong answer， 求大神指点

#include
#include
#include
#include
#include
//#include "user.h"
#include
#include
#include
#include
#include
#include

#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES

using namespace std;

#define OUT_COUT 8 //输出向量维数
#define IN_COUT 72 //输入向量维数
#define COUT 792 //样本数量
#define NN 99 //单个样本数量

typedef struct { //bp人工神经网络结构
int h; //实际使用隐层数量
//double v[IN_COUT][IN_COUT/3]; //隐藏层权矩阵i,隐层节点最大数量为50
double v[IN_COUT/3][IN_COUT];
//double w[IN_COUT/3][OUT_COUT]; //输出层权矩阵
double w[OUT_COUT][IN_COUT/3];

``````double b1[IN_COUT/3];
double b2[OUT_COUT];
double x[COUT][IN_COUT];
double y[COUT][OUT_COUT];

double a;          //学习率
double b;          //精度控制参数
int LoopCout;      //最大循环次数
``````

} bp_nn;

double fnet(double net) { //Sigmoid函数,神经网络激活函数
//return 1/(1+exp(-net));
return 2.0/(1+exp(-net))-1.0;
}

int InitBp(bp_nn *bp) { //初始化bp网络

``````/*printf("请输入隐层节点数，最大数为100：\n");
scanf_s("%d", &(*bp).h);

printf("请输入学习率：\n");
scanf_s("%lf", &(*bp).a);    //(*bp).a为double型数据，所以必须是lf

printf("请输入精度控制参数：\n");
scanf_s("%lf", &(*bp).b);

printf("请输入最大循环次数：\n");
scanf_s("%d", &(*bp).LoopCout);*/

(*bp).h = 24;
(*bp).a = 0.4;
(*bp).b = 0.0001;
(*bp).LoopCout = 2000;

int i, j;
srand((unsigned)time(NULL));
for (i = 0; i < (*bp).h; i++)
{
for (j = 0; j < IN_COUT; j++)
{
(*bp).v[i][j] = rand() / (double)(RAND_MAX);
}
(*bp).b1[i] = rand()/(double)(RAND_MAX);
}

for (i = 0; i < OUT_COUT; i++)
{
for (j = 0; j < (*bp).h; j++)
{
(*bp).w[i][j] = rand() / (double)(RAND_MAX);
}
(*bp).b2[i] = rand()/(double)(RAND_MAX);
}

return 1;
``````

}

int TrainBp(bp_nn *bp, double x[COUT][IN_COUT], double y[COUT][OUT_COUT]) {
//训练bp网络，样本为x，理想输出为y
double f = (*bp).b; //精度控制参数
double a = (*bp).a; //学习率
int h = (*bp).h; //隐层节点数
//double v[IN_COUT][IN_COUT/3], w[IN_COUT/3][OUT_COUT]; //权矩阵
double v[IN_COUT/3][IN_COUT], w[OUT_COUT][IN_COUT/3]; //权矩阵
double b1[IN_COUT/3],b2[OUT_COUT];
double ChgH[IN_COUT/3], ChgO[OUT_COUT]; //修改量矩阵
double O1[IN_COUT/3], O2[OUT_COUT]; //隐层和输出层输出量
int LoopCout = (*bp).LoopCout; //最大循环次数
int i, j, k, n;
double temp;

``````for (i = 0; i < h; i++)
{// 复制结构体中的权矩阵
for (j = 0; j < IN_COUT; j++)
{
v[i][j] = (*bp).v[i][j];
}
b1[i] = (*bp).b1[i];
}

for (i = 0; i < OUT_COUT; i++)
{
for (j = 0; j < h; j++)
{
w[i][j] = (*bp).w[i][j];
}
b2[i] = (*bp).b2[i];
}

double e = f + 1;
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[k][j];
O1[k] = fnet(temp+(*bp).b1[i]);
}

for (k = 0; k < OUT_COUT; k++)
{ //计算输出层输出向量
temp = 0;
for (j = 0; j < h; j++)
temp = temp + O1[j] * w[k][j];
O2[k] = fnet(temp+(*bp).b2[k]);
}

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]);
}

for (j = 0; j < OUT_COUT; j++)
{         //计算隐层权修改量
temp = 0;
for (k = 0; k < h; k++)
temp = temp + w[j][k] * ChgO[k];
ChgH[j] = temp * O1[j] * (1 - O1[j]);
}

for (j = 0; j < OUT_COUT; j++)
{//修改输出层权矩阵
for (k = 0; k < h; k++)
{
w[j][k] = w[j][k] + a * O1[j] * ChgO[k];
}
}
for (j = 0; j < h; j++)
{
for (k = 0; k < IN_COUT; k++)
{
v[j][k] = v[j][k] + a * x[i][j] * ChgH[k];
}
}
}
if (n % 10 == 0)
printf("误差 : %f\n", e);
}

printf("总共循环次数：%d\n", n);
printf("调整后的隐层权矩阵：\n");
for (i = 0; i < h; i++) {
for (j = 0; j < IN_COUT; j++)
printf("%f    ", v[i][j]);
printf("\n");
}
printf("调整后的输出层权矩阵：\n");
for (i = 0; i < OUT_COUT; i++) {
for (j = 0; j < h; j++)
printf("%f    ", w[i][j]);
printf("\n");
}
for (i = 0; i < h; i++)
{//把结果复制回结构体
for (j = 0; j < IN_COUT; j++)
{
(*bp).v[i][j] = v[i][j];
}
(*bp).b1[i] = b1[i];
}
for (i = 0; i < OUT_COUT; i++)
{
for (j = 0; j < h; j++)
{
(*bp).w[i][j] = w[i][j];
}
(*bp).b2[i] = b2[i];
}
printf("bp网络训练结束！\n");

return 1;
``````

}

int UseBp(bp_nn *bp) { //使用bp网络
float Input[IN_COUT];
double O1[50];
double O2[OUT_COUT]; //O1为隐层输出,O2为输出层输出
while (1) { //持续执行，除非中断程序
printf("请输入3个数：\n");
int i, j;
for (i = 0; i < IN_COUT; i++)
scanf_s("%f", &Input[i]);
double temp;
for (i = 0; i < (*bp).h; i++) {
temp = 0;
for (j = 0; j < IN_COUT; j++)
temp += Input[j] * (*bp).v[j][i];
O1[i] = fnet(temp-(*bp).b1[i]);
}
for (i = 0; i < OUT_COUT; i++) {
temp = 0;
for (j = 0; j < (*bp).h; j++)
temp += O1[j] * (*bp).w[j][i];
O2[i] = fnet(temp-(*bp).b2[i]);
}
printf("结果： ");
for (i = 0; i < OUT_COUT; i++)
printf("%.3f ", O2[i]);
printf("\n");
}
return 1;
}

void readFP(double x[COUT][IN_COUT],double y[COUT][OUT_COUT])
{
//bp_nn bp1;
ifstream fileinput1;
ifstream fileinput2;
ifstream fileinput3;
ifstream fileinput4;
ifstream fileinput5;
ifstream fileinput6;
ifstream fileinput7;
ifstream fileinput8;

``````fileinput1.open("emgclose.txt");
fileinput2.open("emgopen.txt");
fileinput3.open("emgext.txt");
fileinput4.open("emgfle.txt");
fileinput5.open("emgsph.txt");
fileinput6.open("emgcyl.txt");
fileinput7.open("emgtri.txt");
fileinput8.open("emgkey.txt");
for(int m = 0;m< NN;++m)
{
for(int i =0;i < IN_COUT;++i)
{
fileinput1 >> x[m][i];
}
}

for(int m = NN;m<2*NN;++m)
{
for(int i =0;i < IN_COUT;++i)
{
fileinput2 >> x[m][i];
}
}

for(int m = 2*NN;m<3*NN;++m)
{
for(int i =0;i < IN_COUT;++i)
{
fileinput3 >> x[m][i];
}
}

for(int m = 3*NN;m<4*NN;++m)
{
for(int i =0;i < IN_COUT;++i)
{
fileinput4 >> x[m][i];
}
}

for(int m = 4*NN;m<5*NN;++m)
{
for(int i =0;i < IN_COUT;++i)
{
fileinput5 >> x[m][i];
}
}

for(int m = 5*NN;m<6*NN;++m)
{
for(int i =0;i < IN_COUT;++i)
{
fileinput6 >> x[m][i];
}
}

for(int m = 6*NN;m<7*NN;++m)
{
for(int i =0;i < IN_COUT;++i)
{
fileinput7 >> x[m][i];
}
}

for(int m = 7*NN;m<8*NN;++m)
{
for(int i =0;i < IN_COUT;++i)
{
fileinput8 >> x[m][i];
}
}

fileinput1.close();
fileinput2.close();
fileinput3.close();
fileinput4.close();
fileinput5.close();
fileinput6.close();
fileinput7.close();
fileinput8.close();

ifstream fileinput;
fileinput.open("teach.txt");

for (int m2 = 0; m2 < OUT_COUT; m2++)
{
for (int i = 0; i < OUT_COUT; i++)
{
fileinput>>y[m2][i];
}
for (int j = m2*NN; j < (m2+1)*NN; j++)
{
for (int k = 0; k < OUT_COUT; k++)
{
y[j][k] = y[m2][k];
}
}

}
for (int i = 0; i < NN; i++)
{
for (int j = 0; j < OUT_COUT; j++)
{
y[i][j] = y[0][j];
}
}

fileinput.close();

double Mininput[IN_COUT] = {0.0};
double Maxinput[IN_COUT] = {0.0};
//找出训练的数据相应的最大值、最小值，为归一化做准备
for (int i = 0; i < IN_COUT; i++)
{
Mininput[i] = Maxinput[i] = x[0][i];
for (int j = 0; j < COUT; j++)
{
Mininput[i] = Mininput[i] < x[j][i]?Mininput[i]:x[j][i];
Maxinput[i] = Maxinput[i] > x[j][i]?Maxinput[i]:x[j][i];
}
}

//归一化处理
for (int i = 0; i < OUT_COUT; i++)
{
for (int j = 0; j < COUT; j++)
{
y[j][i] = 2.0*(y[j][i] - 0.0)/(1.0 - 0.0)-1.0;
}
}

for (int i = 0; i < IN_COUT; i++)
{
for (int j = 0; j < COUT; j++)
{
//X[i][j] = (X1[i][j] - Mininput[i]+1)/(Maxinput[i] - Mininput[i]+1);
x[j][i] = 2.0*(x[j][i] - Mininput[i])/(Maxinput[i] - Mininput[i])-1.0;
}
}
``````

}

int main()
{
/* float x[COUT][IN_COUT] = {{0.8,0.5,0},
{0.9,0.7,0.3},
{1,0.8,0.5},
{0,0.2,0.3},
{0.2,0.1,1.3},
{0.2,0.7,0.8}}; //训练样本
int y[COUT][OUT_COUT] = {{0,1},
{0,1},
{0,1},
{1,0},
{1,0},
{1,0}}; */ //理想输出

``````bp_nn bp;

InitBp(&bp);                    //初始化bp网络结构
TrainBp(&bp, bp.x, bp.y);             //训练bp神经网络
``````

// UseBp(&bp); //测试bp神经网络

``````return 1;
``````

}

• 点赞
• 写回答
• 关注问题
• 收藏
• 复制链接分享
• 邀请回答