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

📄 chooseview.cpp

📁 (原创)研究生期间学习人工神经网张和遗传算法实现的简单的水果识别源码. 水果特征{0,0,1},{0,1,0},{1,0,0}代表{大,圆,光滑}
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ChooseView.cpp : 实现文件
//

#include "stdafx.h"
#include "Apple.h"
#include "ChooseView.h"
#include ".\chooseview.h"
#include "AppleDoc.h"
#include "AppleView.h"
#include "MainFrm.h"
#include <time.h>
#include <math.h>

// CChooseView

#define INPUT_NUMBER 3			/*input*/
#define HIDE_NUMBER 3 			/*hidden*/
#define OUT_NUMBER 1			/*output*/

#define U0  	1
#define YINO 	1
#define BETA 	0.1				//步长
#define AFA    	0.6				//a的值
#define SpNUM 	3
#define MINERR 	0

double dblWeight_IN_HD[HIDE_NUMBER][INPUT_NUMBER];	//初始的三个不同的输入和不同的Weight 
double dblWeight_HD_OT[OUT_NUMBER][HIDE_NUMBER];	//隐含层输出的不同的三个初始Weight

double dblOut_IN[INPUT_NUMBER];	    /*output of input layer*/	//输入层的输出
double dblOut_HD[HIDE_NUMBER];      /*output of hidden layer*/  //隐含层的输出
double dblOut_OT[OUT_NUMBER];       /*output of output layer*/  //最后的输出

	   
double delta_HD[HIDE_NUMBER];
double delta_OT[OUT_NUMBER];

double CW_HD[HIDE_NUMBER];		/*limit value of hidden layer*/ //隐含层的阀值 三个
double CW_OT[OUT_NUMBER];       /*limit value of output layer*/ //输出层的阀值 一个
	
//int X[SpNUM][INNUM];
//int T[SpNUM][ON];
double OT[SpNUM][OUT_NUMBER];

//GA_realated
//const int POPNUM=4;

double GAdblWeight_IN_HD[POPNUM][HIDE_NUMBER][INPUT_NUMBER];	//初始的三个不同的输入和不同的Weight 
double GAdblWeight_HD_OT[POPNUM][OUT_NUMBER][HIDE_NUMBER];		//隐含层输出的不同的三个初始Weight
double GAerrorp[POPNUM];

//total 
double T[SpNUM][OUT_NUMBER] ={1,0.5,0.25};
double X[SpNUM][INPUT_NUMBER] ={{0,0,1},{0,1,0},{1,0,0}};

IMPLEMENT_DYNCREATE(CChooseView, CFormView)

CChooseView::CChooseView()
	: CFormView(CChooseView::IDD)
	, m_check0(FALSE)
	, m_check1(FALSE)
	, m_check2(FALSE)
{
	train_count=0;
	//int *t = new int[POPNUM+1];
}

CChooseView::~CChooseView()
{
}

void CChooseView::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
	DDX_Check(pDX, IDC_CHK0, m_check0);
	DDX_Check(pDX, IDC_CHK1, m_check1);
	DDX_Check(pDX, IDC_CHK2, m_check2);
}

BEGIN_MESSAGE_MAP(CChooseView, CFormView)
	ON_BN_CLICKED(IDC_BTNSTUDY, OnBnClickedBtnstudy)
	ON_BN_CLICKED(IDC_BTNREC, OnBnClickedBtnrec)
	ON_BN_CLICKED(IDC_BTNSTUDY2, OnBnClickedBtnstudy2)
END_MESSAGE_MAP()


// CChooseView 诊断

#ifdef _DEBUG
void CChooseView::AssertValid() const
{
	CFormView::AssertValid();
}

void CChooseView::Dump(CDumpContext& dc) const
{
	CFormView::Dump(dc);
}
CAppleDoc* CChooseView::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CAppleDoc)));
	return (CAppleDoc*)m_pDocument;
}
#endif //_DEBUG


// CChooseView 消息处理程序

//void CChooseView::OnBnClickedCheck1()
//{
//	// TODO: 在此添加控件通知处理程序代码
//	CAppleDoc* pDoc =(CAppleDoc* )GetDocument();
//	pDoc->m =1;
//	pDoc->UpdateAllViews (this);
//}

void CChooseView::OnBnClickedBtnstudy()
{
	// TODO: 在此添加控件通知处理程序代码
	CAppleDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	pDoc->m_Sign=true;
	
	pDoc->UpdateAllViews (this);

	//this->GetDocument()->UpdateAllViews (this);
}
void CChooseView::init()
{
	wgtinit((double*)dblWeight_IN_HD,INPUT_NUMBER*HIDE_NUMBER);   //输入层的9个初始 weight 
	wgtinit((double*)dblWeight_HD_OT,HIDE_NUMBER*OUT_NUMBER);	  // 隐含层的3个 weight
	
	//for (int i=0;i<3;i++)
	//	for (int j=0;j<3;j++)
	//		dblWeight_IN_HD[i][j]=(i+j)/2.0;
	//for (int j=0;j<3;j++)
	//	dblWeight_HD_OT[j][0]=-1;


	wgtinit(CW_HD,HIDE_NUMBER);		//隐含层的三个随机的阀值
	wgtinit(CW_OT,OUT_NUMBER);		//最后的输出层的一个随机的阀值
	

}
void CChooseView::wgtinit(double w[],int sl)
{
	int i;
	double d;
	srand((unsigned)time(NULL));
	for(i=0;i<sl;i++)
	{	
		d= rand()/32767.0;	
		*(w+i)=0.2*d;
	}
}
void CChooseView::forwardcp(int ft,int bk,double w[],double in[],double out[],double cw[])
{
	int i,j;
	double sum;
	for(j=0;j<bk;j++)			//w[j][i],,,样本第i个属性上的在隐层第j个神经元上的权重
	{
		sum=0;
		for(i=0;i<ft;i++)
		{
			sum=sum+w[j*ft+i]*in[i];
		}
		//净输入sum
		sum-=cw[j]/10;
		out[j]=sigmf(sum);			
	}
}
double CChooseView::sigmf(double u)
{
	double su;
	su=-u/U0;
	su=1/(1.0+exp(su));
 //if(su>0.9) su=1; else if (su<0.1) su=0;
	return su;
}
void CChooseView::Bpcal(int p)
{
	int i,j,k;
	double ajtW,Bdelta_OT;
	double MajtW,MBdelta_OT;
	
	//调节隐含层的输出权重  dblWeight_HD_OT[3]共三个;

	for(j=0;j<OUT_NUMBER;j++)
	{
		//用到的公式是: d=X(1-X)(X-Y)									
		delta_OT[j]=dblOut_OT[j]*(1-dblOut_OT[j])*(T[p][j]-dblOut_OT[j]);
		Bdelta_OT=BETA*delta_OT[j];
		for(i=0;i<HIDE_NUMBER;i++)
		{
			//ajtW=YINO*delta_OT[j]*dblOut_HD[i];
			ajtW=Bdelta_OT*dblOut_HD[i];
			dblWeight_HD_OT[j][i] +=ajtW;

			//用到的公式是:对误差和权重都分别取比例的调节公式
			//即W(t+1)=W(t)-n*d*x+a*W(t)
			//dblWeight_HD_OT[j][i] =dblWeight_HD_OT[j][i]-ajtW+AFA*dblWeight_HD_OT[j][i];
		}
		//调整阈值
		CW_OT[j]+=BETA*delta_OT[j];
	}

	//调节初始输入层的权重  dblWeight_IN_HD[3][3]],共九个;

	for(j=0;j<HIDE_NUMBER;j++)
	{
		//用到的公式是: d(k)=x(k)(1-x(k))*(求和w(l_i)*d(k+1));
		
		delta_HD[j]=delta_OT[0]*dblWeight_HD_OT[0][j]*dblOut_HD[j]*(1-dblOut_HD[j]);   //隐层第j个神经元的输入误差;
		MBdelta_OT=BETA*delta_HD[j];
		//开始调节最初输入的9个权重
		//w[j][i],,,样本第i个属性上的在隐层第j个神经元上的权重
		for(k=0;k<INPUT_NUMBER;k++)
		{
			MajtW=MBdelta_OT*dblOut_IN[k];
			dblWeight_IN_HD[j][k]+=MajtW;			//当出现权重不变的时候,是因为有输入为0的情况,这时调节权重为0;所以权重不变。
			//用到的公式是:对误差和权重都分别取比例的调节公式
			//即W(t+1)=W(t)-n*d*x+a*W(t)
			//dblWeight_IN_HD[j][k] =dblWeight_IN_HD[j][k]-MajtW+AFA*dblWeight_IN_HD[j][k];
		}
		//调整阈值
		CW_HD[j]+=BETA*delta_HD[j];
	}
}
void CChooseView::GetChkValue(double  * chk)     //得到界面上的属性的值
{
	if(m_check0)
		chk[0]=1;
	else
		chk[0]=0;

	if(m_check1)
		chk[1]=1;
	else
		chk[1]=0;

	if(m_check2)
		chk[2]=1;
	else
		chk[2]=0;
}
void CChooseView::go_one_step ()
{
	int i,p;
	double Err,Errp[3];
	CString s;
	int flag=0;

	CAppleDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	//pDoc->UpdateAllViews (this);//在这里加上为什么到最后线条会消失.???

	train_count=0;

	//for(p=0;p<SpNUM;p++)
	//{
	//	for(i=0;i<INPUT_NUMBER;i++)
	//		dblOut_IN[i]=X[p][i];		//将开始的三个输入的值给 dblOut_IN[3] 变量;
	//	
	//	//从输入层的一个前向
	//	/*forward computation*/					//输入层 权重      //输入层值  //输出值 //隐层阀值  
	//	forwardcp(INPUT_NUMBER,HIDE_NUMBER,(double*)dblWeight_IN_HD,dblOut_IN,dblOut_HD,CW_HD);
	//	
	//	//从隐含层作为一个输入层的前向
	//	forwardcp(HIDE_NUMBER,OUT_NUMBER,(double*)dblWeight_HD_OT,dblOut_HD,dblOut_OT,CW_OT);

	//	/*adjust weight*/
	//	//Bpcal(p);		
	//}


	init();
	/*compute the error*/
	Err=0;
	//输出权重用到的变量
	CString str,strweight,stri,strj;
	CMainFrame* pMF=(CMainFrame*)AfxGetApp()->m_pMainWnd;
	CChooseView* pLV=(CChooseView*)pMF->m_WndSplitter.GetPane(0,0);
	CAppleView* pRV=(CAppleView*)pMF->m_WndSplitter.GetPane(0,1);
	CClientDC dc(pRV);
	double max1(0), max2(0), max3(0);
	
	
	do
	{
		for(p=0;p<SpNUM;p++)
		{
			for(i=0;i<INPUT_NUMBER;i++)
				dblOut_IN[i]=X[p][i];           //dblOut_IN[i]=x=[0][i]{0,0.1}  第i个样本的输入			

				train_count++;
				pDoc->mycount=train_count;
				
				//Sleep(1);       //时间延迟
				//PeekMessage( &msg, NULL, 0, 0, PM_REMOVE );
				////if( msg.message == WM_QUIT )
				////	break;
				//TranslateMessage( &msg );
				//DispatchMessage( &msg );
				
				
				/*forward computation*/
				forwardcp(INPUT_NUMBER,HIDE_NUMBER,(double*)dblWeight_IN_HD,dblOut_IN,dblOut_HD,CW_HD);
				forwardcp(HIDE_NUMBER,OUT_NUMBER,(double*)dblWeight_HD_OT,dblOut_HD,dblOut_OT,CW_OT);
				

				for(i=0;i<OUT_NUMBER;i++)	//每一个初始样本输入的所对应的最后输出
					OT[p][i]=dblOut_OT[i];

				//pDoc->wout =dblOut_OT[0];

				//这里是误差计算,但在Bpcal()中也有误差的计算.所以这里的代码没用.
				//Errp=0;
				//for(i=0;i<OUT_NUMBER;i++)
				//{
				//	//和教师信号T[0,1,2]的比较在这里体现;
				//	Errp+=0.5*(T[p][i]-OT[p][i])*(T[p][i]-OT[p][i]);
				//}
				
				//Err+=Errp;
				
				//我认为应该在这里加上权重的调节程序
				/*adjust weight*/
				Bpcal(p);	//调节在输入第p个样本时候的权重;
			Errp[p]=OT[p][0]-T[p][0];
			
			////train_count在这里*******************************
			//保存当次的输入权重
			for(int i=0;i<3;i++)
				for(int j=0;j<3;j++)
					pDoc->inweight[i][j]=dblWeight_IN_HD[i][j];
			//保存当次的隐层权重
			for(int u=0;u<3;u++)
				pDoc->hdweight[u]=dblWeight_HD_OT[0][u];
			
			//输出权重
			//当次的权重就输出,而不是和V1.5一样,保存在一个很大的数组中,在做完计算后才进行输出画线;
			for(int i1=0;i1<3;i1++)
				for(int j=0;j<3;j++)
				{
					strweight.Format ("%f",pDoc->inweight[i1][j]);
					stri.Format ("%d",i1);
					strj.Format ("%d",j);
					dc.TextOut (185,60+20*(j+i1*3),strweight);								
				}	
				//隐层
				for(int j=0;j<3;j++)
				{
					strweight.Format ("%f",pDoc->hdweight[j]);
					strj.Format ("%d",j);
					dc.TextOut (185,250+20*j,strweight);
				}
				
				s.Format ("%d",train_count);				
				dc.TextOut (100,0,s);
				
				pDoc->lastout[p]=OT[p][0];
				if(pDoc->lastout[0]>max1)
				{
					CBrush newbrush;
					newbrush.CreateHatchBrush(6,RGB(255,0,0));
					CBrush * pOldpen=(CBrush*)dc.SelectObject (&newbrush);

					max1=pDoc->lastout[0];
					dc.SetPixel((train_count+1)/50+300,280-max1*200,RGB(255,0,0));
					//dc.Ellipse((train_count+1)/50+300,280-max1*200,(train_count+1)/50+302,280-max1*201);
				}

				if(pDoc->lastout[1]>max2)
				{
					CBrush newbrush1;
					newbrush1.CreateHatchBrush(6,RGB(0,255,0));
					CBrush * pOldpen=(CBrush*)dc.SelectObject (&newbrush1);

					max2=pDoc->lastout[1];
					dc.SetPixel((train_count+1)/50+300,340-max1*200,RGB(0,255,0));
					//dc.Ellipse((train_count+1)/50+300,340-max2*200,(train_count+1)/50+302,340-max2*202);
				}

				if(pDoc->lastout[2]>max3)
				{
					CBrush newbrush2;
					newbrush2.CreateHatchBrush(6,RGB(0,0,255));
					CBrush * pOldpen=(CBrush*)dc.SelectObject (&newbrush2);
					max3=pDoc->lastout[2];
					dc.SetPixel((train_count+1)/50+300,380-max1*200,RGB(0,0,255));
					//dc.Ellipse((train_count+1)/50+300,380-max2*200,(train_count+1)/50+302,380-max2*202);
				}

			//保存最后的输出
			//pDoc->lastout[train_count][p]=OT[p][0];

			//pDoc->UpdateAllViews (this);

			//Invalidate(true);为什么不行???
		}
	}while((fabs(Errp[0])>0.1)||(fabs(Errp[1])>0.1)||(fabs(Errp[2])>0.1));
	pDoc->Success=true;
	GetDlgItem(IDC_BTNREC)->EnableWindow(true);
	//s.Format ("%d",train_count);
	//MessageBox("学习完成!"+s);
	//pDoc->UpdateAllViews (this);
}
//BOOL CChooseView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
//{
//	// TODO: 在此添加专用代码和/或调用基类
//
//	return CFormView::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
//}

void CChooseView::OnBnClickedBtnrec()
{
	// TODO: 在此添加控件通知处理程序代码
	//CAppleDoc* pDoc = GetDocument();
	//ASSERT_VALID(pDoc);

	m_result = new char[10];
	UpdateData();
	

	double myfruit[3];
	GetChkValue(myfruit);	

	double result;
	result=recognize(myfruit);

	switch ((int)(result*100))
	{
	case 100:

⌨️ 快捷键说明

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