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