📄 nn.cpp
字号:
break;
n = 0;
// shuffle();
// 下面是修改步长
// 误差增大,则减小步长
if(Error_Average>0.1)
{
if ( Error[count]/Error_Average > 1.0 )
{
yita1=0.05;//0.7;
yita2=0.05;//0.8;
}
else
{
yita1=0.1;//0.9;
yita2=0.1;//1.05;
}
}
else if(Error_Average>0.01)
{
if ( Error[count]/Error_Average > 1.0 )
{
yita1=0.02;//0.7;
yita2=0.02;//0.8;
}
else
{
yita1=0.05;//0.9;
yita2=0.05;//1.05;
}
}
else
{
if ( Error[count]/Error_Average > 1.0 )
{
yita1=0.0005;//0.7;
yita2=0.0005;//0.8;
}
else
{
yita1=0.001;//0.9;
yita2=0.001;//1.05;
}
alpha = 0.7;
}
Error_Average=Error[count];
Iter = count;
count++;
Error[count]=0;
printf("NO. %d circle's error is %f\n",count,Error_Average);
}
}
epoch=count+1;
}
//---------------------------------------------------------------------------
// 释放空间函数
void End()
{
for( int i=0; i<Samplenum; i++ )
{
delete[] Data[i];
}
delete[] Data;
for( i = 0;i < HideNum;i++)
{
delete[] w2[i];
delete[] w2Change[i];
}
delete[] w2;
delete[] w2Change;
for( i = 0;i < OutputNum;i++)
{
delete[] w3[i];
delete[] w3Change[i];
}
delete[] w3;
delete[] w3Change;
delete[] Out_Input;
delete[] Net_Hide;
delete[] Out_Hide;
delete[] Net_Output;
delete[] Out_Output;
delete[] Error;
delete[] Order;
}
//---------------------------------------------------------------------------
// 输入样本随机排序
void shuffle()
{
srand( (unsigned)time( NULL ) );
for( int i=0; i<300; i++ )
{
loop:
int temp = rand() % (300);
for( int k=0; k<i; k++ )
{
// 如果重复产生,则重新开始
if(temp == Order[k])
{
goto loop;
}
}
Order[i] = temp;
}
}
//---------------------------------------------------------------------------
void Test()
{
FILE *stream;
char namebuf[30];
short SampleHeight,SampleWidth;
unsigned char Printpic[100][100];
Test_Data = new float*[1000];
for( int i=0; i<1000; i++ )
{
Test_Data[i] = new float[Dimension + OutputNum];
}
//初始化Data
for( i=0; i<1000; i++ )
{
for(int j=0; j<Dimension + OutputNum; j++)
{
Test_Data[i][j] = 0;
}
}
for(i=0;i<10;i++)
{
for(int j=0;j<100;j++)
{
sprintf((char *)namebuf,".\\test\\%d-%d.raw",i,j+1);
if( (stream = fopen((const char *)namebuf,"rb")) == NULL )
{
Test_Data[i*100+j][Dimension-1]=1;
continue;
//printf("Can not open the file %d_%d.raw",i,j+1);
}
fread(&SampleHeight,sizeof(short),1,stream);
fread(&SampleWidth,sizeof(short),1,stream);
for(int k=0; k<SampleHeight; k++)
{
fread(Printpic[k],sizeof(unsigned char),SampleWidth,stream);
}
fclose(stream);
for( k=0; k<SampleHeight; k++)
{
for(int l=0; l<SampleWidth; l++)
if(Printpic[k][l]>0)
Printpic[k][l]=1;
}
//图像规一化为24×12
int UpRightZhifang[100],HorizenZhifang[100];
int LetterLow,LetterHigh,LetterLeft,LetterRight;
int VerticalScale,HorizenScale;
int x,y,offsetx,offsety;
int tempx,tempy,temp;
int Height,Width;
char Letter[24][12];
for(k=0;k<100;k++)
{
UpRightZhifang[k]=0;
HorizenZhifang[k]=0;
}
//确定上下左右边界
for(k=0; k<SampleHeight; k++)
{
for(int l=0; l<SampleWidth; l++)
{
UpRightZhifang[k]+=Printpic[k][l];
}
}
for(int l=0; l<SampleWidth; l++)
{
for(k=0; k<SampleHeight; k++)
{
HorizenZhifang[l]+=Printpic[k][l];
}
}
for(k=0; k<SampleHeight; k++)
{
if( UpRightZhifang[k+1]>=1 && UpRightZhifang[k]>=1 )
{
LetterHigh=k;
break;
}
}
for(k=SampleHeight; k>=0; k--)
{
if( UpRightZhifang[k]>=1 && UpRightZhifang[k-1]>=1 )
{
LetterLow=k;
break;
}
}
for(k=0; k<SampleWidth; k++)
{
if( HorizenZhifang[k+1]>=1 && HorizenZhifang[k]>=1 )
{
LetterLeft=k;
break;
}
}
for(k=SampleWidth; k>=0; k--)
{
if( HorizenZhifang[k]>=1 && HorizenZhifang[k-1]>=1 )
{
LetterRight=k;
break;
}
}
Height=LetterLow-LetterHigh+1;
Width=LetterRight-LetterLeft+1;
//按比例归一化为24*12图象
VerticalScale=Height*100/24;
HorizenScale=Width*100/12;
for(int i1=0; i1<24; i1++)
{
temp=((i1+1)*VerticalScale+50)/100;
offsetx=(i1*VerticalScale+50)/100;
tempx=temp-offsetx;
if(tempx<1)
tempx=1;
for(int j1=0; j1<12; j1++)
{
temp=((j1+1)*HorizenScale+50)/100;
offsety=(j1*HorizenScale+50)/100;
tempy=temp-offsety;
if(tempy<1)
tempy=1;
Letter[i1][j1]=0;
for(k=0; k<tempx; k++)
{
for(l=0; l<tempy; l++)
{
//???有问题
x=offsetx+k+LetterHigh;
if(x>=100)
x=99;
y=offsety+l+LetterLeft;
if(y>=100)
y=99;
//???可能有问题,只要认为原图象的对应区域有一个1,ij点的值就是1
Letter[i1][j1]|=Printpic[x][y];
}
}
}
}
//
for(k=0;k<24;k++)
{
for(l=0;l<12;l++)
Test_Data[i*100+j][k*12+l]=Letter[k][l];
}
// 阈值对应的输入
Test_Data[i*100+j][Dimension-2]=-1.0;
// 将理想输出写到矩阵中
Test_Data[i*100+j][Dimension+i]=1;
printf("%d-%d has been loaded\n",i,j+1);
}
}
int n=0,m=0;
int max_place=0;
while( n < 1000 )
{
//阈值所对应的输入(即是前一层的输出)
Out_Input[InputNum] = -1.0; //总输出
Out_Hide[HideNum] = -1.0; //总输出
//输入
for( int i=0; i<InputNum; i++ )
{
Out_Input[i] = Test_Data[n][i];
}
//输入层到隐含层
for( i=0; i<HideNum; i++ )
{
Net_Hide[i] = 0.0;
for( int j=0; j<InputNum + 1; j++ )
{
Net_Hide[i] = Net_Hide[i] + w2[i][j] * Out_Input[j];
}
Out_Hide[i] = exp(-Net_Hide[i]*Net_Hide[i]*0.5);
}
//隐含层到输出层
for( i=0; i<OutputNum; i++ )
{
Net_Output[i] = 0.0;
for( int j=0; j<HideNum + 1; j++ )
{
Net_Output[i] = Net_Output[i] + w3[i][j] * Out_Hide[j];
}
Out_Output[i] = 1.0 / ( 1.0+exp(-0.05*Net_Output[i]) );//1.0 / ( 1.0+exp(-0.3*Net_Output[i]) );
if( Out_Output[i]>Out_Output[max_place] )
max_place=i;
}
printf("NO. %d has been test. ",n);
m++;
// 下面判断识别效果
if( Test_Data[n][Dimension-1]==1)
{
m--;
printf("\n");
n=n+1;
continue;
}
else if (Test_Data[n][Dimension+max_place]==1)
{
right++;
printf(" right!\n");
}
else
{
printf("wrong:(\n");
}
n = n + 1;
}
}
//---------------------------------------------------------------------------
void saveweight()
{
FILE *outfile;
if( (outfile = fopen(".\\weight1.txt","w")) == NULL )
{
printf("Can not open the file weight1.txt");
}
for(int i=0; i<100; i++)
{
for(int j=0; j<289; j++)
fprintf(outfile,"%f",w2[i][j]);
//fwrite(w2[i],sizeof(float),289,outfile);
}
fclose(outfile);
if( (outfile = fopen(".\\weight2.txt","w")) == NULL )
{
printf("Can not open the file weight2.txt");
}
for(i=0; i<10; i++)
{
for(int j=0; j<101; j++)
fprintf(outfile,"%f",w3[i][j]);
//fwrite(w3[i],sizeof(float),101,outfile);
}
fclose(outfile);
}
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
char a='y',b='y';
Initial();
Initial_Weight();
LoadData();
Training();
printf("\nDo you want to test all data? If yes, input 'y', else, input 'n':\n");
scanf("%c",&a);
if (a=='y' || a=='Y')
{
printf("begin!");
Test();
}
printf("total recognized right number is %d\n",right);
saveweight();
/*
printf("\nDo you want to write out weight data? If yes, input 'y', else, input 'n':\n");
scanf("%c",&b);
if (b=='y' || b=='Y')
{
saveweight();
}
*/
End();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -