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

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

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

Chainerは、国産の深層学習フレームワークです。あらゆるニューラルネットワークをPythonで柔軟に書くことができ、学習させることが可能。GPUをサポートしており、複数のGPUを用いた学習も直感的に記述できます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

Q&A

解決済

1回答

2070閲覧

ChainerのLSTM学習結果が教師データに近づかない

WLMehdi5

総合スコア11

Chainer

Chainerは、国産の深層学習フレームワークです。あらゆるニューラルネットワークをPythonで柔軟に書くことができ、学習させることが可能。GPUをサポートしており、複数のGPUを用いた学習も直感的に記述できます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

0グッド

0クリップ

投稿2018/09/27 04:05

前提・実現したいこと

Chainer v4を使ってLSTMの勉強をしています.
このページを参考に組んでみたところ,出力が教師データに近づいてくれません.

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

下記のデータを学習させたところ出力が全て0.5付近になってしまいました.

# 円 n_input = 1 n_output = 1 n_units = 10 X_train = np.array([[1.0], [0.8], [.5], [0.2], [0.0], [0.2], [0.5], [0.8]],dtype=np.float32) # 学習 Y_train = np.array([[0.5], [0.8], [1.0], [0.8], [0.5], [0.2], [0.0], [0.2]], dtype=np.float32) # 教師 出力 [[ 0.49993595] [ 0.49770281] [ 0.50214708] [ 0.50402743] [ 0.49146506] [ 0.50402743] [ 0.50214708] [ 0.49770284]]

参考にしていたページで学習させていたデータで試してみたところ,出力ががそれぞれ予測教師データと近い値をとることができています.

# 参考ページのデータ n_input = 3 n_output = 3 n_units = 10 X_train = Variable(np.array([[1,2,3],[2,5,7]],dtype=np.float32)) # 学習 Y_train = Variable(np.array([[2,4,5],[1,1,3]],dtype=np.float32)) # 教師 出力 [[ 2.00009871 3.87778997 4.99956989] [ 0.99989998 1.12260997 3.00038123]]

該当のソースコード

# python # https://gist.github.com/WLMehdi5/82e90c7ff8bd9355d94aec42b2a0dc52 import numpy as np from chainer import Function, Variable, optimizers, serializer, utils, cuda, serializers from chainer import Link, Chain, ChainList import chainer.functions as F import chainer.links as L import matplotlib as plt import pandas as pd import pylab # 参考url https://data-science.gr.jp/implementation/iml_chainer_basic_usage.html class TestLSTM(Chain): n_input = 3 n_output = 3 n_units = 8 # 隠れ層 def __init__(self): super(TestLSTM, self).__init__( l1=L.Linear(self.n_input, self.n_units), l2=L.LSTM(self.n_units, self.n_units), #l2=L.LSTM(self.n_input, self.n_units), l3=L.Linear(self.n_units, self.n_output), ) def reset_state(self): self.l2.reset_state() def __call__(self, x): h1 = self.l1(x) h2 = self.l2(h1) return self.l3(h2) model = TestLSTM() optimizer = optimizers.Adam() optimizer.setup(model) """ # 1次元 X_train = np.array([[1.0], [0.8], [.5], [0.2], [0.0], [0.2], [0.5], [0.8]],dtype=np.float32) Y_train = np.array([[0.5], [0.8], [1.0], [0.8], [0.5], [0.2], [0.0], [0.2]], dtype=np.float32) """ # 3次元 X_train = Variable(np.array([[1,2,3],[2,5,7]],dtype=np.float32)) Y_train = Variable(np.array([[2,4,5],[1,1,3]],dtype=np.float32)) #""" epoch = 20000 for i in range(epoch): #optimizer.target.cleargrads() model.cleargrads() model.reset_state() y = model(X_train) print("Epoch: ",i+1,sep="") for j in range(len(X_train)): print("Data ",end='') print(j+1,end='') print(": Input=",end='') print(X_train[j],end='') print(", Target=",end='') print(Y_train[j],end='') print(", Output=",end='') print(y.data[j]) loss = F.mean_squared_error(y, Y_train) loss.backward() optimizer.update() print('loss=', end='') print(loss) if loss.data < 0.005: break print(y.data) dataf = pd.DataFrame(y.data) dataf.plot() pylab.show()

試したこと

隠れ層の数が足りず,表現能力がないのかと思い隠れ層を増やしたりしてみましたが,特に変化はありませんでした.
また,直接LSTMに入力するのも試してみましたが,変化はなく,3次元データに関しては教師データと離れる値を取るようになってしまいました.

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

chainer==4.1.0
Python 3.6.1
です.

正直なところ,自分のコードが間違っているのか,NNが適していないのかわからない状態なので,是非アドバイスをお願いします.

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

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

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

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

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

guest

回答1

0

ベストアンサー

実は、質問で記載されているコードは、以下のような動きをする関数を学習させています。
イメージ説明
この際、x=0.2の時はy=0.2とy=0.8、x=0.5の時はy=0.0とy=1,0、x=0.8の時はy=0.2とy=0.8を取るので、学習後のパラメータは、各々0.5近辺を通るように学習することが最もコスト関数が小さくなるので、結果として0.5近辺を通過する関数ができることになります。
言い換えると、与えられたデータからすると0.5付近になることが正しい結果であるということができます。
仮にx=0.2の時、y=0.2またはy=0.8近辺を通過するような関数を学習させたいのであれば、特徴量をもう少し増やす必要があるかと思います。
ひとつのやり方として、全部のY値の平均を計算し、平均以上と平均以下を1,0を特徴量として追加して、Xを2次元のデータにして学習させれば、少しは近似するのではないでしょうか。

投稿2018/09/27 14:14

編集2018/09/27 23:19
R.Shigemori

総合スコア3376

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

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

WLMehdi5

2018/09/28 11:27

ご回答ありがとうございます! 自分としては一番右の点から反時計回りにLSTMに入力して学習させているつもりだったので、Shigemori様が提示してくださったような形になっているとは思っても見ませんでした。 さっそく提示してくださった方法を試してみたいと思います。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問