Procedure.cpp
上传用户:guanx8y8
上传日期:2007-07-30
资源大小:326k
文件大小:33k
开发平台:

Visual C++

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Procedure.cpp
  3. // the implementation of the specified arithmetic
  4. // Author : freeia
  5. // E-mail : freeia@163.com
  6. // Date : 3/20/2003
  7. /////////////////////////////////////////////////////////////////////////////
  8. #include "stdafx.h"
  9. #include "Matrix.h"
  10. #include "AllDef.h"
  11. /////////////////////////////////////////////////////////////////////////////
  12. // Levenberg-Marquart ----> 第一次前向计算初始化    //
  13. /////////////////////////////////////////////////////////////////////////////
  14. __declspec (dllexport) void LMForwardCalculateInit( int nInputLayerNumber,
  15. int nHideLayerNumber,
  16. int nOutputLayerNumber,
  17. CMatrix &matrixDemoDataInput,
  18. CMatrix &matrixInputLayerValue,
  19. CMatrix &matrixInputToHideWeightValue,
  20. CMatrix &matrixHideLayerValveValue,
  21. CMatrix &matrixHideToOutputWeightValue,
  22. CMatrix &matrixOutputLayerValveValue
  23.    )
  24. {
  25. /************************************************************************
  26. * --------->Use Matlab Method <---------              *
  27. ************************************************************************/
  28. /////////////////////////////////////////////////////////////////////////
  29. // 构造输入层元素的矩阵
  30. // 构造规则:
  31. // 1. 样本数目做为矩阵的行数;
  32. // 2. 单个样本的输入层的数目做为矩阵的列数;
  33. // 3. 矩阵中的元素即为对应的输入层的值
  34. //
  35. CMatrix cMatrixInputLayerValue(matrixDemoDataInput.GetMatrixRowNumber (), nInputLayerNumber);
  36. // 得到样本的输入值
  37. matrixDemoDataInput.CopySubMatrix (cMatrixInputLayerValue,(unsigned int)0,(unsigned int)0);
  38. CMatrix cMatrixTInputLayerValue = cMatrixInputLayerValue.Transpose ();
  39. matrixInputLayerValue.CopyMatrix (cMatrixTInputLayerValue);
  40. /////////////////////////////////////////////////////////////////////////
  41. // 构造权值矩阵 -----> 由单个样本输入层与隐含层之间的权值做为元素组成
  42. // 构造规则:
  43. // 1. 单个样本的输入层的数目做为矩阵行数;
  44. // 2. 单个样本的隐含层的数目做为矩阵的列数;
  45. // 3. 对矩阵中的元素进行随机初始化,值在(-1,1)之间;
  46. // 4. 所有样本的输入层和隐含层的数目是相等的;
  47. // 5. 所有样本使用的是同一个权值矩阵.
  48. //
  49. CMatrix cMatrixInputToHideWeightValue(nHideLayerNumber, nInputLayerNumber);
  50. // 随机初始化矩阵内元素的值
  51. cMatrixInputToHideWeightValue.RandomInitialize ();
  52. matrixInputToHideWeightValue.CopyMatrix (cMatrixInputToHideWeightValue);
  53. /////////////////////////////////////////////////////////////////////
  54. // 构造样本隐含层的阀值矩阵
  55. // 构造规则:
  56. // 1. 样本的数目做为矩阵行数;
  57. // 2. 单个样本的隐含层的数目做为矩阵的列数;
  58. // 3. 随机初始化矩阵中的元素,使值在(-1,1)之间;
  59. // 4. 矩阵中每行的数据都和第一行数据相对应的位置相等.
  60. //
  61. CMatrix cMatrixHideLayerValveValue(nHideLayerNumber,(unsigned int)1);
  62. // 随机初始化矩阵内元素的值
  63. cMatrixHideLayerValveValue.RandomInitialize ();
  64. matrixHideLayerValveValue.CopyMatrix(cMatrixHideLayerValveValue);
  65. /////////////////////////////////////////////////////////////////////
  66. // 构造权值矩阵 -----> 由单个样本的隐含层与输出层之间权值做为元素
  67. // 组成
  68. // 构造规则:
  69. // 1. 单个样本的隐含层的数目做为矩阵的行数;
  70. // 2. 单个样本的输出层的数目做为矩阵的列数;
  71. // 3. 对矩阵中的元素进行随机初始化,值在(-1,1)之间;
  72. // 4. 所有样本的隐含层和输出层的数目是相等的;
  73. // 5. 所有样本使用的是同一个权值矩阵.
  74. //
  75. CMatrix cMatrixHideToOutputWeightValue(nOutputLayerNumber, nHideLayerNumber);
  76. // 对矩阵的元素随机初始化
  77. cMatrixHideToOutputWeightValue.RandomInitialize ();
  78. matrixHideToOutputWeightValue.CopyMatrix (cMatrixHideToOutputWeightValue);
  79. /////////////////////////////////////////////////////////////////////
  80. // 构造样本的输出层的阀值矩阵
  81. // 构造规则:
  82. // 1. 样本的数目做为矩阵的行数;
  83. // 2. 单个样本的输出层的数目做为矩阵的列数;
  84. // 3. 随机初始化矩阵中的元素,使值在(-1,1)之间;
  85. // 4. 矩阵中每行的数据都和第一行数据相对应的位置相等.
  86. //
  87. CMatrix cMatrixOutputLayerValveValue(nOutputLayerNumber,(unsigned int)1);
  88. // 随机初始化矩阵内元素的值
  89. cMatrixOutputLayerValveValue.RandomInitialize ();
  90. matrixOutputLayerValveValue.CopyMatrix(cMatrixOutputLayerValveValue);
  91. }
  92. /////////////////////////////////////////////////////////////////////////////
  93. // Levenberg-Marquart ----> 前向计算    //
  94. /////////////////////////////////////////////////////////////////////////////
  95. __declspec(dllexport) void LMForwardCalculate ( int nInputLayerNumber,
  96. int nHideLayerNumber,
  97. int nOutputLayerNumber,
  98. bool bSimulateDataFlag,
  99. int nComboFunc,
  100. CMatrix &matrixDemoDataInput,
  101. CMatrix &matrixInputLayerValue,
  102. CMatrix &matrixInputToHideWeightValue,
  103. CMatrix &matrixHideLayerValveValue,
  104. CMatrix &matrixHideLayerOutput,
  105. CMatrix &matrixHideToOutputWeightValue,
  106. CMatrix &matrixOutputLayerOutput,
  107. CMatrix &matrixOutputLayerValveValue
  108.    )
  109. {
  110. if(bSimulateDataFlag)
  111. {
  112. CMatrix cMatrixInputLayerValue(matrixDemoDataInput.GetMatrixRowNumber (), nInputLayerNumber);
  113. // 得到样本的输入值
  114. matrixDemoDataInput.CopySubMatrix (cMatrixInputLayerValue, (unsigned int)0, (unsigned int)0);
  115. CMatrix cMatrixTInputLayerValue = cMatrixInputLayerValue.Transpose ();
  116. matrixInputLayerValue.CopyMatrix (cMatrixTInputLayerValue);
  117. }
  118. /////////////////////////////////////////////////////////////////////////
  119. // 得到所有样本的隐含层的净输入
  120. // 构造规则:
  121. // 1. 样本的数目做为矩阵行数;
  122. // 2. 单个样本的隐含层的数目做为矩阵的列数;
  123. // 3. 矩阵元素中的值即为对应的样本的隐含层的净输入:
  124. //    由 
  125. // cMatrixInputLayerValue * cMatrixInputToHideWeightValue 
  126. // + cMatrixHideLayerValveValue
  127. // 得到.
  128. //
  129. CMatrix cMatrixExHideLayerValveValue;
  130. cMatrixExHideLayerValveValue.nncpyi (matrixHideLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ());
  131. CMatrix cMatrixHideLayerPureInput(nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
  132. cMatrixHideLayerPureInput = matrixInputToHideWeightValue * matrixInputLayerValue;
  133. cMatrixHideLayerPureInput += cMatrixExHideLayerValveValue;
  134. /////////////////////////////////////////////////////////////////////
  135. // 算出所有样本的隐含层的输出
  136. // 构造规则:
  137. // 1. 隐含层的输出y与隐含层的输入x的关系可用函数表示
  138. // y = f(x)
  139. // 2. 矩阵的维数和隐含层的净输入矩阵的维数相等
  140. //
  141. CMatrix cMatrixHideLayerOutput(nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
  142. switch(nComboFunc)
  143. {
  144. case 0:
  145. cMatrixHideLayerOutput = cMatrixHideLayerPureInput.Sigmoid ();
  146. break;
  147. case 1:
  148. cMatrixHideLayerOutput = cMatrixHideLayerPureInput.tanh ();
  149. break;
  150. case 2:
  151. cMatrixHideLayerOutput = cMatrixHideLayerPureInput.Tansig();
  152. break;
  153. default:
  154. return;
  155. }
  156. matrixHideLayerOutput.CopyMatrix(cMatrixHideLayerOutput);
  157. /////////////////////////////////////////////////////////////////////
  158. // 得到所有样本输出层的净输入
  159. // 构造规则;
  160. // 1. 样本的数目做为矩阵的行数;
  161. // 2. 单个样本的输出层的数目做为矩阵的列数;
  162. // 3. 矩阵中元素的值即为对应样本的输出层的净输入:
  163. // 由
  164. // cMatrixHideLayerOutput * cMatrixHideToOutputWeightValue
  165. // + cMatrixOutputLayerValveValue
  166. // 得到
  167. //
  168. CMatrix cMatrixExOutputLayerValveValue;
  169. cMatrixExOutputLayerValveValue.nncpyi (matrixOutputLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ());
  170. CMatrix cMatrixOutputLayerPureInput(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
  171. cMatrixOutputLayerPureInput = matrixHideToOutputWeightValue * cMatrixHideLayerOutput;
  172. cMatrixOutputLayerPureInput  += cMatrixExOutputLayerValveValue;
  173. /////////////////////////////////////////////////////////////////////
  174. // 算出所有样本的输出层的输出
  175. // 构造规则:
  176. // 1. 矩阵的维数与得到的所有样本的输出层的净输入组成的矩阵一样;
  177. // 2. 输出层的输出y和输出层的输入可用关系式
  178. // y = f(x)
  179. // 表示
  180. //
  181. CMatrix cMatrixOutputLayerOutput(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
  182. switch(nComboFunc)
  183. {
  184. case 0:
  185. cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.Sigmoid ();
  186. break;
  187. case 1:
  188. cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.tanh ();
  189. break;
  190. case 2:
  191. cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.Tansig ();
  192. break;
  193. default:
  194. return ;
  195. }
  196. matrixOutputLayerOutput.CopyMatrix(cMatrixOutputLayerOutput);
  197. }
  198. /////////////////////////////////////////////////////////////////////////////
  199. // Levenberg-Marquart ----> 反馈计算    //
  200. /////////////////////////////////////////////////////////////////////////////
  201. __declspec(dllexport) bool LMDemoDataTrainRepeat ( int nInputLayerNumber,
  202. int nHideLayerNumber,
  203. int nOutputLayerNumber,
  204. bool bSimulateDataFlag,
  205. int nComboFunc,
  206. double nSystemErrorOld,
  207. double nSystemErrorNew,
  208. double nSystemErrorLevel,
  209. double nSystemError,
  210. double nStep,
  211. UINT nMaxTrainTimes,
  212. UINT nTrainTimes,
  213. DWORD ID_SYSTEM_ERROR,
  214. DWORD ID_TRAIN_TIMES,
  215. HWND  hWnd,
  216. CMatrix &matrixDemoDataInput,
  217. CMatrix &matrixInputLayerValue,
  218. CMatrix &matrixInputToHideWeightValue,
  219. CMatrix &matrixHideLayerValveValue,
  220. CMatrix &matrixHideLayerOutput,
  221. CMatrix &matrixHideToOutputWeightValue,
  222. CMatrix &matrixOutputLayerOutput,
  223. CMatrix &matrixOutputLayerValveValue
  224.  )
  225. {
  226. LMForwardCalculate (nInputLayerNumber,
  227. nHideLayerNumber,
  228. nOutputLayerNumber,
  229. bSimulateDataFlag,
  230. nComboFunc,
  231. matrixDemoDataInput,
  232. matrixInputLayerValue,
  233. matrixInputToHideWeightValue,
  234. matrixHideLayerValveValue,
  235. matrixHideLayerOutput,
  236. matrixHideToOutputWeightValue,
  237. matrixOutputLayerOutput,
  238. matrixOutputLayerValveValue
  239. );
  240. /////////////////////////////////////////////////////////////////////
  241. // 算出所有样本的输出层的delta矩阵
  242. // 构造规则:
  243. // 1. 样本的数目为矩阵的行数;
  244. // 2. 样本输出层的数目为矩阵的列数;
  245. // 3. 矩阵中的元素的值y为:
  246. // y = -(前向计算出的输出层的值 - 样本的输出层的值) * f'(net)
  247. //
  248. CMatrix cMatrixTDemoOutput(matrixDemoDataInput.GetMatrixRowNumber (), nOutputLayerNumber);
  249. // 得到样本中输出层的数据
  250. matrixDemoDataInput.CopySubMatrix (cMatrixTDemoOutput, (unsigned int)nInputLayerNumber, (unsigned int)0);
  251. CMatrix cMatrixDemoOutput = cMatrixTDemoOutput.Transpose ();
  252. // 得到样本中输出层的误差
  253. CMatrix cMatrixOutputLayerError(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
  254. cMatrixOutputLayerError = cMatrixDemoOutput - matrixOutputLayerOutput;
  255. nSystemErrorOld = cMatrixOutputLayerError.GetSystemError ();
  256. for(int nLoopTimes=1; nLoopTimes < nMaxTrainTimes; nLoopTimes++)
  257. {
  258. if(nSystemErrorOld < nSystemErrorLevel)
  259. {
  260. nLoopTimes--;
  261. break;
  262. }
  263. CMatrix cMatrixExHideLayerOutput;
  264. cMatrixExHideLayerOutput.nncpyi (matrixHideLayerOutput, nOutputLayerNumber);
  265. CMatrix cMatrixOutputLayerDelta (nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber());
  266. // 注意: 此处'/' 是 '点乘'!!!
  267. cMatrixOutputLayerDelta = 1 - matrixOutputLayerOutput / matrixOutputLayerOutput;
  268. CMatrix cMatrixExOutputLayerDelta;
  269. cMatrixExOutputLayerDelta.nncpyd (cMatrixOutputLayerDelta);
  270. cMatrixExOutputLayerDelta = cMatrixExOutputLayerDelta * (-1.0);
  271. CMatrix cMatrixTHideToOutputWeightValue (matrixHideToOutputWeightValue.GetMatrixColNumber(), matrixHideToOutputWeightValue.GetMatrixRowNumber());
  272. cMatrixTHideToOutputWeightValue = matrixHideToOutputWeightValue.Transpose();
  273. CMatrix cMatrixExHideLayerDelta;
  274. // 注意: 此处'/' 是 '点乘'!!!
  275. cMatrixExHideLayerDelta.CopyMatrix ( (1 - (cMatrixExHideLayerOutput / cMatrixExHideLayerOutput)) / ( cMatrixTHideToOutputWeightValue * cMatrixExOutputLayerDelta) );
  276. CMatrix cMatrixExInputLayerValue;
  277. cMatrixExInputLayerValue.nncpyi (matrixInputLayerValue, nOutputLayerNumber);
  278. CMatrix cMatrixJ11;
  279. cMatrixJ11.nncpy (cMatrixExHideLayerDelta.Transpose(), cMatrixExInputLayerValue.GetMatrixRowNumber ());
  280. CMatrix cMatrixJ12;
  281. cMatrixJ12.nncpyi(cMatrixExInputLayerValue.Transpose (), cMatrixExHideLayerDelta.GetMatrixRowNumber());
  282. CMatrix cMatrixJ1;
  283. // 注意: 此处'/' 是 '点乘'!!!
  284. cMatrixJ1.CopyMatrix (cMatrixJ11 / cMatrixJ12);
  285. CMatrix cMatrixJ21;
  286. cMatrixJ21.nncpy (cMatrixExOutputLayerDelta.Transpose (), cMatrixExHideLayerOutput.GetMatrixRowNumber ());
  287. CMatrix cMatrixJ22;
  288. cMatrixJ22.nncpyi (cMatrixExHideLayerOutput.Transpose (), cMatrixExOutputLayerDelta.GetMatrixRowNumber ());
  289. CMatrix cMatrixJ2;
  290. // 注意: 此处'/' 是 '点乘'!!!
  291. cMatrixJ2.CopyMatrix (cMatrixJ21 / cMatrixJ22);
  292. CMatrix cMatrixZ;
  293. cMatrixZ.CopyMatrix (MergeMatrix(MergeMatrix(MergeMatrix(cMatrixJ1, cMatrixExHideLayerDelta.Transpose ()), cMatrixJ2), cMatrixExOutputLayerDelta.Transpose ()));
  294. CMatrix cMatrixMOutputLayerError;
  295. cMatrixMOutputLayerError.CopyMatrix ( cMatrixOutputLayerError.MergeColumnsToColumnVector () );
  296. CMatrix cMatrixJE;
  297. cMatrixJE.CopyMatrix ( (cMatrixZ.Transpose ()) * cMatrixMOutputLayerError );
  298. CMatrix cMatrixJJ;
  299. cMatrixJJ.CopyMatrix ( (cMatrixZ.Transpose ()) * cMatrixZ );
  300. // 定义新的输入层到隐含层的权值
  301. CMatrix cMatrixNewInputToHideWeight;
  302. // 定义的新的隐含层的阀值
  303. CMatrix cMatrixNewHideLayerValve;
  304. // 定义新的隐含层到输出层的权值
  305. CMatrix cMatrixNewHideToOutputWeight;
  306. // 定义新的输出层的阀值
  307. CMatrix cMatrixNewOutputLayerValve;
  308. // 定义新的误差矩阵
  309. CMatrix cMatrixNewOutputLayerError(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
  310. /////////////////////////////////////////////////////////////////
  311. // the weight value is adjusted
  312. while(nStep <= MAX_ADJUST_VALUE)
  313. {
  314. CMatrix cMatrixI (cMatrixZ.GetMatrixColNumber (), cMatrixZ.GetMatrixColNumber ());
  315. cMatrixI.Eye ();
  316. CMatrix cMatrixDX;
  317. cMatrixDX.CopyMatrix ( (((cMatrixJJ + cMatrixI * nStep).Inverse ()) * cMatrixJE) * (-1.0) );
  318. /////////////////////////////////////////////////////////////////////////
  319. // 拆分cMatrixDX矩阵
  320. unsigned int nIndex = 0;
  321. // 得到输入层到隐含层的权值的修正量
  322. CMatrix cMatrixInputToHideWeightChange(nHideLayerNumber, nInputLayerNumber);
  323. cMatrixDX.CopySubMatrixFromVector (cMatrixInputToHideWeightChange, nIndex);
  324. nIndex += nHideLayerNumber * nInputLayerNumber;
  325. // 得到隐含层阀值的修正量
  326. CMatrix cMatrixHideLayerValveChange (nHideLayerNumber, (unsigned int)1);
  327. cMatrixDX.CopySubMatrixFromVector (cMatrixHideLayerValveChange, nIndex);
  328. nIndex += nHideLayerNumber;
  329. // 得到隐含层到输出层的权值的修正量
  330. CMatrix cMatrixHideToOutputWeightChange (nOutputLayerNumber, nHideLayerNumber);
  331. cMatrixDX.CopySubMatrixFromVector (cMatrixHideToOutputWeightChange, nIndex);
  332. nIndex += nOutputLayerNumber * nHideLayerNumber;
  333. // 得到输出层阀值的修正值
  334. CMatrix cMatrixOutputValveChange (nOutputLayerNumber, (unsigned int)1);
  335. cMatrixDX.CopySubMatrixFromVector (cMatrixOutputValveChange, nIndex);
  336. cMatrixNewInputToHideWeight.CopyMatrix (matrixInputToHideWeightValue + cMatrixInputToHideWeightChange);
  337. cMatrixNewHideLayerValve.CopyMatrix (matrixHideLayerValveValue + cMatrixHideLayerValveChange);
  338. cMatrixNewHideToOutputWeight.CopyMatrix (matrixHideToOutputWeightValue + cMatrixHideToOutputWeightChange);
  339. cMatrixNewOutputLayerValve.CopyMatrix (matrixOutputLayerValveValue + cMatrixOutputValveChange);
  340. // 前向计算
  341. LMForwardCalculate (nInputLayerNumber,
  342. nHideLayerNumber,
  343. nOutputLayerNumber,
  344. bSimulateDataFlag,
  345. nComboFunc,
  346. matrixDemoDataInput,
  347. matrixInputLayerValue,
  348. cMatrixNewInputToHideWeight,
  349. cMatrixNewHideLayerValve,
  350. matrixHideLayerOutput,
  351. cMatrixNewHideToOutputWeight,
  352. matrixOutputLayerOutput,
  353. cMatrixNewOutputLayerValve
  354. );
  355. cMatrixNewOutputLayerError = cMatrixDemoOutput - matrixOutputLayerOutput;
  356. nSystemErrorNew =  cMatrixNewOutputLayerError.GetSystemError ();
  357. if(nSystemErrorNew < nSystemErrorOld)
  358. {
  359. break;
  360. }
  361. else
  362. {
  363. nStep *= 10;
  364. }
  365. }// End for while loop
  366. if ( nStep > MAX_ADJUST_VALUE)
  367. {
  368. nLoopTimes--;
  369. return false;
  370. }
  371. nStep *= 0.1;
  372. // 赋值
  373. matrixInputToHideWeightValue = cMatrixNewInputToHideWeight;
  374. matrixHideLayerValveValue = cMatrixNewHideLayerValve;
  375. matrixHideToOutputWeightValue = cMatrixNewHideToOutputWeight;
  376. matrixOutputLayerValveValue = cMatrixNewOutputLayerValve;
  377. cMatrixOutputLayerError = cMatrixNewOutputLayerError;
  378. nSystemErrorOld = nSystemErrorNew;
  379. // 显示数据和程序运行状态
  380. nSystemError = nSystemErrorOld;
  381. nTrainTimes = nLoopTimes;
  382. // 显示系统误差
  383. //char res_buffer[128] = {0};
  384. //sprintf(res_buffer,"%.16lf", nSystemError);
  385. //HWND hwnd = ::GetDlgItem (hWnd, ID_SYSTEM_ERROR);
  386. //::SetWindowText (hwnd, res_buffer);
  387. CString strSystemError;
  388. strSystemError.Format ("%.16lf", nSystemError);
  389. LPCTSTR lpstrSystemError = (LPCTSTR)strSystemError;
  390. HWND hwnd = ::GetDlgItem (hWnd, ID_SYSTEM_ERROR);
  391. ::SetWindowText (hwnd, lpstrSystemError);
  392. // 显示训练次数
  393. CString strTrainTimes;
  394. strTrainTimes.Format ("%u", nTrainTimes + 1);
  395. LPCTSTR lpstrTrainTimes = (LPCTSTR)strTrainTimes;
  396. hwnd = ::GetDlgItem (hWnd, ID_TRAIN_TIMES);
  397. ::SetWindowText (hwnd, lpstrTrainTimes);
  398. }// End the "for" loop
  399. return true;
  400. }
  401. /////////////////////////////////////////////////////////////////////////////
  402. // Back propagation ----> 前向计算(Only for Training)    //
  403. /////////////////////////////////////////////////////////////////////////////
  404. __declspec(dllexport) void BPForwardCalculate ( int nInputLayerNumber,
  405. int nHideLayerNumber,
  406. int nOutputLayerNumber,
  407. bool bSimulateDataFlag,
  408. int nComboFunc,
  409. CMatrix &matrixDemoDataInput,
  410. CMatrix &matrixInputLayerValue,
  411. CMatrix &matrixInputToHideWeightValue,
  412. CMatrix &matrixHideLayerValveValue,
  413. CMatrix &matrixHideLayerOutput,
  414. CMatrix &matrixHideToOutputWeightValue,
  415. CMatrix &matrixOutputLayerOutput,
  416. CMatrix &matrixOutputLayerValveValue,
  417. CMatrix &cMatrixExHideLayerValveValue,
  418. CMatrix &cMatrixExOutputLayerValveValue
  419.    )
  420. {
  421. if(bSimulateDataFlag)
  422. {
  423. CMatrix cMatrixInputLayerValue(matrixDemoDataInput.GetMatrixRowNumber (), nInputLayerNumber);
  424. // 得到样本的输入值
  425. matrixDemoDataInput.CopySubMatrix (cMatrixInputLayerValue, (unsigned int)0, (unsigned int)0);
  426. CMatrix cMatrixTInputLayerValue = cMatrixInputLayerValue.Transpose ();
  427. matrixInputLayerValue.CopyMatrix (cMatrixTInputLayerValue);
  428. }
  429. /////////////////////////////////////////////////////////////////////////
  430. // 得到所有样本的隐含层的净输入
  431. // 构造规则:
  432. // 1. 样本的数目做为矩阵行数;
  433. // 2. 单个样本的隐含层的数目做为矩阵的列数;
  434. // 3. 矩阵元素中的值即为对应的样本的隐含层的净输入:
  435. //    由 
  436. // cMatrixInputLayerValue * cMatrixInputToHideWeightValue 
  437. // + cMatrixHideLayerValveValue
  438. // 得到.
  439. //
  440. //CMatrix cMatrixExHideLayerValveValue;
  441. //cMatrixExHideLayerValveValue.nncpyi (matrixHideLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ());
  442. CMatrix cMatrixHideLayerPureInput(nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
  443. cMatrixHideLayerPureInput = matrixInputToHideWeightValue * matrixInputLayerValue;
  444. cMatrixHideLayerPureInput += cMatrixExHideLayerValveValue;
  445. /////////////////////////////////////////////////////////////////////
  446. // 算出所有样本的隐含层的输出
  447. // 构造规则:
  448. // 1. 隐含层的输出y与隐含层的输入x的关系可用函数表示
  449. // y = f(x)
  450. // 2. 矩阵的维数和隐含层的净输入矩阵的维数相等
  451. //
  452. CMatrix cMatrixHideLayerOutput(nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
  453. switch(nComboFunc)
  454. {
  455. case 0:
  456. cMatrixHideLayerOutput = cMatrixHideLayerPureInput.Sigmoid ();
  457. break;
  458. case 1:
  459. cMatrixHideLayerOutput = cMatrixHideLayerPureInput.tanh ();
  460. break;
  461. case 2:
  462. cMatrixHideLayerOutput = cMatrixHideLayerPureInput.Tansig();
  463. break;
  464. default:
  465. return;
  466. }
  467. matrixHideLayerOutput.CopyMatrix(cMatrixHideLayerOutput);
  468. /////////////////////////////////////////////////////////////////////
  469. // 得到所有样本输出层的净输入
  470. // 构造规则;
  471. // 1. 样本的数目做为矩阵的行数;
  472. // 2. 单个样本的输出层的数目做为矩阵的列数;
  473. // 3. 矩阵中元素的值即为对应样本的输出层的净输入:
  474. // 由
  475. // cMatrixHideLayerOutput * cMatrixHideToOutputWeightValue
  476. // + cMatrixOutputLayerValveValue
  477. // 得到
  478. //
  479. //CMatrix cMatrixExOutputLayerValveValue;
  480. //cMatrixExOutputLayerValveValue.nncpyi (matrixOutputLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ());
  481. CMatrix cMatrixOutputLayerPureInput(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
  482. cMatrixOutputLayerPureInput = matrixHideToOutputWeightValue * cMatrixHideLayerOutput;
  483. cMatrixOutputLayerPureInput  += cMatrixExOutputLayerValveValue;
  484. /////////////////////////////////////////////////////////////////////
  485. // 算出所有样本的输出层的输出
  486. // 构造规则:
  487. // 1. 矩阵的维数与得到的所有样本的输出层的净输入组成的矩阵一样;
  488. // 2. 输出层的输出y和输出层的输入可用关系式
  489. // y = f(x)
  490. // 表示
  491. //
  492. CMatrix cMatrixOutputLayerOutput(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
  493. switch(nComboFunc)
  494. {
  495. case 0:
  496. cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.Sigmoid ();
  497. break;
  498. case 1:
  499. cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.tanh ();
  500. break;
  501. case 2:
  502. cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.Tansig ();
  503. break;
  504. default:
  505. return ;
  506. }
  507. matrixOutputLayerOutput.CopyMatrix(cMatrixOutputLayerOutput);
  508. }
  509. /////////////////////////////////////////////////////////////////////////////
  510. // Back propagation ----> 前向计算(Only for Simulating)    //
  511. /////////////////////////////////////////////////////////////////////////////
  512. __declspec(dllexport) void BPForwardCalculate2( int nInputLayerNumber,
  513. int nHideLayerNumber,
  514. int nOutputLayerNumber,
  515. bool bSimulateDataFlag,
  516. int nComboFunc,
  517. CMatrix &matrixDemoDataInput,
  518. CMatrix &matrixInputLayerValue,
  519. CMatrix &matrixInputToHideWeightValue,
  520. CMatrix &matrixHideLayerValveValue,
  521. CMatrix &matrixHideLayerOutput,
  522. CMatrix &matrixHideToOutputWeightValue,
  523. CMatrix &matrixOutputLayerOutput,
  524. CMatrix &matrixOutputLayerValveValue
  525.    )
  526. {
  527. if(bSimulateDataFlag)
  528. {
  529. CMatrix cMatrixInputLayerValue(matrixDemoDataInput.GetMatrixRowNumber (), nInputLayerNumber);
  530. // 得到样本的输入值
  531. matrixDemoDataInput.CopySubMatrix (cMatrixInputLayerValue, (unsigned int)0, (unsigned int)0);
  532. CMatrix cMatrixTInputLayerValue = cMatrixInputLayerValue.Transpose ();
  533. matrixInputLayerValue.CopyMatrix (cMatrixTInputLayerValue);
  534. }
  535. /////////////////////////////////////////////////////////////////////////
  536. // 得到所有样本的隐含层的净输入
  537. // 构造规则:
  538. // 1. 样本的数目做为矩阵行数;
  539. // 2. 单个样本的隐含层的数目做为矩阵的列数;
  540. // 3. 矩阵元素中的值即为对应的样本的隐含层的净输入:
  541. //    由 
  542. // cMatrixInputLayerValue * cMatrixInputToHideWeightValue 
  543. // + cMatrixHideLayerValveValue
  544. // 得到.
  545. //
  546. CMatrix cMatrixExHideLayerValveValue;
  547. cMatrixExHideLayerValveValue.nncpyi (matrixHideLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ());
  548. CMatrix cMatrixHideLayerPureInput(nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
  549. cMatrixHideLayerPureInput = matrixInputToHideWeightValue * matrixInputLayerValue;
  550. cMatrixHideLayerPureInput += cMatrixExHideLayerValveValue;
  551. /////////////////////////////////////////////////////////////////////
  552. // 算出所有样本的隐含层的输出
  553. // 构造规则:
  554. // 1. 隐含层的输出y与隐含层的输入x的关系可用函数表示
  555. // y = f(x)
  556. // 2. 矩阵的维数和隐含层的净输入矩阵的维数相等
  557. //
  558. CMatrix cMatrixHideLayerOutput(nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
  559. switch(nComboFunc)
  560. {
  561. case 0:
  562. cMatrixHideLayerOutput = cMatrixHideLayerPureInput.Sigmoid ();
  563. break;
  564. case 1:
  565. cMatrixHideLayerOutput = cMatrixHideLayerPureInput.tanh ();
  566. break;
  567. case 2:
  568. cMatrixHideLayerOutput = cMatrixHideLayerPureInput.Tansig();
  569. break;
  570. default:
  571. return;
  572. }
  573. matrixHideLayerOutput.CopyMatrix(cMatrixHideLayerOutput);
  574. /////////////////////////////////////////////////////////////////////
  575. // 得到所有样本输出层的净输入
  576. // 构造规则;
  577. // 1. 样本的数目做为矩阵的行数;
  578. // 2. 单个样本的输出层的数目做为矩阵的列数;
  579. // 3. 矩阵中元素的值即为对应样本的输出层的净输入:
  580. // 由
  581. // cMatrixHideLayerOutput * cMatrixHideToOutputWeightValue
  582. // + cMatrixOutputLayerValveValue
  583. // 得到
  584. //
  585. CMatrix cMatrixExOutputLayerValveValue;
  586. cMatrixExOutputLayerValveValue.nncpyi (matrixOutputLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ());
  587. CMatrix cMatrixOutputLayerPureInput(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
  588. cMatrixOutputLayerPureInput = matrixHideToOutputWeightValue * cMatrixHideLayerOutput;
  589. cMatrixOutputLayerPureInput  += cMatrixExOutputLayerValveValue;
  590. /////////////////////////////////////////////////////////////////////
  591. // 算出所有样本的输出层的输出
  592. // 构造规则:
  593. // 1. 矩阵的维数与得到的所有样本的输出层的净输入组成的矩阵一样;
  594. // 2. 输出层的输出y和输出层的输入可用关系式
  595. // y = f(x)
  596. // 表示
  597. //
  598. CMatrix cMatrixOutputLayerOutput(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
  599. switch(nComboFunc)
  600. {
  601. case 0:
  602. cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.Sigmoid ();
  603. break;
  604. case 1:
  605. cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.tanh ();
  606. break;
  607. case 2:
  608. cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.Tansig ();
  609. break;
  610. default:
  611. return ;
  612. }
  613. matrixOutputLayerOutput.CopyMatrix(cMatrixOutputLayerOutput);
  614. }
  615. /////////////////////////////////////////////////////////////////////////////
  616. // Back propagation ----> 反馈计算    //
  617. /////////////////////////////////////////////////////////////////////////////
  618. __declspec(dllexport) bool BPDemoDataTrainRepeat ( int nInputLayerNumber,
  619. int nHideLayerNumber,
  620. int nOutputLayerNumber,
  621. bool bSimulateDataFlag,
  622. int nComboFunc,
  623. double nSystemErrorOld,
  624. double nSystemErrorNew,
  625. double nSystemErrorLevel,
  626. double nSystemError,
  627. double nStep,
  628. UINT nMaxTrainTimes,
  629. UINT nTrainTimes,
  630. DWORD ID_SYSTEM_ERROR,
  631. DWORD ID_TRAIN_TIMES,
  632. HWND  hWnd,
  633. CMatrix &matrixDemoDataInput,
  634. CMatrix &matrixInputLayerValue,
  635. CMatrix &matrixInputToHideWeightValue,
  636. CMatrix &matrixHideLayerValveValue,
  637. CMatrix &matrixHideLayerOutput,
  638. CMatrix &matrixHideToOutputWeightValue,
  639. CMatrix &matrixOutputLayerOutput,
  640. CMatrix &matrixOutputLayerValveValue
  641.  )
  642. {
  643. // 根据BP算法修正nStep的初始值
  644. nStep = 0.1;
  645. // 前向计算
  646. LMForwardCalculate (nInputLayerNumber,
  647. nHideLayerNumber,
  648. nOutputLayerNumber,
  649. bSimulateDataFlag,
  650. nComboFunc,
  651. matrixDemoDataInput,
  652. matrixInputLayerValue,
  653. matrixInputToHideWeightValue,
  654. matrixHideLayerValveValue,
  655. matrixHideLayerOutput,
  656. matrixHideToOutputWeightValue,
  657. matrixOutputLayerOutput,
  658. matrixOutputLayerValveValue
  659. );
  660. /////////////////////////////////////////////////////////////////////
  661. // 算出所有样本的输出层的delta矩阵
  662. // 构造规则:
  663. // 1. 样本的数目为矩阵的行数;
  664. // 2. 样本输出层的数目为矩阵的列数;
  665. // 3. 矩阵中的元素的值y为:
  666. // y = (前向计算出的输出层的值 - 样本的输出层的值) .* f'(net)
  667. //
  668. CMatrix cMatrixTDemoOutput(matrixDemoDataInput.GetMatrixRowNumber (), nOutputLayerNumber);
  669. // 得到样本中输出层的数据
  670. matrixDemoDataInput.CopySubMatrix (cMatrixTDemoOutput, (unsigned int)nInputLayerNumber, (unsigned int)0);
  671. CMatrix cMatrixDemoOutput = cMatrixTDemoOutput.Transpose ();
  672. // 得到样本中输出层的误差
  673. CMatrix cMatrixOutputLayerError(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
  674. cMatrixOutputLayerError = cMatrixDemoOutput - matrixOutputLayerOutput;
  675. nSystemErrorOld = cMatrixOutputLayerError.GetSystemError ();
  676. for(int nLoopTimes=1; nLoopTimes < nMaxTrainTimes; nLoopTimes++)
  677. {
  678. if(nSystemErrorOld < nSystemErrorLevel)
  679. {
  680. nLoopTimes--;
  681. break;
  682. }
  683. // 求输出层的delta值
  684. // 注意: 此处'/' 是 '点乘'!!!
  685. CMatrix cMatrixOutputLayerDelta (nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber());
  686. cMatrixOutputLayerDelta = (matrixOutputLayerOutput - matrixOutputLayerOutput / matrixOutputLayerOutput) / cMatrixOutputLayerError;
  687. CMatrix cMatrixTHideToOutputWeightValue (matrixHideToOutputWeightValue.GetMatrixColNumber(), matrixHideToOutputWeightValue.GetMatrixRowNumber());
  688. cMatrixTHideToOutputWeightValue = matrixHideToOutputWeightValue.Transpose();
  689. // 求隐含层的delta值
  690. // 注意: 此处'/' 是 '点乘'!!!
  691. CMatrix cMatrixHideLayerDelta;
  692. cMatrixHideLayerDelta.CopyMatrix ( (matrixHideLayerOutput - (matrixHideLayerOutput / matrixHideLayerOutput)) / ( cMatrixTHideToOutputWeightValue * cMatrixOutputLayerDelta) );
  693. // 定义新的输入层到隐含层的权值
  694. CMatrix cMatrixNewInputToHideWeight (matrixInputToHideWeightValue.GetMatrixRowNumber (), matrixInputToHideWeightValue.GetMatrixColNumber ());
  695. // 定义的新的隐含层的阀值
  696. CMatrix cMatrixNewHideLayerValve (nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
  697. // 定义新的隐含层到输出层的权值
  698. CMatrix cMatrixNewHideToOutputWeight (matrixHideToOutputWeightValue.GetMatrixRowNumber (), matrixHideToOutputWeightValue.GetMatrixColNumber ());
  699. // 定义新的输出层的阀值
  700. CMatrix cMatrixNewOutputLayerValve (nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
  701. // 定义新的误差矩阵
  702. CMatrix cMatrixNewOutputLayerError(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
  703. // 权值和阀值调整
  704. cMatrixNewHideToOutputWeight = cMatrixOutputLayerDelta * (matrixHideLayerOutput.Transpose ()) * (nStep);
  705. cMatrixNewOutputLayerValve = cMatrixOutputLayerDelta;
  706. cMatrixNewInputToHideWeight = cMatrixHideLayerDelta * (matrixInputLayerValue.Transpose ()) * (nStep);
  707. cMatrixNewHideLayerValve = cMatrixHideLayerDelta;
  708. // 赋值
  709. matrixInputToHideWeightValue += cMatrixNewInputToHideWeight;
  710. CMatrix cMatrixExHideLayerValveValue;
  711. cMatrixExHideLayerValveValue.nncpyi (matrixHideLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ());
  712. cMatrixExHideLayerValveValue += cMatrixNewHideLayerValve;
  713. matrixHideToOutputWeightValue += cMatrixNewHideToOutputWeight;
  714. CMatrix cMatrixExOutputLayerValveValue;
  715. cMatrixExOutputLayerValveValue.nncpyi (matrixOutputLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ());
  716. cMatrixExOutputLayerValveValue += cMatrixNewOutputLayerValve;
  717. // 前向计算
  718. BPForwardCalculate (nInputLayerNumber,
  719. nHideLayerNumber,
  720. nOutputLayerNumber,
  721. bSimulateDataFlag,
  722. nComboFunc,
  723. matrixDemoDataInput,
  724. matrixInputLayerValue,
  725. matrixInputToHideWeightValue,
  726. matrixHideLayerValveValue,
  727. matrixHideLayerOutput,
  728. matrixHideToOutputWeightValue,
  729. matrixOutputLayerOutput,
  730. matrixOutputLayerValveValue,
  731. cMatrixExHideLayerValveValue,
  732. cMatrixExOutputLayerValveValue
  733. );
  734. cMatrixNewOutputLayerError = cMatrixDemoOutput - matrixOutputLayerOutput;
  735. nSystemErrorNew =  cMatrixNewOutputLayerError.GetSystemError ();
  736. cMatrixOutputLayerError = cMatrixNewOutputLayerError;
  737. if(nSystemErrorNew < nSystemErrorOld)
  738. {
  739. nSystemErrorOld = nSystemErrorNew;
  740. }
  741. else
  742. {
  743. nStep *= -0.1;
  744. }
  745. // 显示数据和程序运行状态
  746. nSystemError = nSystemErrorOld;
  747. nTrainTimes = nLoopTimes;
  748. // 显示系统误差
  749. CString strSystemError;
  750. strSystemError.Format ("%lf", nSystemError);
  751. LPCTSTR lpstrSystemError = (LPCTSTR)strSystemError;
  752. HWND hwnd = ::GetDlgItem (hWnd, ID_SYSTEM_ERROR);
  753. ::SetWindowText (hwnd, lpstrSystemError);
  754. // 显示训练次数
  755. CString strTrainTimes;
  756. strTrainTimes.Format ("%u", nTrainTimes + 1);
  757. LPCTSTR lpstrTrainTimes = (LPCTSTR)strTrainTimes;
  758. hwnd = ::GetDlgItem (hWnd, ID_TRAIN_TIMES);
  759. ::SetWindowText (hwnd, lpstrTrainTimes);
  760. }// End the "for" loop
  761. return true;
  762. }