qq_25351795
我与黑夜
采纳率0%
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;
readFP(bp.x,bp.y);




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

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

return 1;

}

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

1条回答