ニューラルネットワーク

Last-modified: 2013-05-03 (金) 14:22:46

ニューラルネットワーク (ANN, Artificial Neural Network)

生物の神経回路を模した数理モデルで,さまざまなバリエーションがあるが,ここでは,もっとも代表的な
誤差伝播学習則による多層パーセプトロン型ニューラルネットワークのSASプログラムを示す.

これは,2つの機能
1.学習データからニューラルネットワークの重みを学習する
2.与えられたデータに対し学習済みニューラルネットワークの推定値を算出する
からなり,前者が%LearnNN,後者が%Estimateで呼び出される.
特徴としては,パラメータで,隠れ層の総数とユニット数を指定できること,重み計算をSAS/IMLの行列演算で
層単位に一括処理していることである.

サンプルプログラム

/*****************************************************************************************************/
/* Program : bp.sas  - BackPROP Multilayer Perceptron Learning and  Estimation Algorithms            */
/* Author : 翔 10 Jan,1997                                                                           */
/* Environment Required : SAS/IML with Base SAS v6.10 or higher                                      */
/* Module LearnNN (macro) -  Create and Learn Multilayer NN from Learning data                       */
/*        Estimate(macro) -  Estimate value with Learned NN for the data                             */
/*****************************************************************************************************/
%macro LearnNN(data   =learn,    /* Learning Dataset name                                            */
               inputs =&inputs,  /* Name list of input variables in the Learning DS(i.e. x1 x2 x3 x4)*/
               outputs=&outputs, /* Name list of output variables in the Learning DS (i.e. y1 y2)    */
               hidden =&hidden,  /* No list of nodes in hiffen layers(i.e. 3 5 4 for 3 hidden layers)*/
               NNPrfx =BPNN,     /* Name prefix for NN (BPNN:Control, BPNNn:Weight Data of Layer#n)  */
               eta    =0.5,      /* Learning Parameters eta   1<eta<1                                */
               alpha  =0.5,      /*                     alpha 0<alpha<1 moment                       */
               TMAX   =1000,     /*                     max limit of Learning times                  */
               EMIN   =0.001);   /*                     min limit of MSError                         */
/* Internal variable Table                                  */
/*        M : No of Layer                                   */
/*        Nn: No of node in Layer#n                         */
/*        Wn: Wegit Matrices of Layer#n                     */
/*        Dn: Difference Matrices,Wn(t)-Wn(t-1)             */
/*        Yn: Output Matrices of Layer#n                    */
/*        Deltan:Delta Matrices of Layer#n                  */
/*        MSE: Mean Square Error                            */
/*        t   times of Learning                             */
/*        TINT20:MSE print control value [TMAX/20]          */
/*        L : Layer no under processing (work for do-loop)  */
/*        LP: Previous Layer no LP=L-1  (work for do-loop)  */
/* set parameters */
%let M=0;
%do %until("&&N&M"="" or &M>99);
  %let M=%eval(&M+1);
  %let N&M=%qscan(&hidden,&M);
%end;
%let N0=0;
%do %until("&work"="" or &N0>99);
  %let N0=%eval(&N0+1);
  %let work=%qscan(&inputs,&N0);
%end;
%let N0=%eval(&N0-1);
%let N&M=0;
%do %until("&work"="" or &&N&M>99);
  %let N&M=%eval(&&N&M+1);
  %let work=%qscan(&outputs,&&N&M);
%end;
%let N&M=%eval(&&N&M-1);

proc iml;

/* data read */
use &data;
read all var{&outputs} into Y;Y=Y`;
read all var{&inputs}  into X;X=X`;
close &data;

/* initialize weight matrix*/
%do L=1 %to &M;
  %let LP=%eval(&L-1);
  D&L=j(&&N&L,&&N&LP+1,0);
  W&L=uniform(D&L);
%end;

/* BP Learning */
tint20=int(&TMAX/20);
t=-1;
MSE=2#&EMIN;
do until(t>&TMAX | MSE<&EMIN);
  t=t+1;

  /* forward */
  Y0=X;
  %do L=1 %to &M;
    %let LP=%eval(&L-1);
    Y&L=1/(1+exp(-W&L*(j(1,ncol(Y&LP),1)//Y&LP)));           /* Y(L)=tau( W(L)*Y(L-1)) */
  %end;

  /* BackProp */
  Delta&M=(Y&M-Y)`#Y&M`#(1-Y&M)`;                            /* Delta(M)=(Y(M)-Y)xY(M)x(1-Y(M))           */
  %do L=&M %to 1 %by -1;
    %let LP=%eval(&L-1);
    Delta&LP=(Delta&L*W&L[,2:ncol(W&L)])#Y&LP`#(1-Y&LP)`;    /* Delta(L-1)=Delta(L)*W(L)xY(L-1)x(1-Y(L-1) */
    D&L=(&Eta#(j(1,ncol(Y&LP),1)//Y&LP)*Delta&L)`+&Alpha#D&L;/* D(L)new = eta*Y(L-1)*Delta(L) + alphaxD(L)*/
    W&L=W&L-D&L;                                             /* W(L)new = W(L)-D(L)                       */
  %end;

  if t/TINT20=int(t/TINT20) then do;
    MSE1=((Y&M-Y)##2)[:,];
    MSE=MSE1[,:];
    print t mse;
  end;

end;

print MSE,MSE1, Y, Y&M;

/*print %do L=1 %to &M; W&L %end;;*/

NN={%do L=0 %to &M;&&N&L %end;};
print NN;
create &NNPrfx from NN;
append from NN;
close &NNPrfx;
%do L=1 %to &M;
create &NNPrfx&L from W&L;
append from W&L;
close &NNPrfx&L;
%end;

quit;
run;

proc print data=&NNPrfx;run;
%do L=1 %to &M;
proc print data=&NNPrfx&L;run;
%end;


%mend;



%macro Estimate(data   =learn,   /* Learning Dataset name                                            */
                inputs =&inputs, /* Name list of input variables in the Learning DS(i.e. x1 x2 x3 x4)*/
                outputs=&outputs,/* Name list of output variables in the Learning DS (i.e. y1 y2)    */
                NNPrfx =BPNN);   /* Name prefix for NN (BPNN:Control, BPNNn:Weight Data of Layer#n)  */
/* Internal variable Table                                  */
/*        M : No of Layer                                   */
/*        Nn: No of node in Layer#n                         */
/*        Wn: Wegit Matrices of Layer#n                     */
/*        Yn: Output Matrices of Layer#n                    */
/*        L : Layer no under processing (work for do-loop)  */
/*        LP: Previous Layer no LP=L-1  (work for do-loop)  */
/* set parameters */


proc iml;

/* data read */
use &data;
read all var{&inputs}  into X;X=X`;

/*weight read*/
use &NNPrfx;
read all into NN;
close &NNPrfx;
M=char(ncol(NN)-1,3,0);
call symput("MM",M);
%let M=%eval(&MM+0);      /*get M - Number of Layer*/
%do L=1 %to &M;
use &NNPrfx&L;
read all into W&L;
close &NNPrfx&L;
%end;

/* forward */
Y0=X;
%do L=1 %to &M;
  %let LP=%eval(&L-1);
  Y&L=1/(1+exp(-W&L*(j(1,ncol(Y&LP),1)//Y&LP)));           /* Y(L)=tau( W(L)*Y(L-1)) */
%end;

outputs = (Y&M)`;
print outputs;
/*print %do L=1 %to &M; W&L %end;;*/

quit;
run;

%mend;

/****************************************************************************************************/

options nocenter;

*****************************************************
学習データ
説明変数 x1,x2,x3
目的変数 y1,y2
*****************************************************;
data learn;
  input x1 x2 x3 y1 y2;
cards;
0 0 0 0 0
0 0 1 1 0
0 1 0 1 1
0 1 1 0 1
1 0 0 1 1
1 0 1 0 1
1 1 0 0 0
1 1 1 1 0
;

*****************************************************
学習ステップ
ネットワークには,
それぞれ4ユニット,3ユニットの2層の隠れ層
をもつ4層のニューロを指定
*****************************************************;

%LearnNN(data   =learn,
         inputs =x1 x2 x3,
         outputs=y1 y2,
         hidden =4 3,
         NNPrfx =BPNN,
         eta    =0.5,
         alpha  =0.5,
         TMAX   =10000,
         EMIN   =0.01  )

/*
        T       MSE

        0 0.3588053


        T       MSE

      500 0.2325856


        T       MSE

     1000 0.1248992


        T       MSE

     1500 0.0196009


        T       MSE

     2000 0.0012435


   MSE

0.0012435
                                      MSE1

0.0010441 0.0014167 0.0006432 0.0012118 0.0006417 0.0011293 0.0021652  0.001696
                                       Y

        0         1         1         0         1         0         0         1
        0         0         1         1         1         1         0         0
                                       Y3

0.0345352 0.9467825 0.9663701 0.0443397 0.9671098  0.043479 0.0656439 0.9451783
0.0299249 0.0011688 0.9875306 0.9786068 0.9857989 0.9808143 0.0046139 0.0196593


                   NN

        3         4         3         2


OBS    COL1    COL2    COL3    COL4

 1       3       4       3       2

第1隠れ層の重み
OBS      COL1        COL2        COL3        COL4

 1     -4.61235     4.57687     4.58579    -4.96288
 2     -0.20062    -0.92278     3.73186     2.04222
 3     -0.61895     3.46727    -0.59364     2.43451
 4     -0.80703     6.37931     6.75772    -2.69508

第2隠れ層の重み
OBS      COL1        COL2        COL3        COL4          COL5

 1     -1.24925     11.6274     2.31240     2.33378     -5.2051
 2     -2.64519     -2.8484    -3.96705    -4.11945     10.5124
 3     -3.18654      5.5397    -0.56350    -0.62899      0.2970

出力層の重み
OBS      COL1        COL2        COL3       COL4

 1     -6.25570     9.94095     3.8543    -8.16030
 2     -3.23399    -3.78957    12.8689     0.67708


*/

%Estimate(data   =learn,
          inputs = x1 x2 x3,
          outputs=y1 y2,
          NNPrfx =BPNN);

/*
      OUTPUTS

0.0345106 0.0299121
0.9468387 0.0011683
0.9664089 0.9875372
0.0442874 0.9786294
0.9671486 0.9858077
0.0434285  0.980834
0.0655602 0.0046126
0.9452493 0.0196399
*/