📄 123view.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 + -