質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Q&A

解決済

3回答

1000閲覧

NNによるsin波の学習について, nanの発生原因

RyosuK.S

総合スコア45

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

0グッド

0クリップ

投稿2020/05/25 20:11

編集2020/05/26 11:34

前提・実現したいこと

c言語でNNによるsin波の学習を行うプログラムを書いています。

発生している問題・エラーメッセージ

出力信号が全てnanとなってしまったり,すべて1になってしまうなど期待の動作をしない

該当のソースコード

C言語

#include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #define ITERATIONS (100000)//繰り返し回数 //重みの初期値設定(乱数) double default_value(){//重みを−1~1で初期設定 return (rand() / (double)RAND_MAX)*2-1; } int main() { srand((unsigned) time(NULL)); double num = -M_PI; FILE*fp; fp = fopen("data.txt","w"); //教師データ double x[50]; double y[50]; int count = 0; //入力信号,教師データ生成 for(;num <= M_PI;num = num + (double)(2*M_PI/49)){ x[count] = num; y[count] = sin(num); count++; } //バイアス・重みの初期値設定 double bias[9] = {0,0,0,0,0,0,0,0,0}; double w1[9]; //入力層→隠れ層の重み double w2[10];//隠れ層→出力層の重み(w_2[0]はバイアス) for(count = 0;count<=9;count++){ if(count == 9){//訂正 w2[count] = default_value(); } else{ w1[count] = default_value(); w2[count] = default_value(); } } w2[0] = 0;//バイアスの初期値は0に設定 double p = 0.01;//学習率 double net2[9];//隠れ層への入力 double out2[10];//出力層への出力 out2[0] = 1/(1 + exp(-1)); double net3 = 0;//出力層への入力 double out3[50];//出力信号 double E = 0;//二乗誤差 double delta3; //double delta2; //double del_E;//∂E/∂w(or ∂E/∂bias) int i = 0; for(count = 0;count<50;count++){//サンプルされた50点のに対するそ処理 for(int count2 = 0;count2<=9;count2++){//重みの初期値設定 if(count2 == 9){//訂正 w2[count2] = default_value(); } else{ w1[count2] = default_value(); w2[count2] = default_value(); } } w2[0] = 0;//バイアスの初期値は0に設定 for(int learing_count=0;learing_count < ITERATIONS+1;learing_count++){//学習回数10万回についての処理,*「ITERATIONS+1」にした理由→10万回学習させた後に最終的な出力を出すため for(i = 0;i < 9;i++){ net2[i] = w1[i]*x[count] + bias[i]; out2[i+1] = 1/(1 + exp(-net2[i])); } for(i=0;i < 10;i++){ net3 += w2[i]*out2[i]; } out3[count] = 1/(1 + exp(-net3)); //二乗誤差 E = 0.50*(y[count] - out3[count])*(y[count] - out3[count]); if(E == 0.0){ //printf("%d %lf\n",count,out3[count]); break; } else{ //NR } //重み更新(出力~隠れ層間) delta3 = (out3[count] - y[count])*out3[count]*(1-out3[count]);//(out3[count] - y[count])*exp(-net3)/((1+exp(-net3))*(1+exp(-net3))); for(i = 0;i < 10;i++){//w_2の各重み更新 w2[i] = w2[i] - p*delta3*out2[i]; } for(i = 0;i < 9;i++){ bias[i] = bias[i] - p*delta3 * w2[i+1]*out2[i+1]*(1-out2[i+1]);//bias[i] -= p*delta3 * w2[i+1]*exp(-net2[i])/((1+exp(-net2[i]))*(1+exp(-net2[i]))); w1[i] = w1[i] - p*x[count]*delta3 * w2[i+1]*out2[i+1]*(1-out2[i+1]);//w1[i] -= p*x[count]*delta3 * w2[i+1]*exp(-net2[i])/((1+exp(-net2[i]))*(1+exp(-net2[i]))); } if(learing_count < 100){ printf("%lf %lf %lf %lf %lf %lf %lfだよ\n",E,delta3*out2[3],w1[3],w2[3],net2[3],out2[3],out3[count]); } } } for(count = 0;count<50;count++){ fprintf(fp,"%lf\t%lf\t%lf\n",x[count],y[count],out3[count]); } fclose(fp); return 0; }

###一言
自分のできる範囲で参考書を調べ、導出式などを確認してみたのですが、改善されませんでした。どうか相談に乗っていただけると助かります。
計算過程で二乗誤差が小さくならないなど計算過程に問題があるようなのですが・・

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2020/05/25 21:34

具体的に、どういう出力になるんでしょうか
RyosuK.S

2020/05/25 23:41

out3[ ]が教師データy[ ]のデータと近づくような形で学習させています。 なので、data.txtの1行目をx軸にとった時に3行目のデータがsinxに近い形になって欲しいという感じです。
RyosuK.S

2020/05/26 09:25

他の方にご指摘いただいた箇所を修正しました。 ただ、計算結果は変わらず、、という感じなので気がついた部分があれば教えていただけると助かります。
guest

回答3

0

パッと見でおかしい所

  • w1[0]w1[8]までしか存在していないのに、w1[9]に書き込もうとしています。
  • count10にはなりません。なったとしてもw2[10]は範囲外です。

if (count == 9)の誤りでは?

C

1 double w1[9]; //入力層→隠れ層の重み 2 double w2[10];//隠れ層→出力層の重み(w_2[0]はバイアス) 3 for (count = 0; count <= 9; count++) { 4 if (count == 10) { 5 w2[count] = default_value(); 6 } 7 else { 8 w1[count] = default_value(); 9 w2[count] = default_value(); 10 } 11 }
  • out2[0]out2[9]までしか存在していないのに、out2[10]out2[49]を読み取ろうとしています。

out2[count]out2[i]の誤り?

C

1 double out2[10];//出力層への出力 2() 3 for (count = 0; count < 50; count++) {//サンプルされた50点のに対するそ処理コード 4() 5 for (i = 0; i < 9; i++) { 6 bias[i] = bias[i] - p * delta3 * w2[i + 1] * out2[count] * (1 - out2[count]);//bias[i] - p*delta3 * w2[i+1]*exp(-net2[i])/((1+exp(-net2[i]))*(1+exp(-net2[i]))); 7 w1[i] = w1[i] - p * x[count] * delta3 * w2[i + 1] * out2[count] * (1 - out2[count]);//w1[i] - p*x[count]*delta3 * w2[i+1]*exp(-net2[i])/((1+exp(-net2[i]))*(1+exp(-net2[i]))); 8 }
  • fclose(fp)でファイルを閉じていません。

一応プログラム終了で閉じられますが…

投稿2020/05/26 00:52

編集2020/05/26 01:27
SHOMI

総合スコア4079

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

RyosuK.S

2020/05/26 01:42

ご指摘ありがとうございます。SHOMIさんのご指摘の通り、それぞれの箇所にミスがありました。 ただ、修正後も結果が変わらなかったので、根本の原因は別にあるようでした。 out3を計算する過程で何処かがおかしいんだろうと予測していますが、何か思いつくことがあれば、またご指摘ください。
guest

0

自己解決

net3をループの終了時に初期化する必要がありました。

投稿2020/06/03 11:54

RyosuK.S

総合スコア45

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ループの中で、net3を、一旦初期化する必要がありました。

投稿2020/05/27 09:05

RyosuK.S

総合スコア45

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問