⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bp_xor_c.c

📁 C语言版的BP算法
💻 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 + -