+ z6 H+ u. }/ n& d5 k1 J
#include "iostream.h", ^) v, d& n, Y% ^: ? #include "iomanip.h"* w) X/ b( k" h5 M" L7 P0 p/ n #define N 20 //学习样本个数 #define IN 1 //输入层神经元数目 #define HN 8 //隐层神经元数目 #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]; //输入层至隐层权值 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]; //输出层的输入 double H[HN]; //隐层的输出 double O[ON]; //输出层的输出 double sita[HN]; //隐层的阈值# t4 p% P+ A- p [2 n double gama[ON]; //输出层的阈值 double err_m[N]; //第m个样本的总误差: ~% [$ l8 C; c double alpha; //输出层至隐层的学习效率( o. r% a9 k* r @( S# ` double beta; //隐层至输入层学习效率 //定义一个放学习样本的结构8 O- }" R, Q5 X2 T3 F5 O; y struct {! y8 |+ C0 K) S7 L$ Q) h double input[IN]; double teach[ON]; }Study_Data[N][IN]; $ [+ G+ I) R1 d m, @0 F# J' w* T /////////////////////////// //初始化权、阈值子程序/////5 k _ C4 t9 ^# X /////////////////////////// initial()4 d3 H( B( m/ v2 s3 L# b! ~/ h { float sgn; float rnd;4 ^( ?8 J+ ^1 [0 q1 G int i,j; //隐层权、阈值初始化// {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;//隐层权值初始化。 }) ^- n/ z0 j# t //randomize(); { //sgn=pow((-1),random(1000));2 w: j6 O6 Q+ k( @0 o7 j6 o4 [ sgn=rand(); rnd=sgn*(rand()%1000);3 e0 @' \- ^9 K" ` sita[j]= rnd/1000;//中间层阈值初始化6 v% r z$ R- g1 F cout<<"sita"<<sita[j]<<endl; } //输出层权、阈值初始化// //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++) { //sgn=pow((-1),random(1000));- |* o; o1 o7 y) B sgn=rand(); w0 g0 g5 s" h7 @, a rnd=sgn*(rand()%1000); V[k][j]=rnd/1000;//第m个样本输出层权值初始化 } //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); gama[k]=rnd/10;//输出层阈值初始化 cout<<"gama[k]"<<endl; } return 1;/ ?, W! w' P8 V5 @9 b% Z2 Y }//子程序initial()结束
7 s- s8 t; c7 R \3 {# {) F ////////////////////////////////, p# _7 L3 y0 X3 G
////第m个学习样本输入子程序///
///////////////////////////////0 A0 W5 y1 X, o- K0 Z8 _' O6 F1 T
input_P(int m)
{
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个样本的学习输入:
//P[%d]=%f\n",m,P);
return 1;
}//子程序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. {
{
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)结束
/////////////////////////////////0 U" I- A+ V0 j9 [8 A
//隐层各单元输入、输出值子程序///# {9 k, Y) G7 F7 }
/////////////////////////////////
H_I_O(){
double sigma;7 k. C/ n( B( w
int i,j;6 k4 P+ @8 F b
for (j=0;j<HN;j++)
sigma=0.0;
for (i=0;i<IN;i++)" a: Y) O/ i3 B f
sigma+=W[j]*P;//求隐层内积& ~1 o& P- z/ i Q s& s
}
X[j]=sigma - sita;//求隐层净输入
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
///////////////////////////////////
//输出层各单元输入、输出值子程序///
///////////////////////////////////
O_I_O()
{
double sigma;
for (int k=0;k<ON;k++)
sigma=0.0;
for (int j=0;j<HN;j++)% q- }* X. ^& c1 Y1 E3 A* F! O
sigma+=V[k][j]*H[k];//求输出层内积
}
Y[k]=sigma-gama[k]; //求输出层净输入
O[k]=1.0/(1.0+exp(-Y[k]));//求输出层输出
}8 ~! J+ ?; h \- _* I( |
return 1;* d1 {0 l! G3 [2 K& Y- ^ z2 c1 K" \1 |
}//子程序O_I_O()结束
////////////////////////////////////
//输出层至隐层的一般化误差子程序////
////////////////////////////////////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个神经元的绝对误差
sqr_err+=(abs_err[k])*(abs_err[k]);//求第m个样本下输出层的平方误差
d_err[k]=abs_err[k]*O[k]*(1.0-O[k]);//d_err[k]输出层各神经元的一般化误差+ t% h" C m2 I
}
err_m[m]=sqr_err/2;//第m个样本下输出层的平方误差/2=第m个样本的均方误差 i; i z9 H3 ?+ J1 ~: f
return 1;
}//子程序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
////////////////////////////////////
double e_err[HN];
Err_H_I(){
double sigma;
//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++)
sigma=d_err[k]*V[k][j];
}$ ]0 b5 d3 |9 O* W: E! Z3 ^
e_err[j]=sigma*H[j]*(1-H[j]);//隐层各神经元的一般化误差
}
return 1;( i# i' @# Z% P- U8 |# C
}//子程序Err_H_I()结束
////////////////////////////////////////////////////////; H/ k- x- E/ P) s& T$ q, c- N
//输出层至隐层的权值调整、输出层阈值调整计算子程序//////
////////////////////////////////////////////////////////
Delta_O_H(int m,FILE* fp)
{
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<<"第"<
fprintf(fp,"第%d个样本时的输出层至隐层的权值为:%f\n",m,W[k][j]);% ]; V5 G4 Y! T( L$ L
V[k][j]+=alpha*d_err[k]*H[j];//输出层至隐层的权值调整
}+ t4 Q' r6 A1 W: |* k0 x
gama[k]+=alpha*d_err[k];//输出层至隐层的阈值调整
}2 r. P! [0 }1 A" O( h4 a, `
return 1;
}//子程序Delta_O_H()结束; G2 u m6 I1 h: n
/////////////////////////////////////////////////////: H7 ?' K4 |" k! ~
//隐层至输入层的权值调整、隐层阈值调整计算子程序/////
/////////////////////////////////////////////////////
Delta_H_I(int m,FILE* fp)5 V" j4 o. `3 V0 r( _& k6 n! W
{
for (int j=0;j<HN;j++)2 Z3 p) M! d+ K `) ~
for (int i=0;i<IN;i++)
//cout<<"第"< fprintf(fp,"第%d个样本时的输出层至隐层的权值为:%f\n",m,V[j]);
W[j]+=beta*e_err[j]*P;//隐层至输入层的权值调整
}
sita[j]+=beta*e_err[j];% e6 b+ a9 K2 S9 u+ i
}
return 1;
}//子程序Delta_H_I()结束
/////////////////////////////////0 G6 z5 @' i2 o/ h" @( W6 b
//N个样本的全局误差计算子程序////) D: z H! L: r
/////////////////////////////////
double Err_Sum()
{) ^% Q1 Y: i O# G0 C- c
double total_err=0;
for (int m=0;m<N;m++) 6 d1 t {* I U8 Y0 D
total_err+=err_m[m];//每个样本的均方误差加起来就成了全局误差# Z+ ~5 f+ U' v
}
return 1;
}//子程序Err_sum()结束: g5 M7 k' o# D0 C# E
/**********************/
/**程序入口,即主程序**/! k! T3 f4 S4 y! H/ P( ~
/**********************/) l; I3 e: v: x _4 f' x- S
main()
{; |: U" \8 w K3 J
FILE *fp;) m# J1 x4 e$ c, u9 W3 X6 Y
double sum_err;
int study;//训练次数
if ((fp=fopen("bp.txt","a+"))==NULL)
{
printf("不能创建bp.txt文件!\n");- Y& w* C& t! b) k. n
exit(1);) L |' S9 ] y7 ]
}
cout<<"请输入输出层到隐含层学习效率: alpha=\n";9 L3 L+ A( P5 h4 R
cin>>alpha;
cout<<"请输入隐含层到输入层学习效率: beta=\n";
cin>>beta;$ Y, O3 B. W# K5 D. \+ B* g
int study=0; //学习次数
double Pre_error ; //预定误差# p# c" Q2 k4 |' O7 {; X: Z
cout<<"请输入预定误差: Pre_error= \n";7 C5 f. ^! ?' |9 `" p
cin>>
re_error;
int Pre_times;+ A) e! G; e5 E' X% T
cout<<"请输入预定最大学习次数
re_times=\n";
cin>>
re_times;
cout<<"请输入学习样本数据\n";/ L5 g7 Y& v/ G
{/ x% \, _) @, l! F* u3 Q" A. R
for (int m=0;m<N;m++)
cout<<"请输入第"<<m+1<<"组学习样本"<<endl;
for (int i=0;i<IN;i++)/ m6 Y# r* V! B
cin>>Study_Data[m]->input;
}
{ # y) _$ n) X0 O9 Z2 f9 x! m6 R9 W1 X
for (int m=0;m<N;m++)
cout<<"请输入第"<<m+1<<"组教师样本"<<endl;
for (int k=0;k<ON;k++)
cin>>Study_Data[m]->teach[k];, E( N7 B1 b' o- Y8 V: @
}6 D: T1 A4 _3 o* }% B
initial(); //隐层、输出层权、阈值初始化 (1)
do
{
++study; ///???
for (int m=0;m<N;m++) . X6 g4 h3 S, Y
{
input_P(m); //输入第m个学习样本 (2)( t& |6 X6 e4 t7 b& p
input_T(m);//输入第m个样本的教师信号 (3)
H_I_O(); //第m个学习样本隐层各单元输入、输出值 (4)
O_I_O(); //第m个学习样本输出层各单元输入、输出值 (5)
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)
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, `
{
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
}
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);
}
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
}
笑死了,垃圾程序。这个只能是c 程序
而且还不收敛
误差只能到1
里面还有许多bug
| 欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) | Powered by Discuz! X2.5 |