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 = sim(网络,输入);使用 train 和 sim 手动计算得到 0.609299823823181 而不是 0.818483286935909 的地方。

3)与上面的matlab代码相比,我在C中的粗略前向传播有什么不同?

拜托,请帮助我。

4

2 回答 2

0

谢谢 Niclas,我见过适应函数,我猜 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 回答
0

1)我相信Matlabs“训练”命令使用批量学习,而不是在线。也许您应该研究一下 Matlab 中的“适应”功能进行在线培训,但不知道它是否有什么好处。您是在问 train() 和 traingd() 是否实际上是相同的方法,还是在问 train 是否也使用梯度下降?

2)Matlab 帮助说“通常一个时期的训练被定义为对网络的所有输入向量的单一表示。然后根据所有这些表示的结果更新网络。”

我想这意味着 train 将反向传播并“训练”一次网络,然后你根据这个训练有素的网络模拟一个答案。

3)这里列出的C代码是你程序中的所有代码吗?如果是这样,我想不同之处在于 Matlab 更新权重一次然后前馈,而您的 C 代码似乎只前馈?或者我错过了什么/你遗漏了什么?

希望我已经正确理解了您的所有问题,有时它们有点不清楚,如果我有什么问题,请发表评论..

于 2011-11-14T12:51:10.427 回答