//出力層と中間層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という出力になってしまいます。
A 回答 (1件)
- 最新から表示
- 回答順に表示
No.1
- 回答日時:
Cは、ソースを部分的に明示されてもそれに精通した人でないと解答することは極めて困難です。
というか、プログラムは走らせてみないとわからないので、特にこのような専門的な内容の場合は質問自体が無謀のように思います。とりあえずいわせてもらえば「学習」がテーマということですので、学習の係数マトリックスが係数として本当に予想通り更新されているかどうか内容をチェックされることがまず初めにやるべきことではないでしょうか(あてずっぽうです)。その代わり、ここであなたに解答できないものの助言することはできます。それは「自身で何処に間違いがあるかを見つける方法」を教えてあげることです。
ここでは Linux や Mac OSX などのUNIX系OSのパソコンを使っている場合の話をします。チェックの仕方は、プログラムの頭の方からあなたが想定した数値となっているかどうかを調べる、いわゆる「人間デバッガ」のやり方です。使うのは fprintf(stderr, “○×△ ....) を使います。
たとえば↓のように、ループの中に fprintf() を組み入れて(間違えても、ループ内では複数の別の処理を入れないこと)コンパイルし、
//出力層と中間層2の結合荷重を更新
?fprintf(stderr,”\nコメント\n”); //ループ前に置き、 一行あけて見易く区切りを付ける
for ( i = 0; i < NUM_hh+1; i++) {?
for ( j = 0; j < NUM_o; j++) {
?fprintf(stderr, “teach[%d]=%f deltaw3[%d][%d][%d]....?n”, j, teach[j], i, j, ilearn+1, deltaw3[i][j][ilearn+1], ....);
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];?}}
......
exit(0); // ループ毎にひとつひとつ区切ってチェックする
プログラムの起動の際に、シェルプロンプトから
./a.out 2>>my_errfile
と打鍵して、エラー出力パスを my_errfile という名のファイルにリダイレクトして追加書き込みし、実行後、その都度ファイルをエディタなどで開いては各数値がどのように展開しているのか確認するやり方です。最初はひとつのループ毎に終わるようにして、各ループにおける諸数値がどのような状況となっているのか my_errfile を開いて確認します。なお、出力ファイル名はとりあえず my_errfile としましたが、それは自由です。
一通り最初のこの人間デバッグ作業が終われば、次は if() を使って、任意ループ回数毎に 同じように my_errfile に追加書き込みするようにします。これで、どこでどのように数値が変わったのか更にわかるでしょう。
ただし、これはひとつひとつの項目についてチェックする気の遠くなる作業です。焦らず、根気よく確認するしかありません。ちょっと大きな、あるいは難解なプログラムのデバッグはそのようなものです。プログラム作成が1日なら、間違い探しのデバックはその数倍の3日以上の労力を必要とします。頑張ってください。
回答ありがとうございます。
自分が使ってる開発環境はvisual c++ 2005/2008なのでwindowsを使ってます。LinuxやUNIXはあまり手を付けたことが無いのですいません。。
デバッグ機能は付いているのでそれを頼りにいろいろ値の変化を調べることは行っているのですが、それだけでは足りないのですね。。確かに一つ一つチェックするのは時間が掛かってしまうかもしれないですがそれが一番いいですよね。
アドバイスありがとうございました。fprintfでファイル出力なども行ったりして変化を見てみたりして、もっと頑張ってみます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
- Excel(エクセル) VBA フォルダ見える化のコードについて 2 2023/06/19 15:04
- C言語・C++・C# C++ と、 1 2022/11/07 23:45
- その他(プログラミング・Web制作) pythonで変数にオブジェクトを代入するにはどうしたらよいでしょうか 2 2023/08/20 20:36
- C言語・C++・C# C言語でif文が予想と違う動きをする件について7 4 2023/03/20 00:26
- C言語・C++・C# pythonのファイルの並びでの読み込みとリストについて 4 2022/04/13 03:52
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# C言語初心者 ポインタについて、お助けください、、 2 2023/03/15 23:50
- UNIX・Linux 次の要件を満たすにはどのように修正したらよろしいでしょうか 1 2022/11/24 20:57
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Excel VBAで年度をまたぐ期間の...
-
break文でループを一気に抜ける...
-
ループを途中で抜けたいのですが。
-
入力した数値を倍々するプログラム
-
For文の終了値を関数にしても問...
-
C言語forループが完結した場合...
-
strstr()関数の実装内容について。
-
文字列を後ろから1文字ずつ表示...
-
PIC のプログラムについて ど...
-
if文の中にfor文なのか、for文...
-
新たな疑問 for( ; ; ){
-
continueとbreakの位置
-
C言語の2進数変換プログラムの...
-
excel VBA if文について
-
for文while文の無限ループの違...
-
プログラミングC言語についての...
-
エクセルでC言語のfor文と同じ...
-
PAD図の書き方
-
繰り返し文の利点について
-
do-while文が禁止される理由
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
break文でループを一気に抜ける...
-
do-while文が禁止される理由
-
ループを途中で抜けたいのですが。
-
入力した数値を倍々するプログラム
-
入力した文字列から母音だけを...
-
if文の中にfor文なのか、for文...
-
C言語forループが完結した場合...
-
エクセルでC言語のfor文と同じ...
-
Excel VBAで年度をまたぐ期間の...
-
For文の終了値を関数にしても問...
-
エクセルVBAで Do While (1)って?
-
C言語、whileループを抜け出す...
-
Cプログラムが終了しない
-
PAD図の書き方
-
PIC のプログラムについて ど...
-
他言語で言うcontinue文
-
ループの特定入力終了
-
C言語のプログラムみてください...
-
COBOLのEVALUATE文
-
for文while文の無限ループの違...
おすすめ情報