📄 procedure.cpp
字号:
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 ();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -