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

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

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

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

機械学習

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1131閲覧

Kerasを用いた回帰分析(3入力、1出力)で平均二乗誤差が全く減少しません。コードの改善点をアドバイスして頂きたいです。

imoimo117

総合スコア2

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

機械学習

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1グッド

0クリップ

投稿2021/08/19 03:07

前提・実現したいこと

現在、三つの入力から一つの値を出力するニューラルネットワーク(回帰問題)をKerasを用いて作成しています。

○具体的なコードの詳細
全データ数:67240(Excelデータにまとめられている)
訓練データ:53792(全データの80%)
テストデータ:13448(全データの20%)
中間層:3個 ●
中間層のニューロン数:15個 ●
出力層:1個
出力層のニューロン数:1個
中間層の活性化関数:sigmoid ●
損失関数:平均二乗誤差(mse)
評価関数:平均絶対誤差(mae)
最適化アルゴリズム:Adam ●
バッチサイズ:1024 ●
エポック数:100 ●

上記のようなネットワークを構成し、●がついている値を何度も変更(AdamをAdagradに、バッチサイズを2048に等)しているのですが、損失が全く減少しません。(1.2→0.98ほどの微小な減少のみ)

ニューラルネットワークを設計した経験がほとんどなく、また調べても回帰問題より分類問題のソースコードが非常に多く困っています。他に以下のコードを変更する余地はありますでしょうか?

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

損失関数(平均二乗誤差)が減少しない。また平均二乗誤差の評価方法がいまいち把握できていない。(どのくらいの数値まで減少すれば学習が進んでいると言えるのか)

該当のソースコード

%matplotlib inline import tensorflow as tf import openpyxl from sklearn.model_selection import train_test_split import numpy as np import matplotlib.pyplot as plt from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense from tensorflow.keras import optimizers #Excelデータを開く wb = openpyxl.load_workbook('data_for_map.xlsx') #Excelのシートを指定 sheet = wb['parasitic_dataset'] #シート内のセルを指定してリスト化 def get_value_list(s): return([[cell.value for cell in row] for row in s]) sheet_list1 = get_value_list(sheet['A2:C67241']) sheet_list2 = get_value_list(sheet['E2:E67241']) #リストから2次元配列を作成(入力[[t h f]], 出力[[L]]) input_data = np.array(sheet_list1) correct_data = np.array(sheet_list2) n_data = len(input_data) #入力データ, 出力データの標準化 def standardize(x): ave = np.average(x, axis = 0) std = np.std(x, axis = 0) return (x - ave) / std input_data_std = standardize(input_data) correct_data_std = standardize(correct_data) #訓練データを全データの80%, テストデータを全データの20%として分割 input_train, input_test, correct_train, correct_test = train_test_split(input_data_std, correct_data_std, test_size = 0.2, random_state=0) #モデルを構築 model = Sequential() model.add(Dense(15, activation = 'sigmoid', input_shape = (input_train.shape[1],))) model.add(Dense(15, activation = 'sigmoid')) model.add(Dense(15, activation = 'sigmoid')) model.add(Dense(1)) optimizer = tf.keras.optimizers.Adam() model.compile(optimizer = optimizer, loss = 'mean_squared_error', metrics = ['mae']) epoch = 100 #学習を実行 history = model.fit(input_train, correct_train, epochs = epoch, batch_size = 1024, verbose = 1, validation_data = (input_test, correct_test)) #損失をグラフで表示 plt.plot(history.history['loss']) plt.plot(history.history['val_loss']) plt.title('Model loss') plt.ylabel('Loss') plt.xlabel('Epoch') plt.legend(['Train', 'Test'], loc = 'upper left') plt.show() model.summary() #横軸:正解値、縦軸:予測値として分布をプロット(y = x の形状になれば誤差が少ないと判断できる) plt.figure() plt.scatter(correct_train, model.predict(input_train), label = 'Train', c = 'blue') plt.title('Neural Network Predictor') plt.xlabel('Correct') plt.ylabel('Predict') plt.scatter(correct_test, model.predict(input_test), c = 'lightgreen', label = 'Test', alpha = 0.8) plt.legend(loc = 4) plt.show()

試したこと

最適化アルゴリズムの変更
バッチサイズの変更
中間層の数及び中間層のニューロン数の変更
活性化関数の変更
エポック数の変更

補足情報(FW/ツールのバージョンなど)

macOS Big Sur ver11.4
Jupyter Notebook
Python 3.7.11
tensorflow 2.0.0
keras 2.3.1

ysk0507👍を押しています

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

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

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

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

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

toast-uz

2021/08/19 03:49 編集

中間層の次元を15にしているのは、何か理由があるのでしょうか?入力層より広めに、かつ2のべき乗にするとよいです。64とか128にしてはいかがでしょうか? また、3層目はSigmoidのままとして、1層目、2層目の活性化をReLUにしてみるとどうなりますでしょうか?Sigmoidは勾配消失しやすいので、中間層では使わない方が良いです。 学習曲線はサチっているのか、まだ学習が不十分なのかわかりますでしょうか?後者であれば、epoch数を増やす、オプティマイザのlrを増やす、というのが打ち手になります。
toast-uz

2021/08/19 03:51

入力は3次元なのですね。だとすると中間層の次元は15でも問題無いと思います。(2べきのするのが通例ですが、動作には影響ありません)
imoimo117

2021/08/19 03:54 編集

ご回答ありがとうございます。 中間層のニューロン数は64や128でも試してみました。15にしているのは特に意味はなく数を減らしたという感じです。 学習曲線は0.9付近で飽和してしまっています。 また1.2層目の活性化をreluにした所、0.90程までしか減少しませんでした。
guest

回答1

0

ベストアンサー

コードそのものに不具合はありません。データそのものが学習に不向きであるか、モデルがデータに合っていません。

実際に、データのロード部分を、ダミーデータに書き換えて、その他は全く同じコードで、Google Colabで走らせたところ、問題なく学習できました。(loss=0.015くらいになりました。ノイズを考慮してちゃんと学習できています。)

これ以上の分析には、データそのものを公開いただく必要があるとともに、(コードに問題があるか、という)質問の位置づけが全く変わってしまいます。そのため、データを公開いただくか、何らかの公開されたデータで学習できないことを再現いただく前提で、新たに質問いただくことをオススメします。

なお、質問者様のコードで、そもそもinput_datacorrect_dataに正しくデータがロードされているかまでは確認しておりません。Excelに数式等が入っていると正常にロードされない場合がありますので、念のため確認されるとよいと思います。

書き換え前(質問者様のコードでのデータロード部分)

Python

1#Excelデータを開く 2wb = openpyxl.load_workbook('data_for_map.xlsx') 3 4#Excelのシートを指定 5sheet = wb['parasitic_dataset'] 6 7#シート内のセルを指定してリスト化 8def get_value_list(s): 9 return([[cell.value for cell in row] for row in s]) 10 11sheet_list1 = get_value_list(sheet['A2:C67241']) 12sheet_list2 = get_value_list(sheet['E2:E67241']) 13 14#リストから2次元配列を作成(入力[[t h f]], 出力[[L]]) 15input_data = np.array(sheet_list1) 16correct_data = np.array(sheet_list2) 17n_data = len(input_data)

書き換え後(correct_datainput_data(乱数値)からの単純計算とノイズで決定するダミーデータ)
※標準化ができているかを確認するため、入力の3列のスケールをわざと変えています。

Python

1n_data = 67240 2input_data = np.random.rand(n_data, 3) * np.array([1000, 100, 1]) 3noise = np.random.rand(n_data) * 200 - 100 4correct_data = (input_data[:, 0] + input_data[:, 1] * 10 + input_data[:, 2] * 1000 + noise).reshape(-1, 1)

投稿2021/08/19 13:39

編集2021/08/19 14:02
toast-uz

総合スコア3266

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

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

imoimo117

2021/08/20 03:38

モデルのデータを標準化+常用対数を施したら所上手く学習出来ました。 標準化のみではデータの外れ値の影響をなくせなかったようです。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問