📄 annbp.cpp
字号:
void Annbp::SetCoverNodeNum()
{
CoverNodeNum.SetSize(HideCoverNum+2);
CoverNodeNum[0] = InputNum+1;
for (int i=1;i<HideCoverNum+1;i++)
CoverNodeNum[i] = HideNum[i-1]+1;
CoverNodeNum[HideCoverNum+1] = OutputNum;
}
BOOL Annbp::ReadTest()
{
/* CFile f;
CFileException e;
if( !f.Open( TestSet,CFile::modeRead,&e ) )
{
#ifdef _DEBUG
afxDump << "File could not be opened " << e.m_cause << "\n";
#endif
return FALSE;
}*/
FILE *fp;
if((fp = fopen("D:\\jlm\\ANN\\BPNN\\"+TestSet,"r"))==NULL)
{
MessageBox(NULL,"打开测试集样本文件错误","错误",MB_OK);
return FALSE;
}
for (int n=0;n<TestSetNum;n++)
{
for (int i=1;i<InputNum+1;i++)
fscanf(fp,"%lf",&t[n][i]);
for (int j=0;j<OutputNum;j++)
fscanf(fp,"%lf",&p[n][j]);
}
for (n=0;n<TestSetNum;n++) //阈值
t[n][0] = -1;
fclose(fp);
return TRUE;
}
double Annbp::Test()
{
if (InputNum == 0 )
{
MessageBox(NULL,"请先进行神经网络设置!","提示",MB_ICONINFORMATION|MB_OK);
return 9999;
}
if (!IsTrained)
{
MessageBox(NULL,"请先进行神经网络训练!","提示",MB_ICONINFORMATION|MB_OK);
return 9999;
}
for (int i=0;i<t.GetSize();i++)
t[i].RemoveAll();
t.RemoveAll();
t.SetSize(TestSetNum);
for (i=0;i<TestSetNum;i++)
t[i].SetSize(InputNum+1);
for (i=0;i<p.GetSize();i++)
p[i].RemoveAll();
p.RemoveAll();
p.SetSize(TestSetNum);
for (i=0;i<TestSetNum;i++)
p[i].SetSize(OutputNum);
if(ReadTest()==FALSE) return 9999;
CArray<CArray<double,double>,CArray<double,double>&> y;
y.SetSize(HideCoverNum+2);
SetCoverNodeNum();
for (i=0;i<HideCoverNum+1;i++)
y[i].SetSize(CoverNodeNum[i]+1);
y[HideCoverNum+1].SetSize(OutputNum);
double se;
///
FILE *fp;
if((fp = fopen("D:\\jlm\\ANN\\BPNN\\"+TestOutFile,"w"))==NULL)
{
MessageBox(NULL,"打开测试结果文件错误","错误",MB_OK);
return 9999;
}
///
se = 0;
for (int n=0;n<TestSetNum;n++)
{
for (int in=0;in<InputNum+1;in++)
y[0][in] = t[n][in];
for(int c=1;c<HideCoverNum+1;c++)//隐层
{
for(int j=1;j<CoverNodeNum[c];j++)
{
double v=0;
for(int i=0;i<CoverNodeNum[c-1];i++)
v += w[c][j][i]*y[c-1][i];
y[c][j] = 1.0/(1+exp(-v));
}
}
for(int k=0;k<OutputNum;k++)//输出层
{
double v=0;
for(int i=0;i<CoverNodeNum[HideCoverNum];i++)
v += w[HideCoverNum+1][k][i]*y[HideCoverNum][i];
/*
if(OutputFunctionType != 0)//线性
y[HideCoverNum+1][k] = v;
else//sigmoid
y[HideCoverNum+1][k] = 1.0/(1+exp(-v));*/
switch (OutputFunctionType)//0---sigmoid函数;1---线性阈值函数;2---线性多分段函数;3---线性01分段函数;
{
case 0:
y[HideCoverNum+1][k] = 1.0/(1+exp(-v*FuncSlope));
break;
case 1:
y[HideCoverNum+1][k] = v;
break;
case 2:
break;
case 3:
if (v <= 0)
y[HideCoverNum+1][k] = 0.0;
else
y[HideCoverNum+1][k] = 1.0;
break;
}
}
//误差
CArray<double,double> e;
e.SetSize(OutputNum);
for(k=0;k<OutputNum;k++)
{
e[k] = p[n][k]-y[HideCoverNum+1][k];
se = se + 0.5*pow(e[k],2);
}
for (in=1;in<InputNum+1;in++)
{
fprintf(fp,"%f ",y[0][in]);//
}
for(k=0;k<OutputNum;k++)
{
fprintf(fp,":%f ",p[n][k]);//
fprintf(fp," - %f ",y[HideCoverNum+1][k]);//
fprintf(fp," = %f ",(p[n][k]-y[HideCoverNum+1][k]));//
}
fprintf(fp,"\n");
e.RemoveAll();
}
se = se/TestSetNum;
fprintf(fp,"均方误差:%f",se);//
for (i=0;i<y.GetSize();i++)
y[i].RemoveAll();
y.RemoveAll();
fclose(fp);//
::ShellExecute(NULL,NULL,"测试结果.txt",NULL,"D:\\jlm\\ANN\\BPNN",SW_SHOW);//%SystemRoot%\system32\notepad.exe
return se;
}
void Annbp::DrawStru()
{
if (InputNum == 0 )
return;
CWnd* pWnd = AfxGetMainWnd();
CDC* pDC = pWnd->GetDC();
CRect* pRect = new CRect;
pWnd->GetClientRect(pRect);
ASSERT(pRect);
int m_SumWidth = int(pRect->Width()*2/3.0);
int m_Top = int(pRect->Height()*2/15.0);
int m_Bot = int(pRect->Height()*13/15.0);
int m_CellRad = int((m_Bot-m_Top)*1.0/MaxCovNod()*0.9/2.0);
if (m_CellRad > 10)
m_CellRad = 10;
CBrush m_brush;
CBrush* poldbrush;
m_brush.CreateSolidBrush(pDC->GetPixel(2,m_Top));
poldbrush = pDC->SelectObject(&m_brush);
pDC->Rectangle(0,int(pRect->Height()/21.0),pRect->Width(),int(pRect->Height()*20.3/21.0));
pDC->SelectObject(poldbrush);
/*
pDC->MoveTo(m_SumWidth,0);
pDC->LineTo(m_SumWidth,pRect->Height());
pDC->MoveTo(0,m_Bot);
pDC->LineTo(m_SumWidth,m_Bot);
*/
pDC->SetBkMode(TRANSPARENT);
//pDC->SetTextColor(RGB(255,0,255));
LOGFONT logFont;
logFont.lfHeight=20;
logFont.lfWeight=0;
logFont.lfEscapement=0;
logFont.lfOrientation=0;
logFont.lfWeight=FW_BOLD;
logFont.lfItalic=0;
logFont.lfUnderline=0;
logFont.lfStrikeOut=0;
logFont.lfCharSet=GB2312_CHARSET;
logFont.lfQuality=PROOF_QUALITY;
logFont.lfPitchAndFamily=VARIABLE_PITCH|FF_DONTCARE;
strcpy(logFont.lfFaceName,"隶书");
CFont font;
font.CreateFontIndirect(&logFont);
CFont* poldFont=pDC->SelectObject(&font);
pDC->TextOut(int(m_SumWidth/3.0),int(pRect->Height()*1/15.0),"神经网络模型结构");
pDC->SelectObject(poldFont);
logFont.lfHeight=12;
strcpy(logFont.lfFaceName,"宋体");
CFont font1;
font1.CreateFontIndirect(&logFont);
poldFont=pDC->SelectObject(&font1);
CString str,strH0,strH;
str.Format("输入层 %d 个神经元,输出层 %d 个神经元",InputNum,OutputNum);
strH0.Format("共有 %d 个隐含层:",HideCoverNum);
//",隐含层 %d 个神经元",HideNum[0],
pDC->TextOut(int(pRect->Width()/9.0),int(pRect->Height()*13.3/15.0),str);
pDC->TextOut(int(pRect->Width()/9.0),int(pRect->Height()*13.8/15.0),strH0);
for (int n=0;n<HideCoverNum;n++)
{
strH.Format("第 %d 隐含层 %d 个神经元",n+1,HideNum[n]);
pDC->TextOut(int(pRect->Width()/3.6),int(pRect->Height()*(13.8+n/3.0)/15.0),strH);
}
pDC->SelectObject(poldFont);
/* CString str;
str.Format("m_SumWidth:%10d",m_SumWidth);
pWnd->MessageBox(str,NULL,MB_OK);
str.Format("m_Top:%10d",m_Top);
pWnd->MessageBox(str,NULL,MB_OK);
str.Format("m_Bot:%10d",m_Bot);
pWnd->MessageBox(str,NULL,MB_OK);
str.Format("m_CellRad:%10d",m_CellRad);
pWnd->MessageBox(str,NULL,MB_OK);
*/
int x,y;
for (int i=0;i<InputNum;i++)
{
x = int(m_SumWidth*1.0/2/(HideCoverNum+2));
y = int(m_Top+(i+0.5)*(m_Bot-m_Top)*1.0/InputNum);
DrawCell(x,y,m_CellRad,-1);
DrawLine(int(x*1.0/3),y,x-m_CellRad,y,0);
}
for (i=0;i<HideCoverNum;i++)
{
for (int j=0;j<HideNum[i];j++)
{
x = int(m_SumWidth*1.0/(HideCoverNum+2)*(i+1.5));
y = int(m_Top+(j+0.5)*(m_Bot-m_Top)*1.0/HideNum[i]);
DrawCell(x,y,m_CellRad,0);
if (i==0)
{
for (int k=0;k<InputNum;k++)
{
int x0 = int(m_SumWidth*1.0/2/(HideCoverNum+2));
int y0 = int(m_Top+(k+0.5)*(m_Bot-m_Top)*1.0/InputNum);
double a = tanh((y-y0)*1.0/(x-x0));
DrawLine(int(x0+m_CellRad*cos(a)),int(y0+m_CellRad*sin(a)),int(x-m_CellRad*cos(a)),int(y-m_CellRad*sin(a)),1);
}
}
else
{
for (int k=0;k<HideNum[i-1];k++)
{
int x0 = int(m_SumWidth*1.0/(HideCoverNum+2)*(i-1+1.5));
int y0 = int(m_Top+(k+0.5)*(m_Bot-m_Top)*1.0/HideNum[i-1]);
double a = tanh((y-y0)*1.0/(x-x0));
DrawLine(int(x0+m_CellRad*cos(a)),int(y0+m_CellRad*sin(a)),int(x-m_CellRad*cos(a)),int(y-m_CellRad*sin(a)),1);
}
}
}
}
for (i=0;i<OutputNum;i++)
{
x = int(m_SumWidth*1.0/(HideCoverNum+2)*(HideCoverNum+1.5));
y = int(m_Top+(i+0.5)*(m_Bot-m_Top)*1.0/OutputNum);
DrawCell(x,y,m_CellRad,OutputFunctionType);
for (int j=0;j<HideNum[HideCoverNum-1];j++)
{
int x0 = int(m_SumWidth*1.0/(HideCoverNum+2)*(HideCoverNum-1+1.5));
int y0 = int(m_Top+(j+0.5)*(m_Bot-m_Top)*1.0/HideNum[HideCoverNum-1]);
double a = tanh((y-y0)*1.0/(x-x0));
DrawLine(int(x0+m_CellRad*cos(a)),int(y0+m_CellRad*sin(a)),int(x-m_CellRad*cos(a)),int(y-m_CellRad*sin(a)),1);
}
DrawLine(x+m_CellRad,y,x+int(m_SumWidth*1.0/(HideCoverNum+2)/3),y,0);
}
delete pRect;
ReleaseDC(pWnd->m_hWnd,pDC->m_hDC);//Release!!
}
int Annbp::MaxCovNod()
{
int max;
max = InputNum+1;
for (int i=0;i<HideCoverNum;i++)
{
if (HideNum[i]+1 > max)
max = HideNum[i]+1;
}
if (OutputNum > max)
max = OutputNum;
return max;
}
void Annbp::DrawCell(int x,int y,int r,int type)
{
CWnd* pWnd = AfxGetMainWnd();
CDC* pDC = pWnd->GetDC();
pDC->Ellipse(x-r,y-r,x+r,y+r);
ReleaseDC(pWnd->m_hWnd,pDC->m_hDC);//Release!!
}
void Annbp::DrawLine(int x1,int y1,int x2,int y2,int type)
{
CWnd* pWnd = AfxGetMainWnd();
CDC* pDC = pWnd->GetDC();
pDC->MoveTo(x1,y1);
pDC->LineTo(x2,y2);
double a,l,da;
a = tanh((y2-y1)*1.0/(x2-x1));
l = 8;
da = 0.4;
int xp,yp,xp0,yp0;
if (type==1)
{
xp = int((x1+x2)/2.0);
yp = int((y1+y2)/2.0);
}
else
{
xp = x2;
yp = y2;
}
CPen m_pen;
CPen* poldpen;
m_pen.CreatePen(PS_SOLID,1,RGB(255,0,0));
poldpen = pDC->SelectObject(&m_pen);
xp0 = int(xp-l*cos(a+da));
yp0 = int(yp-l*sin(a+da));
pDC->MoveTo(xp0,yp0);
pDC->LineTo(xp,yp);
xp0 = int(xp-l*cos(a-da));
yp0 = int(yp-l*sin(a-da));
pDC->MoveTo(xp0,yp0);
pDC->LineTo(xp,yp);
pDC->SelectObject(poldpen);
ReleaseDC(pWnd->m_hWnd,pDC->m_hDC);//Release!!
}
double Annbp::ExportDem()
{
if (InputNum == 0 )
{
MessageBox(NULL,"请先进行神经网络设置!","提示",MB_ICONINFORMATION|MB_OK);
return 9999;
}
if (!IsTrained)
{
MessageBox(NULL,"请先进行神经网络训练!","提示",MB_ICONINFORMATION|MB_OK);
return 9999;
}
///dem
FILE *fp0;
if((fp0 = fopen("D:\\jlm\\ANN\\BPNN\\"+TrainingSet,"r"))==NULL)
{
MessageBox(NULL,"打开训练集样本文件错误","错误",MB_OK);
return FALSE;
exit(0);
}
double xtemp;
CString stemp;
int ntemp;
for (int n=0;n<TrainingSetNum;n++)
{
for (int i=1;i<InputNum+1;i++)
fscanf(fp0,"%lf",&xtemp);
for (int j=0;j<OutputNum;j++)
fscanf(fp0,"%lf",&xtemp);
}
fscanf(fp0,"%s",stemp);
fscanf(fp0,"%d",&ntemp);//num
fscanf(fp0,"%s",stemp);
int nrows;
fscanf(fp0,"%s",stemp);
fscanf(fp0,"%d",&nrows);//rows
int ncols;
fscanf(fp0,"%s",stemp);
fscanf(fp0,"%d",&ncols);//cols
fclose(fp0);
///
//int nrows = 14;
//int ncols = 17;
int inputunitsnum = 2;
/*for (int i=0;i<t.GetSize();i++)
t[i].RemoveAll();
t.RemoveAll();
t.SetSize(ncols*nrows);
for (i=0;i<TestSetNum;i++)
t[i].SetSize(inputunitsnum+1);
for (i=0;i<p.GetSize();i++)
p[i].RemoveAll();
p.RemoveAll();
p.SetSize(TestSetNum);
for (i=0;i<TestSetNum;i++)
p[i].SetSize(OutputNum);
if(ReadTest()==FALSE) return 9999;
for (i=0;i<ncols*nrows;i++)
{
int row = int(i*1.0/ncols);
int col = i%ncols;
t[i][1] = row*0.8/nrows+0.1;
t[i][2] = col*0.8/ncols+0.1;
}
for (int n=0;n<ncols*nrows;n++) //阈值
t[n][0] = -1;*/
CArray<CArray<double,double>,CArray<double,double>&> y;
y.SetSize(HideCoverNum+2);
SetCoverNodeNum();
for (int i=0;i<HideCoverNum+1;i++)
y[i].SetSize(CoverNodeNum[i]+1);
y[HideCoverNum+1].SetSize(OutputNum);
//double se;
///
FILE *fp;
if((fp = fopen("D:\\jlm\\ANN\\BPNN\\gridresult.txt","w"))==NULL) //"D:\\jlm\\ANN\\BPNN\\"+TestOutFile
{
MessageBox(NULL,"打开gridresult.txt结果文件错误","错误",MB_OK);
return 9999;
}
///
//se = 0;
for (n=0;n<ncols*nrows;n++)
{
//for (int in=0;in<InputNum+1;in++)
// y[0][in] = t[n][in];
int row = int(n*1.0/ncols);
int col = n%ncols;
y[0][0] = -1;
y[0][1] = row*0.8/nrows+0.1;
y[0][2] = col*0.8/ncols+0.1;
for(int c=1;c<HideCoverNum+1;c++)//隐层
{
for(int j=1;j<CoverNodeNum[c];j++)
{
double v=0;
for(int i=0;i<CoverNodeNum[c-1];i++)
v += w[c][j][i]*y[c-1][i];
y[c][j] = 1.0/(1+exp(-v));
}
}
for(int k=0;k<OutputNum;k++)//输出层
{
double v=0;
for(int i=0;i<CoverNodeNum[HideCoverNum];i++)
v += w[HideCoverNum+1][k][i]*y[HideCoverNum][i];
/*
if(OutputFunctionType != 0)//线性
y[HideCoverNum+1][k] = v;
else//sigmoid
y[HideCoverNum+1][k] = 1.0/(1+exp(-v));*/
switch (OutputFunctionType)//0---sigmoid函数;1---线性阈值函数;2---线性多分段函数;3---线性01分段函数;
{
case 0:
y[HideCoverNum+1][k] = 1.0/(1+exp(-v*FuncSlope));
break;
case 1:
y[HideCoverNum+1][k] = v;
break;
case 2:
break;
case 3:
if (v <= 0)
y[HideCoverNum+1][k] = 0.0;
else
y[HideCoverNum+1][k] = 1.0;
break;
}
}
//误差
/*CArray<double,double> e;
e.SetSize(OutputNum);
for(k=0;k<OutputNum;k++)
{
e[k] = p[n][k]-y[HideCoverNum+1][k];
se = se + 0.5*pow(e[k],2);
}
for (in=1;in<InputNum+1;in++)
{
fprintf(fp,"%f ",y[0][in]);//
}*/
/*for(k=0;k<OutputNum;k++)
{
fprintf(fp,":%f ",p[n][k]);//
fprintf(fp," - %f ",y[HideCoverNum+1][k]);//
fprintf(fp," = %f ",(p[n][k]-y[HideCoverNum+1][k]));//
}*/
fprintf(fp,"%lf ",y[HideCoverNum+1][0]);//
if (((n+1)%ncols) == 0)
fprintf(fp,"\n");
//e.RemoveAll();
}
/*se = se/TestSetNum;
fprintf(fp,"均方误差:%f",se);*/
for (i=0;i<y.GetSize();i++)
y[i].RemoveAll();
y.RemoveAll();
fclose(fp);//
::ShellExecute(NULL,NULL,"gridresult.txt",NULL,"D:\\jlm\\ANN\\BPNN",SW_SHOW);//%SystemRoot%\system32\notepad.exe
return 0.0;//se;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -