• 締切済み

4階層型ニューラルネットワークで学習(準ニュートン法)

準ニュートン法の学習方法の中に出てくるヘッセ行列の逆行列の近似行列Hについてなんですが、よく最適化についての本に更新式が載っているのを見るのですけど、(DFP法やBFGS法)アルゴリズムの中に探索方向の計算についてあるんですが、4層のニューラルネットに準ニュートン法を導入すると、それぞれ入力層-中間層1と中間層1-中間層2と中間層2-出力層の3つの所でそれぞれ重みwや微分式∇f(w)の更新を行うと思うのですが、このときにHをそれぞれの層間で探索方向を用いて次のHを更新するみたいですが、このHはよく初期値として単位行列を設定しているようなのですが、これはそれぞれの層のユニット数を同じにする必要とかあるのでしょうか?例えば中間1-2層のユニット数は10個とか

みんなの回答

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

多層ニューラルネットなので, そのようにわけて考えるのが本来のやりかただろうと思います. まぜて (150+900+930)×(150+900+930) とすれば性能はいいと思いますが, なんか邪道っぽい気がします.

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

こっそり #2 で書いてありますが, ヘッセ行列の次数は「重みの個数」と一致します (行列 H の次数も当然に一致する). 例えば, 「ある層に 5個, 次の層に 10個のユニットがあり, すべてのユニット間に結合がある」場合を考えてみます. この場合には 2つの層の間に 50個の結合があり, そのすべての結合に対して重みがありますからヘッセ行列は 50×50 の行列となります. もちろん「あるユニットとあるユニットの間には結合がない」というようなときには (それに対応する重みも存在しないので) ヘッセ行列はもっと小さなものとなります. ということで, 教師データの個数とも無関係です.

G_MANT
質問者

お礼

<例えば, 「ある層に 5個, 次の層に 10個のユニットがあり, すべてのユニット間に結合がある」場合を考えてみます. この場合には 2つの層の間に 50個の結合があり, そのすべての結合に対して重みがありますからヘッセ行列は 50×50 の行列となります. やはりそっちでしたか。。自分がやっている実装では入力層のユニット数が5個(任意)、中間層1と2はそれぞれ30個、出力層は31個(教師データが31個のため)なので、全部の層間に139500個の重みが存在するということでヘッセ行列は139500×139500の行列になるということですね。 …これはもしかしてメモリの問題が関わってくるかもしれないですね。 Visual C++で実装を行っているのですが、素直に入力層のユニット数を2,3個にした方がいいかな。。 返信有難うございました。いろいろ試してみて頑張ってみます。

G_MANT
質問者

補足

度々すいません。。お礼に書いてあるのでは無く、入力層と中間層1の間で重み(w1)が150個なので、ヘッセ行列(H1)は150×150の行列で、中間層1-中間層2の間で重み(w2)が900個だからヘッセ行列(H2)は900×900の行列,中間層2-出力層は重み(w3)が930個より、ヘッセ行列(H3)は930×930の行列である。みたいに分けて行うのでしょうか?

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

「ヘッセ行列」は 2階偏微分をならべた行列ですから, 重み w を変数とする関数 f(w) においては行数・列数ともに「w の個数」であるような正方行列になります. H はその逆行列 (を近似した行列) ですから, 行数・列数はヘッセ行列と等しくなります. ひょっとすると (i, j) 要素を「ある層のユニットi と次の層のユニットj で決まる何か」と思ったのかもしれませんが, そうではありません. ですので, 各層のユニット数が等しい必要性はありません.

G_MANT
質問者

お礼

返信有難うございます。 >ひょっとすると (i, j) 要素を「ある層のユニットi と次の層のユニットj で決まる何か」と思ったのかもしれませんが, そうではありません. まさにその通りでした。。自分は参考にしている文献で、中間層1(L-1層目)と中間層2(L層目)での結合荷重w(k+1)[L,ユニットj:L-1,ユニットi]やHを更新する式から、他の層間でもHを独立に更新するからユニット数を同じにすると思いました。どうやらヘッセ行列の事について理解が足りないみたいです。。今、勉強しているのは一変数関数の近似を行って学習を行い、その過程でニューラルネットの誤差評価関数Errというのを最小化していくということです。教師データ:31個でErr=0.5*ΣΣ(ユニットからの出力値-教師データ)^2なのですが、出力値は重みwによって出力されるので31個の正方行列にすればよいのでしょうか? 度々すいません。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

えぇと.... どうして「それぞれの層のユニット数を同じにする必要とかあるのでしょうか」と思ったのでしょうか? それぞれの層の間で結合の重みを独立に変えるのがいいかどうかは知らないけど, 「ユニット数を等しくする」必要は全くありません. 関連して, 最後の「例えば」の文は意図がわかりません? 「それぞれの層のユニット数を同じにする」と言っているにもかかわらず「中間1-2層のユニット数 (って何だ?)」としか書いていないのは不自然です. 「それぞれ」の中には入力層や出力層も含まれると読んでしまうのが普通でしょう. ついでだけど, 老婆心ながら文をもっと短くした方がいい. 特に, 最初の「準ニュートン法の」から「あるのでしょうか」までが 1文だけど, いくらなんでも長過ぎ. もっと各文を短くして, 「それぞれの文で言いたいこと」を明確にした方がいいと思うよ.

G_MANT
質問者

お礼

間違えて補足に打ってしまいました。。

G_MANT
質問者

補足

回答ありがとうございます。文章を書くのは少々苦手でして申し訳ないです えと、Hの初期値を単位行列に設定するということなので行と列は同じ数であるから、どれかの層間でHを探索方向の計算に利用するにはユニット数を同じにする必要があると考えました。 後、例えで書いたことなんですが、ある文献で中間層1-中間層2において重みwや微分式∇f(w)やHの更新や探索方向の計算式が書いてあり、ユニット数がそれぞれ同じであったのでこうする必要があるのかなと思いました。。そのために中間層1-中間層2は更新できるが、その他の層間ではユニット数が違うのにどうするのだろ?と疑問に思ってしまいました。

関連するQ&A

  • 4階層型ニューラルネット(逆伝播法)

     現在、実験のために4階層型のニューラルネットを作成しているのですが上手く収束しません。使用は入力層、中間層2層、出力層の計4層です。  各変数はo1が入力ユニットからの出力、o2とo3は中間層ユニットの出力、o4が出力層ユニットの出力です。w43,w32,w21はそれぞれの結合強度です。biasはそのままバイアスです。変数の前にdがついてるものは変化を表したものです。etaは学習率、alphaは慣性項係数です。この値と中間層ユニット数を変更してみても収束しませんでした。  問題があるのは逆伝播法での結合強度の更新です。以下にそのルーチンを示しますのでお気づきの点がありましたらお願いします。特に問題があるのは中間層~入力層間についてだと思うのですが。。  ご意見お願いします。また、よろしければ4層以上のニューラルネットについてのサイトがあればお願いします。

  • C言語で準ニュートン法(DFP法)でヘッセ逆行列を近似する

    階層型ニューラルネットワーク(4層)で準ニュートン法を用いて関数近似を 行っているのですが、ヘッセ行列の逆行列をDFP法を用いて更新を行っています。しかしヘッセ行列の更新をどのように行えばいいのかわからず、そのためにプログラムの誤差評価関数(error)の式がうまく出力できません。なぜか-1.#ind00や1.#qNaN(?)のようなエラーが出てきてしまいます。どなたか教えていただけると助かります。

  • ニューラルネットワークについて

    最近ニューラルネットについて勉強しています。 特に準ニュートン法での学習について考えています。 ある日手に入れたデータで学習したところ、誤差があまり小さくならなかったので(何度も学習を試し、ノイズ混入も試したので、ローカルミニマムに引っかかっている感じではないと思います)、中間層のユニット数を莫大に大きくしました(最初試したときの100倍以上です)。 しかし誤差が全然変らない、という結果が出ました。 このように、自由度を上げても学習しきらないことってあるんでしょうか。もしあるのなら、その原因は何でしょうか。また、学習しない原因となっている邪魔なデータを探す方法ってあるのでしょうか(出来れば視覚的に見えると嬉しいです)。 宜しくお願い致します。

  • ニューラルネットワーク

    0~9までの7セグメントディスプレイで表す数字を識別するニューラルネットワークを作成したいのですがなかなかわからないので質問したい所存です。 7セグメントを1~7のノードに割り振り中間層に10個のノード8~17でつなぎ出力するノードを18~27として18から0~9まで出力するようにしたいのですが、やり方としてまず、 27個のノードの結合関係を隣接行列で表す。 つぎに内部状態と重みのとる値の範囲を示す。 そしてそのニューラルネットワークに入力を与え、出力を計算する手順を説明するとのことなのですが。 よろしければアドバイス等お願いいたします。

  • 階層型ニューラルネットに準ニュートン法のDFPを用いて学習するプログラムをC言語で作成する

    //出力層と中間層2の結合荷重を更新 for ( i = 0; i < NUM_hh+1; i++)   {  for ( j = 0; j < NUM_o; j++) { deltaw3[i][j][ilearn+1] = (y[j] - teach[j]) * y[j] * (1.0 - y[j]) * hh[i]; w3[i][j][ilearn+1] = w3[i][j][ilearn] -0.05 * H2[i][j][ilearn] * deltaw3[i][j][ilearn]; //中間層2と中間層1の結合荷重更新 for ( i = 0; i < NUM_hh+1; i++ )  {   net_input1[j] = 0;  for ( j = 0; j < NUM_o; j++ )   { net_input1[j] += w3[i][j][ilearn] * deltaw3[i][j][ilearn];   }     net_input1[i] = net_input1[j];  } for ( i = 0; i < NUM_h+1; i++)  {  for ( j = 0; j < NUM_hh; j++)   { deltaw2[i][j][ilearn+1] = net_input1[j] * (1.0 - hh[j]) * h[i]; w2[i][j][ilearn+1] = w2[i][j][ilearn] - (0.005 * H2[i][j][ilearn] * deltaw2[i][j][ilearn] );   }  } //中間層1と入力層の結合荷重更新 for ( i = 0; i < NUM_h; i++ )  {  net_input2[j] = 0;  for ( j = 0; j < NUM_hh; j++ )   {  net_input2[j] += w2[i][j][ilearn] * deltaw2[i][j][ilearn];   }  net_input2[i] = net_input2[j];  } for ( i = 0; i < NUM_i+1; i++)  {  for ( j = 0; j < NUM_h; j++)   { deltaw1[i][j][ilearn+1] = net_input2[j] * (1.0 - h[j]) * x[i]; w1[i][j][ilearn+1] = w1[i][j][ilearn] - (0.005 * H2[i][j][ilearn] * deltaw1[i][j][ilearn] );   }  } for ( i = 0; i < NUM_h; i++) // Hの更新 //  {   for ( j = 0; j < NUM_hh; j++)   { sigma2[i][j] = w2[i][j][ilearn+1] - w2[i][j][ilearn]; gamma2[i][j] = deltaw2[i][j][ilearn+1] - deltaw2[i][j][ilearn];   }  } for ( i = 0; i < NUM_h; i++) {  for ( j = 0; j < NUM_hh; j++)   { H2[i][j][ilearn+1] = H2[i][j][ilearn] + ((sigma2[i][j] * sigma2[j][i]) / (sigma2[j][i] * gamma2[i][j])) - ((H2[i][j][ilearn]*gamma2[i][j]*gamma2[j][i]*H2[i][j][ilearn])/(gamma2[j][i]*H2[i][j][ilearn]*gamma2[i][j]));   } } プログラムの最初に戻り学習を繰り返す。 準ニュートン法(DFP)を階層型ニューラルネットに用いて学習を行うプログラムを作成しているのですが、ヘッセ行列の逆行列を更新がうまくできず、学習ができません。どこに問題があるのかわからず困っています。。 ※各層のニューロン数は、NUM_i:5 NUM_hhとNUM_h:30 NUM_o:31 w123は結合荷重、deltaw123は勾配 gamma2は勾配の差分 sigma2は結合係数の差分 学習結果を見るために関数近似を行ってます。誤差は二乗誤差を用いているのですが、結果が学習回数2回目辺りから1.#qNaN0になり、それ以降は-1.#ind00という出力になってしまいます。

  • 準ニュートン法の直線探索と収束性

     プログラムとして直線探索を実装した準ニュートン法を作成しました。 これについて、2次関数で試行すると、ヘッセ行列の逆は理論値の[0.5 0; 0 0.5]に収束することが確認できました。  他方で、直線探索を外し、一定値の間隔で進む?ようにしますと、逆行列の理論値から外れた値に収束することが見受けられました(探索点は2次関数の最小値に収束します)。 これは、プログラムミスなのか、準ニュートン法で直線探索をしないことによる帰結なのか、どちらなのでしょうか?また、後者であれば、その理由は数学的に明らかにされているのでしょうか?

  • ニューラルネットワークの正規化されたデータを元に戻すには

    ニューラルネットワークで正規化し、パラメータを求めた後、パラメータの正規化をもとに戻したいのですが、方法が分かりません。 以下は、私がやっている途中を示します。 たとえば、データの入力が年齢と身長、出力が体重のデータがあるとします。 年齢x1  身長x2   体重y 21    160     55 24    172     63 私は、正規化するために  x1’=(x1-ave(x1))/std(x1)  x2’=(x2-ave(x2))/std(x2)  y’=(y-ave(y))/std(y) として正規化しました。aveは平均、stdは標準偏差 ニューラルネットとしては、次の式で表される三層パーセプトロンを利用しています。  f=W0+Σ{Wj*hj} Σはj=1からJまで  (中間層-出力層)  hj=sigmoid(Σ{Wjk*xk’}) Σはk=1,2  (入力層-中間層)  Error=(f-y’)*(f-y’) 入力層のバイアスはなしで、中間層のバイアスはありを考えています。 活性化関数は、中間層がシグモイド関数、出力層が線形関数です。 正規化したxとyに対して各wを求めるプログラムは作れたのですが、 ここからどうやってwの正規化を解除すればよいか分かりません。 正規化する方法は載っているサイトはいくつかあるのですが、解除する 方法が載っているのは見つかりませんでした。 回答よろしくお願いします。

  • ニューラルネットの教師あり学習について質問です。

    最近誤差逆伝搬法を用いたニューラルネットについて プログラムを組んで実装してみようと思ったのですが あまり理解できていない部分があるのでよろしくお願いします。 私が作りたいのはフォントの違う数字画像の認識を 3つの特徴量(a,b,c)、3層のニューラルネット、 閾値関数にシグモイド関数、教師有り学習で作りたいのですが、 私の理解があっているかわからないのでご指摘をお願いします。 ・入力層は特徴量が3つなのでニューロンは3つ(a,b,cを入力)。 ・中間層は任意でいいということなので10つ。 ・出力層は数字が0~9までなので10つ。 教師ベクトルの与え方なのですが 出力層(0~9番とします)において各数字に対応する番号のニューロンは1、それ以外は0、 つまり 出力層の0番の教師ベクトルは{1,0,0,0,0,0,0,0,0,0} 1番目の教師ベクトルは{0,1,0,0,0,0,0,0,0,0} 9番目の教師ベクトルは{0,0,0,0,0,0,0,0,0,1} (シグモイド関数のため正確には0、1にはなりませんが・・) とあらかじめ決めておき、 教師ベクトルの学習の際は 0の画像ならば出力層は{1,0,0,0,0,0,0,0,0,0}^T となるように誤差逆伝搬を用いて中間層・出力層の重みの修正を行い、 同様に1~9の教師画像も対応する出力の番号以外0となるように 学習を行い、 識別を行いたい画像の特徴量を入力した際は 重みの修正は行わず 10この出力の誤差が最小となる教師ベクトルが第一候補、 誤差が最大となる教師ベクトルが第10候補 ということでよろしいのでしょうか? でもそうすると重みの値が一番最後に学習した教師ベクトルに 対応する重みになっているから ニューラルネット自体を10個つ用意する必要が ありますよね・・・? いま一つ理解できていないのでよろしくお願いします。

  • 共役勾配法を用いた最適化について

    弾性体の変形を見るために,停留ポテンシャル法を用いようとしているのですが,その際に目的関数にひずみエネルギーをとり 独立な24変数の関数の極小値を共役勾配法で求めようとしています. Hesse行列を手計算でだし,最適化を行うプログラムを書いたのですが どうも上手くいきません. 下にプログラムの一部分をのせます. 共役勾配法について勘違いしている可能性もあるので 問題点を教えて頂ければ幸いです. x_vectorは24変数ベクトルで,dは探索方向,HはHesse行列です. for(i=0;i<10;i++) { lambda = (x_vector*d)/(d*H*d); x_save_vector = x_vector; x_vector=x_vector - lambda*H*d;//変数べクトル再設定 if(i==0) { // 初期値 gamma = 1; } else { gamma =x_vector*x_vector/(x_save_vector*x_save_vector); } d = x_vector + gamma*d;//探索方向再設定 }

  • ニューラルネットワークのプログラムの翻訳

    初めて質問させて頂きます。 大学の教授に、MATLABのプログラムを配られました。 そのプログラムがどういう処理を行って、何をしているのかを、何も知識のない学生に向けて発表しなければいけません。 しかし、自分もほとんど知識がなく、具体的に配られたプログラムがどういう処理を行っているのか、よくわかりません。ニューラルネットワークを使って何かをしているのはわかるのですが。 どなたかこのプログラムの意味を、何もわからない自分でもわかるように教えて頂けますでしょうか。 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%% Neural Network for Classification %%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%% clear, clf, and close %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% clear; clf; close all hidden; %%%%%%%%%%%%%% True Classfication Rule %%%%%%%%%%%%%%%%%%%%%%%%%%%% true_rule=@(x1,x2)(x1.^2+x2.^2-2); %%%%%%%%%%%%%%%%%%%%% Generate Training Data %%%%%%%%%%%%%%%%%%%%% n=50; %%%%% Number of Training samples xdata=-4*rand(2,n)+2; ydata(1,:)=0.01+0.98*(sign(true_rule(xdata(1,:),xdata(2,:)))+1)/2; %%%%%%%%%%%%%%%%%%%%% Draw Training Samples %%%%%%%%%%%%%%%%%%%% for i=1:1:n if(ydata(i)>0.5) plot(xdata(1,i),xdata(2,i),'ro'); hold on; else plot(xdata(1,i),xdata(2,i),'b*'); hold on; end end xlim([-2,2]); ylim([-2,2]); drawnow; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%% Begin Neural Network Learning %%%%%%%%%%%% neuron=@(u,ph,h)(1./(1+exp(-(u*h+ph)))); %%%%%%%%%%%%%%%%%%%%%%%% Hyperparameters %%%%%%%%%%%%% HYPERPARAMETER=0.0001; diffhyper=@(a)(HYPERPARAMETER*a); %%%%%%%%%%%%%%%%%%%%%%% Training Conditions %%%%%%%%%%%%%%%%% CYCLE=2000; %%% training cycles N=1; %%% output Units H=8; %%% hidden Units M=2; %%% input Units ETA=0.8; %%% gradient constant ALPHA=0.3; %%% accelerator EPSILON=0.01; %%% regularization %%%%%%%%%%%%%%%%%%%%%% Training Initialization %%%%%%%% u=0.1*randn(N,H); %%% weight from hidden to output w=0.1*randn(H,M); %%% weight from input to hidden ph=0.1*randn(N,1); %%% bias of output th=0.1*randn(H,1); %%% bias of hidden du=zeros(N,H); %%% gradient weight from hidden to output dw=zeros(H,M); %%% gradient weight from input to hidden dph=zeros(N,1); %%% gradient bias of output dth=zeros(H,1); %%% gradient bias of hidden %%%%%%%%%%%%%%%%%%%% Backpropagation Learning %%%%%%%%%%%% for cycle=1:1:CYCLE for i=1:1:n x=xdata(:,i); t=ydata(:,i); h=neuron(w,th,x); o=neuron(u,ph,h); %%%%%%%%%%%%%%%%%% delta calculation %%%%%%%%%%%% delta1=(o-t).*(o.*(1-o)+EPSILON); delta2=(delta1'*u)'.*(h.*(1-h)+EPSILON); %%%%%%%%%%%%%%%%%% gradient %%%%%%%%%%% du=delta1*h'+ALPHA*du; dph=delta1+ALPHA*dph; dw=delta2*x'+ALPHA*dw; dth=delta2+ALPHA*dth; %%%%%%%%%%%%%%%%%%% steepest descent %%%%%%%%%% u=u-ETA*du-diffhyper(u); ph=ph-ETA*dph; w=w-ETA*dw-diffhyper(w); th=th-ETA*dth; end end %%%%%%%%%% End Neural Network Learning %%%%%%%%%%%%%%%% %%%%%%%%%% Draw Trained Results %%%%%%%%%%%%%%%% for j=1:1:41 for k=1:1:41 xxx(1,1)=-2+(j-1)/10; xxx(2,1)=-2+(k-1)/10; testx1(j,k)=-2+(j-1)/10; testx2(j,k)=-2+(k-1)/10; h=neuron(w,th,xxx); testy(j,k)=neuron(u,ph,h); end end contour(testx1,testx2,testy,5); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    • 締切済み
    • XML