数学建模社区-数学中国

标题: [转帖]C++的BP算法源程序 [打印本页]

作者: ilikenba    时间: 2004-12-15 21:18
标题: [转帖]C++的BP算法源程序

+ z6 H+ u. }/ n& d5 k1 J
$ T! {) u" O; q6 @; `

#include "iostream.h", ^) v, d& n, Y% ^: ? #include "iomanip.h"* w) X/ b( k" h5 M" L7 P0 p/ n #define N 20 //学习样本个数 ) X1 ^: I) \* B #define IN 1 //输入层神经元数目 / @* x9 h' l v5 ? #define HN 8 //隐层神经元数目 5 }" b* o/ w5 ^6 j" j7 [' G+ Q4 I #define ON 1 //输出层神经元数目. \2 d- k. s: f3 c# v( p double P[IN]; //单个样本输入数据3 W% c i( A) |- W double T[ON]; //单个样本教师数据" f4 C" b6 D; v6 D$ z0 @8 U; P: V double W[HN][IN]; //输入层至隐层权值 ; T: s( N6 D, F/ F8 O: w double V[ON][HN]; //隐层至输出层权值' |, v, U* L% ~+ C7 P; S! K double X[HN]; //隐层的输入 l* e: C q, U& z( W4 u. ? double Y[ON]; //输出层的输入 ! K4 t4 s0 O2 t+ _' } double H[HN]; //隐层的输出 1 v7 K0 h; o& ?5 _% @9 O double O[ON]; //输出层的输出 4 O( J7 c9 z. ? double sita[HN]; //隐层的阈值# t4 p% P+ A- p [2 n double gama[ON]; //输出层的阈值 6 o" V2 f! K4 d7 M double err_m[N]; //第m个样本的总误差: ~% [$ l8 C; c double alpha; //输出层至隐层的学习效率( o. r% a9 k* r @( S# ` double beta; //隐层至输入层学习效率 0 P- i! Z: u; v y2 D5 T" y //定义一个放学习样本的结构8 O- }" R, Q5 X2 T3 F5 O; y struct {! y8 |+ C0 K) S7 L$ Q) h double input[IN]; 5 k+ d8 v, i/ P4 j7 m2 Z4 } double teach[ON]; 6 a" ?$ u8 I" Y }Study_Data[N][IN]; 8 V& x/ b( T8 m" s# Z, E; j0 ~% M $ [+ G+ I) R1 d m, @0 F# J' w* T /////////////////////////// 7 ~* [: P! i9 A8 l7 | b& ]; L //初始化权、阈值子程序/////5 k _ C4 t9 ^# X /////////////////////////// . d) J( p/ ]* {9 n4 t! c- p/ V initial()4 d3 H( B( m/ v2 s3 L# b! ~/ h { |( K: v9 x4 }% k* m3 `5 U8 C float sgn; . d# X3 b" C2 A* G1 M float rnd;4 ^( ?8 J+ ^1 [0 q1 G int i,j; % ^% h/ D' ]; s0 @ //隐层权、阈值初始化// # W, L/ `7 I! E4 T% ^* A% b" ] {8 h! o! j* G; t; z //sgn=pow((-1),random(100));9 b; [7 G! o; v5 T3 b' g/ B sgn=rand();, z4 D+ g4 L& p# ^ |* u rnd=sgn*(rand()%100); |, P6 `5 }: |' y8 Q: s5 f W[j]= rnd/100;//隐层权值初始化。 " X0 W! J- k% i; g ~ }) ^- n/ z0 j# t //randomize(); # U. U+ @, n9 k" N V" |7 i# G, G5 \ { o4 k1 z, l/ |/ Q* E //sgn=pow((-1),random(1000));2 w: j6 O6 Q+ k( @0 o7 j6 o4 [ sgn=rand(); 2 q: q8 `4 n3 y2 i+ x rnd=sgn*(rand()%1000);3 e0 @' \- ^9 K" ` sita[j]= rnd/1000;//中间层阈值初始化6 v% r z$ R- g1 F cout<<"sita"<<sita[j]<<endl; / l m, ]! i# H+ ~! Q } * F x7 S. i9 J5 I: V+ S# N //输出层权、阈值初始化// ( J! u/ _6 f0 v: z( c //randomize();* Y# g1 E+ X: U4 N' _ for (int k=0;k<ON;k++)6 R0 E5 Q( O6 f# Q$ Z: u for (int j=0;j<HN;j++) 8 R% ?/ ^ b( W7 ` { ) i6 ]3 h+ x# S T6 x //sgn=pow((-1),random(1000));- |* o; o1 o7 y) B sgn=rand(); w0 g0 g5 s" h7 @, a rnd=sgn*(rand()%1000); * M9 C) M1 l/ A+ x- j V[k][j]=rnd/1000;//第m个样本输出层权值初始化 ! Z5 B" n$ v! i) j! [3 [ } 6 |$ Z6 A- c# t, ~1 ` //randomize();7 d4 H# v6 R5 ^" S. s1 u) } {% O5 G4 o( e( x //sgn=pow((-1),random(10)); }7 H! z4 y D9 p1 Z4 E9 ^ sgn=rand();2 P) O. X- Q9 d+ h* \ rnd=sgn*(rand()%10); C& X3 n. k* s3 S2 o% O, ]6 ~ gama[k]=rnd/10;//输出层阈值初始化 : ~4 N2 A4 Y6 H- d/ t P& V6 o cout<<"gama[k]"<<endl; ' A: Q5 W: {% D: u8 C } - {9 T* \4 b6 p k _# ? return 1;/ ?, W! w' P8 V5 @9 b% Z2 Y : i1 m( B% a9 t7 F' i# p }//子程序initial()结束

7 s- s8 t; c7 R \3 {# {) F

////////////////////////////////, p# _7 L3 y0 X3 G ////第m个学习样本输入子程序/// 6 s& K& f( R K; v& n ///////////////////////////////0 A0 W5 y1 X, o- K0 Z8 _' O6 F1 T input_P(int m) 3 [6 }) W& M9 L { 1 v4 n$ f' e1 ?5 b- a" e) P+ k for (int i=0;i<IN;i++) z* O q' x7 X5 @1 W P=Study_Data[m]->input;& ~5 J( T8 O) T9 M //获得第m个样本的数据1 I M$ k c5 ]! I4 U+ u //cout<<"第"< //fprintf(fp,"第%d个样本的学习输入: 4 m @* m; b6 S, I9 O0 x4 z$ }( g: \ //P[%d]=%f\n",m,P); ! p# \ ]) ~8 l7 ?3 g& w return 1; 8 j+ T# v9 I1 q- w" C p }//子程序input_P(m)结束1 H% |: E7 \6 A- P6 v& v& }& W7 n /////////////////////////////* z4 ?$ l* j W+ f- s# I# n" O ////第m个样本教师信号子程序//+ ?+ t' ~, _' s8 V /////////////////////////////: S* B- H$ r3 O7 y) `8 y4 ~( j9 G& x* ] input_T(int m), ]+ R4 N. @, s" t' j& @" E* h# i/ g. { { 8 d- q. ^7 S; X$ V for (int k=0;k<m;k++): p2 a4 P) E, b( S+ F5 i# ~ T[k]=Study_Data[m]->teach[k];; G: C: ]7 ?& e0 d8 J //cout<<"第"< //fprintf(fp,"第%d个样本的教师信号:T[% d] =%f\n",m,T[k]);: L9 s( E {( s& B- s: x return 1;) h! \4 Y: }- R% B s1 g: m }//子程序input_T(m)结束 ) Q% m. k: d. G; j- s /////////////////////////////////0 U" I- A+ V0 j9 [8 A //隐层各单元输入、输出值子程序///# {9 k, Y) G7 F7 } ///////////////////////////////// ( u5 O# c$ X& t! j8 U1 d ` H_I_O(){ 3 y2 c) c3 I! |- D double sigma;7 k. C/ n( B( w int i,j;6 k4 P+ @8 F b for (j=0;j<HN;j++) 5 K* X% A- [ r$ B: Y) m sigma=0.0; ) z$ c- ]! B& O* k6 u" f for (i=0;i<IN;i++)" a: Y) O/ i3 B f sigma+=W[j]*P;//求隐层内积& ~1 o& P- z/ i Q s& s } 9 o4 u( s, r# Q" t j/ ? X[j]=sigma - sita;//求隐层净输入 % i1 T' T5 r/ }3 Z7 y H[j]=1.0/(1.0+exp(-X[j]));//求隐层输出1 C* v+ ^. Y# e }' Y( S8 A3 E* U) ~9 ^% }( | return 1;9 C& t/ U E5 i0 B3 v4 a9 f7 f }//子程序H_I_O()结束 Z+ p7 x m$ Q /////////////////////////////////// 1 f2 Y( t5 y3 v; j( P //输出层各单元输入、输出值子程序/// 2 g$ F3 {2 X1 C' S /////////////////////////////////// 4 o' e8 V! e/ E6 P: f3 H O_I_O() + l; j5 l) H7 | r+ a { # b$ R4 _- }3 C6 Q7 q double sigma; " Y' ^! p; X2 g+ h for (int k=0;k<ON;k++) 9 u: m$ o' j* y0 x- n sigma=0.0; ; P# U: `$ k0 H for (int j=0;j<HN;j++)% q- }* X. ^& c1 Y1 E3 A* F! O sigma+=V[k][j]*H[k];//求输出层内积 ! J, k1 h% X. S( ^ } 2 C$ U& l5 [+ e- s# C- N; C Y[k]=sigma-gama[k]; //求输出层净输入 " R$ H, ~7 o9 n O[k]=1.0/(1.0+exp(-Y[k]));//求输出层输出 + G. j/ }7 Z8 `- X4 y* y$ V, n3 l }8 ~! J+ ?; h \- _* I( | return 1;* d1 {0 l! G3 [2 K& Y- ^ z2 c1 K" \1 | }//子程序O_I_O()结束 , k3 S- ]# I# E; J //////////////////////////////////// 1 w( {6 q f8 n- p' k //输出层至隐层的一般化误差子程序//// z+ O9 L* Z1 s0 z: c9 J( k5 f ////////////////////////////////////7 z2 e- G' B) \' i double d_err[ON];7 ^7 _0 O5 u: _4 W( t) R; X Err_O_H(int m)* L& M8 t/ S# z/ ~5 N# {6 b8 B: H8 a {! B$ x7 x8 P; r* N4 p9 _0 O. P double abs_err[ON];//每个样本的绝对误差都是从0开始的6 l- k: \: p' [5 Z- [ double sqr_err=0;//每个样本的平方误差计算都是从0开始的' K/ ?- w" F& _4 P! _, s( |2 b! w8 T //for (int output=0;output<ON;output++) //output???( K$ D U$ m3 L5 G( P* Z/ R& { for (int k=0;k<ON;k++)4 R3 q7 G3 q: p* W3 W# s4 y abs_err[k]=T[k]-O[k];+ m k/ D" u/ c" w |$ r //求第m个样本下的第k个神经元的绝对误差 * w; O$ e% Z! p* N0 L sqr_err+=(abs_err[k])*(abs_err[k]);//求第m个样本下输出层的平方误差 $ P0 O5 ~7 T, j/ Z& a d_err[k]=abs_err[k]*O[k]*(1.0-O[k]);//d_err[k]输出层各神经元的一般化误差+ t% h" C m2 I } t$ ~' j# R+ k1 R* h5 W err_m[m]=sqr_err/2;//第m个样本下输出层的平方误差/2=第m个样本的均方误差 i; i z9 H3 ?+ J1 ~: f return 1; * h3 G6 H/ b k8 C$ b3 s }//子程序Err_O_H(m)结束( I$ g; G1 I% a) b ////////////////////////////////////; T+ e# h3 Y9 n1 f m# z4 d //隐层至输入层的一般化误差子程序////8 b) U! b* v) e& L7 o( r; [; T9 u //////////////////////////////////// * U7 }0 W# H, X- B7 h$ O double e_err[HN]; / C u& a; I: f4 a n Err_H_I(){ ( Y7 y) I* A: A" z$ Y9 u9 q0 }/ c double sigma; " [# a% e% k% i( x //for (int hidden=0;hidden/ }! U) ?7 G0 e: e! V+ Y/ c$ q for (int j=0;j<HN;j++) 0 ^' F! _, }- a1 Q9 s' u5 o sigma=0.0;+ K% c& B7 e5 g3 v for (int k=0;k<ON;k++) " p* q+ e2 `1 ~: Y. ?, _ sigma=d_err[k]*V[k][j]; % u5 s4 Q4 J+ K4 m# @ }$ ]0 b5 d3 |9 O* W: E! Z3 ^ e_err[j]=sigma*H[j]*(1-H[j]);//隐层各神经元的一般化误差 2 w: ~% d+ s. j& e5 Y! j& l$ H } ^/ h. ^5 Y) E; n6 e* C return 1;( i# i' @# Z% P- U8 |# C }//子程序Err_H_I()结束 ) j/ Z0 _- r0 i' e V: `/ M1 D ////////////////////////////////////////////////////////; H/ k- x- E/ P) s& T$ q, c- N //输出层至隐层的权值调整、输出层阈值调整计算子程序////// 7 ]% M( h; x+ i0 h: E' d | //////////////////////////////////////////////////////// 0 y! y- ~4 ?! [2 ]/ z7 r Delta_O_H(int m,FILE* fp) 4 T: g' }) T! u { 4 s w1 L }, q for (int k=0;k<ON;k++)6 y; v8 N/ X8 y2 P" }- ] for (int j=0;j<HN;j++). ~1 \( ^: T0 n/ i //cout<<"第"< ) v4 K# o4 ~7 Q4 jfprintf(fp,"第%d个样本时的输出层至隐层的权值为:%f\n",m,W[k][j]);% ]; V5 G4 Y! T( L$ L V[k][j]+=alpha*d_err[k]*H[j];//输出层至隐层的权值调整 3 ~. h. g6 N K8 y$ h' \7 W z }+ t4 Q' r6 A1 W: |* k0 x gama[k]+=alpha*d_err[k];//输出层至隐层的阈值调整 ' L4 M$ T+ b: J }2 r. P! [0 }1 A" O( h4 a, ` return 1; ) ` ?% v- U1 I, [5 I }//子程序Delta_O_H()结束; G2 u m6 I1 h: n /////////////////////////////////////////////////////: H7 ?' K4 |" k! ~ //隐层至输入层的权值调整、隐层阈值调整计算子程序///// * G- s% R# w8 o2 ]! } w. [- T ///////////////////////////////////////////////////// 0 b) |* s* m. V v Delta_H_I(int m,FILE* fp)5 V" j4 o. `3 V0 r( _& k6 n! W { / N/ z% l5 A8 v$ C1 d& r for (int j=0;j<HN;j++)2 Z3 p) M! d+ K `) ~ for (int i=0;i<IN;i++) . Y1 x, C, v2 g" Z% i6 v //cout<<"第"< fprintf(fp,"第%d个样本时的输出层至隐层的权值为:%f\n",m,V[j]); / Y8 J8 S* N7 t% P3 a' l W[j]+=beta*e_err[j]*P;//隐层至输入层的权值调整 # q& H6 }1 l3 i6 z4 M } ' B! M. J& M* M% [9 O- | sita[j]+=beta*e_err[j];% e6 b+ a9 K2 S9 u+ i } ) @8 i& p; d! g& t% n+ ^: X return 1; 0 a- }2 C; n3 _4 v6 E) r7 | }//子程序Delta_H_I()结束 + N% \; S: u4 y6 @( _. |5 @ /////////////////////////////////0 G6 z5 @' i2 o/ h" @( W6 b //N个样本的全局误差计算子程序////) D: z H! L: r ///////////////////////////////// $ Z% Z/ d) {5 { @, r% [ double Err_Sum() & J/ @% R" [3 @/ s3 d5 Z% l+ h {) ^% Q1 Y: i O# G0 C- c double total_err=0; - B1 ~9 x/ J; Q for (int m=0;m<N;m++) 6 d1 t {* I U8 Y0 D total_err+=err_m[m];//每个样本的均方误差加起来就成了全局误差# Z+ ~5 f+ U' v } 7 u2 ^9 z1 n8 ~7 g' Y5 S9 v return 1; ) L5 V1 Z( k* B4 t+ y( G# a }//子程序Err_sum()结束: g5 M7 k' o# D0 C# E /**********************/ - [; |% R& c- Z$ y2 X W/ n1 [3 M- n /**程序入口,即主程序**/! k! T3 f4 S4 y! H/ P( ~ /**********************/) l; I3 e: v: x _4 f' x- S main() 5 p# P4 o# L Y2 q9 c$ z+ d- d4 J {; |: U" \8 w K3 J FILE *fp;) m# J1 x4 e$ c, u9 W3 X6 Y double sum_err; 1 }! Z6 f( d9 t6 |$ \8 c# s1 w int study;//训练次数 0 F6 K, |+ e1 D& C% R if ((fp=fopen("bp.txt","a+"))==NULL) - F8 {/ k* Z* ^9 S8 W+ f( R5 ]0 w2 j { N9 ~& E8 Z+ x' |$ h2 u9 K6 O printf("不能创建bp.txt文件!\n");- Y& w* C& t! b) k. n exit(1);) L |' S9 ] y7 ] } 1 J9 v+ ]+ F$ f0 f7 X% q cout<<"请输入输出层到隐含层学习效率: alpha=\n";9 L3 L+ A( P5 h4 R cin>>alpha; 9 e( ]( N1 |& P( i cout<<"请输入隐含层到输入层学习效率: beta=\n"; " y f4 @7 H/ m) t2 T% r& m cin>>beta;$ Y, O3 B. W# K5 D. \+ B* g int study=0; //学习次数 9 d8 C2 B. Y. E7 F4 y double Pre_error ; //预定误差# p# c" Q2 k4 |' O7 {; X: Z cout<<"请输入预定误差: Pre_error= \n";7 C5 f. ^! ?' |9 `" p cin>>re_error; 3 b' e, K4 E. P6 O P+ G int Pre_times;+ A) e! G; e5 E' X% T cout<<"请输入预定最大学习次数re_times=\n"; 4 J( ]4 C+ r; j* K2 f cin>>re_times; & W4 c; v5 O& F. L( Q, g cout<<"请输入学习样本数据\n";/ L5 g7 Y& v/ G {/ x% \, _) @, l! F* u3 Q" A. R for (int m=0;m<N;m++) ! S# K" F l( W cout<<"请输入第"<<m+1<<"组学习样本"<<endl; & S! I* W6 U9 {& m for (int i=0;i<IN;i++)/ m6 Y# r* V! B cin>>Study_Data[m]->input; ; g% R& k6 r0 K6 j } 7 h1 a! r8 f; x c { # y) _$ n) X0 O9 Z2 f9 x! m6 R9 W1 X for (int m=0;m<N;m++) . Y+ Z! q( g. R- v8 ]8 L! z cout<<"请输入第"<<m+1<<"组教师样本"<<endl; 8 K- _1 G" P( Y for (int k=0;k<ON;k++) $ o! m& z( b/ I1 W( Z) a cin>>Study_Data[m]->teach[k];, E( N7 B1 b' o- Y8 V: @ }6 D: T1 A4 _3 o* }% B initial(); //隐层、输出层权、阈值初始化 (1) % C1 Y' U3 l! N do ) C; ~1 h! g m. X' i { 8 M5 w* Y' q9 j ++study; ///??? 0 L" T9 V( J2 v3 A9 J& j4 m2 c for (int m=0;m<N;m++) . X6 g4 h3 S, Y { : }+ y- f7 K( p3 | input_P(m); //输入第m个学习样本 (2)( t& |6 X6 e4 t7 b& p input_T(m);//输入第m个样本的教师信号 (3) . n2 M" X* o, F1 ]' s' c H_I_O(); //第m个学习样本隐层各单元输入、输出值 (4) - I) y- n* E+ V. C; K O_I_O(); //第m个学习样本输出层各单元输入、输出值 (5) 3 X# f. D+ \- a# t Err_O_H(m); //第m个学习样本输出层至隐层一般化误差 (6) ` P4 p& \! G Err_H_I(); //第m个学习样本隐层至输入层一般化误差 (7) J# j* {+ ]; P- Q5 u" X Delta_O_H(m,fp); //第m个学习样本输出层至隐层权阈值调整、修改 (8) * Z. X# }0 E1 L/ ~. m Delta_H_I(m,fp); //第m个学习样本隐层至输入层权阈值调整、修改 (9)# W% J) K+ f- ]% C } //全部样本训练完毕9 [, }7 E: O% k8 A- b sum_err=Err_Sum(); //全部样本全局误差计算 (10)7 K3 M" m- m/ i. r% W, ` { 8 }! S6 z- v& C cout<<"第"<<study<<"次学习的均方误差为"<<sum_err<<endl;; C7 J7 x1 Y/ K; A# k1 w fprintf(fp,"第%d次学习的均方误差为:%f\n",study,sum_err);( Y9 u$ h5 ?& J# h' b } : D! @3 b/ Q5 l+ |5 P: a while (sum_err > Pre_error) //or(study% w7 o0 j* w& G" f$ h { //N个样本全局误差小于预定误差否? 小于则退出 (11)) ~& e/ l% W/ l' p2 M6 B cout<<"网络已经学习了"<<study<<"次,学习的均方误差为"<<sum_err<<endl;) f1 P* R0 `4 I0 `1 [ fprintf(fp,"网络已经学习了%d次,现在的全局误差为:%f\n",study,total_err); J+ J" i& S2 Z% | fclose(fp); - w* ]. ^& a1 j } 1 [" K# a/ A$ L: x; g3 Y char s;# Z7 z8 R7 ^( Q) s cout<<"请随便输入一个字符,按回车退出程序!\n";9 W0 P3 R4 `. K6 ] E8 L# F! } cin>>s;/ A% M6 n4 V5 R6 v: | return 1;$ Z8 C$ F, E" e }


作者: devil1980    时间: 2006-3-28 11:51

笑死了,垃圾程序。这个只能是c 程序

而且还不收敛

误差只能到1

里面还有许多bug


作者: chz0829    时间: 2006-6-1 19:19
看不懂




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5