📄 ly.cpp
字号:
#include <stdio.h>
#include <math.h>
#include <string.h>
void feedforward(int layernum,int n[],int k,double y[],double w[],double b[]);
void calcdelta(int layernum,int n[],int k,double d[],double y[],double w[],double delta[]);
void update(int layernum,int n[],int k,double y[],double delta[],double miu,double w[],double b[]);
void update(int layernum,int n[],int k,double y[],double delta[],double miu,double w[],double b[]);
static double f(double x);
static double fd(double x);
void init(int layernum,int n[],int k,double w[],double b[]);
void input(int n[],double y[]);
void output(int layernum,int n[],int k,double y[]);
void saveparameter(int layernum,int n[],int k,double w[],double b[]);
void readparameter(int *layernum,int n[],int *k,double w[],double b[]);
//主函数
void main(void)
{
int i,j=0,k,l,l1,p,choice,layernum,iternum,sampnum;
double miu,eps,e,ep;
int n[10];
char fname[14];
char chyn[1];
static double w[500],b[100],y[100],d[100],delta[100];
FILE *fp;;
puts("1--Training,2--Output");
scanf("%d",&choice);
if(choice==1)
{
puts("Input name of training sample data file");
scanf("%s",fname);
sampnum=4;
miu=0.5;
eps=0.0001;
puts("Input the number of training(iteration)");
scanf("%d",&iternum);
puts("Input layer number of 数据");
scanf("%d",&layernum);
puts("Input node number of each layer");
for(l=0;l<layernum;l++)
{
printf("N(%d)=",l);
scanf("%d",&n[l]);
printf("\n");
}
k=n[0];
for(l=1;l<layernum;l++)//layernum=3
{
if(k<n[l]) {
k=n[l];
}
}
init(layernum,n,k,w,b);
for(p=1;p<=iternum;p++)
{
e=0.0;
if((fp=fopen(fname,"r"))==NULL){
puts("\ncannot open the sample file");
return;
}
ep=0.0;
for(i=0;i<sampnum;i++)
{
for(j=0;j<n[0];j++){
fscanf(fp,"%lf,",&y[j]);
}
for(j=0;j<n[layernum-1];j++){
fscanf(fp,"%lf,",&d[j]);
}
feedforward(layernum,n,k,y,w,b);
calcdelta(layernum,n,k,d,y,w,delta);
update(layernum,n,k,y,delta,miu,w,b);
for(l=0;l<n[layernum-1];l++) {
l1=layernum-1;
ep += (d[l]-y[(l1)*k+l])*(d[l]-y[(l1)*k+l]);}
e=e+ep/2.0;
}
fclose(fp);
if(e<eps)
{
printf("\nActual training number=%d\n other=%lf",p,eps);
printf("\nThe overall error=%lf\n",e);
break;
}
}
printf("\nDo you want to save the network data(Y/N)?");
scanf("%s",chyn);
if(chyn[0]=='Y'||chyn[0]=='y')
{
saveparameter(layernum,n,k,w,b);
}
}
else
{
readparameter(&layernum,n,&k,w,b);
}
do
{
input(n,y);
feedforward(layernum,n,k,y,w,b);
output(layernum,n,k,y);
printf("\nDo you want to output again(Y/N)?");
scanf("%s",chyn);
}while(chyn[0]=='Y'||chyn[0]=='y');
}
//信息前向传送
static void feedforward(int layernum,int n[],int k,double y[],double w[],double b[])
{
int i,j,l;
double u;
for(l=1;l<layernum;l++)
{
for(j=0;j<n[l];j++)
{
u=0.0;
for(i=0;i<n[l-1];i++)
{
u=u+w[(l*k+i)*k+j]*y[(l-1)*k+i];
}
u=u+b[l*k+j];
y[l*k+j]=f(u);
}
}
}
//误差反向传播(计算 )
static void calcdelta(int layernum,int n[],int k,double d[],double y[],double w[],double delta[])
{
int i,j,l,l1;
for(j=0;j<n[layernum-1];j++)
{
l1=layernum-1;
delta[l1*k+j]=(d[j]-y[l1*k+j])*fd(y[l1*k+j]);
}
for(l=layernum-2;l>0;l--)
{
for(j=0;j<n[l];j++)
{
delta[l*k+j]=0.0;
for(i=0;i<n[l+1];i++)
{
delta[l*k+j]+=delta[(l+1)*k+i]*w[((l+1)*k+j)*k+i];
}
delta[l*k+j]=fd(y[l*k+j])*delta[l*k+j];
}
}
}
//更新连接权值 和阈值
static void update(int layernum,int n[],int k,double y[],double delta[],double miu,double w[],double b[])
{
int i,j,l;
for(l=1;l<layernum;l++)
{
for(j=0;j<n[l];j++)
{
for(i=0;i<n[l-1];i++)
{
w[(l*k+i)*k+j]+=miu*delta[l*k+j]*y[(l-1)*k+i];
}
b[l*k+j]+=miu*delta[l*k+j];
}
}
}
//计算S型函数的值
static double f(double x)
{
double f1;
f1=1.0/(1.0+exp(-x));
return(f1);
}
//计算S型函数的导数值
static double fd(double x)
{
double fd1;
fd1=x*(1-x);
return(fd1);
}
//初始化权值 和阈值
double uniform(double a,double c,long int *seed)
{double t;
*seed=2045*(*seed)+1;
*seed=*seed-(*seed/1048576)*1048576;
t=(*seed)/1048576.0;
t=a+(c-a)*t;
return (t);
}
static void init(int layernum,int n[],int k,double w[],double b[])
{
int i,j,l;
long int seed;
double uniform(double,double,long int *);
seed=13579l;
for(l=1;l<layernum;l++)
{
for(j=0;j<n[l];j++)
{
for(i=0;i<n[l-1];i++)
{
w[(l*k+i)*k+j]=uniform(0.0,1.0,&seed);
}
b[l*k+j]=uniform(0.0,1.0,&seed);
}
}
}
//输入网络的输入模式
static void input(int n[],double y[])
{
int j;
printf("\n Input of feed");
for(j=0;j<n[0];j++)
{
printf("\n\nInput pattern Y(0,%d)=",j);
scanf("%lf",&y[j]);
}
}
//输出(显示)网络的结果
static void output(int layernum,int n[],int k,double y[])
{
int j;
printf("\nOutput of feed\n");
for(j=0;j<n[layernum-1];j++)
{
printf("\nY(%d,%d)=%lf",layernum-1,j,y[(layernum-1)*k+j]);
}
}
//存储网络的各种参数
static void saveparameter(int layernum,int n[],int k,double w[],double b[])
{
int i,j,l;
char fname1[14];
FILE *fp;
puts("\nInput the name of network data file:");
scanf("%s",fname1);
if((fp=fopen(fname1,"a"))==NULL)
{
puts("\ncannot open file");
return;
}
fprintf(fp,"%d\n",layernum);
for(l=0;l<layernum;l++)
{
for(j=0;j<n[l];j++)
{
fprintf(fp,"%lf\n",b[l*k+j]);
for(i=0;i<n[l-1];i++)
{
fprintf(fp,"%lf\n",w[(l*k+i)*k+j]);
}
}
}
fclose(fp);
}
//读取网络的各种参数
static void readparameter(int *layernum,int n[],int *k,double w[],double b[])
{
int i,j,l;
char fname2[14];
FILE *fp;
puts("\nInput the name of trained network data file");
scanf("%s",fname2);
if((fp=fopen(fname2,"r"))==NULL)
{
puts("\ncannot open file");
return;
}
fscanf(fp,"%d",layernum);
for(l=0;l<(*layernum);l++)
{
fscanf(fp,"%d",&n[l]);}
*k=n[0];
for(l=1;l<(*layernum);l++)
{
if(*k<n[l]) *k=n[l];}
for(l=1;l<(*layernum);l++)
{
for(j=0;j<n[l];j++)
{
fscanf(fp,"%lf",&b[l*(*k)+j]);
for(i=0;i<n[l-1];i++)
{
fscanf(fp,"%lf",&w[(l*(*k)+i)*(*k)+j]);
}
}
}
fclose(fp);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -