#include "iostream.h"/ F) P- E8 t1 u. Q# s- t( n #include "iomanip.h"7 x. {) p! d) P3 s- B! L; w #define N 20 //学习样本个数/ x* C2 t( i. u4 h+ T- z$ u #define IN 1 //输入层神经元数目- y& p" d' ~% \, G2 M5 h #define HN 8 //隐层神经元数目3 x C( G, u1 ?) q3 ^3 k #define ON 1 //输出层神经元数目; \8 l y6 C% J# l double P[IN]; //单个样本输入数据 double T[ON]; //单个样本教师数据 double W[HN][IN]; //输入层至隐层权值0 X- o; e( ~. l9 G1 a double V[ON][HN]; //隐层至输出层权值 double X[HN]; //隐层的输入) H- P7 z; c% k5 k6 Z double Y[ON]; //输出层的输入7 ` ^1 ^8 Q' B6 M! }# u double H[HN]; //隐层的输出, J2 M/ l0 \$ y1 ~7 p5 I* m, v double O[ON]; //输出层的输出 double sita[HN]; //隐层的阈值, v# K4 l$ `% I7 N. c* f* V+ Y1 y double gama[ON]; //输出层的阈值& M' I) F2 Q0 i; A double err_m[N]; //第m个样本的总误差 double alpha; //输出层至隐层的学习效率 double beta; //隐层至输入层学习效率 //定义一个放学习样本的结构# x8 T* D7 |: C) b struct {( S) A8 u a- r6 c* u1 u double input[IN]; double teach[ON];. f4 l+ z8 J; r6 r }Study_Data[N][IN];& {: n7 N8 W. J2 s1 w- P5 F /////////////////////////// //初始化权、阈值子程序/////" W' z W% e: N6 s: ? ///////////////////////////% H4 n0 G3 {2 q6 E: O initial() {# H/ ?+ F1 F! v* F5 f float sgn; float rnd;- X; j. c' s7 Z) k$ l9 M( Y int i,j;2 S5 V, l6 ~/ z1 x# C0 \! Q& A //隐层权、阈值初始化// {" i9 }! j W; x" S //sgn=pow((-1),random(100)); sgn=rand();+ K; ]# ]9 s0 J, i- T rnd=sgn*(rand()%100);% U7 } `+ ^ H" Z W[j]= rnd/100;//隐层权值初始化。 } //randomize(); {8 n" S2 C J% T2 e. P C1 w$ o //sgn=pow((-1),random(1000));" a" H+ y' T$ ]- c$ A& c0 y sgn=rand(); rnd=sgn*(rand()%1000);( \7 H. G; W+ P- [6 s' I( P+ P sita[j]= rnd/1000;//中间层阈值初始化9 d2 d4 M v4 f+ d cout<<"sita"<<sita[j]<<endl; }+ D9 R" t7 K! c( @ //输出层权、阈值初始化// //randomize();% T. c' c1 f$ P0 J6 G for (int k=0;k<ON;k++)5 K2 ?* E) U, v% m6 m for (int j=0;j<HN;j++) 1 X$ m$ P$ r% q { //sgn=pow((-1),random(1000));: l0 B# u& t5 W _. M sgn=rand(); rnd=sgn*(rand()%1000);# z5 D/ V4 [3 _# }0 r V[k][j]=rnd/1000;//第m个样本输出层权值初始化 } //randomize(); {' ?& j' b: M6 i" h //sgn=pow((-1),random(10)); sgn=rand(); rnd=sgn*(rand()%10);% x5 r* \3 X) s1 Q( N& B; s, Y gama[k]=rnd/10;//输出层阈值初始化 N% E; c, E1 u- f9 z, z cout<<"gama[k]"<<endl; } return 1;9 O2 m/ e3 {2 u6 K0 U+ ~2 P0 h& ^ }//子程序initial()结束
0 a4 u0 f, |& c. L: n+ s ////////////////////////////////
////第m个学习样本输入子程序///* w1 B- {# f1 h: Z% X
///////////////////////////////9 X+ s5 d+ ~9 ]5 F
input_P(int m)
{) E8 d% G$ \: e6 w2 g
for (int i=0;i<IN;i++)
P=Study_Data[m]->input;. H- I$ T0 A1 h* H
//获得第m个样本的数据
//cout<<"第"< //fprintf(fp,"第%d个样本的学习输入:
//P[%d]=%f\n",m,P);
return 1;0 r6 Q# m. K+ P" `/ y z, @" J
}//子程序input_P(m)结束6 o6 J3 j- _' d7 U! W8 Q
/////////////////////////////
////第m个样本教师信号子程序//7 k- ^6 l* a }# `
/////////////////////////////
input_T(int m)
{; M0 z" X! w# v% R) t
for (int k=0;k<m;k++)8 X, z3 ^1 t+ z0 v+ e& A
T[k]=Study_Data[m]->teach[k];
//cout<<"第"< //fprintf(fp,"第%d个样本的教师信号:T[% d] =%f\n",m,T[k]);
return 1;
}//子程序input_T(m)结束
/////////////////////////////////5 V9 l/ e0 A2 o U
//隐层各单元输入、输出值子程序///( S0 i$ c! r: a2 A; o- ^
/////////////////////////////////4 o3 u! H. ~- p1 S9 ^" Y
H_I_O(){
double sigma;- O: `! d5 ^; e8 p9 t. L& t' L3 I+ e
int i,j;
for (j=0;j<HN;j++)
sigma=0.0;7 f6 H: b% d5 Q
for (i=0;i<IN;i++)
sigma+=W[j]*P;//求隐层内积
}
X[j]=sigma - sita;//求隐层净输入
H[j]=1.0/(1.0+exp(-X[j]));//求隐层输出
}
return 1;0 y) Q# F9 J* h# I* h# s8 V
}//子程序H_I_O()结束8 C1 y& y; H1 T5 G
///////////////////////////////////! f( b8 n/ D! z
//输出层各单元输入、输出值子程序///
///////////////////////////////////( |9 `6 D+ Y) s S" }
O_I_O()
{
double sigma;/ P) {4 G( E2 M
for (int k=0;k<ON;k++)8 @# W9 X% w: d: y K7 ^2 X: P
sigma=0.0;/ D5 Q* Q( i4 `. }7 {8 N K/ W
for (int j=0;j<HN;j++)8 T- K! X( A$ R& U2 ~. Y; W
sigma+=V[k][j]*H[k];//求输出层内积2 J) G/ a5 W: p' s! r
}. T6 L1 U5 Q9 p! ~* I" _( s
Y[k]=sigma-gama[k]; //求输出层净输入
O[k]=1.0/(1.0+exp(-Y[k]));//求输出层输出
}
return 1;9 l0 R1 S% M/ t5 h
}//子程序O_I_O()结束
////////////////////////////////////$ n1 E: d! |& j( b/ L, l. A
//输出层至隐层的一般化误差子程序////8 M$ l6 }3 l& P
////////////////////////////////////+ J7 J3 j9 G9 t7 a" |0 M
double d_err[ON];+ E/ l/ ?# U2 `9 B
Err_O_H(int m)& J) Y1 _% Q5 p& [4 v
{
double abs_err[ON];//每个样本的绝对误差都是从0开始的# n+ F* u) r) _" Q
double sqr_err=0;//每个样本的平方误差计算都是从0开始的" h$ h9 f: Y6 L# Q" I; m' d
//for (int output=0;output<ON;output++) //output???7 P' w* w7 _ a' w1 k
for (int k=0;k<ON;k++)( i0 b2 d. t, \2 ]) R+ S' w
abs_err[k]=T[k]-O[k];
//求第m个样本下的第k个神经元的绝对误差
sqr_err+=(abs_err[k])*(abs_err[k]);//求第m个样本下输出层的平方误差
d_err[k]=abs_err[k]*O[k]*(1.0-O[k]);//d_err[k]输出层各神经元的一般化误差- u: C! S% h0 H4 g2 I# F
}
err_m[m]=sqr_err/2;//第m个样本下输出层的平方误差/2=第m个样本的均方误差$ M, r7 G( [8 i( c9 e7 V
return 1;
}//子程序Err_O_H(m)结束' \( g# v& p+ T" s
////////////////////////////////////% E* u# J! Q3 E- h/ L# Z( r
//隐层至输入层的一般化误差子程序////
////////////////////////////////////
double e_err[HN];
Err_H_I(){
double sigma;
//for (int hidden=0;hidden4 W( c% q, M7 b4 k/ s. G* L: K z
for (int j=0;j<HN;j++) ) \+ z: t6 ?9 Y$ i
sigma=0.0;2 Y$ R9 Q& |6 \3 ~; ~# w
for (int k=0;k<ON;k++) 1 k5 m+ m; p" x( U1 w# ^
sigma=d_err[k]*V[k][j];, K* P" Y% A" L$ d( L _- a
}
e_err[j]=sigma*H[j]*(1-H[j]);//隐层各神经元的一般化误差
}9 {- W' p% e0 Q% ]1 ^) S) k
return 1;
}//子程序Err_H_I()结束
////////////////////////////////////////////////////////
//输出层至隐层的权值调整、输出层阈值调整计算子程序/////// V0 f1 b# q! }0 I
////////////////////////////////////////////////////////; M3 @/ R$ q) p3 N
Delta_O_H(int m,FILE* fp)
{% _" @1 P1 b* G- U! y8 q
for (int k=0;k<ON;k++)
for (int j=0;j<HN;j++)
//cout<<"第"< 6 k2 y% T# E k
fprintf(fp,"第%d个样本时的输出层至隐层的权值为:%f\n",m,W[k][j]);& G" o: i; E. v1 ^: k7 u
V[k][j]+=alpha*d_err[k]*H[j];//输出层至隐层的权值调整3 F$ t4 l+ I7 n8 b d
}3 Y! m1 ^3 R3 P5 H' J: W
gama[k]+=alpha*d_err[k];//输出层至隐层的阈值调整- _+ V- K+ ^* R6 c+ T( ^
}& ~- x1 |& e8 |
return 1;
}//子程序Delta_O_H()结束- D" x$ |+ Z: y0 F b6 ^
/////////////////////////////////////////////////////# n9 s! g! X( G! {6 F
//隐层至输入层的权值调整、隐层阈值调整计算子程序/////
/////////////////////////////////////////////////////
Delta_H_I(int m,FILE* fp)0 k D! _. u# Z: k( q i% p
{! l \5 S3 i" Y+ _* m) A
for (int j=0;j<HN;j++)
for (int i=0;i<IN;i++) 2 z) r: x# {: s
//cout<<"第"< fprintf(fp,"第%d个样本时的输出层至隐层的权值为:%f\n",m,V[j]);
W[j]+=beta*e_err[j]*P;//隐层至输入层的权值调整
}
sita[j]+=beta*e_err[j];9 W" j4 g/ `" ]6 P+ [
}# W: u3 _7 |& i
return 1;
}//子程序Delta_H_I()结束9 Z1 V% q4 P- F( j( a {
/////////////////////////////////
//N个样本的全局误差计算子程序////- Q9 X( I0 U- K5 t- r+ n/ j2 o4 h R
/////////////////////////////////
double Err_Sum()& N2 T" f) P4 b% b7 u [ p9 `) R
{
double total_err=0;
for (int m=0;m<N;m++) 9 C+ L& j" r/ ~" A/ Q, r% {
total_err+=err_m[m];//每个样本的均方误差加起来就成了全局误差" C: p: [9 }! }/ e. ?5 W
}: H" _' B9 W; e9 R1 l
return 1;
}//子程序Err_sum()结束
/**********************/
/**程序入口,即主程序**/
/**********************// ^2 a3 X/ H# q8 \3 f6 b/ Y
main()5 z: g" A6 y; U) x! }! K% w
{! v0 [" v# `- y8 g# v3 y5 d2 X; I7 `
FILE *fp;
double sum_err;3 B- M# I: d d+ M4 A" u
int study;//训练次数
if ((fp=fopen("bp.txt","a+"))==NULL); K, y T$ @% r: k# C
{
printf("不能创建bp.txt文件!\n");
exit(1);
}6 _ y+ d! A0 [8 R9 y- h( J0 C
cout<<"请输入输出层到隐含层学习效率: alpha=\n";9 Z" B7 z& |8 ^8 E* V$ z
cin>>alpha;
cout<<"请输入隐含层到输入层学习效率: beta=\n";
cin>>beta;
int study=0; //学习次数
double Pre_error ; //预定误差2 x! Q: T* j z( w, Z
cout<<"请输入预定误差: Pre_error= \n";
cin>>
re_error;9 ^4 v! C% X6 k! [( r. a% x7 k
int Pre_times;
cout<<"请输入预定最大学习次数
re_times=\n";! y v+ Q' i' y; F
cin>>
re_times;
cout<<"请输入学习样本数据\n";& Z7 ?! K( S, V" A
{
for (int m=0;m<N;m++)) @; u f6 p/ P4 u! ?' ^
cout<<"请输入第"<<m+1<<"组学习样本"<<endl;
for (int i=0;i<IN;i++)8 S4 U7 u2 [( [% e
cin>>Study_Data[m]->input;
}0 R- @9 a3 f8 I+ f7 Y
{
for (int m=0;m<N;m++)- @* A9 D, d3 i, T0 [0 a1 r1 ]' [
cout<<"请输入第"<<m+1<<"组教师样本"<<endl;
for (int k=0;k<ON;k++), w1 E7 M& t$ h9 f/ m3 G( ]' {
cin>>Study_Data[m]->teach[k];5 I! w" U( y) i i& Y7 I
}
initial(); //隐层、输出层权、阈值初始化 (1) 6 r1 J) t s* h1 N
do" {, u. I X* W1 L6 R+ K& @
{0 r; d8 |, T! ^9 I9 P
++study; ///???
for (int m=0;m<N;m++) 4 i& ` ^. Z1 Z+ N! y6 W
{) \+ n- O: z3 G p- r0 V1 }0 A
input_P(m); //输入第m个学习样本 (2)
input_T(m);//输入第m个样本的教师信号 (3)0 x1 M/ J% Y( r
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)
} //全部样本训练完毕
sum_err=Err_Sum(); //全部样本全局误差计算 (10)
{( b% A+ T' C) |/ w( J6 n+ C5 @
cout<<"第"<<study<<"次学习的均方误差为"<<sum_err<<endl;3 x, f" A5 v, O0 a# ^
fprintf(fp,"第%d次学习的均方误差为:%f\n",study,sum_err);0 q4 O. a/ c" J, f4 y; N
}5 g5 b4 v4 L, p3 i, l
while (sum_err > Pre_error) //or(study
{ //N个样本全局误差小于预定误差否? 小于则退出 (11)9 M" `, l5 k$ N8 j7 A2 H
cout<<"网络已经学习了"<<study<<"次,学习的均方误差为"<<sum_err<<endl;: e0 I3 e& K1 z; c
fprintf(fp,"网络已经学习了%d次,现在的全局误差为:%f\n",study,total_err);$ t; G( Y$ c7 b0 n7 r3 J- R4 y
fclose(fp);: f! B$ x8 H, _3 A, Z- H
}' F* A9 S; n/ L7 c7 j7 k
char s;
cout<<"请随便输入一个字符,按回车退出程序!\n";
cin>>s;6 b+ j7 l z9 o
return 1;
}
笑死了,垃圾程序。这个只能是c 程序
而且还不收敛
误差只能到1
里面还有许多bug
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) | Powered by Discuz! X2.5 |