📄 bp11.cpp
字号:
// BP11.cpp : Defines the entry point for the console application.
//
// MYBP0.cpp : Defines the entry point for the console application.
// BPNN1.cpp : Defines the entry point for the console application.
//
#include "StdAfx.h"
#include <fstream>
#include <iostream.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iomanip.h>
using namespace std;
//设计神经网络结构
#define NUM_AYER 3 //网络层数
#define IN 1 //输入层神经元个数 1
#define HN 10 //隐含层神经元个数 6
#define ON 1 //输出层神经元个数 1
#define SAM_NUM 100 //学习样本数
#define SAM_YAN 200 //校验样本数
#define MAX_EPOCH 100000 //最大迭代次数
const double alpha=0.1; //动量项系数
const double stepH=0.8; //输出到隐层的学习步长
const double stepQ=0.8; //隐层到输入的学习步长
double SAM_P[SAM_NUM]; //训练样本
double SAM_T[SAM_NUM]; //训练样本
double Test_P[SAM_YAN]; //校验样本
double Test_T[SAM_YAN]; //期望校验样本
double out_I; //输入层的输出
double In_H[HN]; //隐层的输入
double out_H[HN]; //隐层的输出
double In_O; //输出层的输入
double out_O; //输出层的输出
double out_e; //输出层的期望输出
double Yu_H[HN]; //隐层的阈值
double detaYu_H[HN]; //隐层阈值的变化量
double plusYu_H[HN]; //隐层阈值的冲量项
double Yu_O; //输出层的阈值
double detaYu_O; //输出层阈值的变化量
double plusYu_O; //输出层阈值的冲量项
double w_H_I[HN]; //输入层到隐含层的权值
double detaw_H_I[HN]; //输入层到隐含层的权值的变化量
double plusw_H_I[HN]; //输入层到隐层的权值的冲量项
double w_O_H[HN]; //隐含层到输出层的权值
double detaw_O_H[HN]; //隐含层到输出层的权值的变化量
double plusw_O_H[HN]; //隐层到输出层的权值的冲量项
double deta_H[HN]; //隐含层的局部梯度
double deta_O; //输出层的局部梯度
double Err; //网络学习的评价误差
double pre_Err=0.001; //预定义的网络训练精度
double tem_err; //出层的局部误差
double tem_err_LR; //网络的整体误差
double sigma; //中间变量
double RandomEqualREAL(double Low, double High) //产生Low-High之间的随机数
{
return ((double) rand() / RAND_MAX) * (High-Low) + Low;
}
int main(int argc, char* argv[])
{
int n;
ifstream Ex_out("exout.txt",ios::in); //网络的期望输出
ifstream Train_in("Trainin.txt",ios::in); //网络的训练输入
ifstream Test_in("Yanin.txt",ios::in); //测试输入
ifstream Test_out("Yanout.txt",ios::in); //测试输出
ofstream Act_out("Actout.txt",ios::out); //网络的实际输出
ofstream out_weightH("outweightH.txt",ios::out); //隐层权值输出
ofstream out_weightO("outweightO.txt",ios::out); //输出层权值输出
ofstream Err_out("err.txt",ios::out); //误差输出
//文件打开检查
if((Ex_out.fail())||(Train_in.fail())||(Test_in.fail())||(Test_out.fail()))
{
printf("Error input file!\n");
exit(0);
}
if((out_weightH.fail())||(Act_out.fail())||Err_out.fail()||(out_weightO.fail()))
{
printf("Error output file!\n");
exit(0);
}
//网络初始化
for(n=0;n<HN;n++)
{
w_H_I[n] = RandomEqualREAL(-0.5,0.5);
w_O_H[n] = RandomEqualREAL(-0.5,0.5);
Yu_H[n] = RandomEqualREAL(-0.5,0.5);
plusYu_H[n]=0.0;
plusw_H_I[n]=0.0;
plusw_O_H[n]=0.0;
}
Yu_O=0.12061; //输出层阈值初始化
plusYu_O=0.0;
int epoch=0; //训练循环次数
int ts=0; //样本训练次数
//误差值初始化 正向传播
Err = 1.0 + pre_Err;
while((Err>pre_Err)&&(epoch<MAX_EPOCH))
{
Err=0.0;
for(ts=0;ts<SAM_NUM;ts++)
{
//输入样本
Train_in>>SAM_P[ts]; //输入样本
Ex_out>>SAM_T[ts]; //输出样本
out_I = SAM_P[ts];
out_e=SAM_T[ts];
sigma=0.0;
//隐层的输入输出
for(n=0;n<HN;n++)
{
In_H[n]=out_I*w_H_I[n]+Yu_H[n]; //隐层的输入
out_H[n]=1.0/(1.0+exp(-In_H[n])); //隐层各神经元的输出
sigma+=out_H[n]*w_O_H[n];
}
//输出层的输入输出
In_O=sigma+Yu_O; ////输出层的输入
out_O=1.0/(1.0+exp(-In_O)); //输出层的输出
//计算评价误差
tem_err = out_e-out_O;
tem_err_LR=0.5*pow(tem_err,2); //网络的整体误差的平方和
Err+=tem_err_LR; //网络学习的评价误差
//计算局部误差 //反向传播
deta_O=tem_err*out_O*(1.0-out_O); //输出层的局部梯度
detaYu_O=stepH*deta_O;
Yu_O+=detaYu_O+alpha*plusYu_O;
plusYu_O=detaYu_O+alpha*plusYu_O;
for(n=0;n<HN;n++)
{
deta_H[n]=deta_O*w_O_H[n]*out_H[n]*(1.0-out_H[n]); //隐层的局部梯度
detaw_O_H[n]=stepH*deta_O*out_H[n]; //调整输出层到隐层的变化权值
w_O_H[n]+=detaw_O_H[n]+alpha*plusw_O_H[n];
plusw_O_H[n]=detaw_O_H[n]+alpha*plusw_O_H[n];
detaw_H_I[n]=stepQ*deta_H[n]*out_I; //调整隐层到输入层的变化权值
w_H_I[n]+=detaw_H_I[n]+alpha*plusw_H_I[n];
plusw_H_I[n]=detaw_H_I[n]+alpha*plusw_H_I[n];
detaYu_H[n]=stepQ*deta_H[n];
Yu_H[n]+=detaYu_H[n]+alpha*plusYu_H[n];
plusYu_H[n]=detaYu_H[n]+alpha*plusYu_H[n];
}
}
epoch++;
cout<<epoch<<" "<<Err<<"\n";
Err_out<<Err<<"\n";
}
for(n=0;n<HN;n++)
{
out_weightH<<w_H_I[n]<<"\n";
out_weightO<<w_O_H[n]<<"\n";
}
int i,j;
for(i=0;i<SAM_YAN;i++)
{
Test_in>>Test_P[i]; //输入样本
Test_out>>Test_T[i]; //输出样本
out_I = Test_P[i];
out_e=Test_T[i];
//隐层的输入输出
sigma=0.0;
for(j=0;j<HN;j++)
{
In_H[j]=out_I*w_H_I[j]+Yu_H[j]; //隐层的输入
out_H[j]=1.0/(1.0+exp(-In_H[j])); //隐层各神经元的输出
sigma+=out_H[j]*w_O_H[j];
}
//输出层的输入输出
In_O=sigma+Yu_O; //网络输入
out_O=1.0/(1.0+exp(-In_O)); //网络输出
Act_out<<out_O<<" "<<out_I<<"\n";
cout<<out_I<<" "<<out_O<<"\n";
}
Ex_out.close();
Train_in.close();
Err_out.close();
Act_out.close();
out_weightH.close();
out_weightO.close();
Test_in.close();
Test_out.close();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -