?? main.cpp
字號:
******************************************************************************/
void InitializeApplication(NET* Net)
{
INT n, i,j;
for (n=0; n<NUM_DATA; n++) {
for (i=0; i<Y; i++) {
for (j=0; j<X; j++) {
if ( Pattern[n][i][j] == 'O' )
Input[n][i*X+j] = HI ;
else Input[n][i*X+j] =LO ;
//NUM_DATA輸入模式,輸入層X*Y個神經(jīng)元
}
}
}
f = fopen("result.txt", "w");
}
/******************************************************************************
訓(xùn)練網(wǎng)絡(luò)
//將每個樣本投入網(wǎng)絡(luò)運作,Input是轉(zhuǎn)換后的輸入模式,Target為導(dǎo)師信號,通過布爾型
//的Training和Ptotocoling值控制是否訓(xùn)練和打印輸入/輸出模式
******************************************************************************/
void SimulateNet(NET* Net, REAL* Input, REAL* Target, BOOL Training,BOOL Protocoling)
{
REAL Output[M]; //用來記錄輸出層輸出
SetInput(Net, Input,Protocoling);//設(shè)置輸入層,獲得輸入層的輸出
PropagateNet(Net);//計算網(wǎng)絡(luò)各層的輸出
GetOutput(Net, Output,Protocoling);//獲得輸出層的輸出
ComputeOutputError(Net, Target);//計算輸出層誤差
if (Training) {
BackpropagateNet(Net);//誤差反向傳播
AdjustWeights(Net);//調(diào)整聯(lián)接權(quán)
}
}
/******************************************************************************
獲得輸入層的輸出
******************************************************************************/
void SetInput(NET* Net, REAL* Input,BOOL Protocoling)
{
INT i;
for (i=1; i<=Net->InputLayer->Units; i++) {
Net->InputLayer->Output[i] = Input[i-1]; //輸入層輸入
}
if (Protocoling) {
WriteInput(Net, Input);//根據(jù)Protocoling值輸出輸入模式
}
}
/******************************************************************************
//計算當(dāng)前層的網(wǎng)絡(luò)輸出,upper 為當(dāng)前層,LOWER為前一層
******************************************************************************/
void PropagateLayer(NET* Net, LAYER* Lower, LAYER* Upper)
{
INT i,j;
REAL Sum;
for (i=1; i<=Upper->Units; i++) {
Sum = 0;
for (j=0; j<=Lower->Units; j++) {
Sum += Upper->Weight[i][j] * Lower->Output[j]; //計算本層的凈輸入
}
Upper->Activation[i] = Sum;//保留激活值
//計算本層的輸出,激活函數(shù)必須是S形函數(shù),這樣才可導(dǎo),這是BP網(wǎng)絡(luò)的理論前提
Upper->Output[i]=1/(1+exp(-Sum));
}
}
/******************************************************************************
//計算整個網(wǎng)絡(luò)各層的輸出
******************************************************************************/
void PropagateNet(NET* Net)
{
INT l;
for (l=0; l<NUM_LAYERS-1; l++) {
PropagateLayer(Net, Net->Layer[l], Net->Layer[l+1]);
}
}
/******************************************************************************
//獲得輸出層的輸出
******************************************************************************/
void GetOutput(NET* Net, REAL* Output,BOOL Protocoling)
{
INT i;
for (i=1; i<=Net->OutputLayer->Units; i++) {
Output[i-1] = Net->OutputLayer->Output[i];//輸出層輸出
}
if (Protocoling) {
WriteOutput(Net, Output);//根據(jù)Protocoling值輸出輸出模式
}
}
/******************************************************************************
//計算輸出層誤差,* Target是導(dǎo)師信號
******************************************************************************/
void ComputeOutputError(NET* Net, REAL* Target)
{
INT i;
REAL Err,Out;
Net->Error = 0;
for (i=1; i<=Net->OutputLayer->Units; i++) {
Out = Net->OutputLayer->Output[i];//輸出層的輸出
Err = Target[i-1]-Out;//誤差計算
Net->OutputLayer->Error[i] = Out * (1-Out) * Err;
//用delta規(guī)則計算誤差,因為用了可導(dǎo)的s形函數(shù)
Net->Error += 0.5 * sqr(Err);//平方差公式
}
}
/******************************************************************************
//誤差反向傳播 Upper 為前層,Lower為后層 ,層數(shù)值大的為前層
******************************************************************************/
void BackpropagateLayer(NET* Net, LAYER* Upper, LAYER* Lower)
{
INT i,j;//循環(huán)變量
REAL Out, Err;
for (i=1; i<=Lower->Units; i++) {
Out = Lower->Output[i];//后層的輸出
Err = 0;//用來記錄隱含層輸出的誤差的估計值
for (j=1; j<=Upper->Units; j++) {
Err += Upper->Weight[j][i] * Upper->Error[j];
//誤差的反饋,通過已經(jīng)處理的前層的delta值和聯(lián)接權(quán)去估計,有理論基礎(chǔ)
}
Lower->Error[i] =Out * (1-Out) * Err; //delta規(guī)則
}
}
/******************************************************************************
//整個網(wǎng)絡(luò)誤差的后傳
******************************************************************************/
void BackpropagateNet(NET* Net)
{
INT l;//循環(huán)變量
for (l=NUM_LAYERS-1; l>1; l--) {
BackpropagateLayer(Net, Net->Layer[l], Net->Layer[l-1]);//對每層處理
}
}
/******************************************************************************
//調(diào)整網(wǎng)絡(luò)每一層的聯(lián)接權(quán)
******************************************************************************/
void AdjustWeights(NET* Net)
{
INT l,i,j;//循環(huán)變量
REAL Out, Err, dWeight;
//記錄后層的輸出、當(dāng)前層的輸出誤差、當(dāng)前神經(jīng)元聯(lián)接權(quán)上次的調(diào)整量
for (l=1; l<NUM_LAYERS; l++) {
for (i=1; i<=Net->Layer[l]->Units; i++) {
for (j=0; j<=Net->Layer[l-1]->Units; j++) {
Out = Net->Layer[l-1]->Output[j];//后層的輸出
Err = Net->Layer[l]->Error[i];//當(dāng)前層的輸出誤差
dWeight = Net->Layer[l]->dWeight[i][j];
//將本神經(jīng)元聯(lián)接權(quán)上次的調(diào)整量取出,初始值為0,初始化網(wǎng)絡(luò)時賦值的
Net->Layer[l]->Weight[i][j] += Net-> Eta * Err * Out + Net->Alpha * dWeight;
//Alpha為沖量參數(shù),加快網(wǎng)絡(luò)的收斂速度
Net->Layer[l]->dWeight[i][j] = Net->Eta * Err * Out;
//記錄本次神經(jīng)元聯(lián)接權(quán)的調(diào)整量
}
}
}
}
/******************************************************************************
//顯示輸入模式
******************************************************************************/
void WriteInput(NET* Net, REAL* Input)
{
INT i;
for (i=0; i<N; i++) {
if (i%X == 0) {
fprintf(f, "\n");
}
fprintf(f, "%c", (Input[i] == HI) ? 'O' : ' ');
}
fprintf(f, " -> ");
}
/******************************************************************************
//顯示輸出模式
******************************************************************************/
void WriteOutput(NET* Net, REAL* Output)
{
INT i;//循環(huán)變量
INT Index;//用來記錄最大輸出值的下標(biāo),也就是最后識別的結(jié)果
REAL MaxOutput;//用來記錄最大的輸出值
MaxOutput=0;//初始化
for (i=0; i<M; i++)
{
if(MaxOutput<Output[i]){
MaxOutput=MAX(MaxOutput,Output[i]);//保存最大值
Index=i;
}
}
fprintf(f, "%i\n", Index);//寫進文件
}
/******************************************************************************
初始化測試樣本
******************************************************************************/
void Initializetest()
{
INT n,i,j;//循環(huán)變量
for (n=0; n<NUM_DATA; n++) {
for (i=0; i<Y; i++) {
for (j=0; j<X; j++)
if (testPattern[n][i][j]=='O')
Inputtest[n][i*X+j] = HI;
else Inputtest[n][i*X+j] =LO; //NUM_DATA輸入模式,輸入層X*Y個神經(jīng)元
}
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -