Procedure.cpp
上传用户:guanx8y8
上传日期:2007-07-30
资源大小:326k
文件大小:33k
- /////////////////////////////////////////////////////////////////////////////
- // Procedure.cpp
- // the implementation of the specified arithmetic
- // Author : freeia
- // E-mail : freeia@163.com
- // Date : 3/20/2003
- /////////////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "Matrix.h"
- #include "AllDef.h"
- /////////////////////////////////////////////////////////////////////////////
- // Levenberg-Marquart ----> 第一次前向计算初始化 //
- /////////////////////////////////////////////////////////////////////////////
- __declspec (dllexport) void LMForwardCalculateInit( int nInputLayerNumber,
- int nHideLayerNumber,
- int nOutputLayerNumber,
- CMatrix &matrixDemoDataInput,
- CMatrix &matrixInputLayerValue,
- CMatrix &matrixInputToHideWeightValue,
- CMatrix &matrixHideLayerValveValue,
- CMatrix &matrixHideToOutputWeightValue,
- CMatrix &matrixOutputLayerValveValue
- )
- {
- /************************************************************************
- * --------->Use Matlab Method <--------- *
- ************************************************************************/
-
- /////////////////////////////////////////////////////////////////////////
- // 构造输入层元素的矩阵
- // 构造规则:
- // 1. 样本数目做为矩阵的行数;
- // 2. 单个样本的输入层的数目做为矩阵的列数;
- // 3. 矩阵中的元素即为对应的输入层的值
- //
- CMatrix cMatrixInputLayerValue(matrixDemoDataInput.GetMatrixRowNumber (), nInputLayerNumber);
- // 得到样本的输入值
- matrixDemoDataInput.CopySubMatrix (cMatrixInputLayerValue,(unsigned int)0,(unsigned int)0);
- CMatrix cMatrixTInputLayerValue = cMatrixInputLayerValue.Transpose ();
- matrixInputLayerValue.CopyMatrix (cMatrixTInputLayerValue);
- /////////////////////////////////////////////////////////////////////////
- // 构造权值矩阵 -----> 由单个样本输入层与隐含层之间的权值做为元素组成
- // 构造规则:
- // 1. 单个样本的输入层的数目做为矩阵行数;
- // 2. 单个样本的隐含层的数目做为矩阵的列数;
- // 3. 对矩阵中的元素进行随机初始化,值在(-1,1)之间;
- // 4. 所有样本的输入层和隐含层的数目是相等的;
- // 5. 所有样本使用的是同一个权值矩阵.
- //
- CMatrix cMatrixInputToHideWeightValue(nHideLayerNumber, nInputLayerNumber);
- // 随机初始化矩阵内元素的值
- cMatrixInputToHideWeightValue.RandomInitialize ();
- matrixInputToHideWeightValue.CopyMatrix (cMatrixInputToHideWeightValue);
- /////////////////////////////////////////////////////////////////////
- // 构造样本隐含层的阀值矩阵
- // 构造规则:
- // 1. 样本的数目做为矩阵行数;
- // 2. 单个样本的隐含层的数目做为矩阵的列数;
- // 3. 随机初始化矩阵中的元素,使值在(-1,1)之间;
- // 4. 矩阵中每行的数据都和第一行数据相对应的位置相等.
- //
- CMatrix cMatrixHideLayerValveValue(nHideLayerNumber,(unsigned int)1);
- // 随机初始化矩阵内元素的值
- cMatrixHideLayerValveValue.RandomInitialize ();
- matrixHideLayerValveValue.CopyMatrix(cMatrixHideLayerValveValue);
- /////////////////////////////////////////////////////////////////////
- // 构造权值矩阵 -----> 由单个样本的隐含层与输出层之间权值做为元素
- // 组成
- // 构造规则:
- // 1. 单个样本的隐含层的数目做为矩阵的行数;
- // 2. 单个样本的输出层的数目做为矩阵的列数;
- // 3. 对矩阵中的元素进行随机初始化,值在(-1,1)之间;
- // 4. 所有样本的隐含层和输出层的数目是相等的;
- // 5. 所有样本使用的是同一个权值矩阵.
- //
- CMatrix cMatrixHideToOutputWeightValue(nOutputLayerNumber, nHideLayerNumber);
- // 对矩阵的元素随机初始化
- cMatrixHideToOutputWeightValue.RandomInitialize ();
- matrixHideToOutputWeightValue.CopyMatrix (cMatrixHideToOutputWeightValue);
- /////////////////////////////////////////////////////////////////////
- // 构造样本的输出层的阀值矩阵
- // 构造规则:
- // 1. 样本的数目做为矩阵的行数;
- // 2. 单个样本的输出层的数目做为矩阵的列数;
- // 3. 随机初始化矩阵中的元素,使值在(-1,1)之间;
- // 4. 矩阵中每行的数据都和第一行数据相对应的位置相等.
- //
- CMatrix cMatrixOutputLayerValveValue(nOutputLayerNumber,(unsigned int)1);
- // 随机初始化矩阵内元素的值
- cMatrixOutputLayerValveValue.RandomInitialize ();
- matrixOutputLayerValveValue.CopyMatrix(cMatrixOutputLayerValveValue);
- }
- /////////////////////////////////////////////////////////////////////////////
- // Levenberg-Marquart ----> 前向计算 //
- /////////////////////////////////////////////////////////////////////////////
- __declspec(dllexport) void LMForwardCalculate ( int nInputLayerNumber,
- int nHideLayerNumber,
- int nOutputLayerNumber,
- bool bSimulateDataFlag,
- int nComboFunc,
- CMatrix &matrixDemoDataInput,
- CMatrix &matrixInputLayerValue,
- CMatrix &matrixInputToHideWeightValue,
- CMatrix &matrixHideLayerValveValue,
- CMatrix &matrixHideLayerOutput,
- CMatrix &matrixHideToOutputWeightValue,
- CMatrix &matrixOutputLayerOutput,
- CMatrix &matrixOutputLayerValveValue
- )
- {
- if(bSimulateDataFlag)
- {
- CMatrix cMatrixInputLayerValue(matrixDemoDataInput.GetMatrixRowNumber (), nInputLayerNumber);
- // 得到样本的输入值
- matrixDemoDataInput.CopySubMatrix (cMatrixInputLayerValue, (unsigned int)0, (unsigned int)0);
- CMatrix cMatrixTInputLayerValue = cMatrixInputLayerValue.Transpose ();
- matrixInputLayerValue.CopyMatrix (cMatrixTInputLayerValue);
- }
- /////////////////////////////////////////////////////////////////////////
- // 得到所有样本的隐含层的净输入
- // 构造规则:
- // 1. 样本的数目做为矩阵行数;
- // 2. 单个样本的隐含层的数目做为矩阵的列数;
- // 3. 矩阵元素中的值即为对应的样本的隐含层的净输入:
- // 由
- // cMatrixInputLayerValue * cMatrixInputToHideWeightValue
- // + cMatrixHideLayerValveValue
- // 得到.
- //
-
- CMatrix cMatrixExHideLayerValveValue;
- cMatrixExHideLayerValveValue.nncpyi (matrixHideLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ());
- CMatrix cMatrixHideLayerPureInput(nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
- cMatrixHideLayerPureInput = matrixInputToHideWeightValue * matrixInputLayerValue;
- cMatrixHideLayerPureInput += cMatrixExHideLayerValveValue;
- /////////////////////////////////////////////////////////////////////
- // 算出所有样本的隐含层的输出
- // 构造规则:
- // 1. 隐含层的输出y与隐含层的输入x的关系可用函数表示
- // y = f(x)
- // 2. 矩阵的维数和隐含层的净输入矩阵的维数相等
- //
- CMatrix cMatrixHideLayerOutput(nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
- switch(nComboFunc)
- {
- case 0:
- cMatrixHideLayerOutput = cMatrixHideLayerPureInput.Sigmoid ();
- break;
- case 1:
- cMatrixHideLayerOutput = cMatrixHideLayerPureInput.tanh ();
- break;
- case 2:
- cMatrixHideLayerOutput = cMatrixHideLayerPureInput.Tansig();
- break;
- default:
- return;
- }
-
- matrixHideLayerOutput.CopyMatrix(cMatrixHideLayerOutput);
- /////////////////////////////////////////////////////////////////////
- // 得到所有样本输出层的净输入
- // 构造规则;
- // 1. 样本的数目做为矩阵的行数;
- // 2. 单个样本的输出层的数目做为矩阵的列数;
- // 3. 矩阵中元素的值即为对应样本的输出层的净输入:
- // 由
- // cMatrixHideLayerOutput * cMatrixHideToOutputWeightValue
- // + cMatrixOutputLayerValveValue
- // 得到
- //
- CMatrix cMatrixExOutputLayerValveValue;
- cMatrixExOutputLayerValveValue.nncpyi (matrixOutputLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ());
- CMatrix cMatrixOutputLayerPureInput(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
- cMatrixOutputLayerPureInput = matrixHideToOutputWeightValue * cMatrixHideLayerOutput;
- cMatrixOutputLayerPureInput += cMatrixExOutputLayerValveValue;
- /////////////////////////////////////////////////////////////////////
- // 算出所有样本的输出层的输出
- // 构造规则:
- // 1. 矩阵的维数与得到的所有样本的输出层的净输入组成的矩阵一样;
- // 2. 输出层的输出y和输出层的输入可用关系式
- // y = f(x)
- // 表示
- //
- CMatrix cMatrixOutputLayerOutput(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
- switch(nComboFunc)
- {
- case 0:
- cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.Sigmoid ();
- break;
- case 1:
- cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.tanh ();
- break;
- case 2:
- cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.Tansig ();
- break;
- default:
- return ;
- }
- matrixOutputLayerOutput.CopyMatrix(cMatrixOutputLayerOutput);
- }
- /////////////////////////////////////////////////////////////////////////////
- // Levenberg-Marquart ----> 反馈计算 //
- /////////////////////////////////////////////////////////////////////////////
- __declspec(dllexport) bool LMDemoDataTrainRepeat ( int nInputLayerNumber,
- int nHideLayerNumber,
- int nOutputLayerNumber,
- bool bSimulateDataFlag,
- int nComboFunc,
- double nSystemErrorOld,
- double nSystemErrorNew,
- double nSystemErrorLevel,
- double nSystemError,
- double nStep,
- UINT nMaxTrainTimes,
- UINT nTrainTimes,
- DWORD ID_SYSTEM_ERROR,
- DWORD ID_TRAIN_TIMES,
- HWND hWnd,
- CMatrix &matrixDemoDataInput,
- CMatrix &matrixInputLayerValue,
- CMatrix &matrixInputToHideWeightValue,
- CMatrix &matrixHideLayerValveValue,
- CMatrix &matrixHideLayerOutput,
- CMatrix &matrixHideToOutputWeightValue,
- CMatrix &matrixOutputLayerOutput,
- CMatrix &matrixOutputLayerValveValue
- )
- {
- LMForwardCalculate (nInputLayerNumber,
- nHideLayerNumber,
- nOutputLayerNumber,
- bSimulateDataFlag,
- nComboFunc,
- matrixDemoDataInput,
- matrixInputLayerValue,
- matrixInputToHideWeightValue,
- matrixHideLayerValveValue,
- matrixHideLayerOutput,
- matrixHideToOutputWeightValue,
- matrixOutputLayerOutput,
- matrixOutputLayerValveValue
- );
-
- /////////////////////////////////////////////////////////////////////
- // 算出所有样本的输出层的delta矩阵
- // 构造规则:
- // 1. 样本的数目为矩阵的行数;
- // 2. 样本输出层的数目为矩阵的列数;
- // 3. 矩阵中的元素的值y为:
- // y = -(前向计算出的输出层的值 - 样本的输出层的值) * f'(net)
- //
- CMatrix cMatrixTDemoOutput(matrixDemoDataInput.GetMatrixRowNumber (), nOutputLayerNumber);
-
- // 得到样本中输出层的数据
- matrixDemoDataInput.CopySubMatrix (cMatrixTDemoOutput, (unsigned int)nInputLayerNumber, (unsigned int)0);
- CMatrix cMatrixDemoOutput = cMatrixTDemoOutput.Transpose ();
- // 得到样本中输出层的误差
- CMatrix cMatrixOutputLayerError(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
- cMatrixOutputLayerError = cMatrixDemoOutput - matrixOutputLayerOutput;
-
- nSystemErrorOld = cMatrixOutputLayerError.GetSystemError ();
- for(int nLoopTimes=1; nLoopTimes < nMaxTrainTimes; nLoopTimes++)
- {
- if(nSystemErrorOld < nSystemErrorLevel)
- {
- nLoopTimes--;
- break;
- }
- CMatrix cMatrixExHideLayerOutput;
- cMatrixExHideLayerOutput.nncpyi (matrixHideLayerOutput, nOutputLayerNumber);
- CMatrix cMatrixOutputLayerDelta (nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber());
-
- // 注意: 此处'/' 是 '点乘'!!!
- cMatrixOutputLayerDelta = 1 - matrixOutputLayerOutput / matrixOutputLayerOutput;
- CMatrix cMatrixExOutputLayerDelta;
- cMatrixExOutputLayerDelta.nncpyd (cMatrixOutputLayerDelta);
-
- cMatrixExOutputLayerDelta = cMatrixExOutputLayerDelta * (-1.0);
-
- CMatrix cMatrixTHideToOutputWeightValue (matrixHideToOutputWeightValue.GetMatrixColNumber(), matrixHideToOutputWeightValue.GetMatrixRowNumber());
- cMatrixTHideToOutputWeightValue = matrixHideToOutputWeightValue.Transpose();
- CMatrix cMatrixExHideLayerDelta;
- // 注意: 此处'/' 是 '点乘'!!!
- cMatrixExHideLayerDelta.CopyMatrix ( (1 - (cMatrixExHideLayerOutput / cMatrixExHideLayerOutput)) / ( cMatrixTHideToOutputWeightValue * cMatrixExOutputLayerDelta) );
-
- CMatrix cMatrixExInputLayerValue;
- cMatrixExInputLayerValue.nncpyi (matrixInputLayerValue, nOutputLayerNumber);
-
- CMatrix cMatrixJ11;
- cMatrixJ11.nncpy (cMatrixExHideLayerDelta.Transpose(), cMatrixExInputLayerValue.GetMatrixRowNumber ());
- CMatrix cMatrixJ12;
- cMatrixJ12.nncpyi(cMatrixExInputLayerValue.Transpose (), cMatrixExHideLayerDelta.GetMatrixRowNumber());
- CMatrix cMatrixJ1;
- // 注意: 此处'/' 是 '点乘'!!!
- cMatrixJ1.CopyMatrix (cMatrixJ11 / cMatrixJ12);
- CMatrix cMatrixJ21;
- cMatrixJ21.nncpy (cMatrixExOutputLayerDelta.Transpose (), cMatrixExHideLayerOutput.GetMatrixRowNumber ());
- CMatrix cMatrixJ22;
- cMatrixJ22.nncpyi (cMatrixExHideLayerOutput.Transpose (), cMatrixExOutputLayerDelta.GetMatrixRowNumber ());
- CMatrix cMatrixJ2;
- // 注意: 此处'/' 是 '点乘'!!!
- cMatrixJ2.CopyMatrix (cMatrixJ21 / cMatrixJ22);
-
- CMatrix cMatrixZ;
- cMatrixZ.CopyMatrix (MergeMatrix(MergeMatrix(MergeMatrix(cMatrixJ1, cMatrixExHideLayerDelta.Transpose ()), cMatrixJ2), cMatrixExOutputLayerDelta.Transpose ()));
- CMatrix cMatrixMOutputLayerError;
- cMatrixMOutputLayerError.CopyMatrix ( cMatrixOutputLayerError.MergeColumnsToColumnVector () );
- CMatrix cMatrixJE;
- cMatrixJE.CopyMatrix ( (cMatrixZ.Transpose ()) * cMatrixMOutputLayerError );
- CMatrix cMatrixJJ;
- cMatrixJJ.CopyMatrix ( (cMatrixZ.Transpose ()) * cMatrixZ );
-
- // 定义新的输入层到隐含层的权值
- CMatrix cMatrixNewInputToHideWeight;
- // 定义的新的隐含层的阀值
- CMatrix cMatrixNewHideLayerValve;
- // 定义新的隐含层到输出层的权值
- CMatrix cMatrixNewHideToOutputWeight;
- // 定义新的输出层的阀值
- CMatrix cMatrixNewOutputLayerValve;
- // 定义新的误差矩阵
- CMatrix cMatrixNewOutputLayerError(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
- /////////////////////////////////////////////////////////////////
- // the weight value is adjusted
- while(nStep <= MAX_ADJUST_VALUE)
- {
- CMatrix cMatrixI (cMatrixZ.GetMatrixColNumber (), cMatrixZ.GetMatrixColNumber ());
- cMatrixI.Eye ();
- CMatrix cMatrixDX;
- cMatrixDX.CopyMatrix ( (((cMatrixJJ + cMatrixI * nStep).Inverse ()) * cMatrixJE) * (-1.0) );
-
- /////////////////////////////////////////////////////////////////////////
- // 拆分cMatrixDX矩阵
- unsigned int nIndex = 0;
-
- // 得到输入层到隐含层的权值的修正量
- CMatrix cMatrixInputToHideWeightChange(nHideLayerNumber, nInputLayerNumber);
- cMatrixDX.CopySubMatrixFromVector (cMatrixInputToHideWeightChange, nIndex);
- nIndex += nHideLayerNumber * nInputLayerNumber;
- // 得到隐含层阀值的修正量
- CMatrix cMatrixHideLayerValveChange (nHideLayerNumber, (unsigned int)1);
-
- cMatrixDX.CopySubMatrixFromVector (cMatrixHideLayerValveChange, nIndex);
- nIndex += nHideLayerNumber;
- // 得到隐含层到输出层的权值的修正量
- CMatrix cMatrixHideToOutputWeightChange (nOutputLayerNumber, nHideLayerNumber);
-
- cMatrixDX.CopySubMatrixFromVector (cMatrixHideToOutputWeightChange, nIndex);
- nIndex += nOutputLayerNumber * nHideLayerNumber;
- // 得到输出层阀值的修正值
- CMatrix cMatrixOutputValveChange (nOutputLayerNumber, (unsigned int)1);
- cMatrixDX.CopySubMatrixFromVector (cMatrixOutputValveChange, nIndex);
-
- cMatrixNewInputToHideWeight.CopyMatrix (matrixInputToHideWeightValue + cMatrixInputToHideWeightChange);
- cMatrixNewHideLayerValve.CopyMatrix (matrixHideLayerValveValue + cMatrixHideLayerValveChange);
- cMatrixNewHideToOutputWeight.CopyMatrix (matrixHideToOutputWeightValue + cMatrixHideToOutputWeightChange);
- cMatrixNewOutputLayerValve.CopyMatrix (matrixOutputLayerValveValue + cMatrixOutputValveChange);
-
- // 前向计算
- LMForwardCalculate (nInputLayerNumber,
- nHideLayerNumber,
- nOutputLayerNumber,
- bSimulateDataFlag,
- nComboFunc,
- matrixDemoDataInput,
- matrixInputLayerValue,
- cMatrixNewInputToHideWeight,
- cMatrixNewHideLayerValve,
- matrixHideLayerOutput,
- cMatrixNewHideToOutputWeight,
- matrixOutputLayerOutput,
- cMatrixNewOutputLayerValve
- );
-
- cMatrixNewOutputLayerError = cMatrixDemoOutput - matrixOutputLayerOutput;
- nSystemErrorNew = cMatrixNewOutputLayerError.GetSystemError ();
- if(nSystemErrorNew < nSystemErrorOld)
- {
- break;
- }
- else
- {
- nStep *= 10;
- }
-
- }// End for while loop
- if ( nStep > MAX_ADJUST_VALUE)
- {
- nLoopTimes--;
- return false;
- }
- nStep *= 0.1;
- // 赋值
- matrixInputToHideWeightValue = cMatrixNewInputToHideWeight;
- matrixHideLayerValveValue = cMatrixNewHideLayerValve;
- matrixHideToOutputWeightValue = cMatrixNewHideToOutputWeight;
- matrixOutputLayerValveValue = cMatrixNewOutputLayerValve;
- cMatrixOutputLayerError = cMatrixNewOutputLayerError;
- nSystemErrorOld = nSystemErrorNew;
- // 显示数据和程序运行状态
- nSystemError = nSystemErrorOld;
- nTrainTimes = nLoopTimes;
- // 显示系统误差
- //char res_buffer[128] = {0};
- //sprintf(res_buffer,"%.16lf", nSystemError);
- //HWND hwnd = ::GetDlgItem (hWnd, ID_SYSTEM_ERROR);
- //::SetWindowText (hwnd, res_buffer);
- CString strSystemError;
- strSystemError.Format ("%.16lf", nSystemError);
- LPCTSTR lpstrSystemError = (LPCTSTR)strSystemError;
- HWND hwnd = ::GetDlgItem (hWnd, ID_SYSTEM_ERROR);
- ::SetWindowText (hwnd, lpstrSystemError);
-
-
- // 显示训练次数
- CString strTrainTimes;
- strTrainTimes.Format ("%u", nTrainTimes + 1);
- LPCTSTR lpstrTrainTimes = (LPCTSTR)strTrainTimes;
- hwnd = ::GetDlgItem (hWnd, ID_TRAIN_TIMES);
- ::SetWindowText (hwnd, lpstrTrainTimes);
- }// End the "for" loop
-
- return true;
- }
- /////////////////////////////////////////////////////////////////////////////
- // Back propagation ----> 前向计算(Only for Training) //
- /////////////////////////////////////////////////////////////////////////////
- __declspec(dllexport) void BPForwardCalculate ( int nInputLayerNumber,
- int nHideLayerNumber,
- int nOutputLayerNumber,
- bool bSimulateDataFlag,
- int nComboFunc,
- CMatrix &matrixDemoDataInput,
- CMatrix &matrixInputLayerValue,
- CMatrix &matrixInputToHideWeightValue,
- CMatrix &matrixHideLayerValveValue,
- CMatrix &matrixHideLayerOutput,
- CMatrix &matrixHideToOutputWeightValue,
- CMatrix &matrixOutputLayerOutput,
- CMatrix &matrixOutputLayerValveValue,
- CMatrix &cMatrixExHideLayerValveValue,
- CMatrix &cMatrixExOutputLayerValveValue
- )
- {
- if(bSimulateDataFlag)
- {
- CMatrix cMatrixInputLayerValue(matrixDemoDataInput.GetMatrixRowNumber (), nInputLayerNumber);
- // 得到样本的输入值
- matrixDemoDataInput.CopySubMatrix (cMatrixInputLayerValue, (unsigned int)0, (unsigned int)0);
- CMatrix cMatrixTInputLayerValue = cMatrixInputLayerValue.Transpose ();
- matrixInputLayerValue.CopyMatrix (cMatrixTInputLayerValue);
- }
- /////////////////////////////////////////////////////////////////////////
- // 得到所有样本的隐含层的净输入
- // 构造规则:
- // 1. 样本的数目做为矩阵行数;
- // 2. 单个样本的隐含层的数目做为矩阵的列数;
- // 3. 矩阵元素中的值即为对应的样本的隐含层的净输入:
- // 由
- // cMatrixInputLayerValue * cMatrixInputToHideWeightValue
- // + cMatrixHideLayerValveValue
- // 得到.
- //
-
- //CMatrix cMatrixExHideLayerValveValue;
- //cMatrixExHideLayerValveValue.nncpyi (matrixHideLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ());
- CMatrix cMatrixHideLayerPureInput(nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
- cMatrixHideLayerPureInput = matrixInputToHideWeightValue * matrixInputLayerValue;
- cMatrixHideLayerPureInput += cMatrixExHideLayerValveValue;
- /////////////////////////////////////////////////////////////////////
- // 算出所有样本的隐含层的输出
- // 构造规则:
- // 1. 隐含层的输出y与隐含层的输入x的关系可用函数表示
- // y = f(x)
- // 2. 矩阵的维数和隐含层的净输入矩阵的维数相等
- //
- CMatrix cMatrixHideLayerOutput(nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
- switch(nComboFunc)
- {
- case 0:
- cMatrixHideLayerOutput = cMatrixHideLayerPureInput.Sigmoid ();
- break;
- case 1:
- cMatrixHideLayerOutput = cMatrixHideLayerPureInput.tanh ();
- break;
- case 2:
- cMatrixHideLayerOutput = cMatrixHideLayerPureInput.Tansig();
- break;
- default:
- return;
- }
-
- matrixHideLayerOutput.CopyMatrix(cMatrixHideLayerOutput);
- /////////////////////////////////////////////////////////////////////
- // 得到所有样本输出层的净输入
- // 构造规则;
- // 1. 样本的数目做为矩阵的行数;
- // 2. 单个样本的输出层的数目做为矩阵的列数;
- // 3. 矩阵中元素的值即为对应样本的输出层的净输入:
- // 由
- // cMatrixHideLayerOutput * cMatrixHideToOutputWeightValue
- // + cMatrixOutputLayerValveValue
- // 得到
- //
- //CMatrix cMatrixExOutputLayerValveValue;
- //cMatrixExOutputLayerValveValue.nncpyi (matrixOutputLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ());
- CMatrix cMatrixOutputLayerPureInput(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
- cMatrixOutputLayerPureInput = matrixHideToOutputWeightValue * cMatrixHideLayerOutput;
- cMatrixOutputLayerPureInput += cMatrixExOutputLayerValveValue;
- /////////////////////////////////////////////////////////////////////
- // 算出所有样本的输出层的输出
- // 构造规则:
- // 1. 矩阵的维数与得到的所有样本的输出层的净输入组成的矩阵一样;
- // 2. 输出层的输出y和输出层的输入可用关系式
- // y = f(x)
- // 表示
- //
- CMatrix cMatrixOutputLayerOutput(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
- switch(nComboFunc)
- {
- case 0:
- cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.Sigmoid ();
- break;
- case 1:
- cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.tanh ();
- break;
- case 2:
- cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.Tansig ();
- break;
- default:
- return ;
- }
- matrixOutputLayerOutput.CopyMatrix(cMatrixOutputLayerOutput);
- }
- /////////////////////////////////////////////////////////////////////////////
- // Back propagation ----> 前向计算(Only for Simulating) //
- /////////////////////////////////////////////////////////////////////////////
- __declspec(dllexport) void BPForwardCalculate2( int nInputLayerNumber,
- int nHideLayerNumber,
- int nOutputLayerNumber,
- bool bSimulateDataFlag,
- int nComboFunc,
- CMatrix &matrixDemoDataInput,
- CMatrix &matrixInputLayerValue,
- CMatrix &matrixInputToHideWeightValue,
- CMatrix &matrixHideLayerValveValue,
- CMatrix &matrixHideLayerOutput,
- CMatrix &matrixHideToOutputWeightValue,
- CMatrix &matrixOutputLayerOutput,
- CMatrix &matrixOutputLayerValveValue
- )
- {
- if(bSimulateDataFlag)
- {
- CMatrix cMatrixInputLayerValue(matrixDemoDataInput.GetMatrixRowNumber (), nInputLayerNumber);
- // 得到样本的输入值
- matrixDemoDataInput.CopySubMatrix (cMatrixInputLayerValue, (unsigned int)0, (unsigned int)0);
- CMatrix cMatrixTInputLayerValue = cMatrixInputLayerValue.Transpose ();
- matrixInputLayerValue.CopyMatrix (cMatrixTInputLayerValue);
- }
- /////////////////////////////////////////////////////////////////////////
- // 得到所有样本的隐含层的净输入
- // 构造规则:
- // 1. 样本的数目做为矩阵行数;
- // 2. 单个样本的隐含层的数目做为矩阵的列数;
- // 3. 矩阵元素中的值即为对应的样本的隐含层的净输入:
- // 由
- // cMatrixInputLayerValue * cMatrixInputToHideWeightValue
- // + cMatrixHideLayerValveValue
- // 得到.
- //
-
- CMatrix cMatrixExHideLayerValveValue;
- cMatrixExHideLayerValveValue.nncpyi (matrixHideLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ());
- CMatrix cMatrixHideLayerPureInput(nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
- cMatrixHideLayerPureInput = matrixInputToHideWeightValue * matrixInputLayerValue;
- cMatrixHideLayerPureInput += cMatrixExHideLayerValveValue;
- /////////////////////////////////////////////////////////////////////
- // 算出所有样本的隐含层的输出
- // 构造规则:
- // 1. 隐含层的输出y与隐含层的输入x的关系可用函数表示
- // y = f(x)
- // 2. 矩阵的维数和隐含层的净输入矩阵的维数相等
- //
- CMatrix cMatrixHideLayerOutput(nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
- switch(nComboFunc)
- {
- case 0:
- cMatrixHideLayerOutput = cMatrixHideLayerPureInput.Sigmoid ();
- break;
- case 1:
- cMatrixHideLayerOutput = cMatrixHideLayerPureInput.tanh ();
- break;
- case 2:
- cMatrixHideLayerOutput = cMatrixHideLayerPureInput.Tansig();
- break;
- default:
- return;
- }
-
- matrixHideLayerOutput.CopyMatrix(cMatrixHideLayerOutput);
- /////////////////////////////////////////////////////////////////////
- // 得到所有样本输出层的净输入
- // 构造规则;
- // 1. 样本的数目做为矩阵的行数;
- // 2. 单个样本的输出层的数目做为矩阵的列数;
- // 3. 矩阵中元素的值即为对应样本的输出层的净输入:
- // 由
- // cMatrixHideLayerOutput * cMatrixHideToOutputWeightValue
- // + cMatrixOutputLayerValveValue
- // 得到
- //
- CMatrix cMatrixExOutputLayerValveValue;
- cMatrixExOutputLayerValveValue.nncpyi (matrixOutputLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ());
- CMatrix cMatrixOutputLayerPureInput(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
- cMatrixOutputLayerPureInput = matrixHideToOutputWeightValue * cMatrixHideLayerOutput;
- cMatrixOutputLayerPureInput += cMatrixExOutputLayerValveValue;
- /////////////////////////////////////////////////////////////////////
- // 算出所有样本的输出层的输出
- // 构造规则:
- // 1. 矩阵的维数与得到的所有样本的输出层的净输入组成的矩阵一样;
- // 2. 输出层的输出y和输出层的输入可用关系式
- // y = f(x)
- // 表示
- //
- CMatrix cMatrixOutputLayerOutput(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
- switch(nComboFunc)
- {
- case 0:
- cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.Sigmoid ();
- break;
- case 1:
- cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.tanh ();
- break;
- case 2:
- cMatrixOutputLayerOutput = cMatrixOutputLayerPureInput.Tansig ();
- break;
- default:
- return ;
- }
- matrixOutputLayerOutput.CopyMatrix(cMatrixOutputLayerOutput);
- }
- /////////////////////////////////////////////////////////////////////////////
- // Back propagation ----> 反馈计算 //
- /////////////////////////////////////////////////////////////////////////////
- __declspec(dllexport) bool BPDemoDataTrainRepeat ( int nInputLayerNumber,
- int nHideLayerNumber,
- int nOutputLayerNumber,
- bool bSimulateDataFlag,
- int nComboFunc,
- double nSystemErrorOld,
- double nSystemErrorNew,
- double nSystemErrorLevel,
- double nSystemError,
- double nStep,
- UINT nMaxTrainTimes,
- UINT nTrainTimes,
- DWORD ID_SYSTEM_ERROR,
- DWORD ID_TRAIN_TIMES,
- HWND hWnd,
- CMatrix &matrixDemoDataInput,
- CMatrix &matrixInputLayerValue,
- CMatrix &matrixInputToHideWeightValue,
- CMatrix &matrixHideLayerValveValue,
- CMatrix &matrixHideLayerOutput,
- CMatrix &matrixHideToOutputWeightValue,
- CMatrix &matrixOutputLayerOutput,
- CMatrix &matrixOutputLayerValveValue
- )
- {
- // 根据BP算法修正nStep的初始值
- nStep = 0.1;
- // 前向计算
- LMForwardCalculate (nInputLayerNumber,
- nHideLayerNumber,
- nOutputLayerNumber,
- bSimulateDataFlag,
- nComboFunc,
- matrixDemoDataInput,
- matrixInputLayerValue,
- matrixInputToHideWeightValue,
- matrixHideLayerValveValue,
- matrixHideLayerOutput,
- matrixHideToOutputWeightValue,
- matrixOutputLayerOutput,
- matrixOutputLayerValveValue
- );
-
- /////////////////////////////////////////////////////////////////////
- // 算出所有样本的输出层的delta矩阵
- // 构造规则:
- // 1. 样本的数目为矩阵的行数;
- // 2. 样本输出层的数目为矩阵的列数;
- // 3. 矩阵中的元素的值y为:
- // y = (前向计算出的输出层的值 - 样本的输出层的值) .* f'(net)
- //
- CMatrix cMatrixTDemoOutput(matrixDemoDataInput.GetMatrixRowNumber (), nOutputLayerNumber);
-
- // 得到样本中输出层的数据
- matrixDemoDataInput.CopySubMatrix (cMatrixTDemoOutput, (unsigned int)nInputLayerNumber, (unsigned int)0);
- CMatrix cMatrixDemoOutput = cMatrixTDemoOutput.Transpose ();
- // 得到样本中输出层的误差
- CMatrix cMatrixOutputLayerError(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
- cMatrixOutputLayerError = cMatrixDemoOutput - matrixOutputLayerOutput;
- nSystemErrorOld = cMatrixOutputLayerError.GetSystemError ();
- for(int nLoopTimes=1; nLoopTimes < nMaxTrainTimes; nLoopTimes++)
- {
- if(nSystemErrorOld < nSystemErrorLevel)
- {
- nLoopTimes--;
- break;
- }
- // 求输出层的delta值
- // 注意: 此处'/' 是 '点乘'!!!
- CMatrix cMatrixOutputLayerDelta (nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber());
- cMatrixOutputLayerDelta = (matrixOutputLayerOutput - matrixOutputLayerOutput / matrixOutputLayerOutput) / cMatrixOutputLayerError;
-
- CMatrix cMatrixTHideToOutputWeightValue (matrixHideToOutputWeightValue.GetMatrixColNumber(), matrixHideToOutputWeightValue.GetMatrixRowNumber());
- cMatrixTHideToOutputWeightValue = matrixHideToOutputWeightValue.Transpose();
- // 求隐含层的delta值
- // 注意: 此处'/' 是 '点乘'!!!
- CMatrix cMatrixHideLayerDelta;
- cMatrixHideLayerDelta.CopyMatrix ( (matrixHideLayerOutput - (matrixHideLayerOutput / matrixHideLayerOutput)) / ( cMatrixTHideToOutputWeightValue * cMatrixOutputLayerDelta) );
-
- // 定义新的输入层到隐含层的权值
- CMatrix cMatrixNewInputToHideWeight (matrixInputToHideWeightValue.GetMatrixRowNumber (), matrixInputToHideWeightValue.GetMatrixColNumber ());
- // 定义的新的隐含层的阀值
- CMatrix cMatrixNewHideLayerValve (nHideLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
- // 定义新的隐含层到输出层的权值
- CMatrix cMatrixNewHideToOutputWeight (matrixHideToOutputWeightValue.GetMatrixRowNumber (), matrixHideToOutputWeightValue.GetMatrixColNumber ());
- // 定义新的输出层的阀值
- CMatrix cMatrixNewOutputLayerValve (nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
- // 定义新的误差矩阵
- CMatrix cMatrixNewOutputLayerError(nOutputLayerNumber, matrixDemoDataInput.GetMatrixRowNumber ());
- // 权值和阀值调整
- cMatrixNewHideToOutputWeight = cMatrixOutputLayerDelta * (matrixHideLayerOutput.Transpose ()) * (nStep);
- cMatrixNewOutputLayerValve = cMatrixOutputLayerDelta;
- cMatrixNewInputToHideWeight = cMatrixHideLayerDelta * (matrixInputLayerValue.Transpose ()) * (nStep);
- cMatrixNewHideLayerValve = cMatrixHideLayerDelta;
- // 赋值
- matrixInputToHideWeightValue += cMatrixNewInputToHideWeight;
- CMatrix cMatrixExHideLayerValveValue;
- cMatrixExHideLayerValveValue.nncpyi (matrixHideLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ());
- cMatrixExHideLayerValveValue += cMatrixNewHideLayerValve;
- matrixHideToOutputWeightValue += cMatrixNewHideToOutputWeight;
- CMatrix cMatrixExOutputLayerValveValue;
- cMatrixExOutputLayerValveValue.nncpyi (matrixOutputLayerValveValue, matrixDemoDataInput.GetMatrixRowNumber ());
- cMatrixExOutputLayerValveValue += cMatrixNewOutputLayerValve;
- // 前向计算
- BPForwardCalculate (nInputLayerNumber,
- nHideLayerNumber,
- nOutputLayerNumber,
- bSimulateDataFlag,
- nComboFunc,
- matrixDemoDataInput,
- matrixInputLayerValue,
- matrixInputToHideWeightValue,
- matrixHideLayerValveValue,
- matrixHideLayerOutput,
- matrixHideToOutputWeightValue,
- matrixOutputLayerOutput,
- matrixOutputLayerValveValue,
- cMatrixExHideLayerValveValue,
- cMatrixExOutputLayerValveValue
- );
- cMatrixNewOutputLayerError = cMatrixDemoOutput - matrixOutputLayerOutput;
- nSystemErrorNew = cMatrixNewOutputLayerError.GetSystemError ();
- cMatrixOutputLayerError = cMatrixNewOutputLayerError;
- if(nSystemErrorNew < nSystemErrorOld)
- {
- nSystemErrorOld = nSystemErrorNew;
- }
- else
- {
- nStep *= -0.1;
- }
- // 显示数据和程序运行状态
- nSystemError = nSystemErrorOld;
- nTrainTimes = nLoopTimes;
- // 显示系统误差
- CString strSystemError;
- strSystemError.Format ("%lf", nSystemError);
- LPCTSTR lpstrSystemError = (LPCTSTR)strSystemError;
- HWND hwnd = ::GetDlgItem (hWnd, ID_SYSTEM_ERROR);
- ::SetWindowText (hwnd, lpstrSystemError);
-
- // 显示训练次数
- CString strTrainTimes;
- strTrainTimes.Format ("%u", nTrainTimes + 1);
- LPCTSTR lpstrTrainTimes = (LPCTSTR)strTrainTimes;
- hwnd = ::GetDlgItem (hWnd, ID_TRAIN_TIMES);
- ::SetWindowText (hwnd, lpstrTrainTimes);
- }// End the "for" loop
-
- return true;
- }