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

📄 123view.cpp

📁 用vc++编写的神经网络算法识别数字的一个程序
💻 CPP
字号:
// 123View.cpp : implementation of the CMy123View class
//

#include "stdafx.h"
#include "123.h"

#include "123Doc.h"
#include "123View.h"
#include "zifudlg.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
    static int flag,flag1,flag2,flag3,flag4;
    double output[3];//前向计算结果
    static double eps[900];//误差值
	double w1[144];//第0层--〉第1层 权值 
	double w2[27];//第1层--〉第2层 权值
	double o1[9];//第1层阈值
	double o2[3];//第2层阈值
    double y2[3];//第2层  输出值
	char ch;
static double input[48]={1,1,1,1,1,0,0,1,1,1,1,1,1,0,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,1,1,1,1,1,0,0,1,1,0,0,1,1,1,1,1};
void compute(double *x,double *t);
double ecalculate(double *t);
double f(double x);
double fd(double x);
/////////////////////////////////////////////////////////////////////////////
// CMy123View

IMPLEMENT_DYNCREATE(CMy123View, CView)

BEGIN_MESSAGE_MAP(CMy123View, CView)
	//{{AFX_MSG_MAP(CMy123View)
	ON_COMMAND(ID_training, Ontraining)
	ON_COMMAND(ID_work, Onwork)
	ON_COMMAND(ID_paint, Onpaint)
	ON_COMMAND(ID_jianjie, Onjianjie)
	ON_COMMAND(ID_xianshi, Onxianshi)
	ON_COMMAND(ID_input, Oninput)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMy123View construction/destruction

CMy123View::CMy123View()
{
	// TODO: add construction code here

}

CMy123View::~CMy123View()
{
}

BOOL CMy123View::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CMy123View drawing

void CMy123View::OnDraw(CDC* pDC)
{
	    CMy123Doc* pDoc = GetDocument();
	    ASSERT_VALID(pDoc);
        CRect rectclient;
     	GetClientRect(rectclient);
    	pDC->SetMapMode(MM_ANISOTROPIC);
        pDC->SetWindowExt(2000,-1000);
    	pDC->SetViewportExt(rectclient.right,rectclient.bottom);
	    pDC->SetViewportOrg(rectclient.right/4,rectclient.bottom*3/4);
	// TODO: add draw code for native data here
    LOGFONT lf; 
    pDC->GetCurrentFont()->GetLogFont(&lf); 
    CFont font; 
    CFont *pOldFont; // 保存设备上下文最初使用的字体对象 
    lf.lfCharSet=40; 
    lf.lfHeight=-40; 
    lf.lfWidth=28; 
    strcpy(lf.lfFaceName, "宋体"); 
    font.CreateFontIndirect(&lf); 
    pOldFont=pDC->SelectObject(&font); 
     pDC->SetBkMode(TRANSPARENT); 
 if(flag1==1)
	{
	    int i;
		CPen pen1,pen2;
        pen1.CreatePen(PS_SOLID,2,RGB(0,0,0));
		pen2.CreatePen(PS_SOLID,10,RGB(255,0,0));
        pDC->SelectObject(&pen2);
    	pDC->TextOut(400,700,"训练曲线如下");
		pDC->MoveTo(0,(int)(eps[0]*200));
		for(i=0;i<100;i++)
		pDC->LineTo(i*12,(int)(eps[i]*200));
		pDC->SelectObject(&pen1);
		pDC->MoveTo(0,0);
		pDC->LineTo(0,600);
		pDC->MoveTo(300,0);
        pDC->LineTo(300,600);
		pDC->MoveTo(600,0);
        pDC->LineTo(600,600);
		pDC->MoveTo(900,0);
        pDC->LineTo(900,600);
		pDC->MoveTo(1200,0);
        pDC->LineTo(1200,600);
		pDC->MoveTo(0,0);
        pDC->LineTo(1200,0);
		pDC->MoveTo(0,200);
        pDC->LineTo(1200,200);
		pDC->MoveTo(0,400);
        pDC->LineTo(1200,400);
		pDC->MoveTo(0,600);
        pDC->LineTo(1200,600);
        pDC->TextOut(500,-100,"迭代次数");
	    pDC->TextOut(275,-10,"250");
        pDC->TextOut(575,-10,"500");
        pDC->TextOut(875,-10,"750");
        pDC->TextOut(1160,-10,"1000");
        pDC->TextOut(-300,320,"均方误差");
        pDC->TextOut(-60,0,"0");
        pDC->TextOut(-60,200,"1");
        pDC->TextOut(-60,400,"2");
        pDC->TextOut(-60,600,"3");
    
	}
	if(flag3==1)
	{
	
		CString jianjie;
        pDC->SetWindowExt(535,400);
		pDC->SetViewportOrg(0,0);
        CFont NewFont;
        NewFont.CreateFont(25,0,0,0,250,FALSE,FALSE,0,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH&FF_SWISS,"Arial");
		CFont *pOldFont=(CFont *)pDC->SelectObject(&NewFont);
        jianjie.Format("设计任务与要求");
		pDC->TextOut(50,50,jianjie);
		jianjie.Format("1 设计任务:");
		pDC->TextOut(45,70,jianjie);
		jianjie.Format("“编写一个利用BP神经网络进行字符识别的程序,需要识别的字符有三个:”");
        pDC->TextOut(45,90,jianjie);
		jianjie.Format("A,I,O,其输入为4*4个像素的扫描输入(二值图像),目标输出分别为A=(1,0,0)");
		pDC->TextOut(40,110,jianjie);
		jianjie.Format("I=(0,0,1),O=(0,0,1).即输入层16个节点,隐层9个节点,输出层3个节点。");
	    pDC->TextOut(40,130,jianjie);
		jianjie.Format("2设计要求:");
		pDC->TextOut(45,150,jianjie);
		jianjie.Format("(1) 完成训练程序和测试程序的编写和调试。");
		pDC->TextOut(50,170,jianjie);
		jianjie.Format("(2) 可计算机显示训练曲线和识别结果。");
		pDC->TextOut(50,190,jianjie );
  

	}
 if((flag2==1))
	
		
 {
	if((flag==0))
		{
			pDC->TextOut(200,350,"请先训练网络!");
		}
		else
		{
			if((flag4==1))
			{
                CString string;
			    string.Format("%c 的辨识结果:%f,%f,%f",ch,output[0],output[1],output[2]);
				pDC->TextOut(100,350,string);
			}
		}
	}
}
/////////////////////////////////////////////////////////////////////////////
// CMy123View printing

BOOL CMy123View::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CMy123View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CMy123View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CMy123View diagnostics

#ifdef _DEBUG
void CMy123View::AssertValid() const
{
	CView::AssertValid();
}

void CMy123View::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CMy123Doc* CMy123View::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMy123Doc)));
	return (CMy123Doc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMy123View message handlers

//训练网络
void training(double x[48],double t[9],int iternum)
{	int i;
	//初始化权值阈值
    //srand((unsigned )time(NULL));
	for(i=0;i<144;i++)
	{
	   w1[i]=rand()/32767.0;
	}
	for(i=0;i<27;i++)
	{
		w2[i]=rand()/32767.0;
	}
	for(i=0;i<9;i++)
	{
    	o1[i]=rand()/32767.0;
	}
    for(i=0;i<3;i++)
	{
		o2[i]=rand()/32767.0;
	}
	//迭代计算求权值阈值

	for(i=0;i<iternum;i++)
	{
		eps[i]=0.0;
		compute(x,t);
		eps[i]+=ecalculate(t);
		compute(x+16,t+3);
		eps[i]+=ecalculate(t+3);
		compute(x+32,t+6);
		eps[i]+=ecalculate(t+6);
	}
}		

//计算各层输入输出值并调整各层权值阈值

void compute(double *x,double*t)
{
	//局部变量定义
	double b1[9]={0,0,0,0,0,0,0,0,0};//第1层输入值
	double y1[9]={0,0,0,0,0,0,0,0,0};//第1层输出值
    double b2[3]={0,0,0};//第2层输入值
	double delta1[9]={0,0,0,0,0,0,0,0,0};//第1层误差值
    double delta2[3]={0,0,0};//第2层误差值

	int i,j,k;
	//计算第1层输入值
	for(j=0;j<9;j++)
		for(i=0;i<16;i++)
			b1[j]+=x[i]*w1[i*9+j];
    //计算第1层输出值
	for(j=0;j<9;j++)
		y1[j]=f(b1[j]-o1[j]);
    //计算第2层输入值
    for(k=0;k<3;k++)
		for(j=0;j<9;j++)
			b2[k]=b2[k]+y1[j]*w2[j*3+k];
    //计算第2层输出值
	for(k=0;k<3;k++)
		y2[k]=f(b2[k]-o2[k]);
	//计算第2层误差
	for(k=0;k<3;k++)
		delta2[k]=fd(y2[k])*(t[k]-y2[k]);
    //计算第1层误差
    for(j=0;j<9;j++)
	{
		for(k=0;k<3;k++)
        delta1[j]+=delta2[k]*w2[j*3+k];
		delta1[j]*=fd(y1[j]);
	}
	// *************调整权值阈值*****************//
	//调整权值 第0层--〉第1层
    for(i=0;i<16;i++)
		for(j=0;j<9;j++)
          w1[i*9+j]+=0.99*x[i]*delta1[i];
	//调整阈值 第1层
	for(i=0;i<9;i++)
		o1[i]+=0.99*delta1[i];
    //调整权值 第1层--〉第2层
    for(j=0;j<9;j++)
		for(k=0;k<3;k++)
          w2[j*3+k]+=0.99*y1[j]*delta2[k];
	//调整阈值 第2层
	for(i=0;i<3;i++)
		o2[i]+=0.99*delta2[i];
}
//计算误差
double ecalculate(double *t)
{
	double ee=0;
	int k;
	for(k=0;k<3;k++)
		ee+=(t[k]-y2[k])*(t[k]-y2[k])/2;
	return ee;
}
//************神经元函数与导数计算********************//
double f(double x)
{
	double f1;
	f1=1.0/(1.0+exp(-x));
	return (f1);
}
//////////
double fd(double x)
{
	double fd1;
	fd1=(x)*(1.0-x);
	return(fd1);
}
//*************前向计算*********************//
void work(double *x)
{
	//局部变量定义
    double b1[9]={0,0,0,0,0,0,0,0,0};//第1层输入值
	double y1[9]={0,0,0,0,0,0,0,0,0};//第1层输出值
    double b2[3]={0,0,0};//第2层输入值
	int i,j,k;
	//计算第1层输入值
	for(j=0;j<9;j++)
		for(i=0;i<16;i++)
			b1[j]+=x[i]*w1[i*9+j];
    //计算第1层输出值
	for(j=0;j<9;j++)
		y1[j]=f(b1[j]+o1[j]);
    //计算第2层输入值
    for(k=0;k<3;k++)
		for(j=0;j<9;j++)
			b2[k]+=y1[j]*w2[j*3+k];
    //计算第2层输出值
	for(k=0;k<3;k++)
	{
		y2[k]=f(b2[k]+o2[k]);
        output[k]=y2[k];
	}
}

////////////////菜单显示///////////////////
void CMy123View::Ontraining() 
{
	// TODO: Add your command handler code here	

	double t[9]={0,0,1,0,1,0,1,0,0};
    
	training(input,t,900);
 }

void CMy123View::Onwork() 
{
	// TODO: Add your command handler code here
	
}

void CMy123View::Onpaint() 
{
	// TODO: Add your command handler code here
	CPaintDC dc(this);
	OnPrepareDC(&dc);
	OnDraw (&dc);
	flag1=1;
    flag2=0;
    flag3=0;
    flag4=0;
    flag=1;
    Invalidate(TRUE);
}

void CMy123View::Onjianjie() 
{
// TODO: Add your command handler code here
    CPaintDC dc(this);
	OnPrepareDC(&dc);
	OnDraw (&dc);
	flag3=1;
	flag2=0;
    flag1=0;
    flag4=0;
   Invalidate(TRUE);
}

void CMy123View::Onxianshi() 
{
	// TODO: Add your command handler code here
    CPaintDC dc(this);
	OnPrepareDC(&dc);
  	OnDraw (&dc);
    Invalidate(TRUE);
	flag2=1;
    flag4=1;
    flag1=0;
    flag3=0;
}

void CMy123View::Oninput() 
{
	// TODO: Add your command handler code here
	int select=0;
	Czifudlg dlg;
	dlg.m_zifu = 0;
if (flag==1)
{

   if(dlg.DoModal()==IDOK)
	{
		flag4=1;	
		select=dlg.m_zifu;

       switch (select)
	   {
         case 0:
	           work(input);
	            ch='A';
             	break;
          case 1:
	            work(input+16);
                 ch='I';
	              break;
           case 2:
	             work(input+32);
                   ch='O';
	               break;
	   }
            Invalidate(TRUE);
   }  
else 
  Invalidate(TRUE);
  flag1=0;
  flag2=1;
  flag3=0;
}
}

⌨️ 快捷键说明

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