📄 backpropogation.c
字号:
#include <stdio.h>
#include <math.h>
#define sixfour 64
#define ten 10
#define size1 5
#define size2 5
void main()
{ float w1[sixfour][size1],w3[size1];//各层的权值
float w2[size1][size1];
float in[2*ten][sixfour+1]; //输入数据,其中,第sixfour+1个元素是期望输出值
float hide1[size1],hide2[size1];//第一、二隐层的输出数据
float delta,delta1[size1],delta2[size1];//输出层、第一、二隐层的局部梯度
double output; //实际输出值
float yita; //学习步长
float error; //误差
float temp[size1],ini; //用于存放中间结果
int i,j,k,l,m,n,mid; //计数器
double iptr,x;
int s;
float sigmoid(float x); //函数原型,本程序激活函数采用sigmoid函数
double modf(double,double * );
FILE *fp,*fp2,*weight1,*weight2; //fp是训练数据文件,fp2是输出文件,weight1,weight2是输出的权值文件,weight1
//用于保存训练是的权值,weight2是识别时的权值文件
yita=0.8;
// 读入训练数据in[][]
if((fp=fopen("train.txt","r"))==NULL)
{printf("\n the file train.txt can not be opened");
exit(0);
}
if((fp2=fopen("output.txt","w"))==NULL)
{printf("\n can't create the output.txt file");
exit(0);
}
if((weight2=fopen("weight.txt","r"))==NULL)
{printf("\n the file weight.txt can not be opened");
exit(0);
}
//读入并产生输入数据,读入十个标准样本,通过对这十个标准样本随机加噪,另外产生十个样本,
//这二十个样本作为训练数据进行训练
for(i=0;i<ten;i++)
for(j=0;j<sixfour+1;j++)
fscanf(fp,"%f",&in[i][j]);
/*
//随机加噪声
srand((unsigned)time(NULL));
s=rand();
for(k=ten;k<2*ten;k++)
{in[k][sixfour]=in[k-ten][sixfour];
for(n=0;n<5;n++)
{srand(s);
s+=1;
mid=rand()%64;
if(in[k-ten][mid]>0.5)
in[k][mid]=0.0;
else
in[k][mid]=1.0;
}
}
if((weight1=fopen("weight.txt","w"))==NULL)
{printf("\n the file weight.txt can not be opened");
exit(0);
}
//初始化第一隐层权值w1[][]
for(i=0;i<sixfour;i++)
for(j=0;j<size1;j++)
{ini=rand()%100;
ini/=100;
if(ini>0.5) ini-=1;
w1[i][j]=ini;
}
//初始化第二隐层权值w2[][]和输出层权值w3[[]
for(i=0;i<size1;i++)
{ ini=rand()%100;
ini/=100;
if(ini>0.5) ini-=1;
w3[i]=ini;
for(j=0;j<size2;j++)
{ini=rand()%100;
ini/=100;
if(ini>0.5) ini-=1;
w2[i][j]=ini;
}
}
//主循环
do
{ error=0.0;
for(m=0;m<2*ten;m++)
{ delta=0.0;
output=0.0;
for(i=0;i<size1;i++)
{ temp[i]=0.0;
hide1[i]=0.0;
hide2[i]=0.0;
delta1[i]=0.0;
delta2[i]=0.0;
}
//计算第一隐层的输出
for(i=0;i<size1;i++)
{for(k=0;k<sixfour;k++)
{hide1[i]+=w1[k][i]*in[m][k];}
hide1[i]=sigmoid(hide1[i]);
}
//计算第二隐层的输出
for(i=0;i<size1;i++)
{for(j=0;j<size1;j++)
{hide2[i]+=w2[j][i]*hide1[j]; }
hide2[i]=sigmoid(hide2[i]);
}
//计算输出节点的输出
for(i=0;i<size1;i++)
{output+=w3[i]*hide2[i]; }
output=sigmoid(output);
//输出层的误差
error+=fabs(output-in[m][sixfour]);
//计算输出层的局部梯度
delta=output*(1-output)*(in[m][sixfour]-output);
//计算第二隐层的局部梯度
for(i=0;i<size1;i++)
temp[i]+=delta*w3[i];
for(i=0;i<size1;i++)
delta2[i]=hide2[i]*(1-hide2[i])*temp[i];
//计算第一隐层的局部梯度
for(i=0;i<size1;i++)
temp[i]=0.0;
for(j=0;j<size1;j++)
for(i=0;i<size1;i++)
{temp[j]+=delta2[i]*w2[j][i];}
for(i=0;i<size1;i++)
{delta1[i]=hide1[i]*(1-hide1[i])*temp[i];}
//修正输出层权值
for(i=0;i<size1;i++)
w3[i]+=yita*delta*hide2[i];
//修正第二隐层权值
for(i=0;i<size1;i++)
for(j=0;j<size1;j++)
{w2[i][j]+=yita*delta2[j]*hide1[i];
// printf("the weight1 is:%f\n",w2[i][j]);
}
//修正第一隐层权值
for(i=0;i<sixfour;i++)
for(j=0;j<size1;j++)
{w1[i][j]+=yita*delta1[j]*in[m][i];
}
}
error=error/(2*ten);
printf("the error is:%f\n",error);
}while(error>0.06 );
//将训练好的权值保存在weight.txt文件中
for(i=0;i<sixfour;i++)
for(j=0;j<size1;j++)
{fprintf(weight1,"%f\n",w1[i][j]);}
fprintf(weight1,"\n\n\n");
for(i=0;i<size1;i++)
for(j=0;j<size1;j++)
{fprintf(weight1,"%f\n",w2[i][j]);}
fprintf(weight1,"\n\n\n");
for(i=0;i<size1;i++)
{fprintf(weight1,"%f\n",w3[i]);}
fprintf(weight1,"\n\n\n");
*/
for(i=0;i<sixfour;i++)
for(j=0;j<size1;j++)
fscanf(weight2,"%f",&w1[i][j]);
for(i=0;i<size1;i++)
for(j=0;j<size1;j++)
fscanf(weight2,"%f",&w2[i][j]);
for(i=0;i<size1;i++)
fscanf(weight2,"%f",&w3[i]);
//开始进行字符识别
//随机加噪声
srand((unsigned)time(NULL));
s=rand();
for(k=0;k<ten;k++)
{
for(n=0;n<5;n++)
{srand(s);
s+=1;
mid=rand()%64;
if(in[k][mid]>0.5)
in[k][mid]=0.0;
else
in[k][mid]=1.0;
}
}
for(m=0;m<ten;m++)
{
output=0.0;
for(i=0;i<ten;i++)
{ hide1[i]=0.0;
hide2[i]=0.0;
}
//计算第一隐层的输出
for(i=0;i<size1;i++)
{for(k=0;k<sixfour;k++)
{hide1[i]+=w1[k][i]*in[m][k];}
hide1[i]=sigmoid(hide1[i]);
}
//计算第二隐层的输出
for(i=0;i<size1;i++)
{for(j=0;j<size1;j++)
{hide2[i]+=w2[j][i]*hide1[j];}
hide2[i]=sigmoid(hide2[i]);
}
//计算输出结果
for(i=0;i<size1;i++)
{output+=w3[i]*hide2[i];}
output=sigmoid(output);
//识别结束
//fprintf(fp2,"%f",in[m][sixfour]);
fprintf(fp2,"\n\n期望输出值为:%f\n",10*in[m][sixfour]);
output=10*output;
x=modf(output,&iptr);
if(x>0.5)
output=(iptr)+1.0;
else output=iptr;
fprintf(fp2,"实际输出值为%f\n",output);
}
fclose(fp);
fclose(fp2);
fclose(weight2);
}
float sigmoid(float x)
{ float w;
w=1/(1+exp(-1.0*x));
return w;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -