ニューラルネットワーク (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
*/