📄 bp_xor_c.c
字号:
#include <stdio.h>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#define sigmoid(x) 1.0/(1+exp(-x))
#define MINE 0.03 //误差
#define IN_NUM 2 //输入个数
#define HID_NUM 5 //隐层个数
#define OUT_NUM 1 //输出个数
#define SAMPLE_NUM 4 // 样本个数
#define TEST_NUM 2 //测试个数
void main()
{
char c;
int i,j;
float input[4][2];//输入样本
float hope_output[SAMPLE_NUM][OUT_NUM];//期望输出
float w_input_hid[IN_NUM][HID_NUM];//输入至隐层权值
float w_hid_output[HID_NUM][OUT_NUM];//隐层至输出权值
//double hid_q[HID_NUM];//阶层阈值
void init(float w_input_hid[IN_NUM][HID_NUM],float w_hid_output[HID_NUM][OUT_NUM]);
void input_learning_sample(float input[4][2],float hope_output[4]);//输入样本,期望输出
void train(float w_input_hid[IN_NUM][HID_NUM],float w_hid_output[HID_NUM][OUT_NUM],float input[4][2],float hope_output[SAMPLE_NUM][OUT_NUM]);
void test(float w_input_hid[IN_NUM][HID_NUM],float w_hid_output[HID_NUM][OUT_NUM]);
srand(time(NULL));
printf("test or learn(t/l)?\n");
c=getch();
if (c=='t')
{
init(w_input_hid,w_hid_output);
test(w_input_hid,w_hid_output);
}
else
{
init(w_input_hid,w_hid_output);
input_learning_sample(input,hope_output);
train(w_input_hid,w_hid_output,input,hope_output);
}
}
void init(float w_input_hid[IN_NUM][HID_NUM],float w_hid_output[HID_NUM][OUT_NUM])
{
int i,j;
//从文件初始化输入至隐层权值,如程序没有运行过,随机模拟权值
FILE *FP=NULL;
FP=fopen("wj_input_hid.txt","r");
if (FP==NULL)
{
FILE *FW=NULL;
FW=fopen("init_wj_input_hid.txt","w");
for(i=0;i<IN_NUM;i++)
{
for (j=0;j<HID_NUM;j++)
{
w_input_hid[i][j]=(rand());
w_input_hid[i][j]=1-2*w_input_hid[i][j]/32767;
fprintf(FW,"%f\n", w_input_hid[i][j]);
}
}
fclose(FW);
}
else
{
for(i=0;i<IN_NUM;i++)
{
for(j=0;j<HID_NUM;j++)
{
fscanf(FP,"%f",&w_input_hid[i][j]);
}
}
fclose(FP);
}
//从文件初始化隐层至输出权值,如程序没有运行过,随机模拟权值
FP=fopen("wj_hid_output.txt","r");
if (FP==NULL)
{
FILE *FW=NULL;
FW=fopen("init_wj_hid_output.txt","w");
for(i=0;i<HID_NUM;i++)
{
for (j=0;j<OUT_NUM;j++)
{
w_hid_output[i][j]=rand();
w_hid_output[i][j]=1-2*w_hid_output[i][j]/32767.0;
fprintf(FW,"%f\n", w_hid_output[i][j]);
}
}
fclose(FW);
}
else
{
for(i=0;i<IN_NUM;i++)
{
for(j=0;j<HID_NUM;j++)
fscanf(FP,"%f",&w_hid_output[i][j]);
}
fclose(FP);
}
}
void input_learning_sample(float input[4][2],float hope_output[SAMPLE_NUM][OUT_NUM])
{
int i,j;
FILE *FP=NULL;
FP=fopen("sample.txt","r");
if(FP==NULL)
{
printf("NO INPUT!");
getch();
exit(0);
}
for(i=0;i<SAMPLE_NUM;i++)
{
for(j=0;j<IN_NUM;j++)
{
fscanf(FP,"%f",&input[i][j]);//读入样本
// printf(" %f",input[i][j]);
}
fscanf(FP,"%f",&hope_output[i][0]);//读入期望输出
//printf(" %f\n",hope_output[i]);
}
fclose(FP);
}
void train(float w_input_hid[IN_NUM][HID_NUM],float w_hid_output[HID_NUM][OUT_NUM],float input[4][2],float hope_output[SAMPLE_NUM][OUT_NUM])
{
int i,j,k,t=0;
float temp,e;
float hid_receive[SAMPLE_NUM][HID_NUM],hid_output[SAMPLE_NUM][HID_NUM];//隐层输入,输出
float deltaa,deltab=0;
float error=0;//总误差
float error_output[SAMPLE_NUM][OUT_NUM],error_hid[SAMPLE_NUM][HID_NUM];//单个样本误差
float out_in[SAMPLE_NUM][OUT_NUM];//输出层输入
float output[SAMPLE_NUM][OUT_NUM];//实际输出
FILE *FP=NULL;
FILE *FQ=NULL;
FILE *FW=NULL;
FP=fopen("errot.txt","w");
if(FP==NULL) {
printf("Can not open error.txt\n");
getch();
exit(0);
}
FW=fopen("output_output.txt","w");
if(FW==NULL) {
printf("Can not open output_output.txt\n");
getch();
exit(0);
}
do
{
error=0;
//前向
for(k=0;k<SAMPLE_NUM;k++)
{
for(i=0;i<HID_NUM;i++)
{
hid_receive[k][i]=0;
for(j=0;j<IN_NUM;j++)
{
hid_receive[k][i]+=(input[k][j])*w_input_hid[j][i];//隐层输入
}
hid_output[k][i]=1.0/(1+exp(-hid_receive[k][i]));//隐层输出
}
for(i=0;i<OUT_NUM;i++)
{
out_in[k][i]=0;
for(j=0;j<HID_NUM;j++)
out_in[k][i]+=hid_output[k][j]*w_hid_output[j][i];//输出层输入
output[k][i]=sigmoid(out_in[k][i]);//实际输出
fprintf(FW,"%f\n",output[k][i]);
}
for(i=0;i<OUT_NUM;i++)
{
temp=((hope_output[k][i]-output[k][i]));
if (temp<0) temp=-temp;
error+=temp;//样本总误差
//printf("%f %f\n",temp,error);
}
}
error=1.0*error/2;
fprintf(FP,"%f\n",error);
if(error<MINE) break;//如果误差充许,退出
e=0;
temp=0;
for (k=0;k<SAMPLE_NUM;k++)
{
// COMPUTE ERRORSIGNAL FOR OUTPUT UNITS
for (j=0;j<OUT_NUM;j++)
{
error_output[k][j]=hope_output[k][j]-output[k][j];//(t-y)
e+=error_output[k][j]*error_output[k][j];//e = (?(t-y)^2)/2
error_output[k][j]*=output[k][j]*(1-output[k][j]);//d= y*(1-y)*(t-y)
}
// COMPUTE ERRORSIGNAL FOR HIDDEN UNITS
for(i=0;i<HID_NUM;i++)
{
for(j=0;j<OUT_NUM;j++)
{
temp+=error_output[k][j]*w_hid_output[i][j];
}
error_hid[k][i]=hid_output[k][i]*(1-hid_output[k][i])*temp;//Xk*(1-Xk)?d*W
temp=0;
}
// ADJUST WEIGHTS OF CONNECTIONS FROM HIDDEN TO OUTPUT UNITS
for(i=0;i<HID_NUM;i++)
{
for (j=0;j<OUT_NUM;j++)
w_hid_output[i][j]+=0.5*error_output[k][j]*hid_output[k][i];
}
for(i=0;i<IN_NUM;i++)
{
for(j=0;j<HID_NUM;j++)
{
w_input_hid[i][j]+=0.5*error_hid[k][j]*input[k][i];
}
}
}
t++;
}while((t<=100000));
fclose(FP);
fclose(FW);
//保存训练之后的网络权值
FP=fopen("wj_input_hid.txt","w");
if(FP==NULL) {
printf("Can not open wj_input_hid.txt\n");
getch();
exit(0);
}
for(i=0;i<IN_NUM;i++)
{
for(j=0;j<HID_NUM;j++)
{
fprintf(FP,"%f ",w_input_hid[i][j]);
}
fprintf(FP,"\n");
}
fclose(FP);
FP=fopen("wj_hid_output.txt","w");
if(FP==NULL) {
printf("Can not open error.txt\n");
getch();
exit(0);
}
for(j=0;j<OUT_NUM;j++)
{
for(i=0;i<HID_NUM;i++)
{
fprintf(FP,"%f\n",w_hid_output[i][j]);
}
}
fclose(FP);
if (t>100000) {
printf("NO SUCCESS\n");
}
else{
printf("train over\n");
printf("train time is %d\n",t);
}
}
//测试
void test(float w_input_hid[IN_NUM][HID_NUM],float w_hid_output[HID_NUM][OUT_NUM])
{
int i,j,k;
float test_out_in[TEST_NUM][OUT_NUM],test_out_real[TEST_NUM][OUT_NUM],test_out[TEST_NUM][OUT_NUM];
float text[TEST_NUM][IN_NUM];
float test_hid_in[TEST_NUM][HID_NUM],test_hid_out[TEST_NUM][HID_NUM];
FILE *FP=NULL;
FP=fopen("test.txt","r");
if(FP==NULL)
{
printf("can not open test.txt\n");
getch();
exit(0);
}
for(i=0;i<TEST_NUM;i++)
{
for(j=0;j<IN_NUM;j++)
{
fscanf(FP,"%f",&text[i][j]);
//printf("%f \n",text[i][j]);
}
}
fclose(FP);
for(k=0;k<TEST_NUM;k++)
{
for (j=0;j<HID_NUM;j++)
{
test_hid_in[k][j]=0;
for(i=0;i<IN_NUM;i++)
test_hid_in[k][j]+=(text[k][i])*w_input_hid[i][j];
test_hid_out[k][j]=sigmoid(test_hid_in[k][j]);
}
for (i=0;i<OUT_NUM;i++)
{
test_out_in[k][i]=0;
for(j=0;j<HID_NUM;j++)
test_out_in[k][i]+=test_hid_out[k][j]*w_hid_output[j][i];
test_out_real[k][i]=sigmoid(test_out_in[k][i]);
if (test_out_real[k][i]<0.1)
{
test_out[k][i]=0;
}
else if (test_out_real[k][i]>0.9)
{
test_out[k][i]=1.0;
}
}
}
FP=fopen("test_result.txt","w");
if(FP==NULL)
{
printf("can not open test_result.txt\n");
getch();
exit(0);
}
fprintf(FP,"%s %s %s\n","NO.","Output","Real_Output");
for(k=0;k<TEST_NUM;k++)
{
for(j=0;j<OUT_NUM;j++)
{
fprintf(FP,"%d %f ",k+1,test_out[k][j]);
fprintf(FP,"%f\n",test_out_real[k][j]);
}
}
fclose(FP);
printf("test is over!\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -