📄 nnbpdlg.cpp
字号:
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);
}
bool CNNBPDlg::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;
// 显示系统误差
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;
}
bool CNNBPDlg::SimulateData()
{
(CNNBPDlg *)GetDlgItem(IDC_STATE)->EnableWindow(FALSE);
if(!m_bSimulateDataFlag)
{
(CNNBPDlg *)GetDlgItem(IDC_STATE)->EnableWindow(TRUE);
return false;
}
if(m_strSimuNetworkFold.IsEmpty ())
{
::MessageBox (this->m_hWnd, _T("你还没选取提供网络参数的文件的装载路径!"), _T(":("),MB_OK | MB_ICONWARNING);
(CNNBPDlg *)GetDlgItem(IDC_STATE)->EnableWindow(TRUE);
return false;
}
if(m_strSimuDataInput.IsEmpty ())
{
::MessageBox (this->m_hWnd, _T("你还没选取用来仿真的数据文件的装载路径!"), _T(":("),MB_OK | MB_ICONWARNING);
(CNNBPDlg *)GetDlgItem(IDC_STATE)->EnableWindow(TRUE);
return false;
}
if(m_strSimuResult.IsEmpty ())
{
::MessageBox (this->m_hWnd, _T("你还没选取最终仿真结果的数据文件的存放路径!"), _T(":("),MB_OK | MB_ICONWARNING);
(CNNBPDlg *)GetDlgItem(IDC_STATE)->EnableWindow(TRUE);
return false;
}
// 装载网络参数文件
m_matrixSimuNetwork.LoadDataFromFileSpecial(m_strSimuNetworkFold,
m_matrixInputToHideWeightValue,
m_matrixHideLayerValveValue,
m_matrixHideToOutputWeightValue,
m_matrixOutputLayerValveValue,
m_nInputLayerNumber,
m_nHideLayerNumber,
m_nOutputLayerNumber,
m_nComboArithmetic,
m_nComboFunc);
// 装载仿真数据文件
m_matrixDemoDataInput.LoadDataFromFile (m_strSimuDataInput);
if( m_matrixDemoDataInput.GetMatrixColNumber () != m_nInputLayerNumber )
{
::MessageBox (this->m_hWnd, _T("待仿真数据文件的输入层数目与网络中的输入层数目不相等!!!"), _T("错误!"), MB_OK | MB_ICONERROR);
// 释放全局变量所占的内存
m_matrixSimuNetwork.InitializeZero ();
m_matrixInputToHideWeightValue.InitializeZero ();
m_matrixHideLayerValveValue.InitializeZero ();
m_matrixHideToOutputWeightValue.InitializeZero ();
m_matrixOutputLayerValveValue.InitializeZero ();
m_matrixDemoDataInput.InitializeZero ();
m_strSimuNetworkFold = TEXT("");
m_strSimuDataInput = TEXT("");
m_strSimuResult = TEXT("");
m_nInputLayerNumber = 0;
m_nHideLayerNumber = 0;
m_nOutputLayerNumber = 0;
(CNNBPDlg *)GetDlgItem(IDC_STATE)->EnableWindow(TRUE);
//*******************************************************************
// Update the UI
//
HWND hWnd = ::GetDlgItem (this->m_hWnd, IDC_SIMU_NETWORK_FOLD);
::SetWindowText (hWnd, _T(""));
hWnd = ::GetDlgItem (this->m_hWnd, IDC_SIMU_DATA_INPUT);
::SetWindowText (hWnd, _T(""));
hWnd = ::GetDlgItem (this->m_hWnd, IDC_SIMU_RESULT);
::SetWindowText (hWnd, _T(""));
return false;
}
else // Successful!!!
{
// 前向计算
LMForwardCalculate( m_nInputLayerNumber,
m_nHideLayerNumber,
m_nOutputLayerNumber,
m_bSimulateDataFlag,
m_nComboFunc,
m_matrixDemoDataInput,
m_matrixInputLayerValue,
m_matrixInputToHideWeightValue,
m_matrixHideLayerValveValue,
m_matrixHideLayerOutput,
m_matrixHideToOutputWeightValue,
m_matrixOutputLayerOutput,
m_matrixOutputLayerValveValue
);
// 存储模拟结果
(m_matrixOutputLayerOutput.Transpose()).SaveDataToFile(m_strSimuResult);
// 释放全局变量所占的内存
m_matrixSimuNetwork.InitializeZero ();
m_matrixInputToHideWeightValue.InitializeZero ();
m_matrixHideLayerValveValue.InitializeZero ();
m_matrixHideToOutputWeightValue.InitializeZero ();
m_matrixOutputLayerValveValue.InitializeZero ();
m_matrixDemoDataInput.InitializeZero ();
m_matrixHideLayerOutput.InitializeZero ();
m_matrixOutputLayerOutput.InitializeZero ();
m_strSimuNetworkFold = _T("");
m_strSimuDataInput = _T("");
m_strSimuResult = _T("");
m_nComboFunc = -1;
m_nInputLayerNumber = 0;
m_nHideLayerNumber = 0;
m_nOutputLayerNumber = 0;
::MessageBox (this->m_hWnd, _T("数据仿真结果保存成功!"), _T("恭喜!"), MB_OK);
(CNNBPDlg *)GetDlgItem(IDC_STATE)->EnableWindow(TRUE);
//*******************************************************************
// Update the UI
//
HWND hWnd = ::GetDlgItem (this->m_hWnd, IDC_SIMU_NETWORK_FOLD);
::SetWindowText (hWnd, _T(""));
hWnd = ::GetDlgItem (this->m_hWnd, IDC_SIMU_DATA_INPUT);
::SetWindowText (hWnd, _T(""));
hWnd = ::GetDlgItem (this->m_hWnd, IDC_SIMU_RESULT);
::SetWindowText (hWnd, _T(""));
}
return true;
}
void CNNBPDlg::ForwardCalculateInit()
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -