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

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

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

null値の参照型変数を参照しようとした場合に投げられる、Javaにおける例外のひとつです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

1回答

1387閲覧

javaでの多数パーセプトロン

riririra

総合スコア12

NullPointerException

null値の参照型変数を参照しようとした場合に投げられる、Javaにおける例外のひとつです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2018/05/24 03:33

###質問内容
javaでのニューラルネットワーク、多数パーセプトロンを実装しようとしていますがlearnメソッド内の出力計算でNullPointerExceptionを吐いてしまいます、一体何が間違っているのでしょうか
入力と中間層の数が一致していれば問題なく作動します

public void learn( double[][] x , double[] answer ) { // 変数初期化 double[] in = null; // i回目の試行で利用する教師入力データ double ans = 0; // i回目の試行で利用する教師出力データ double[] h = new double[ middleNumber ]; // 中間層の出力 double[] o = new double[ outputNumber ]; // 出力層の出力 int i = 0; double[][] seikai = new double [MAX_TRIAL][1]; double seigo = 0; // 学習 int succeed = 0; // 連続正解回数を初期化 for( i=0 ; i<MAX_TRIAL ; i++ ) { // 行間を空ける if(i % 1000 == 0){ System.out.println(); System.out.println( String.format( "Trial:%d" , i ) ); } // 使用する教師データを選択 in = x[ i % answer.length ]; ans = answer[ i % answer.length ]; // 出力値を推定:中間層の出力計算 for( int j=0 ; j<middleNumber ; j++ ) { h[j] = middleNeurons[j].output( in ); } // 出力値を推定:出力層の出力計算 for( int j=0 ; j<outputNumber ; j++ ) { //ここでNullPointerException o[j] = outputNeurons[j].output( h ); } if(i % 1000 == 0){ System.out.println( String.format( "[input] %f , %f , %f" , in[0] , in[1] , in[2] ) ); System.out.println( String.format( "[answer] %f" , ans ) ); System.out.println( String.format( "[output] %f" , o[0] ) ); System.out.println( String.format( "[middle] %f , %f" , h[0] , h[1] ) ); System.out.println(Math.abs(ans - o[0])); } if(Math.abs(ans - o[0]) < 0.01470588235){ seikai[i][0] = 1; } // 評価・判定 boolean successFlg = true; for( int j=0 ; j<outputNumber ; j++ ) { // 出力層ニューロンの学習定数δを計算 double delta = ( ans - o[j] ) * o[j] * ( 1.0d - o[j] ); // 教師データとの誤差が十分小さい場合は次の処理へ // そうでなければ正解フラグを初期化 if( Math.abs( ans - o[j] ) < MAX_GAP ){ continue; } else{ successFlg = false; } // 学習 //if(i % 1000 == 0){ //System.out.println( "[learn] before o :" + outputNeurons[j] ); //} outputNeurons[j].learn( delta , h ); //if(i % 10000 == 0){ //System.out.println( "[learn] after o :" + outputNeurons[j] ); //} } // 連続成功回数による終了判定 if( successFlg ) { // 連続成功回数をインクリメントして、 // 終了条件を満たすか確認 succeed++; if( succeed >= x.length ){ break; }else{ continue; } }else{ succeed = 0; } // 中間層の更新 for( int j=0 ; j<middleNumber ; j++ ) { // 中間層ニューロンの学習定数δを計算 double sumDelta = 0; for( int k=0 ; k<outputNumber ; k++ ) { Neuron n = outputNeurons[k]; sumDelta += n.getInputWeightIndexOf(j) * n.getDelta(); } double delta = h[j] * ( 1.0d - h[j] ) * sumDelta; // 学習 //if(i % 1000 == 0){ //System.out.println( "[learn] before m :" + middleNeurons[j] ); //} middleNeurons[j].learn( delta , in ); //if(i % 1000 == 0){ //System.out.println( "[learn] after m :" + middleNeurons[j] ); //} } // 再度出力 // 出力値を推定:中間層の出力計算 for( int j=0 ; j<middleNumber ; j++ ) { h[j] = middleNeurons[j].output( in ); } // 出力値を推定:出力層の出力計算 for( int j=0 ; j<outputNumber ; j++ ) { o[j] = outputNeurons[j].output( h ); } if(i % 1000 == 0){ System.out.println( String.format( "[input] %f , %f" , in[0] , in[1] ) ); System.out.println( String.format( "[output] %f" , o[0] ) ); System.out.println( String.format( "[middle] %f , %f" , h[0] , h[1] ) ); } } // すべての教師データで正解を出すか // 収束限度回数を超えた場合に終了 System.out.println( "[finish] " + this ); System.out.println( String.format( "Trial:%d" , i ) ); //正誤判定 for(int j = 500; j >= 1; j--){ System.out.println(seikai[i-1][0]); seigo += seikai[i-1][0]; i--; } System.out.println( String.format("正解回数は %f" , seigo )); } @Override public String toString() { // 戻り値変数 String str = ""; // 中間層ニューロン出力 str += " middle neurons ( "; for( Neuron n : middleNeurons ){ str += n; } str += ") "; // 出力層ニューロン出力 str += " output neurons ( "; for( Neuron n : outputNeurons ){ str += n; } str += ") "; return str; } /** * 多層パーセプトロン内部で利用するニューロン * @author karura */ class Neuron { // 内部変数 protected int inputNeuronNum = 0; // 入力の数 protected double[] inputWeights = null; // 入力ごとの結合加重 protected double delta = 0; // 学習定数δ protected double threshold = 0; // 閾値θ protected double eater = 1.0d; // 学習係数η /** * 初期化 * @param inputNeuronNum 入力ニューロン数 */ public Neuron( int inputNeuronNum ) { // 変数初期化 Random r = new Random(); this.inputNeuronNum = inputNeuronNum; this.inputWeights = new double[ inputNeuronNum ]; this.threshold = r.nextDouble(); // 閾値をランダムに生成 // 結合加重を乱数で初期化 for( int i=0 ; i<inputWeights.length ; i++ ) { this.inputWeights[i] = r.nextDouble();} } /** * 学習(バックプロパゲーション学習) * @param inputValues 入力データ * @param delta δ */ public void learn( double delta , double[] inputValues ) { // 内部変数の更新 this.delta = delta; // 結合加重の更新 for( int i=0 ; i<inputWeights.length ; i++ ) { // バックプロパゲーション学習 inputWeights[i] += eater * delta * inputValues[i]; } // 閾値の更新 threshold -= eater * delta; } /** * 計算 * @param inputValues 入力ニューロンからの入力値 * @return 推定値 */ public double output( double[] inputValues ) { // 入力値の総和を計算 double sum = -threshold; //System.out.println(inputNeuronNum); for( int i=0 ; i<inputNeuronNum ; i++ ){ sum += inputValues[i] * inputWeights[i]; } // 活性化関数を適用して、出力値を計算 double out = activation( sum ); return out; } /** * 活性化関数(シグモイド関数) * @param x * @return */ protected double activation( double x ) { return 1 / ( 1 + Math.pow( Math.E , -x ) ); } /** * * 入力iに対する結合加重を取得 * @param i * @return */ public double getInputWeightIndexOf( int i ) { if( i>=inputNumber ){ new RuntimeException("outbound of index"); } return inputWeights[i]; } /** * 学習定数δの取得 * @return 学習定数δ */ public double getDelta() { return delta; } /** * クラス内部確認用の文字列出力 */ @Override public String toString() { // 出力文字列の作成 String output = "weight : "; for( int i=0 ; i<inputNeuronNum ; i++ ){ output += inputWeights[i] + " , "; } return output; } } }

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

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

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

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

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

guest

回答1

0

エラーメッセージがないのと、クラスの定義がないのとで答えづらいですが……

java

1o[j] = outputNeurons[j].output( h );

ここで例外が発生するとのことですので、outputNeuronsoutputNeurons[j]null になっているんじゃないでしょうか。
その場合、初期化で何かミスしているのだと思います。
outputNeurons はクラスのメンバですよね? ローカル変数を定義し忘れているとかでなく。

あと、これは質問とは無関係ですが、outputNumberoutputNeurons.Length と別で管理しているのはなぜでしょうか?

投稿2018/05/24 12:21

pute

総合スコア134

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問