#include "iostream.h" #include "iomanip.h" #define N 20 //学习样本个数 #define IN 1 //输入层神经元数目% P: `) N* ^- A8 E; K0 W' H #define HN 8 //隐层神经元数目 #define ON 1 //输出层神经元数目 double P[IN]; //单个样本输入数据0 I+ ?: ^9 T. U; L& u double T[ON]; //单个样本教师数据- H. n( K+ b# B1 k' P% C# U7 a3 W* r double W[HN][IN]; //输入层至隐层权值 double V[ON][HN]; //隐层至输出层权值! ]; W" R$ G: u3 P double X[HN]; //隐层的输入 double Y[ON]; //输出层的输入5 k3 Q& [, S0 o: L% s double H[HN]; //隐层的输出 double O[ON]; //输出层的输出 double sita[HN]; //隐层的阈值 double gama[ON]; //输出层的阈值# [7 ~! \: h+ c g+ U0 M7 d double err_m[N]; //第m个样本的总误差# R! W4 }% e5 s" ]4 k( ` double alpha; //输出层至隐层的学习效率2 M8 p& Y- ^ f5 p" o4 Q% Z' c double beta; //隐层至输入层学习效率 r0 Z3 [" }. }& M m //定义一个放学习样本的结构. k4 |& J7 F& B" e' `* ~- w' E) N struct { double input[IN];# L p( E! Z3 m1 g double teach[ON]; }Study_Data[N][IN]; ///////////////////////////& M) v3 M; {' I7 I //初始化权、阈值子程序/////! t, T5 q2 H& o# z* a* @* Q ///////////////////////////7 {' @# h) R# I4 B0 Y initial() {: l" |" V7 S( i* Z7 U( B2 ? float sgn;4 @2 x9 C. B5 V, M" I9 P float rnd;. t8 e, y8 A+ ^# Z" t int i,j;% I7 R" g% l! y. ] //隐层权、阈值初始化//# S V" |. L9 O8 o8 T4 d { //sgn=pow((-1),random(100)); sgn=rand(); rnd=sgn*(rand()%100);* K# g2 s7 X( X8 f" i. h! U W[j]= rnd/100;//隐层权值初始化。 } //randomize(); {' ^7 S* l9 A' H //sgn=pow((-1),random(1000));$ z# q7 p2 W. Y; e7 o3 E4 T sgn=rand(); rnd=sgn*(rand()%1000);* x* o w6 R0 t. J9 Q, \ sita[j]= rnd/1000;//中间层阈值初始化9 `3 B" V" G% X( g# P2 }2 } cout<<"sita"<<sita[j]<<endl;9 e$ i4 m4 z, C4 {# y6 M0 C& B" O }5 F& d- V- W. z. Z) h //输出层权、阈值初始化//; F) G* Q; f1 E" p' J5 @ //randomize();4 _& a" q2 h2 v1 X5 a6 B+ D for (int k=0;k<ON;k++) for (int j=0;j<HN;j++) , j/ @8 K, N1 | x- n1 _ { //sgn=pow((-1),random(1000));9 C4 w/ b0 Z0 \5 R( p4 i sgn=rand(); rnd=sgn*(rand()%1000); V[k][j]=rnd/1000;//第m个样本输出层权值初始化 } //randomize(); { //sgn=pow((-1),random(10)); sgn=rand(); rnd=sgn*(rand()%10);4 Q; I$ b8 W# w! P7 C, a; E9 _ gama[k]=rnd/10;//输出层阈值初始化9 F' u0 N3 a c2 z cout<<"gama[k]"<<endl;. Y& m4 I c. B& v# }; \% w } return 1;$ |6 h# B6 B( x% U) a }//子程序initial()结束
$ I& J6 s" K1 D7 ~ @ ////////////////////////////////2 p5 P# J" L# E3 S; }* `6 ]6 N
////第m个学习样本输入子程序///
///////////////////////////////
input_P(int m)9 _" P$ E9 g% k
{) b+ v+ ` o4 [
for (int i=0;i<IN;i++)
P=Study_Data[m]->input;
//获得第m个样本的数据
//cout<<"第"< //fprintf(fp,"第%d个样本的学习输入:
//P[%d]=%f\n",m,P);
return 1;
}//子程序input_P(m)结束" E, d# B) c0 b9 p7 y. J
/////////////////////////////
////第m个样本教师信号子程序//
/////////////////////////////
input_T(int m)
{
for (int k=0;k<m;k++)
T[k]=Study_Data[m]->teach[k];, S& u% Z% p$ g: f6 v4 q- X# H
//cout<<"第"< //fprintf(fp,"第%d个样本的教师信号:T[% d] =%f\n",m,T[k]);
return 1;
}//子程序input_T(m)结束
/////////////////////////////////
//隐层各单元输入、输出值子程序///
/////////////////////////////////
H_I_O(){3 S1 j9 a& L+ F9 Q' Q
double sigma;
int i,j;- @. D; |8 H, S+ m
for (j=0;j<HN;j++)1 }. Y8 n0 z4 A1 T9 U9 r! F( b
sigma=0.0;
for (i=0;i<IN;i++)
sigma+=W[j]*P;//求隐层内积0 e) Q. I1 Z" s6 o8 H# R) ?9 ~- a3 @
}- G$ L$ k4 {# P, G* A- n
X[j]=sigma - sita;//求隐层净输入5 |2 t' b: _6 _9 t
H[j]=1.0/(1.0+exp(-X[j]));//求隐层输出
}4 l( k, G; v- P. r# L
return 1;
}//子程序H_I_O()结束' B! I/ H3 y2 j6 O( j/ b
///////////////////////////////////, r, h" M0 V7 Z. p
//输出层各单元输入、输出值子程序///2 ?; ]9 [/ M6 r
///////////////////////////////////
O_I_O()9 F. W6 t. t* d
{5 H+ T; {$ u5 ?( |* k$ {. }) B/ j8 W
double sigma;
for (int k=0;k<ON;k++)7 c' q6 w6 Q+ q7 p+ S
sigma=0.0;
for (int j=0;j<HN;j++)
sigma+=V[k][j]*H[k];//求输出层内积3 {3 O6 I: h9 o% ?7 ~( w
}
Y[k]=sigma-gama[k]; //求输出层净输入- @ r* i1 U N6 Y
O[k]=1.0/(1.0+exp(-Y[k]));//求输出层输出
}3 s) f" M; X1 x. ^
return 1;7 D- ~4 D9 x8 T% F
}//子程序O_I_O()结束
////////////////////////////////////# j2 q) f/ G5 `/ s) c+ l9 M) ]
//输出层至隐层的一般化误差子程序////2 {! u7 P+ c6 y! e6 F$ c
////////////////////////////////////
double d_err[ON];
Err_O_H(int m)
{
double abs_err[ON];//每个样本的绝对误差都是从0开始的6 P5 E* S5 f1 F5 H
double sqr_err=0;//每个样本的平方误差计算都是从0开始的
//for (int output=0;output<ON;output++) //output???8 ]3 J+ v6 {0 _2 }! K6 x
for (int k=0;k<ON;k++)
abs_err[k]=T[k]-O[k];8 ?" p3 I- P* V' [2 q( q; U
//求第m个样本下的第k个神经元的绝对误差# z8 I* `% q# ~: V( p
sqr_err+=(abs_err[k])*(abs_err[k]);//求第m个样本下输出层的平方误差
d_err[k]=abs_err[k]*O[k]*(1.0-O[k]);//d_err[k]输出层各神经元的一般化误差
}
err_m[m]=sqr_err/2;//第m个样本下输出层的平方误差/2=第m个样本的均方误差
return 1;, H4 _* M$ p( I! C, h
}//子程序Err_O_H(m)结束
////////////////////////////////////! Q9 j( ]+ _$ |: F8 v M% v
//隐层至输入层的一般化误差子程序////
////////////////////////////////////8 S. t# R2 Y9 d- i9 f- \# h
double e_err[HN];+ s! c" d! |. l% ~/ ~
Err_H_I(){; J' R7 h0 ^7 Q. `# F/ d, z
double sigma;
//for (int hidden=0;hidden/ h- @! e7 F* W; P
for (int j=0;j<HN;j++)
sigma=0.0;
for (int k=0;k<ON;k++) o6 B3 P' E3 l6 x' V
sigma=d_err[k]*V[k][j];
}5 y. b& C% j0 y3 K6 `0 D; m7 ]
e_err[j]=sigma*H[j]*(1-H[j]);//隐层各神经元的一般化误差
}
return 1;7 q0 l2 Z; `+ K" N+ ?6 [
}//子程序Err_H_I()结束) ^; j; ]8 B4 S3 o
////////////////////////////////////////////////////////& F) I6 a* _" b+ C3 D
//输出层至隐层的权值调整、输出层阈值调整计算子程序//////7 d8 A5 T5 D0 ]0 v7 S
////////////////////////////////////////////////////////
Delta_O_H(int m,FILE* fp)
{" g0 H% k ?/ Q* b& @" [
for (int k=0;k<ON;k++)
for (int j=0;j<HN;j++)6 j1 b+ K1 `* p( b5 Q6 ~
//cout<<"第"<
fprintf(fp,"第%d个样本时的输出层至隐层的权值为:%f\n",m,W[k][j]);
V[k][j]+=alpha*d_err[k]*H[j];//输出层至隐层的权值调整
}
gama[k]+=alpha*d_err[k];//输出层至隐层的阈值调整3 E9 K; w$ e) z7 e0 P* R
}
return 1;* | ]/ q: t# G' a6 \% P" ^$ W! F
}//子程序Delta_O_H()结束+ e) F) o: \+ ^: B \
/////////////////////////////////////////////////////. z/ E" [' Z" }( x$ Z; M0 w
//隐层至输入层的权值调整、隐层阈值调整计算子程序/////
/////////////////////////////////////////////////////
Delta_H_I(int m,FILE* fp)# e" M6 L! r/ l" U3 F! W
{
for (int j=0;j<HN;j++)8 E7 j" P" D: `, V$ ~# \4 P6 G" O
for (int i=0;i<IN;i++) $ _1 O7 Z! P: P0 f7 e
//cout<<"第"< fprintf(fp,"第%d个样本时的输出层至隐层的权值为:%f\n",m,V[j]);
W[j]+=beta*e_err[j]*P;//隐层至输入层的权值调整
}
sita[j]+=beta*e_err[j];
}
return 1; E' B" c/ n8 A/ O% }
}//子程序Delta_H_I()结束
/////////////////////////////////! C: D7 }" G2 q z3 R
//N个样本的全局误差计算子程序////5 J+ {& c5 [! Y! o" u# |
/////////////////////////////////
double Err_Sum()0 a. q4 @7 O# y6 `
{1 c- X, p" y9 ?& c; I: P C
double total_err=0;
for (int m=0;m<N;m++) q' G" J5 T% z: V* e. k
total_err+=err_m[m];//每个样本的均方误差加起来就成了全局误差, _2 E- w# U& f( c
}
return 1;0 a; f2 D6 U4 y: r. p
}//子程序Err_sum()结束
/**********************/5 ^. ]$ @0 _# Y' C; m; d
/**程序入口,即主程序**// r: L9 S. D/ A& u& C+ g
/**********************/
main()% v! |4 Q4 l' Q5 D' L1 L- h
{3 k1 t* @8 J4 ]3 y/ m
FILE *fp;
double sum_err;
int study;//训练次数' V% h% u7 p( {. p2 P2 P
if ((fp=fopen("bp.txt","a+"))==NULL)
{+ m: s. k5 ]: Q( ~; u) F
printf("不能创建bp.txt文件!\n");6 z7 U, e' ?0 W" g6 W( z! Z* L! T
exit(1);
}/ I: L2 h5 O6 H" z: V
cout<<"请输入输出层到隐含层学习效率: alpha=\n";1 n( J1 Z) b! [- b% D3 c& ?
cin>>alpha;
cout<<"请输入隐含层到输入层学习效率: beta=\n";9 _0 S) U# o: o' a# |
cin>>beta;
int study=0; //学习次数+ O$ u2 H! I1 l4 d9 q, V
double Pre_error ; //预定误差
cout<<"请输入预定误差: Pre_error= \n";# u# Q( e3 a6 @# `% Z
cin>>
re_error;7 J, W7 S2 p. i- N! f/ q6 b
int Pre_times;* J/ l2 E% _9 x$ I# M8 ]
cout<<"请输入预定最大学习次数
re_times=\n";& |) `- x3 C4 O+ z6 e/ K
cin>>
re_times;
cout<<"请输入学习样本数据\n";
{
for (int m=0;m<N;m++)* _& S6 V7 M$ z+ d' m7 I
cout<<"请输入第"<<m+1<<"组学习样本"<<endl;
for (int i=0;i<IN;i++)" Y! Z7 |5 ^! I; R
cin>>Study_Data[m]->input;. m9 r: B: x- l1 U$ u
}
{
for (int m=0;m<N;m++) Y5 m1 g% E" b0 b7 h0 Z
cout<<"请输入第"<<m+1<<"组教师样本"<<endl; $ o/ e5 Z8 f9 _& A; i) }
for (int k=0;k<ON;k++)
cin>>Study_Data[m]->teach[k];% V7 J ~8 J) {7 k" g
}7 \! G/ F& ], ~ L: F5 o
initial(); //隐层、输出层权、阈值初始化 (1) 1 i1 J" P8 @+ U
do
{3 I2 {, @2 C; d' I& `: U
++study; ///???
for (int m=0;m<N;m++) 8 F) X, L& n& X
{0 Z' ]; g. h1 q8 G( `' T" K
input_P(m); //输入第m个学习样本 (2)0 }& d- D3 U( p4 d; @
input_T(m);//输入第m个样本的教师信号 (3)
H_I_O(); //第m个学习样本隐层各单元输入、输出值 (4)
O_I_O(); //第m个学习样本输出层各单元输入、输出值 (5)
Err_O_H(m); //第m个学习样本输出层至隐层一般化误差 (6)
Err_H_I(); //第m个学习样本隐层至输入层一般化误差 (7)
Delta_O_H(m,fp); //第m个学习样本输出层至隐层权阈值调整、修改 (8)
Delta_H_I(m,fp); //第m个学习样本隐层至输入层权阈值调整、修改 (9): z6 E: X! v$ C* ~6 U9 o
} //全部样本训练完毕$ z/ B$ H! N, w1 B1 b( y
sum_err=Err_Sum(); //全部样本全局误差计算 (10)
{
cout<<"第"<<study<<"次学习的均方误差为"<<sum_err<<endl;$ ]$ N, |7 k/ s
fprintf(fp,"第%d次学习的均方误差为:%f\n",study,sum_err);3 t0 {+ `7 x! _2 \7 Q( ]- o6 l! K3 R
}4 Y' ~, T% l$ {0 t! l+ s
while (sum_err > Pre_error) //or(study4 H& i% l% {$ o! M" n1 F0 f9 S
{ //N个样本全局误差小于预定误差否? 小于则退出 (11): a5 T" j) q/ H- I
cout<<"网络已经学习了"<<study<<"次,学习的均方误差为"<<sum_err<<endl;1 H7 |; i: {* p5 I8 P6 j
fprintf(fp,"网络已经学习了%d次,现在的全局误差为:%f\n",study,total_err);3 h& \4 ]2 h3 l/ v5 G* v8 _
fclose(fp);
}- Y4 Y1 F4 d9 f/ l! O. ^8 C
char s;
cout<<"请随便输入一个字符,按回车退出程序!\n";
cin>>s;
return 1;
}
笑死了,垃圾程序。这个只能是c 程序
而且还不收敛
误差只能到1
里面还有许多bug
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) | Powered by Discuz! X2.5 |