Chinaunix首页 | 论坛 | 博客
  • 博客访问: 161827
  • 博文数量: 76
  • 博客积分: 1513
  • 博客等级: 上尉
  • 技术积分: 755
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-25 15:15
文章分类

全部博文(76)

文章存档

2012年(2)

2011年(74)

我的朋友

分类: C/C++

2011-11-27 14:27:44

  1. #pragma hdrstop
  2. #include "stdafx.h"
  3. #include <stdio.h>
  4. #include <iostream>
  5. //#include <stdlib.h>
  6. #include "math.h"
  7. using namespace std;
  8. const float A=30.0;
  9. const float B=10.0;
  10. const int MAX=500; //最大训练次数
  11. const double COEF=0.0035; //网络的学习效率
  12. const double BCOEF=0.001;//网络的阀值调整效率
  13. const double ERROR=0.002 ; // 网络训练中的允许误差
  14. const double ACCURACY=0.0005;//网络要求精度
  15. double sample[41][4]={{0,0,0,0},{5,1,4,19.020},{5,3,3,14.150},
  16. {5,5,2,14.360},{5,3,3,14.150},{5,3,2,15.390},
  17. {5,3,2,15.390},{5,5,1,19.680},{5,1,2,21.060},
  18. {5,3,3,14.150},{5,5,4,12.680},{5,5,2,14.360},
  19. {5,1,3,19.610},{5,3,4,13.650},{5,5,5,12.430},
  20. {5,1,4,19.020},{5,1,4,19.020},{5,3,5,13.390},
  21. {5,5,4,12.680},{5,1,3,19.610},{5,3,2,15.390},
  22. {1,3,1,11.110},{1,5,2,6.521},{1,1,3,10.190},
  23. {1,3,4,6.043},{1,5,5,5.242},{1,5,3,5.724},
  24. {1,1,4,9.766},{1,3,5,5.870},{1,5,4,5.406},
  25. {1,1,3,10.190},{1,1,5,9.545},{1,3,4,6.043},
  26. {1,5,3,5.724},{1,1,2,11.250},{1,3,1,11.110},
  27. {1,3,3,6.380},{1,5,2,6.521},{1,1,1,16.000},
  28. {1,3,2,7.219},{1,5,3,5.724}};
  29. double w[4][10][10],wc[4][10][10],b[4][10],bc[4][10];
  30. double o[4][10],netin[4][10],d[4][10],differ;//单个样本的误差
  31. double is; //全体样本均方差
  32. int count,a;
  33. void netout(int m, int n);//计算网络隐含层和输出层的输出
  34. void calculd(int m,int n); //计算网络的反向传播误差
  35. void calcalwc(int m,int n);//计算网络权值的调整量
  36. void calcaulbc(int m,int n); //计算网络阀值的调整量
  37. void changew(int m,int n); //调整网络权值
  38. void changeb(int m,int n);//调整网络阀值
  39. void clearwc(int m,int n);//清除网络权值变化量wc
  40. void clearbc(int m,int n);//清除网络阀值变化量bc
  41. void initialw(void);//初始化NN网络权值W
  42. void initialb(void); //初始化NN网络阀值
  43. void calculdiffer(void);//计算NN网络单个样本误差
  44. void calculis(void);//计算NN网络全体样本误差
  45. void trainNN(void);//训练NN网络
  46. /*计算NN网络隐含层和输出层的输出 */
  47. void netout(int m,int n)
  48. {
  49. int i,j,k;
  50. //隐含层各节点的的输出
  51. for (j=1,i=2;j<=m;j++) //m为隐含层节点个数
  52. {
  53. netin[i][j]=0.0;
  54. for(k=1;k<=3;k++)//隐含层的每个节点均有三个输入变量
  55. netin[i][j]=netin[i][j]+o[i-1][k]*w[i][k][j];
  56. netin[i][j]=netin[i][j]-b[i][j];
  57. o[i][j]=A/(1+exp(-netin[i][j]/B));
  58. }
  59. //输出层各节点的输出
  60. for (j=1,i=3;j<=n;j++)
  61. {
  62. netin[i][j]=0.0;
  63. for (k=1;k<=m;k++)
  64. netin[i][j]=netin[i][j]+o[i-1][k]*w[i][k][j];
  65. netin[i][j]=netin[i][j]-b[i][j];
  66. o[i][j]=A/(1+exp(-netin[i][j]/B)) ;
  67. }
  68. }
  69. /*计算NN网络的反向传播误差*/
  70. void calculd(int m,int n)
  71. {
  72. int i,j,k;
  73. double t;
  74. a=count-1;
  75. d[3][1]=(o[3][1]-sample[a][3])*(A/B)*exp(-netin[3][1]/B)/pow(1+exp(-netin[3][1]/B),2);
  76. //隐含层的误差
  77. for (j=1,i=2;j<=m;j++)
  78. {
  79. t=0.00;
  80. for (k=1;k<=n;k++)
  81. t=t+w[i+1][j][k]*d[i+1][k];
  82. d[i][j]=t*(A/B)*exp(-netin[i][j]/B)/pow(1+exp(-netin[i][j]/B),2);
  83. }
  84. }

  85. /*计算网络权值W的调整量*/
  86. void calculwc(int m,int n)
  87. {
  88. int i,j,k;
  89. // 输出层(第三层)与隐含层(第二层)之间的连接权值的调整
  90. for (i=1,k=3;i<=m;i++)
  91. {
  92. for (j=1;j<=n;j++)
  93. {
  94. wc[k][i][j]=-COEF*d[k][j]*o[k-1][i]+0.5*wc[k][i][j];
  95. }
  96. // printf("\n");
  97. }
  98. //隐含层与输入层之间的连接权值的调整
  99. for (i=1,k=2;i<=m;i++)
  100. {
  101. for (j=1;j<=m;j++)
  102. {
  103. wc[k][i][j]=-COEF*d[k][j]*o[k-1][i]+0.5*wc[k][i][j];
  104. }
  105. // printf("\n");
  106. }
  107. }
  108. /*计算网络阀值的调整量*/
  109. void calculbc(int m,int n)
  110. {
  111. int j;
  112. for (j=1;j<=m;j++)
  113. {
  114. bc[2][j]=BCOEF*d[2][j];
  115. }
  116. for (j=1;j<=n;j++)
  117. {
  118. bc[3][j]=BCOEF*d[3][j];
  119. }
  120. }
  121. /*调整网络权值*/
  122. void changw(int m,int n)
  123. {
  124. int i,j;
  125. for (i=1;i<=3;i++)
  126. for (j=1;j<=m;j++)
  127. {
  128. w[2][i][j]=0.9*w[2][i][j]+wc[2][i][j];
  129. //为了保证系统有较好的鲁棒性,计算权值时乘惯性系数0.9
  130. printf("w[2][%d][%d]=%f\n",i,j,w[2][i][j]);
  131. }
  132. for (i=1;i<=m;i++)
  133. for (j=1;j<=n;j++)
  134. {
  135. w[3][i][j]=0.9*w[3][i][j]+wc[3][i][j];
  136. printf("w[3][%d][%d]=%f\n",i,j,w[3][i][j]);
  137. }
  138. }
  139. /*调整网络阀值*/
  140. void changb(int m,int n)
  141. {
  142. int j;
  143. for (j=1;j<=m;j++)
  144. b[2][j]=b[2][j]+bc[2][j];
  145. for (j=1;j<=n;j++)
  146. b[3][j]=b[3][j]+bc[3][j];
  147. }
  148. /*清除网络权值变化量wc*/
  149. void clearwc(void)
  150. {
  151. for (int i=0;i<4;i++)
  152. for (int j=0;j<10;j++)
  153. for (int k=0;k<10;k++)
  154. wc[i][j][k]=0.00;
  155. }
  156. /*清除网络阀值变化量*/
  157. void clearbc(void)
  158. {
  159. for (int i=0;i<4;i++)
  160. for (int j=0;j<10;j++)
  161. bc[i][j]=0.00;
  162. }
  163. /*初始化网络权值W*/
  164. void initialw(void)
  165. {
  166. int i,j,k,x;
  167. double weight;
  168. for (i=0;i<4;i++)
  169. for (j=0;j<10;j++)
  170. for (k=0;k<10;k++)
  171. {
  172. srand(NULL);
  173. x=100+rand();
  174. weight=(double)x/5000.00;
  175. w[i][j][k]=weight;
  176. }
  177. }
  178. /*初始化网络阀值*/
  179. void initialb(void)
  180. {
  181. int i,j,x;
  182. double fazhi;
  183. for (i=0;i<4;i++)
  184. for (j=0;j<10;j++)
  185. {
  186. srand(NULL);
  187. for (int k=0;k<12;k++)
  188. {
  189. x=100+rand();
  190. }
  191. fazhi=(double)x/50000.00;
  192. b[i][j]=fazhi;
  193. }
  194. }

  195. /*计算网络单个样本误差*/
  196. void calculdiffer(void)
  197. {
  198. a=count-1;
  199. differ=0.5*(o[3][1]-sample[a][3])*(o[3][1]-sample[a][3]);
  200. }
  201. void calculis(void)
  202. {
  203. int i;
  204. is=0.0;
  205. for (i=0;i<=19;i++)
  206. {
  207. o[1][1]=sample[i][0];
  208. o[1][2]=sample[i][1];
  209. o[1][3]=sample[i][2];
  210. netout(8,1);
  211. is=is+(o[3][1]-sample[i][3])*(o[3][1]-sample[i][3]);
  212. }
  213. is=is/20;
  214. }
  215. /*训练网络*/
  216. void trainNN(void)
  217. {
  218. long int time;
  219. int i,x[4];
  220. initialw();
  221. initialb();
  222. for (time=1;time<=MAX;time++)
  223. {
  224. count=0;
  225. while(count<=40)
  226. {
  227. o[1][1]=sample[count][0];
  228. o[1][2]=sample[count][1];
  229. o[1][3]=sample[count][2];
  230. count=count+1;
  231. clearwc();
  232. clearbc();
  233. netout(8,1);
  234. calculdiffer();
  235. while(differ>ERROR)
  236. {
  237. calculd(8,1);
  238. calculwc(8,1);
  239. calculbc(8,1);
  240. changw(8,1);
  241. changb(8,1);
  242. netout(8,1);
  243. calculdiffer();
  244. }
  245. }
  246. printf("This is %d times training NN...\n",time);
  247. calculis();
  248. printf("is==%f\n",is);
  249. if (is<ACCURACY) break;
  250. }
  251. }
  252. //---------------------------------------------------------------------------
  253. #pragma argsused
  254. int main(int argc, char* argv[])
  255. {
  256. double result;
  257. int m,test[4];
  258. char ch='y';
  259. cout<<"Please wait for the train of NN:"<<endl;
  260. trainNN();
  261. cout<<"Now,this modular network can work for you."<<endl;
  262. while(ch=='y' || ch=='Y')
  263. {
  264. cout<<"Please input data to be tested."<<endl;
  265. for (m=1;m<=3;m++)
  266. cin>>test[m];
  267. ch=getchar();
  268. o[1][1]=test[1];
  269. o[1][2]=test[2];
  270. o[1][3]=test[3];
  271. netout(8,1);
  272. result=o[3][1];
  273. printf("Final result is %f.\n",result);
  274. printf("Still test?[Yes] or [No]\n");
  275. ch=getchar();
  276. }
  277. return 0;
  278. }
阅读(918) | 评论(0) | 转发(0) |
0

上一篇:friend函数

下一篇:“&&”和“&”的区别

给主人留下些什么吧!~~