⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nnbpdlg.cpp

📁 bp神经网络源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:

	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 + -