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

📄 testdoc.cpp

📁 C++编写的BP神经网络源程序,标准程序
💻 CPP
字号:
// testDoc.cpp : implementation of the CTestDoc class
//

#include "stdafx.h"
#include "test.h"

#include "testDoc.h"
#include "DataInput.h"
#include "ValueInput.h"
#include "MyTestDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CTestDoc

IMPLEMENT_DYNCREATE(CTestDoc, CDocument)

BEGIN_MESSAGE_MAP(CTestDoc, CDocument)
	//{{AFX_MSG_MAP(CTestDoc)
	ON_COMMAND(ID_MENU_LOAD, OnMenuLoad)
	ON_COMMAND(ID_MENU_LEARN, OnMenuLearn)
	ON_COMMAND(ID_MENU_NEWFILE, OnMenuNewfile)
	ON_COMMAND(ID_MENU_TEST, OnMenuTest)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTestDoc construction/destruction

CTestDoc::CTestDoc()
{
	// TODO: add one-time construction code here
	max_error_tollerance = 0.09;
	file_loaded = FALSE;
	data_learned = FALSE;
	can_learn = FALSE;
	dispmode = 0;
	ytemp = 0;
	ztemp = 0;
	total = 0;

	input = NULL;
	hidden = NULL;
	output = NULL;
	target = NULL;
	bias = NULL;
	weight_i_h = NULL;
	weight_h_o = NULL;
	errorsignal_hidden = NULL;
	errorsignal_output = NULL;
}

CTestDoc::~CTestDoc()
{
	if (file_loaded)
	{
		clear_memory();
	}
}

BOOL CTestDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)

	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CTestDoc serialization

void CTestDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

/////////////////////////////////////////////////////////////////////////////
// CTestDoc diagnostics

#ifdef _DEBUG
void CTestDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CTestDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CTestDoc commands

void CTestDoc::OnMenuLoad() 
{
	// TODO: Add your command handler code here
    CFileDialog dlg_file(TRUE,"txt","*.txt");
	if (dlg_file.DoModal()==IDOK)
	{
		if (file_loaded)
		{
			clear_memory();
		}
		else
		{
			file_loaded = TRUE;
		}
		ifstream in(dlg_file.GetPathName());
	
		TRACE("\nfilename=%s\n",dlg_file.GetPathName());
		data_learned = FALSE;
		can_learn = TRUE;
	
		in >> input_array_size;
		in >> hidden_array_size;
		in >> output_array_size;
		in >> learning_rate;
		in >> number_of_input_patterns;
		TRACE("\n\nparameter=%d,%d,%d,%f,%d\n\n",input_array_size,
										   hidden_array_size,
										   output_array_size,
										   learning_rate,
										   number_of_input_patterns);
		bias_array_size = hidden_array_size + output_array_size;
		initialize_net();
		int x,y;
		for(x=0; x<bias_array_size; x++) 
		{
			in >> bias[x];
			TRACE("BIAS[%d]=%f\n",x,bias[x]);
		}
		for(x=0; x<input_array_size; x++) 
		{ 
			for(y=0; y<hidden_array_size; y++)
			{
				in >> weight_i_h[x][y];
				TRACE("Weight_i_h[%d][%d]=%f\n",x,y,weight_i_h[x][y]);
			}
		}
		for(x=0; x<hidden_array_size; x++) 
		{ 
			for(y=0; y<output_array_size; y++)
			{
				in >> weight_h_o[x][y];
				TRACE("Weight_h_o[%d][%d]=%f\n",x,y,weight_h_o[x][y]);
			}
		}
		
		
		double sin_delta,
				sin_x ;
		double pai = 3.1415926535897932;
        sin_x = 0;
		sin_delta = pai/(number_of_input_patterns-1);
		
		for(x=0; x<number_of_input_patterns; x++) 
		{
			for(y=0; y<input_array_size; y++) 
			{
				//in >> input[x][y];
				input[x][y] = sin_x;
				sin_x += sin_delta;
				TRACE("input[%d][%d]=%.0f\n",x,y,input[x][y]);
			}
		}
		for(x=0; x<number_of_input_patterns; x++)
		{
			for(y=0; y<output_array_size; y++)
			{
				//in >> target[x][y];
				target[x][y] = sin(input[x][y]);
				TRACE("target[%d][%d]=%.0f\n",x,y,target[x][y]);
			}
		}
		in.close();
		::AfxMessageBox("Data loaded");
	}
}

void CTestDoc::initialize_net()
{
	int x;
	input = new double * [number_of_input_patterns];
	if(!input) { ::AfxMessageBox("memory problem!"); exit(1); }
	for(x=0; x<number_of_input_patterns; x++)
	{
		input[x] = new double [input_array_size];
		if(!input[x]) { ::AfxMessageBox("memory problem!"); exit(1); }
	}

	//hidden = new double [hidden_array_size];
	hidden = new double * [number_of_input_patterns];
	if(!hidden) { ::AfxMessageBox("memory problem!"); exit(1); }
	for (x=0; x<number_of_input_patterns; x++)
	{
		hidden[x] = new double [hidden_array_size];
		if(!hidden[x]) {::AfxMessageBox("memory problem!"); exit(1); }
	}

	output = new double * [number_of_input_patterns];
	if(!output) { ::AfxMessageBox("memory problem!"); exit(1); }
	for(x=0; x<number_of_input_patterns; x++)
	{
		output[x] = new double [output_array_size];
		if(!output[x]) { ::AfxMessageBox("memory problem!"); exit(1); }
	}

	target = new double * [number_of_input_patterns];
	if(!target) { ::AfxMessageBox("memory problem!"); exit(1); }
	for(x=0; x<number_of_input_patterns; x++)
	{
		target[x] = new double [output_array_size];
		if(!target[x]) { ::AfxMessageBox("memory problem!"); exit(1); }
	}

	bias = new double [bias_array_size];
	if(!bias) { ::AfxMessageBox("memory problem!"); exit(1); }

	weight_i_h = new double * [input_array_size];
	if(!weight_i_h) { ::AfxMessageBox("memory problem!"); exit(1); }
	for(x=0; x<input_array_size; x++)
	{
		weight_i_h[x] = new double [hidden_array_size];
		if(!weight_i_h[x]) { ::AfxMessageBox("memory problem!"); exit(1); }
	}
	weight_h_o = new double * [hidden_array_size];
	if(!weight_h_o) { ::AfxMessageBox("memory problem!"); exit(1); }
	for(x=0; x<hidden_array_size; x++)
	{
		weight_h_o[x] = new double [output_array_size];
		if(!weight_h_o[x]) { ::AfxMessageBox("memory problem!"); exit(1); }
	}

	errorsignal_hidden = new double [hidden_array_size];
	if(!errorsignal_hidden) { ::AfxMessageBox("memory problem!"); exit(1); }
	errorsignal_output = new double [output_array_size];
	if(!errorsignal_output) { ::AfxMessageBox("memory problem!"); exit(1); }
	return;
}

void CTestDoc::clear_memory()
{	
	int x;
	for(x=0; x<number_of_input_patterns; x++)
	{
		delete [] input[x];
	}
	delete [] input;

	for (x=0; x<number_of_input_patterns; x++)
	{
		delete [] hidden[x];
	}
	delete [] hidden;

	for(x=0; x<number_of_input_patterns; x++)
	{
		delete [] output[x];
	}
	delete [] output;

	for(x=0; x<number_of_input_patterns; x++)
	{
		delete [] target[x];
	}
	delete [] target;

	delete [] bias;

	for(x=0; x<input_array_size; x++)
	{
		delete [] weight_i_h[x];
	}
	delete [] weight_i_h;

	for(x=0; x<hidden_array_size; x++)
	{
		delete [] weight_h_o[x];
	}
	delete [] weight_h_o;

	delete [] errorsignal_hidden;
	
	delete [] errorsignal_output;
	file_loaded = FALSE;
	return;
}


void CTestDoc::OnMenuLearn() 
{
	// TODO: Add your command handler code here
	ofstream out(BIAS_FILE);
	BOOL success = FALSE;
	total = 0;

	dispmode = 2;
	UpdateAllViews(NULL);
	register int y;
	notkeyhit = TRUE;
	while(notkeyhit) 
	{
		for(y=0; y<number_of_input_patterns; y++) 
		{
			forward_pass(y);
		}
	
		if(compare_output_to_target())
		{
			success = TRUE;
			break;
		}
		else
		{
			backward_pass(out);
			total++;
		}

		MSG message;
		if (::PeekMessage(&message,NULL,0,0,PM_REMOVE))
		{
			::TranslateMessage(&message);
			::DispatchMessage(&message);
		}
	}
	dispmode = 0;
	UpdateAllViews(NULL);

	out.close();
	ofstream out_e(BIASNUM_FILE);
	out_e << total;
	out_e.close();
	if (success)
	{
		::AfxMessageBox("Learning successful");
		data_learned = TRUE;
	}
	else
	{
		::AfxMessageBox("Learning not successful yet");
	}
	return;
}

void CTestDoc::forward_pass(int pattern)
{
	_control87 (MCW_EM, MCW_EM);
	register double temp=0;
	register int x,y;

// INPUT -> HIDDEN
	for(y=0; y<hidden_array_size; y++) {
		for(x=0; x<input_array_size; x++) {
			temp += (input[pattern][x] * weight_i_h[x][y]); //∑Wi*Xi
		}
		hidden[pattern][y] = (1.0 / (1.0 + exp(-1.0 * (temp + bias[y]))));//1/(1+e^(-uj)); uj=∑Wi*Xi - θj
		temp = 0;                                                //各隐层结点的输出
	}

// HIDDEN -> OUTPUT
	for(y=0; y<output_array_size; y++) {	//有output_array_size个输出结点
		for(x=0; x<hidden_array_size; x++) {
			temp += (hidden[pattern][x] * weight_h_o[x][y]);
		}
		output[pattern][y] = (1.0 / (1.0 + exp(-1.0 * (temp + bias[y + hidden_array_size]))));
		temp = 0;
	}
	return;
}

void CTestDoc::backward_pass(ofstream& f_out)
{
	register int x, y, p;
	register double temp = 0;
	double e = 0;
	for (p=0; p<number_of_input_patterns; p++)
	{
	// COMPUTE ERRORSIGNAL FOR OUTPUT UNITS
		for(x=0; x<output_array_size; x++) {
			errorsignal_output[x] = (target[p][x]-output[p][x]);//(t-y)
			e += errorsignal_output[x] * errorsignal_output[x];	//e = (∑(t-y)^2)/2
			errorsignal_output[x] *= output[p][x] * (1-output[p][x]);//δ= y*(1-y)*(t-y)	
		}
	
	// COMPUTE ERRORSIGNAL FOR HIDDEN UNITS
		for(x=0; x<hidden_array_size; x++) {
			for(y=0; y<output_array_size; y++) { 
				temp += (errorsignal_output[y] * weight_h_o[x][y]);
			}
			errorsignal_hidden[x] = hidden[p][x] * (1-hidden[p][x]) * temp;//Xk*(1-Xk)∑δ*W
			temp = 0.0;
		}

	// ADJUST WEIGHTS OF CONNECTIONS FROM HIDDEN TO OUTPUT UNITS
		double length = 0.0;
		for (x=0; x<hidden_array_size; x++) {
			length += hidden[p][x]*hidden[p][x];
		}
		if (length<=0.1) length = 0.1;
		for(x=0; x<hidden_array_size; x++) {
			for(y=0; y<output_array_size; y++) {
				weight_h_o[x][y] += (learning_rate * errorsignal_output[y] * hidden[p][x]/length);
			}
		}

	// ADJUST BIASES OF HIDDEN UNITS
		for(x=hidden_array_size; x<bias_array_size; x++) {
			bias[x] += (learning_rate * errorsignal_output[x] / length);
		}

	// ADJUST WEIGHTS OF CONNECTIONS FROM INPUT TO HIDDEN UNITS
		length = 0.0;
		for (x=0; x<input_array_size; x++) 
		{
			length += input[p][x]*input[p][x];
		}
		if (length<=0.1) length = 0.1;
		for(x=0; x<input_array_size; x++)
		{                     
			for(y=0; y<hidden_array_size; y++) 
			{
				weight_i_h[x][y] += (learning_rate * errorsignal_hidden[y] * input[p][x]/length);
			}
		}

	// ADJUST BIASES FOR OUTPUT UNITS
		for(x=0; x<hidden_array_size; x++) {
			bias[x] += (learning_rate * errorsignal_hidden[x] / length);
		}
	}
	e /= 2.0;
	f_out << e << endl;
	return;
}

int CTestDoc::compare_output_to_target()
{
	register int y,z;
	register double temp, error = 0.0;
	temp = target[ytemp][ztemp] - output[ytemp][ztemp];//(t-y)<ε
	if (temp < 0) error -= temp;
	else error += temp;
	if(error > max_error_tollerance) return 0;
	error = 0.0;
	for(y=0; y < number_of_input_patterns; y++) {
		for(z=0; z < output_array_size; z++) {
			temp = target[y][z] - output[y][z];
			if (temp < 0) error -= temp;
			else error += temp;
			if(error > max_error_tollerance) {
				ytemp = y;
				ztemp = z;
				return 0;
			}
			error = 0.0;
		}
	}
	return 1;
}

void CTestDoc::OnMenuNewfile() 
{
	// TODO: Add your command handler code here
	CFileDialog dlg_save(FALSE,"txt","*.txt");
	if (dlg_save.DoModal()==IDOK)
	{
		CDataInput dlg_d_input;
		CValueInput dlg_v_input;
		if (dlg_d_input.DoModal() == IDOK)
		{
			int x, y, mode;
			int bias_array_size, input_array_size, hidden_array_size, output_array_size;
			double inpx, val;
			CString str_in,str_tar;
	
			can_learn = FALSE;
			data_learned = FALSE;
		
			ofstream out(dlg_save.GetPathName());
			if (!out)
			{
				::AfxMessageBox("Can not open the file");
				return;
			}

			input_array_size = dlg_d_input.m_nInput;
			hidden_array_size = dlg_d_input.m_nHidden;
			output_array_size = dlg_d_input.m_nOut;
			inpx = dlg_d_input.m_dLearn;
			mode = dlg_d_input.m_nMode;
			bias_array_size = hidden_array_size + output_array_size;
	
			out << input_array_size << endl;
			out << hidden_array_size << endl;
			out << output_array_size << endl;
			out << inpx << endl;
			out << mode << endl << endl;

			srand((unsigned)time(NULL));
			for(x=0; x<bias_array_size; x++) 
			{	
				out << (double)(rand()-10000)/RAND_MAX << ' ';
			}
			out << endl << endl;
			for(x=0; x<input_array_size; x++) {//Weight Input->Hidden
				for(y=0; y<hidden_array_size; y++) 
				{
					out << (double)(rand()-10000)/RAND_MAX << ' ';
				}
			}
			out << endl << endl;
			for(x=0; x<hidden_array_size; x++) {//Weight Hidden->Output
				for(y=0; y<output_array_size; y++) 
				{
					out << (double)(rand()-10000)/RAND_MAX << ' ';
				}
			}
			out << endl << endl;
		
			ofstream output("tmp_1011.txt");
			if (!output)
			{
				::AfxMessageBox("Can not open the tmeporary file");
				return;
			}
	
			for (count = 1; count <=mode; count+=dlg_v_input.delta)
			{
				 if(dlg_v_input.DoModal()==IDOK)
				{
					str_in = dlg_v_input.m_strInput;
					str_tar = dlg_v_input.m_strTarget;
					out << str_in << endl;
					output << str_tar << endl;

				}
			}
			output.close();
			out << endl;
			ifstream f_input("tmp_1011.txt");
			for (count=1; count<=mode; count++)
			{
				for (x=0; x<output_array_size; x++)
				{
					f_input >> val;
					out << val << ' ';;
				}
				out << endl;
			}
			f_input.close();
			out.close();
			CFile::Remove("tmp_1011.txt");
		}
	}
}


void CTestDoc::OnMenuTest() 
{
	// TODO: Add your command handler code here
	CMyTestDlg dlg_test;
	if (dlg_test.DoModal()==IDOK)
	{
		selpattern = dlg_test.m_nModeNum-1;
		TRACE("\nselPATTERN=%d\n",selpattern);
		forward_pass(selpattern);
		dispmode = 1;
	    UpdateAllViews(NULL);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -