当前位置:文档之家› 人工神经网络作业-单层感知器

人工神经网络作业-单层感知器

3.5单层感知器# include <stdio.h># include <math.h># define N 100int sgn(double x) //符号运算函数{int y;if(x>0||x==0)y=1;elsey=-1;return y;}void main(){double W[4]={0.0,0.0,0.0,0.0},X[6][4]={{-1,0.8,0.5,0},{-1,0.9,0.7,0.3},{-1,1,0.8,0.5}, {-1,0,0.2,0.3},{-1,0.2,0.1,1.3},{-1,0.2,0.7,0.8}};int err,o[6],i,j,k,num,d[6]={1,1,1,-1,-1,-1};double n,WX;n=1.0;k=0;do {k++;num=0;for(i=0;i<6;i++){WX=0.0;for(j=0;j<4;j++)WX=WX+W[j]*X[i][j];o[i]=sgn(WX);err=d[i]-o[i];for(j=0;j<4;j++)W[j]=W[j]+n*err*X[i][j];if(err==0)num++;}}while(num!=6);printf("调整后的权值矩阵为:\n");for(j=0;j<4;j++)printf("%f\n",W[j]);printf("分类结果为:\n");for(i=0;i<6;i++)printf("%d\n",o[i]);}3.6单次训练的结果# include <stdio.h># include <math.h>double Sig(double x) //单极性函数{double y;y=1.0/(1.0+exp(-x));return y;}void main(){doublex[3]={-1,1,3},V[3][3]={{0,3,-1},{0,1,2},{0,-2,0}},W[3][3]={{0,2,3},{0,1,1},{0,0,-2}};double d[3]={0,0.95,0.05},nety[3],neto[3],Y[3],O[3],dety[3],deto[3];double D,yita;int i,j;yita=1.0;FILE *fp;fp=fopen("out.txt","w");fprintf(fp,"初始W矩阵:\n");for(i=0;i<3;i++){for(j=1;j<3;j++)fprintf(fp,"%f ",W[i][j]);fprintf(fp,"\n");}fprintf(fp,"初始V矩阵:\n");for(i=0;i<3;i++){for(j=1;j<3;j++)fprintf(fp,"%f ",V[i][j]);fprintf(fp,"\n");}//计算隐层的输出fprintf(fp,"隐层的净输入:\n");for(j=1;j<3;j++){nety[j]=0.0;for(i=0;i<3;i++)nety[j]=nety[j]+V[i][j]*x[i];fprintf(fp,"%f\t",nety[j]);}fprintf(fp,"\n");Y[0]=-1.0;fprintf(fp,"隐层的输出:\n");for(i=1;i<3;i++)Y[i]=Sig(nety[i]);for(j=1;j<3;j++)fprintf(fp,"%f\t",Y[j]);fprintf(fp,"\n");//计算输出层的输出fprintf(fp,"输出层的净输入:\n");for(j=1;j<3;j++){neto[j]=0.0;for(i=0;i<3;i++)neto[j]=neto[j]+W[i][j]*Y[i];fprintf(fp,"%f\t",neto[j]);}fprintf(fp,"\n");fprintf(fp,"输出层的输出:\n");for(i=1;i<3;i++)O[i]=Sig(neto[i]);for(j=1;j<3;j++)fprintf(fp,"%f\t",O[j]);fprintf(fp,"\n");//计算导数fprintf(fp,"隐层输出的一阶导数:\n");for(i=1;i<3;i++)fprintf(fp,"%f\t",Sig(nety[i])*(1.0-Sig(nety[i])));fprintf(fp,"\n");fprintf(fp,"输出层输出的一阶导数:\n");for(i=1;i<3;i++)fprintf(fp,"%f\t",Sig(neto[i])*(1.0-Sig(neto[i])));//计算输出层误差fprintf(fp,"\n输出层误差:\n");for(i=1;i<3;i++){deto[i]=(d[i]-O[i])*O[i]*(1.0-O[i]);fprintf(fp,"%f\t",deto[i]);}fprintf(fp,"\n隐层误差:\n");//计算隐层误差for(i=1;i<3;i++){D=0.0;for(j=1;j<3;j++)D=D+deto[j]*W[i][j];dety[i]=D*Y[i]*(1.0-Y[i]);fprintf(fp,"%f\t",dety[i]);}fprintf(fp,"\n");//调整W矩阵for(i=1;i<3;i++){for(j=0;j<3;j++)W[j][i]=W[j][i]+yita*deto[i]*Y[j];}//调整V矩阵for(i=1;i<3;i++){for(j=0;j<3;j++)V[j][i]=V[j][i]+yita*dety[i]*x[j];}//输出调整一次后的权值矩阵fprintf(fp,"调整一次后的W矩阵:\n");for(i=0;i<3;i++){for(j=1;j<3;j++)fprintf(fp,"%f ",W[i][j]);fprintf(fp,"\n");}fprintf(fp,"调整一次后的V矩阵:\n");for(i=0;i<3;i++){for(j=1;j<3;j++)fprintf(fp,"%f ",V[i][j]);fprintf(fp,"\n");}本程序的输出为输出到文本文件中,结果如下:初始W矩阵:2.0000003.0000001.000000 1.0000000.000000 -2.000000初始V矩阵:3.000000 -1.0000001.0000002.000000-2.000000 0.000000隐层的净输入:-8.000000 3.000000隐层的输出:0.000335 0.952574输出层的净输入:-1.999665 -4.904813输出层的输出:0.119238 0.007356隐层输出的一阶导数:0.000335 0.045177输出层输出的一阶导数:0.105020 0.007302输出层误差:0.087247 0.000311隐层误差:0.000029 -0.000028调整一次后的W矩阵:1.9127532.9996891.000029 1.0000000.083109 -1.999703调整一次后的V矩阵:2.999971 -0.9999721.000029 1.999972-1.999912 -0.0000843.7 批训练BP算法# include <stdio.h>#include<time.h># include <math.h># include <stdlib.h># define N 100# define NUM 1e5 //循环最大次数int IN,HN,ON; //IN为输入层节点数,HN为隐层节点数,ON为输出层节点数double Sig(double x) //单极性函数double y;y=1.0/(1.0+exp(-x));return y;}double DSig(double x) //双极性函数{double y;y=(1.0-exp(-x))/(1.0+exp(-x));return y;}void main(){float x[N][N],V[N][N],W[N][N];float d[N][N],nety[N],neto[N],Y[N],O[N][N],dety[N],deto[N];float D,E,Ep,Emin;float yita;int i,j,k,choose,p,yb;//p用于计数,看样本是否输入完毕,choose用于选择单极性、双极性函数k=0;Emin=1e-5;//输入各层节点数和学习率printf("请输入输入层节点数IN=");scanf("%d",&IN);printf("请输入隐层节点数HN=");scanf("%d",&HN);printf("请输入输出层节点数ON=");scanf("%d",&ON);printf("请输入学习率yita=");scanf("%f",&yita);printf("请输入函数选择参数choose,1代表单极性,2代表双极性:");scanf("%d",&choose);printf("请输入样本总数yb=");scanf("%d",&yb);printf("输入样本(第一个为-1):\n");for(j=0;j<yb;j++)for(i=0;i<=IN;i++)scanf("%f",&x[j][i]);printf("输入期望输出值(在期望值前加0):\n");for(j=0;j<yb;j++)for(i=0;i<=ON;i++)scanf("%f",&d[j][i]);printf("\n");//初始化权值矩阵,取-1到1的随机数for(i=0;i<=IN;i++)for(j=0;j<=HN;j++){srand((unsigned)time(NULL));V[i][j]=(double)((rand()/32767.0)*2-1);}for(i=0;i<=HN;i++)for(j=0;j<=ON;j++){srand((unsigned)time(NULL));W[i][j]=(double)((rand()/32767.0)*2-1);}do{p=0;E=0.0;while(p<yb){/**************************计算隐层的输出*****************************/ for(j=1;j<=HN;j++){nety[j]=0.0;for(i=0;i<=IN;i++)nety[j]=nety[j]+V[i][j]*x[p][i];}Y[0]=-1.0;for(i=1;i<=HN;i++){if(choose==1)Y[i]=Sig(nety[i]);else if(choose==2)Y[i]=DSig(nety[i]);}/*************************计算输出层的输出*****************************/ for(j=1;j<=ON;j++){neto[j]=0.0;for(i=0;i<=HN;i++)neto[j]=neto[j]+W[i][j]*Y[i];}for(i=1;i<=ON;i++){if(choose==1)O[p][i]=Sig(neto[i]);else if(choose==2)O[p][i]=DSig(neto[i]);}/************************求样本的误差累计******************************/ for(i=1;i<=ON;i++)E=E+(d[p][i]-O[p][i])*(d[p][i]-O[p][i]);p++;}Ep=E/2.0;//sqrt(E);/************************计算输出层误差********************************/ for(i=1;i<=ON;i++){if(choose==1)deto[i]=(d[p][i]-O[p][i])*O[p][i]*(1.0-O[p][i]);else if(choose==2)deto[i]=(d[p][i]-O[p][i])*0.5*(1.0-O[p][i]*O[p][i]);}/*************************计算隐层误差*********************************/ for(i=1;i<=HN;i++){D=0.0;for(j=1;j<=ON;j++)D=D+deto[j]*W[i][j];if(choose==1)dety[i]=D*Y[i]*(1.0-Y[i]);else if(choose==2)dety[i]=D*0.5*(1.0-Y[i]*Y[i]);}/***************************调整输出层权值矩阵W*************************/ for(i=1;i<=ON;i++){for(j=0;j<=HN;j++)W[j][i]=W[j][i]+yita*deto[i]*Y[j];}/****************************调整隐层权值矩阵V**************************/ for(i=1;i<=HN;i++){for(j=0;j<=IN;j++)V[j][i]=V[j][i]+yita*dety[i]*x[p][j];}k++;printf("%d\n",k);if(k>NUM){printf("到达最大循环次数");break;}}while(Ep>Emin);//输出结果,验证for(p=0;p<yb;p++){for(i=1;i<=ON;i++)printf("%f\t",O[p][i]);printf("\n");}for(i=1;i<=ON;i++)printf("%f\t",deto[i]);printf("\n");//输出误差printf("%f\tEp=%f\n",E,Ep);//输出调整后的权值矩阵for(i=0;i<=HN;i++){for(j=0;j<=ON;j++)printf("%f ",W[i][j]);printf("\n");}for(i=0;i<=IN;i++){for(j=0;j<=HN;j++)printf("%f ",V[i][j]);printf("\n");}}3.8 字符分类(标准BP算法):# include <stdio.h># include <math.h>#include<time.h># include <stdlib.h># define N 100# define NUM 1e6 //循环最大次数int IN,HN,ON; //IN为输入层节点数,HN为隐层节点数,ON为输出层节点数float Sig(float x) //双极性函数{float y;y=(1.0-exp(-x))/(1.0+exp(-x));return y;}void main(){float x[N][N]={{-1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,0.0,1.0},{-1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},{-1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1}},V[N][N],W[N][N];// floatd[N][N]={{0.0,1.0,-1.0,-1.0},{0.0,-1.0,1.0,-1.0},{0.0,-1.0,-1.0,1.0}},nety[N],neto[N],Y[N],O[N][ N],dety[N],deto[N];//float D,E,Ep,Emin;float yita;int i,j,p,yb;//p用于计数,看样本是否输入完毕long int k;k=0;Emin=0.001;IN=16;ON=3;/******************输入隐层节点数和学习率***********************/printf("请输入隐层节点数HN=");scanf("%d",&HN);printf("请输入学习率yita=");scanf("%f",&yita);printf("请输入样本总数yb=");scanf("%d",&yb);/**************初始化权值矩阵,取-1到1的随机数******************/for(i=0;i<=IN;i++)for(j=0;j<=HN;j++){srand((unsigned)time(NULL));V[i][j]=(double)((rand()/32767.0)*2-1);}for(i=0;i<=HN;i++)for(j=0;j<=ON;j++){srand((unsigned)time(NULL));W[i][j]=(double)((rand()/32767.0)*2-1);}while(k<NUM){p=0;k++;while(p<yb){E=0.0;/**************************计算隐层的输出*****************************/ for(j=1;j<=HN;j++){nety[j]=0.0;for(i=0;i<=IN;i++)nety[j]=nety[j]+V[i][j]*x[p][i];}Y[0]=-1.0;for(i=1;i<=HN;i++)Y[i]=Sig(nety[i]);/*************************计算输出层的输出*****************************/ for(j=1;j<=ON;j++){neto[j]=0.0;for(i=0;i<=HN;i++)neto[j]=neto[j]+W[i][j]*Y[i];}for(i=1;i<=ON;i++)O[p][i]=Sig(neto[i]);/************************求样本的误差累计******************************/ for(i=1;i<=ON;i++)E=E+(d[p][i]-O[p][i])*(d[p][i]-O[p][i]);Ep=sqrt(E);/************************计算输出层误差********************************/ for(i=1;i<=ON;i++)deto[i]=(d[p][i]-O[p][i])*0.5*(1.0-O[p][i]*O[p][i]);/*************************计算隐层误差*********************************/ for(i=1;i<=HN;i++){D=0.0;for(j=1;j<=ON;j++)D=D+deto[j]*W[i][j];dety[i]=D*0.5*(1.0-Y[i]*Y[i]);}/***************************调整输出层权值矩阵W*************************/ for(i=1;i<=ON;i++){for(j=0;j<=HN;j++)W[j][i]=W[j][i]+yita*deto[i]*Y[j];}/****************************调整隐层权值矩阵V**************************/ for(i=1;i<=HN;i++){for(j=0;j<=IN;j++)V[j][i]=V[j][i]+yita*dety[i]*x[p][j];}// printf("%d\n",k);p++;}if(Ep<Emin)break;}//输出结果,验证printf("分类输出结果为:\n");for(p=0;p<yb;p++){for(i=1;i<=ON;i++)printf("%f\t",O[p][i]);printf("\n");}//输出误差printf("Ep=%f\n",E,Ep);printf("运行次数:%d\n",k);}运行结果:《选取不同的隐节点,观察运行结果》隐节点为5时隐节点为6时隐节点为7时隐节点为8时隐节点为9时隐节点为10时隐节点为11时隐节点为12时隐节点为13时3.11函数逼近# include<stdio.h># include<math.h># include <stdlib.h>#include<time.h># define NUM 200# define N 110# define e 1e-10# define pi 3.14159double F(double x){double y;y=1.1*(1-x+2*x*x)*exp(-x*x/2);return y;}double Sig(double x) //单极性函数{double y;y=1.0/(1.0+exp(-x));return y;}double zaosh(){double y;y=(double)(rand()/32767.0/10.0);return y;}void main(){double x[N],o[N],y[N],d[N],dd[N];int i,j,P,p,k=1,HN;double w[N],v[N][N],Do,Dy[N],nety[N],neto,dnety[N],dneto;double yita,E,Ez=0,t,Emin;P=100;FILE *fp;fp=fopen("out.txt","w");if(fopen==NULL){printf("Error!");exit(0);}for(i=1;i<=P;i++)x[i]=-4.0+(i-1)*8.0/(P-1);for(i=1;i<=P;i++){srand((unsigned)time(NULL));d[i]=F(x[i]);dd[i]=d[i]+zaosh();}yita=1.0;HN=80;//printf("输入隐层节点数:\n");// scanf("%d",&HN);//初始化权值矩阵for(j=1;j<=HN;j++){v[0][j]=0;v[1][j]=0;}for(j=0;j<=HN;j++){w[j]=0;}y[0]=-1,x[0]=-1;do{t=0;Ez=0;for(p=1;p<=P;p++){E=0;for(j=1;j<=HN;j++){nety[j]=v[0][j]*x[0]+v[1][j]*x[p];y[j]=Sig(nety[j]);dnety[j]=y[j]*(1-y[j]);}neto=0;for(j=0;j<=HN;j++){neto=neto+w[j]*y[j];}o[p]=neto;dneto=1;E=dd[p]-o[p];Ez=Ez+E;t=t+E*E;Do=(dd[p]-o[p])*dneto; //计算输出层误差for(j=1;j<=HN;j++) //计算隐层误差Dy[j]=Do*w[j]*dnety[j];/*********调整权值矩阵w************/for(j=0;j<=HN;j++)w[j]=w[j]+yita*Do*y[j];/*********调整权值矩阵v************/for(j=1;j<=HN;j++){v[0][j]=v[0][j]+yita*Dy[j]*x[0];v[1][j]=v[1][j]+yita*Dy[j]*x[p];}}Emin=sqrt(t);Ez=Ez/P;k++;if(k>NUM)break;}while(Ez>e||Emin>0.1);printf("%d\n",k);printf("%f\t%f\n",Ez,Emin);for(p=1;p<=P;p++)fprintf(fp,"%f\t%f\t%f\t%f\n",x[p],d[p],o[p],dd[p]);}结果如下图所示,B代表的是函数的真值,C代表的是网路计算值,D代表的是加噪声后的函数输出值:Y A x i s T i t l eX Axis Title。

相关主题