0

私は MATLAB の初心者です。C のオンライン逆伝播 (BP) コードを検証したいと考えています。コードが同じネットワーク設定でまったく同じかどうかをテストする必要があります。ネットワーク設定はオリジナルBP(XOR問題用)2入力、2隠しノード、1出力です。使用される学習率設定は 0.01、モメンタム 0.95 で、停止基準は 0.01、パフォーマンス メジャーは sse です。エポックは1です(ネットワーク設定がCとまったく同じであることを確認するために、順方向伝播から逆方向伝播までの正確な計算を確認したいため)ここに私のコードがあります:

   clear all;clc
   input =  [0 0; 0 1; 1 0; 1 1]';
   target = [0 1 1 0];   % p = [-1 -1 2 2; 0 5 0 5]; % t = [-1 -1 1 1];
   state0 =  1367;
   rand('state',state0)
   net = newff(input,target,2,{},'traingd');
   net.divideFcn = '';

   %set max epoh, goal, learning rate, show stp
   net.trainParam.epochs        =1;
   net.trainParam.goal        = 0.01;
   net.performFcn ='sse';
   net.trainParam.lr          = 0.01;
   net.adaptFcn=' ';

   net.trainParam.show        = 100;
   net.trainparam.mc          = 0.95;
   net.layers{1}.transferFcn = 'logsig';
   net.layers{2}.transferFcn = 'logsig';

   wih     = net.IW{1,1};
   wihb= net.b{1,1};
   who   = net.LW{2,1};
   whob = net.b{2,1};

   %Train
   net = train(net,input,target); %adapt
   y= sim(net,input);
   e=target-y;
   perf = sse(e)

実行後、y(1)が0.818483286935909であることがわかりました.0.609299823823181である手動カウントとは異なります(計算で再確認==>

for i=1:size(input,2)
hidden(1) = logsig( wih (1)*input(1) + wih(2)*input(2) + wihb(1) );
hidden(2) = logsig( wih (3)*input(1) + wih(4)*input(2) + wihb(2) );
out(i) = logsig( hidden(1)*who(1) + hidden(2)*who(2) + whob(1) );end  )

私の質問は: 1) 元の MATLAB は traingd を使用していますか? 2) 本当に net = train(net,input,target); とは何ですか? y= シム (ネット、入力); 手動計算では、train と sim を使用して 0.818483286935909 ではなく 0.609299823823181 が得られました。

3) 上記の matlab コードと比較して、C での私の粗雑な順伝播との違いは何ですか?

助けてください。

4

2 に答える 2

0

1)Matlabsの「train」コマンドは、オンラインではなくバッチ学習を使用していると思います。おそらく、オンライントレーニングのためにMatlabの「適応」機能を調べる必要がありますが、それが良いかどうかはわかりません。train() と traingd() が実際に同じメソッドであるかどうかを尋ねていますか、それとも train も勾配降下法を使用しているかどうかを尋ねていますか?

2) Matlab のヘルプには、「通常、トレーニングの 1 つのエポックは、ネットワークへのすべての入力ベクトルの単一のプレゼンテーションとして定義されます。ネットワークは、これらすべてのプレゼンテーションの結果に従って更新されます。」

これは、train がネットワークを 1 回逆伝播して「トレーニング」し、このトレーニング済みネットワークに基づいて回答をシミュレートすることを意味すると思います。

3) ここにリストされている C コードは、プログラム内のすべてのコードですか? もしそうなら、違いはMatlabが重みを一度更新してからフィードフォワードするのに対し、あなたのCコードはフィードフォワードだけのように見えるということだと思います?? または、私は何かを逃しましたか/あなたは何かを忘れましたか?

私はあなたのすべての質問を正しく理解したと思っています.時々少し不明確でした.

于 2011-11-14T12:51:10.427 に答える
0

Niclas に感謝します。adapt 関数を見てきました。newff 関数は異なる重みを初期化すると思います (newff init と reinit アクティベーション関数の間)

2)バッチトレーニングを使用したtraingdも信じています。しかし、出力を確認したとき:

 for i=1:size(input,2)
     hidden(1) = logsig( wih (1)*input(1) + wih(2)*input(2) + wihb(1) );
     hidden(2) = logsig( wih (3)*input(1) + wih(4)*input(2) + wihb(2) );
     out(i) = logsig( hidden(1)*who(1) + hidden(2)*who(2) + whob(1) );
 end  

3) C コードは次のとおりです。

void forwardPropagate(double *Input)
{  
  int i,j,k;
  double sumIH=0.0,sumHO=0.0;

for(j=0; j< numHid; j++)
{ 
    for(i=0; i<numInput; i++) //numInput+1
    {     //   
        sumIH+=Input[i] * wtIH[j][i]; 
    }
    sumIH+=(1.0 * wtIH[j][numInput]); 
    Hidden[j]=sigmoid(sumIH);          
}     


    for(k = 0 ; k< numOutput ; k++ ) 
{ 
    for(j =0 ; j <numHid ; j++ ) //numHid+1
    { 
        sumHO+=Hidden[j] * wtHO[k][j];          
    }
    sumHO+=(1.0 * wtHO[k][numHid]);   
    Output[k]=sigmoid(sumHO);
}
}


void backPropagate (double *target)
{  
  int j,k;  
  double sumOutErr, desired[numOutput];

  for(k = 0 ; k<numOutput ; k++ ) 
  {   
     desired[k]=target[k];
         error[k]=desired[k]-Output[k];      
  deltaOutput[k]=beta *(Output[k] * (1 - Output[k]))*(error[k]);
   }

 for( j =0 ; j <numHid; j++ ) 
 {    
  sumOutErr= 0.0 ;     
  for( k = 0 ; k < numOutput ; k++ )    
  {
      sumOutErr+= wtHO[k][j] * deltaOutput[k] ;         
  } 
  deltaHidden[j] = beta* sumOutErr * Hidden[j] * (1.0 - Hidden[j]); 
   }
 }     


 void weight_changes(double *test_pat){

int h,i,j,k;

for( k = 0 ; k < numOutput ; k ++ ) {    // update weights WeightHO           

    for( j = 0 ; j < numHid ; j++ ) { //asal numHid+1;    


        delta_wtHO[k][j]= alpha * Hidden[j]*deltaOutput[k] +   
                        M*delta_wtHO[k][j];
        wtHO[k][j] += delta_wtHO[k][j];

    }//bias
    delta_wtHO[k][numHid]= alpha * 1.0 *deltaOutput[k] + M*delta_wtHO[k]'
            [numHid];   
    wtHO[k][numHid] += delta_wtHO[k][numHid];
}

for( h = 0 ; h < numHid ; h++ ) {     // update weights WeightIH                
    for( i = 0 ; i < numInput ; i++ ) { //asal numInput+1

        delta_wtIH[h][i] =alpha * test_pat[i] *              
                        deltaHidden[h]+M*delta_wtIH[h][i]; 
        wtIH[h][i] += delta_wtIH[h][i] ;

    }   //bias
    delta_wtIH[h][numInput] =alpha * 1.0 * deltaHidden[h]+M*delta_wtIH[h]
                  [numInput];   
    wtIH[h][numInput] += delta_wtIH[h][numInput] ;
 }
    }

ありがとう。

于 2011-12-06T08:17:10.143 に答える