网络层数.docx
《网络层数.docx》由会员分享,可在线阅读,更多相关《网络层数.docx(28页珍藏版)》请在冰豆网上搜索。
网络层数
#include
#include
#include
#include
/******************************************************************************
宏定义
******************************************************************************/
typedefintBOOL;
typedefintINT;
typedefdoubleREAL;
typedefcharCHAR;
#defineFALSE0
#defineTRUE1
#defineNOT!
#defineAND&&
#defineOR||
#defineMIN(x,y)((x)<(y)?
(x):
(y))
#defineMAX(x,y)((x)>(y)?
(x):
(y))
#definesqr(x)((x)*(x))
#defineLO0.1
#defineHI0.9
#defineBIAS0.5
#defineNUM_LAYERS3//网络层数
#defineNUM_DATA10//样本数
#defineX6//每个样本的列数
#defineY7//每个样本的行数
#defineN(X*Y)//输入层神经元个数
#defineM10//输出层神经元个数
/////////////////////////////////////////////////////////////////////////////////////////
//结构变量声明//
/////////////////////////////////////////////////////////////////////////////////////////
typedefstruct{
INTUnits;//层神经元数量
REAL*Output;//输出数(即输出个矢量元素个数)
REAL*Activation;//激活值
REAL*Error;//本层误差
REAL**Weight;//连接权
REAL**WeightSave;//保存训练调整后的连接权
REAL**dWeight;//调整量
}LAYER;//神经网络层结构
typedefstruct{
LAYER**Layer;//神经网络各层指针
LAYER*InputLayer;//输入层
LAYER*OutputLayer;//输出层
REALAlpha;//冲量参数
REALEta;//学习率
REALError;//总误差
REALEpsilon;//控制精度
}NET;//神经网络
INTUnits[NUM_LAYERS]={N,10,M};//用一维数组记录各层神经元个数
FILE*f;//声明文件指针
REALInput[NUM_DATA][N];//用来记录学习样本输入模式
REALInputtest[NUM_DATA][N];//用来记录测试样本输入模式
/******************************************************************************
各函数声明
******************************************************************************/
voidInitializeRandoms();//设置伪随机数种子
INTRandomEqualINT(INTLow,INTHigh);//产生一个LOW-TOP之间的伪随机整数
REALRandomEqualREAL(REALLow,REALHigh);//产生一个LOW-TOP之间的伪随机浮点数
voidFinalizeApplication(NET*Net);//关闭文件
voidRandomWeights(NET*Net);//随机生成网络各层联接权
voidSaveWeights(NET*Net);//保存网络各层联接权,以防丢失宝贵的联接权
voidRestoreWeights(NET*Net);//恢复网络各层联接权,以便重建网络
voidGenerateNetwork(NET*Net);//创建网络,为网络分配空间
voidInitializeApplication(NET*Net);//将学习样本转换成为输入模式,并创建一个文件以保存显示结果
voidSimulateNet(NET*Net,REAL*Input,REAL*Target,BOOLTraining,BOOLProtocoling);//将每个样本投入网络运作
voidSetInput(NET*Net,REAL*Input,BOOLProtocoling);//获得输入层的输出
voidPropagateLayer(NET*Net,LAYER*Lower,LAYER*Upper);//计算当前层的网络输出,upper为当前层,LOWER为前一层
voidPropagateNet(NET*Net);//计算整个网络各层的输出
voidGetOutput(NET*Net,REAL*Output,BOOLProtocoling);//获得输出层的输出
voidComputeOutputError(NET*Net,REAL*Target);//计算网络输出层的输出误差
voidBackpropagateLayer(NET*Net,LAYER*Upper,LAYER*Lower);//当前层误差反向传播
voidBackpropagateNet(NET*Net);////整个网络误差的后传
voidAdjustWeights(NET*Net);//调整网络各层联接权,提取样本特征
voidWriteInput(NET*Net,REAL*Input);//显示输入模式
voidWriteOutput(NET*Net,REAL*Output);//显示输出模式
voidInitializetest();//将测试样本转换成为输入模式
/******************************************************************************
学习样本
******************************************************************************/
CHARPattern[NUM_DATA][Y][X]={{"OOO",
"OO",
"OO",
"OO",
"OO",
"OO",
"OOO"},
{"O",
"OO",
"OO",
"O",
"O",
"O",
"O"},
{"OOO",
"OO",
"O",
"O",
"O",
"O",
"OOOOO"},
{"OOO",
"OO",
"O",
"OOO",
"O",
"OO",
"OOO"},
{"O",
"OO",
"OO",
"OO",
"OOOOO",
"O",
"O"},
{"OOOOO",
"O",
"O",
"OOOO",
"O",
"OO",
"OOO"},
{"OOO",
"OO",
"O",
"OOOO",
"OO",
"OO",
"OOO"},
{"OOOOO",
"O",
"O",
"O",
"O",
"O",
"O"},
{"OOO",
"OO",
"OO",
"OOO",
"OO",
"OO",
"OOO"},
{"OOO",
"OO",
"OO",
"OOOO",
"O",
"OO",
"OOO"}};
/******************************************************************************
测试样本
******************************************************************************/
CHARtestPattern[NUM_DATA][Y][X]={{"OO",
"OO",
"O",
"OO",
"",
"OO",
"OOO"},
{"OO",
"OO",
"O",
"",
"O",
"O",
"O"},
{"OOO",
"OO",
"OO",
"",
"O",
"O",
"OOOOO"},
{"OOO",
"OO",
"O",
"OOO",
"O",
"O",
"OOO"},
{"O",
"OO",
"OO",
"OO",
"OO",
"O",
"O"},
{"OOOOO",
"O",
"O",
"O",
"O",
"OO",
"OOO"},
{"OOO",
"O",
"O",
"OOOO",
"OO",
"O",
"OO"},
{"OOO",
"O",
"O",
"O",
"O",
"O",
"O"},
{"OOO",
"O",
"OO",
"OOO",
"OO",
"O",
"OOO"},
{"OO",
"O",
"OO",
"OOO",
"",
"O",
"OOO"}};
/******************************************************************************
//导师信号,按从上到下的顺序分别表示0~9
******************************************************************************/
REALTarget[NUM_DATA][M]=
{{HI,LO,LO,LO,LO,LO,LO,LO,LO,LO},
{LO,HI,LO,LO,LO,LO,LO,LO,LO,LO},
{LO,LO,HI,LO,LO,LO,LO,LO,LO,LO},
{LO,LO,LO,HI,LO,LO,LO,LO,LO,LO},
{LO,LO,LO,LO,HI,LO,LO,LO,LO,LO},
{LO,LO,LO,LO,LO,HI,LO,LO,LO,LO},
{LO,LO,LO,LO,LO,LO,HI,LO,LO,LO},
{LO,LO,LO,LO,LO,LO,LO,HI,LO,LO},
{LO,LO,LO,LO,LO,LO,LO,LO,HI,LO},
{LO,LO,LO,LO,LO,LO,LO,LO,LO,HI}};
/******************************************************************************
主程序
******************************************************************************/
voidmain()
{
INTm,n,count;//循环变量
NETNet;//网络变量声明
BOOLStop;//学习是否结束的控制变量
REALError;//记录当前所有样本的最大误差
InitializeRandoms();//生成随机数
GenerateNetwork(&Net);//创建网络并初始化网络,分配空间
RandomWeights(&Net);//初始化网络联接权
InitializeApplication(&Net);//初始化输入层,将学习样本转换成输入模式
count=0;//显示学习进度的控制变量
do{
Error=0;//误差
Stop=TRUE;//初始化
for(n=0;nSimulateNet(&Net,Input[n],Target[n],FALSE,FALSE);//计算模拟神经网络误差
Error=MAX(Error,Net.Error);//巧妙的做法,获取结构的值,获取误差最大值
Stop=StopAND(Net.Errorcount++;
}
Error=MAX(Error,Net.Epsilon);//作用:
防止溢出,保证到100%的时候停止训练,获取误差最大值
if(count%300==0){
printf("Training%0.0f%%completed\n",(Net.Epsilon/Error)*100);
}//只能做一个参考,并非单调上升的值
if(NOTStop){
for(m=0;m<10*NUM_DATA;m++){//对各模式进行训练
n=RandomEqualINT(0,NUM_DATA-1);//随机选择训练模式
SimulateNet(&Net,Input[n],Target[n],TRUE,FALSE);
}
}
}while(NOTStop);
printf("BP神经网络学习结束!
\n请按一键继续工作:
读入测试数据进行识别!
\n");
getch();
SaveWeights(&Net);//学习结束后保存宝贵的联接权
//网络开始工作
Initializetest();//初始化测试样本,将其转化成输入模式
for(n=0;nSimulateNet(&Net,Inputtest[n],Target[n],FALSE,TRUE);
}
FinalizeApplication(&Net);//关闭文件
printf("BP神经网络完成了识别任务!
\n请在result.txt文件中检查识别结果。
\n");
printf("请按任意键以结束程序!
\n");
//getch();
getch();
}
/******************************************************************************
产生随机数
******************************************************************************/
//设置伪随机数种子
voidInitializeRandoms()
{
srand(4711);
}
//产生一个LOW-TOP之间的伪随机整数
INTRandomEqualINT(INTLow,INTHigh)
{
returnrand()%(High-Low+1)+Low;
}
//产生一个LOW-TOP之间的伪随机浮点数
REALRandomEqualREAL(REALLow,REALHigh)
{
return((REAL)rand()/RAND_MAX)*(High-Low)+Low;
}
/******************************************************************************
//关闭文件
******************************************************************************/
voidFinalizeApplication(NET*Net)
{
fclose(f);
}
/******************************************************************************
//随机生成联接权
******************************************************************************/
voidRandomWeights(NET*Net)
{
INTl,i,j;
for(l=1;lfor(i=1;i<=Net->Layer[l]->Units;i++){
for(j=0;j<=Net->Layer[l-1]->Units;j++){
Net->Layer[l]->Weight[i][j]=RandomEqualREAL(-0.5,0.5);//随机值
}
}
}
}
/******************************************************************************
//保存连接权,防止丢失宝贵的联接权
******************************************************************************/
voidSaveWeights(NET*Net)
{
INTl,i,j;
for(l=1;lfor(i=1;i<=Net->Layer[l]->Units;i++){
for(j=0;j<=Net->Layer[l-1]->Units;j++){
Net->Layer[l]->WeightSave[i][j]=Net->Layer[l]->Weight[i][j];
}
}
}
}
/******************************************************************************
//恢复连接权,以便需要的时候可以重新调用,重组网络
******************************************************************************/
voidRestoreWeights(NET*Net)
{
INTl,i,j;
for(l=1;lfor(i=1;i<=Net->Layer[l]->Units;i++){
for(j=0;j<=Net->Layer[l-1]->Units;j++){
Net->Layer[l]->Weight[i][j]=Net->Layer[l]->WeightSave[i][j];
}
}
}
}
/******************************************************************************
//创建网络,为网络分配空间
******************************************************************************/
voidGenerateNetwork(NET*Net)
{
INTl,i;
Net->Layer=(LAYER**)calloc(NUM_LAYERS,sizeof(LAYER*));
for(l=0;lNet->Layer[l]=(LAYER*)malloc(sizeof(LAYER));
Net->Layer[l]->Units=Units[l];
Net->Layer[l]->Output=(REAL*)calloc(Units[l]+1,sizeof(REAL));
Net->Layer[l]->Activation=(REAL*)calloc(Units[l]+1,sizeof(REAL));
Net->Layer[l]->Error=(REAL*)calloc(Units[l]+1,sizeof(REAL));
Net->Layer[l]->Weight=(REAL**)calloc(Units[l]+1,size