📄 anndlg.cpp
字号:
m_nInputLayerNumber = 0;
m_nHideLayerNumber = 0;
m_nOutputLayerNumber = 0;
return;
}
ForCalc(m_nInputLayerNumber,
m_nHideLayerNumber,
m_nOutputLayerNumber,
m_matrixDataInput,
m_matrixInputLayerValue,
m_matrixInputToHideWeight,
m_matrixHideLayerThreshold,
m_matrixHideLayerOutput,
m_matrixHideToOutputWeight,
m_matrixOutputLayerOutput,
m_matrixOutputLayerThreshold
);
if (m_matrixDataInput.GetMatrixColNumber () == m_nInputLayerNumber)
{
Display(m_nOutputLayerNumber,
m_matrixOutputLayerOutput);
}
else
Display(m_nInputLayerNumber,
m_nOutputLayerNumber,
m_matrixDataInput,
m_matrixOutputLayerOutput);
}
else
{
return;
}
}
bool CANNDlg::BPtrain(int nInputLayerNumber,
int nHideLayerNumber,
int nOutputLayerNumber,
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 &matrixDataInput,
CMatrix &matrixInputLayerValue,
CMatrix &matrixInputToHideWeight,
CMatrix &matrixHideLayerThreshold,
CMatrix &matrixHideLayerOutput,
CMatrix &matrixHideToOutputWeight,
CMatrix &matrixOutputLayerOutput,
CMatrix &matrixOutputLayerThreshold)
{
// 根据BP算法修正nStep的初始值
nStep = 0.1;
// 前向计算
ForCalc(nInputLayerNumber,
nHideLayerNumber,
nOutputLayerNumber,
matrixDataInput,
matrixInputLayerValue,
matrixInputToHideWeight,
matrixHideLayerThreshold,
matrixHideLayerOutput,
matrixHideToOutputWeight,
matrixOutputLayerOutput,
matrixOutputLayerThreshold
);
/////////////////////////////////////////////////////////////////////
// 算出所有样本的输出层的delta矩阵
// 构造规则:
// 1. 样本的数目为矩阵的行数;
// 2. 样本输出层的数目为矩阵的列数;
// 3. 矩阵中的元素的值y为:
// y = (前向计算出的输出层的值 - 样本的输出层的值) .* f'(net)
//
CMatrix cMatrixTOutput(matrixDataInput.GetMatrixRowNumber (), nOutputLayerNumber);
// 得到样本中输出层的数据
matrixDataInput.CopySubMatrix (cMatrixTOutput, (unsigned int)nInputLayerNumber, (unsigned int)0);
CMatrix cMatrixOutput = cMatrixTOutput.Transpose ();
// 得到样本中输出层的误差
CMatrix cMatrixOutputLayerError(nOutputLayerNumber, matrixDataInput.GetMatrixRowNumber ());
cMatrixOutputLayerError = cMatrixOutput - matrixOutputLayerOutput;
nSystemErrorOld = cMatrixOutputLayerError.GetSystemError ();
for(int nLoopTimes=1; nLoopTimes < nMaxTrainTimes; nLoopTimes++)
{
if(nSystemErrorOld < nSystemErrorLevel)
{
nLoopTimes--;
break;
}
// 求输出层的delta值
CMatrix cMatrixOutputLayerDelta (nOutputLayerNumber, matrixDataInput.GetMatrixRowNumber());
cMatrixOutputLayerDelta = (matrixOutputLayerOutput - matrixOutputLayerOutput / matrixOutputLayerOutput) / cMatrixOutputLayerError;
CMatrix cMatrixTHideToOutputWeight (matrixHideToOutputWeight.GetMatrixColNumber(), matrixHideToOutputWeight.GetMatrixRowNumber());
cMatrixTHideToOutputWeight = matrixHideToOutputWeight.Transpose();
// 求隐含层的delta值
CMatrix cMatrixHideLayerDelta;
cMatrixHideLayerDelta.CopyMatrix ( (matrixHideLayerOutput - (matrixHideLayerOutput / matrixHideLayerOutput)) / ( cMatrixTHideToOutputWeight * cMatrixOutputLayerDelta) );
// 定义新的输入层到隐含层的权值
CMatrix cMatrixNewInputToHideWeight (matrixInputToHideWeight.GetMatrixRowNumber (), matrixInputToHideWeight.GetMatrixColNumber ());
// 定义的新的隐含层的阈值
CMatrix cMatrixNewHideLayerValve (nHideLayerNumber, matrixDataInput.GetMatrixRowNumber ());
// 定义新的隐含层到输出层的权值
CMatrix cMatrixNewHideToOutputWeight (matrixHideToOutputWeight.GetMatrixRowNumber (), matrixHideToOutputWeight.GetMatrixColNumber ());
// 定义新的输出层的阈值
CMatrix cMatrixNewOutputLayerValve (nOutputLayerNumber, matrixDataInput.GetMatrixRowNumber ());
// 定义新的误差矩阵
CMatrix cMatrixNewOutputLayerError(nOutputLayerNumber, matrixDataInput.GetMatrixRowNumber ());
// 权值和阈值调整
cMatrixNewHideToOutputWeight = cMatrixOutputLayerDelta * (matrixHideLayerOutput.Transpose ()) * (nStep);
cMatrixNewOutputLayerValve = cMatrixOutputLayerDelta;
cMatrixNewInputToHideWeight = cMatrixHideLayerDelta * (matrixInputLayerValue.Transpose ()) * (nStep);
cMatrixNewHideLayerValve = cMatrixHideLayerDelta;
// 赋值
matrixInputToHideWeight += cMatrixNewInputToHideWeight;
CMatrix cMatrixExHideLayerThreshold;
cMatrixExHideLayerThreshold.nncpyi (matrixHideLayerThreshold, matrixDataInput.GetMatrixRowNumber ());
cMatrixExHideLayerThreshold += cMatrixNewHideLayerValve;
matrixHideToOutputWeight += cMatrixNewHideToOutputWeight;
CMatrix cMatrixExOutputLayerThreshold;
cMatrixExOutputLayerThreshold.nncpyi (matrixOutputLayerThreshold, matrixDataInput.GetMatrixRowNumber ());
cMatrixExOutputLayerThreshold += cMatrixNewOutputLayerValve;
// 前向计算
ForCalc (nInputLayerNumber,
nHideLayerNumber,
nOutputLayerNumber,
matrixDataInput,
matrixInputLayerValue,
matrixInputToHideWeight,
matrixHideLayerThreshold,
matrixHideLayerOutput,
matrixHideToOutputWeight,
matrixOutputLayerOutput,
matrixOutputLayerThreshold,
cMatrixExHideLayerThreshold,
cMatrixExOutputLayerThreshold
);
cMatrixNewOutputLayerError = cMatrixOutput - 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;
}
void CANNDlg::OnSetSavepath()
{
// TODO: Add your control notification handler code here
static char BASED_CODE szFilter[] = TEXT("文本文件(*.txt)|*.txt|All Files (*.*)|*.*||");
static char BASED_CODE lpszDefExt[] = TEXT("txt");
//Create the dialog to select the data file to save the network
CFileDialog dlg(FALSE,
lpszDefExt,
NULL,
OFN_HIDEREADONLY |
OFN_CREATEPROMPT |
OFN_OVERWRITEPROMPT,
szFilter,
this );
if(dlg.DoModal ()==IDOK)
{
m_strNetWorkPath = dlg.GetPathName ();
HWND hWnd = ::GetDlgItem (this->m_hWnd,IDC_SAVE_NETWORK);
::SetWindowText (hWnd,m_strNetWorkPath);
}
else
{
return;
}
}
bool CANNDlg::SaveConstantStringToFile(CString &strFileName, CString &strConstantData)
{
// Convert CString to LPCTSTR
LPCTSTR lpszFileName = "";
strFileName.TrimLeft ();
strFileName.TrimRight ();
lpszFileName = (LPCTSTR)strFileName;
CStdioFile dataFile;
if(!dataFile.Open (lpszFileName, CFile::modeCreate | CFile::modeNoTruncate | CFile::modeWrite | CFile::typeText))
{
::MessageBox(this->m_hWnd, _T("不能创建存储网络参数的文件!"), _T("错误!"), MB_OK | MB_ICONERROR);
dataFile.Close ();
return FALSE;
}
dataFile.SeekToEnd ();
// Write data into the file
char *pBuffer = new char[strConstantData.GetLength ()];
memcpy(pBuffer,strConstantData,strConstantData.GetLength ());
dataFile.Write (pBuffer,strConstantData.GetLength ());
dataFile.Close ();
return TRUE;
}
void CANNDlg::Display(int nInputLayerNumber,
int nOutputLayerNumber,
CMatrix &matrixDataInput,
CMatrix &matrixOutputLayerOutput)
{
CString temp1="";
CString temp2="";
CMatrix cMatrixExceptOutput(m_matrixDataInput.GetMatrixRowNumber (), m_nOutputLayerNumber);
matrixDataInput.CopySubMatrix (cMatrixExceptOutput, (unsigned int)nInputLayerNumber, (unsigned int)0);
for (int k=0;k<cMatrixExceptOutput.GetMatrixRowNumber();k++)
{
temp2.Format("%d",k);
temp1+=temp2;
temp1+="号测试样本期望输出\r\n";
for (int i=0;i<nOutputLayerNumber;i++)
{
temp2.Format("%10f",cMatrixExceptOutput.m_pTMatrix[k][i]);
temp1+=temp2;
temp1+="\r\n";
}
temp2.Format("%d",k);
temp1+=temp2;
temp1+="号测试样本实际输出\r\n";
for (i=0;i<nOutputLayerNumber;i++)
{
temp2.Format("%10f",matrixOutputLayerOutput.m_pTMatrix[i][k]);
temp1+=temp2;
temp1+="\r\n";
}
m_Display=temp1;
UpdateData(false);
}
}
void CANNDlg::NetworkInit(int nInputLayerNumber,
int nHideLayerNumber,
int nOutputLayerNumber,
CMatrix &matrixDataInput,
CMatrix &matrixInputLayerValue)
{
// 从读入的数据得到样本的输入值的初始化(用于测试样本)
CMatrix cMatrixInputLayerValue(matrixDataInput.GetMatrixRowNumber (), nInputLayerNumber);
matrixDataInput.CopySubMatrix (cMatrixInputLayerValue,(unsigned int)0,(unsigned int)0);
CMatrix cMatrixTInputLayerValue = cMatrixInputLayerValue.Transpose ();
matrixInputLayerValue.CopyMatrix (cMatrixTInputLayerValue);
}
void CANNDlg::Display(int nOutputLayerNumber,
CMatrix &matrixOutputLayerOutput)
{
CString temp1="";
CString temp2="";
for (int k=0;k<matrixOutputLayerOutput.GetMatrixColNumber();k++)
{
temp2.Format("%d",k);
temp1+=temp2;
temp1+="号测试样本输出为:\r\n";
for (int i=0;i<nOutputLayerNumber;i++)
{
temp2.Format("%10f",matrixOutputLayerOutput.m_pTMatrix[i][k]);
temp1+=temp2;
temp1+="\r\n";
}
m_Display=temp1;
UpdateData(false);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -