大家,各位高手,帮帮一起讨论下我的BP神经网络C语言程序吧,急急急
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<malloc.h>
#define TRUE 1
#define FALSE 0
#define NUM_LAYERS 3
#define NUM 124 //训练实例个数
#define N 5 //输入层单元数
#define M 1 //输出层单元数
int Units = {N,7,M}; //每层单元数
FILE *fp,*fb;
typedef struct //训练实例
{
float x;
float y;
}TRAIN;
typedef struct //网络层结构
{
int Units; //该层中单元的个数
float *Output; //第 i 个单元的输出
float *Error ; //第 i 个单元的校正误差
float **Weight; //第 i 个单元的连接权值
}LAYER;
typedef struct //网络
{
LAYER **Layer; //隐层定义
LAYER *Inputlayer; //输入层
LAYER *Outputlayer; //输出层
float Error; //允许误差
float Eta; //学习率
}NET;
//初始化伪随机数发生器
void InitializeRandoms()
{
srand(4711);
return;
}
//产生随机实数并规范化
float RandomReal() //产生(-0.5,0.5)之间的随机数
{
return (float)(((rand()%200)-100)/200.0);
}
//初始化训练数据
void InitializeTrainingData(TRAIN *training)
{
int i,j;
char filename;
printf("\n请输入训练实例的数据文件名: \n");
gets(filename);
fb = fopen(filename,"r");
fprintf(fp,"\n\n--Saving initialization training datas ...\n");
for(i=0;i<NUM;i++)
{
for(j=0;j<N;j++)
{
fscanf(fb,"%f",&(training+i)->x);
fprintf(fp,"%10.4f",(training+i)->x);
}
for(j=0;j<M;j++)
{
fscanf(fb,"%f",&(training+i)->y);
fprintf(fp,"%10.4f",(training+i)->y);
}
fprintf(fp,"\n");
}
fclose(fb);
return;
}
//应用程序初始化
void InitializeApplication(NET *Net)
{
Net->Eta = (float)0.3;
Net->Error = (float)0.0001;
fp = fopen("BPResultData.txt","w+");
return;
}
//应用程序关闭时终止打开的文件
void FinalizeApplication(NET *Net)
{
fclose(fp);
return;
}
//分配内存,建立网络
void GenerateNetwork(NET *Net)
{
int l,i;
Net->Layer = (LAYER **)calloc(NUM_LAYERS,sizeof(LAYER *));
for(l=0;l<NUM_LAYERS;l++)
{
Net->Layer = (LAYER *)malloc(sizeof(LAYER));
Net->Layer->Units = Units;
Net->Layer->Output = (float *) calloc(Units+1,sizeof(float));
Net->Layer->Error = (float *) calloc(Units+1,sizeof(float));
Net->Layer->Weight = (float **)calloc(Units+1,sizeof(float *));
Net->Layer->Output = 1;
if(l != 0)
for(i=1;i <= Units;i++) //下标从"1"开始
Net->Layer->Weight = (float *)calloc(Units+1,sizeof(float));
}
Net->Inputlayer = Net->Layer;
Net->Outputlayer = Net->Layer;
return;
}
//产生随机实数作为初始连接权值
void RandomWeights(NET *Net)
{
int l,i,j;
for(l=1;l<NUM_LAYERS;l++)
for(i=1;i <= Net->Layer->Units;i++)
for(j=0;j <= Net->Layer->Units;j++)
Net->Layer->Weight = RandomReal();
return;
}
//设置输入层的输出值
void SetInput(NET *Net,float *Input)
{
int i;
for(i=1;i <= Net->Inputlayer->Units;i++)
Net->Inputlayer->Output = Input; //输入层采用 u(x) = x
return;
}
//设置输出层的输出值
void GetOutput(NET *Net,float *Output)
{
int i;
for(i=1;i <= Net->Outputlayer->Units;i++)
Output = (float)(1/(1 + exp(-Net->Outputlayer->Output))); //输出层采用 f(x)=1/(1+e^(-x))
return;
}
//层间顺传播
void PropagateLayer(NET *Net,LAYER *Lower,LAYER *Upper)
{
int i,j;
float sum;
for(i=1;i <= Upper->Units;i++)
{
sum = 0;
for(j=1;j <= Lower->Units;j++)
sum += (Upper->Weight * Lower->Output);
Upper->Output = (float)(1/(1 + exp(-sum)));
}
return;
}
//整个网络所有层间的顺传播
void PropagateNet(NET *Net)
{
int l;
for(l=0;l < NUM_LAYERS-1;l++)
PropagateLayer(Net,Net->Layer,Net->Layer);
return;
}
//计算输出层误差
void ComputeOutputError(NET *Net,float *target)
{
int i;
float Out,Err;
for(i=1;i <= Net->Outputlayer->Units;i++)
{
Out = Net->Outputlayer->Output;
Err = target - Out;
Net->Outputlayer->Error = Out*(1-Out)*Err;
}
return;
}
//层间逆传播
void BackpropagateLayer(NET *Net,LAYER *Upper,LAYER *Lower)
{
int i,j;
float Out,Err;
for(i=1;i <= Lower->Units;i++)
{
Out = Lower->Output;
Err = 0;
for(j=1;j <= Upper->Units;j++)
Err += (Upper->Weight * Upper->Error);
Lower->Error = Out*(1-Out)*Err;
}
return;
}
//整个网络所有层间的逆传播
void BackpropagateNet(NET *Net)
{
int l;
for(l=NUM_LAYERS-1;l>1;l--)
BackpropagateLayer(Net,Net->Layer,Net->Layer);
return;
}
//权值调整
void AdjustWeights(NET *Net)
{
int l,i,j;
float Out,Err;
for(l=1;l<NUM_LAYERS;l++)
for(i=1;i <= Net->Layer->Units;i++)
for(j=0;j <= Net->Layer->Units;j++)
{
Out = Net->Layer->Output;
Err = Net->Layer->Error;
Net->Layer->Weight += (Net->Eta*Err*Out);
}
return;
}
//网络处理过程
void SimulateNet(NET *Net,float *Input,float *Output,float *target,int TrainOrNot)
{
SetInput(Net,Input); //输入数据
PropagateNet(Net); //模式顺传播
GetOutput(Net,Output); //形成输出
ComputeOutputError(Net,target); //计算输出误差
if(TrainOrNot)
{
BackpropagateNet(Net); //误差逆传播
AdjustWeights(Net); //调整权值
}
return;
}
//训练过程
void TrainNet(NET *Net,TRAIN *training)
{
int l,i,j,k;
int count=0,flag=0;
float Output,outputfront,ERR,err,sum;
do
{
flag = 0;
sum = 0;
ERR = 0;
if(count >= 1)
for(j=0;j<M;j++)
outputfront=Output;
SimulateNet(Net,(training+(count%NUM))->x,Output,(training+(count%NUM))->y,TRUE);
if(count >= 1)
{
k = count%NUM;
for(i=1;i <= Net->Outputlayer->Units;i++)
{
sum += Net->Outputlayer->Error;
err = (training+k-1)->y - outputfront;
ERR += (outputfront * (1 - outputfront) * err);
}
if(sum <= ERR)
Net->Eta = (float)(0.9999 * Net->Eta);
else
Net->Eta = (float)(1.0015 * Net->Eta);
}
if(count >= NUM)
{
for(k=1;k <= M;k++)
if(Net->Outputlayer->Error > Net->Error)
{ flag=1; break; }
if(k>M)
flag=0;
}
count++;
}while(flag || count <= NUM);
fprintf(fp,"\n\n\n");
fprintf(fp,"--training results ... \n");
fprintf(fp,"training times: %d\n",count);
fprintf(fp,"\n*****the final weights*****\n");
for(l=1;l<NUM_LAYERS;l++)
{
for(i=1;i <= Net->Layer->Units;i++)
{
for(j=1;j <= Net->Layer->Units;j++)
fprintf(fp,"%15.6f",Net->Layer->Weight);
fprintf(fp,"\n");
}
fprintf(fp,"\n\n");
}
}
//评估过程
void EvaluateNet(NET *Net)
{
int i;
printf("\n\n(");
fprintf(fp,"\n\n(");
for(i=1;i <= Net->Inputlayer->Units;i++)
{
printf(" %.4f",Net->Inputlayer->Output);
fprintf(fp,"%10.4f",Net->Inputlayer->Output);
}
printf(")\t");
fprintf(fp,")\t");
for(i=1;i <= Net->Outputlayer->Units;i++)
{
if(fabs(Net->Outputlayer->Output - 1.0) <= 0.0499)
{
printf("肯定是第 %d 类, ",i);
fprintf(fp,"肯定是第 %d 类, ",i);
}
if(fabs(Net->Outputlayer->Output - 0.9) <= 0.0499)
{
printf("几乎是第 %d 类, ",i);
fprintf(fp,"几乎是第 %d 类, ",i);
}
if(fabs(Net->Outputlayer->Output - 0.8) <= 0.0499)
{
printf("极是第 %d 类, ",i);
fprintf(fp,"极是第 %d 类, ",i);
}
if(fabs(Net->Outputlayer->Output - 0.7) <= 0.0499)
{
printf("很是第 %d 类, ",i);
fprintf(fp,"很是第 %d 类, ",i);
}
if(fabs(Net->Outputlayer->Output - 0.6) <= 0.0499)
{
printf("相当是第 %d 类, ",i);
fprintf(fp,"相当是第 %d 类, ",i);
}
if(fabs(Net->Outputlayer->Output - 0.5) <= 0.0499)
{
printf("差不多是第 %d 类, ",i);
fprintf(fp,"差不多是第 %d 类, ",i);
}
if(fabs(Net->Outputlayer->Output - 0.4) <= 0.0499)
{
printf("比较像是第 %d 类, ",i);
fprintf(fp,"比较像是第 %d 类, ",i);
}
if(fabs(Net->Outputlayer->Output - 0.3) <= 0.0499)
{
printf("有些像是第 %d 类, ",i);
fprintf(fp,"有些像是第 %d 类, ",i);
}
if(fabs(Net->Outputlayer->Output - 0.2) <= 0.0499)
{
printf("有点像是第 %d 类, ",i);
fprintf(fp,"有点像是第 %d 类, ",i);
}
if(fabs(Net->Outputlayer->Output - 0.1) <= 0.0499)
{
printf("稍稍像是第 %d 类, ",i);
fprintf(fp,"稍稍像是第 %d 类, ",i);
}
if(Net->Outputlayer->Output <= 0.0499)
{
printf("肯定不是第 %d 类, ",i);
fprintf(fp,"肯定不是第 %d 类, ",i);
}
}
printf("\n\n");
fprintf(fp,"\n\n\n");
return;
}
//测试过程
void TestNet(NET *Net)
{
TRAIN Testdata;
float Output;
int i,j,flag=0;
char select;
fprintf(fp,"\n\n--Saving test datas ...\n");
do
{
printf("\n请输入测试数据(x1,x2,x3,x4,x5,y): \n");
for(j=0;j<N;j++)
{
scanf("%f",&Testdata.x);
fprintf(fp,"%10.4f",Testdata.x);
}
for(j=0;j<M;j++)
{
scanf("%f",&Testdata.y);
fprintf(fp,"%10.4f",Testdata.y);
}
fprintf(fp,"\n");
SimulateNet(Net,Testdata.x,Output,Testdata.y,FALSE);
fprintf(fp,"\n--NET Output and Error of the Test Data ....\n");
for(i=1;i <= Net->Outputlayer->Units;i++)
fprintf(fp,"%10.6f %10.6f\n",Net->Outputlayer->Output,Net->Outputlayer->Error);
EvaluateNet(Net);
printf("\n继续测试?(y/n):\n");
getchar();
scanf("%c",&select);
printf("\n");
if((select == 'y')||(select == 'Y'))
flag = 1;
else
flag=0;
}while(flag);
return;
}
void OUTPUT(NET *Net)
{
float a={0.0};
float b={0.0};
float sum1={0.0};
float sum2={0.0};;
float test;
//int i,j,k;
fprintf(fp,"\n\n--true input datas ...\n");
printf("\n请输入要判别岩性的自然伽马值、密度值、中子值、声波时差值、深电阻率值:\n\n");
for(int i=0;i<N;i++)
{
scanf("%f",&test);
fprintf(fp,"%10.4f",test);
}
for(int l=1;l<NUM_LAYERS;l++)
{
if(l==1)
{
for(int i=1;i <= Net->Layer->Units;i++)
{
for(int j=1;j <= Net->Layer->Units;j++)
(float)sum1+=test*Net->Layer->Weight;
(float)a=1/(1+exp(-sum1));
}
printf("\n");
}
if(l==2)
{
for(int i=1;i <= Net->Layer->Units;i++)
{
for(int j=1;j <= Net->Layer->Units;j++)
(float)sum1+=a*Net->Layer->Weight;
(float)a=1/(1+exp(-sum1));
printf("%f\t",a);
}
}
}
}
//主函数
void main()
{
TRAIN TrainingData;
NET Net;
InitializeRandoms(); //初始化伪随机数发生器
GenerateNetwork(&Net); //建立网络
RandomWeights(&Net); //形成初始权值
InitializeApplication(&Net); //应用程序初始化,准备运行
InitializeTrainingData(TrainingData); //记录训练数据
TrainNet(&Net,TrainingData); //开始训练
TestNet(&Net);
OUTPUT(&Net);
FinalizeApplication(&Net); //程序关闭,完成善后工作
return;
}
页:
[1]