強化学習とは何か、調べてみた
皆さんこんにちは
お元気ですか。私は元気です。
今日は強化学習の勉強がてらメモを書いてみました。
個人的には最近、注目している分野で、ゴールがあるような(クラス分類やRegression)
機械学習と異なり、汎用的に色々問題が解けそうだからというのが理由です。
(なんか色々語弊を生みそう)
間違っていれば教えて下さい。
強化学習
強化学習はある環境ないにおけるエージェントが、
現在の状態を観測し、取るべき行動を決定する問題を扱う
機械学習の一種 by wikipedia
この中で登場するのは、「状態」と「行動を決定する」といったところでしょうか。
つまり、「ある状態の時に、どう行動をするか」といったことを解く問題となります。
強化学習における要因
強化学習について考えなければならないことが4点あります。
①ポリシー(policy)・・・どのように行動するか
②報酬関数(reward function)・・・強化学習問題のゴールを定義する関数
③値関数(value function)・・・長期間に渡る評価指標
④環境モデル(model of the environment)・・・アクション・状態の定義
Policy
ある状態が与えられた時、観測された状態からどう行動するか規則のこと。
一番、簡単な方法はLook up table(「この状態の時は、こうする。」が一覧表で決まっている)
Reward Function
強化学習を実施する時に使うゴール部分
イベントに対して、良いか悪いかをagentに伝える
Value function
Value functionは長期的に行動が悪いか良いかを評価する指標
model of the environment
所謂解きたい問題でしょうか。状態とそれに対するアクションがどういった形式で
定義できるのか。
つまり、これらを絵にするとこんな感じでしょうか。
強化学習で解ける問題
強化学習では解ける問題は以下のような問題です。
ロボットの動作最適化
強化学習 - Google 検索
迷路を解く
http://qiita.com/hogefugabar/items/74bed2851a84e978b61c
Alpha Go
AlphaGo - Wikipedia
つまり、状態を持ち、ゴールを持っており、試行錯誤で解ける問題について
解けるといえるでしょう。
また、n-Armed Bandit Problemも含まれ、こういった部分は勉強していきたいと思います。
参考文献
Richard S. Sutton and Andrew G. Barto「Reinforcement Learning: An Introduction」
Go言語を触ったことのない人間がSensorBeeを使ってみた Part2
皆さんこんにちは
お元気ですか。
前回からあいてしまいましたが、引き続き
SensorBeeのturtorialをやってみます。
こちらは準備段階に2段階あり、elasticsearch,kibanaのインストールとtutrialの実施です。
準備
Elastisearch並びにkibanaのインストール
elasticsearch、kibanaは公式から取得するのが良いと思います。
公式ではversion2.2.0ですが、今回は最新の安定版2.3.2で実行してみます。
$ ./bin/elasticsearch [2016-05-04 23:13:01,634][INFO ][node ] [Impulse] version[2.3.2], pid[41126], build[b9e4a6a/2016-04-21T16:03:47Z] [2016-05-04 23:13:01,635][INFO ][node ] [Impulse] initializing ...
起動確認は以下のcurlコマンドで実施できます。
curlコマンドのレスポンスがかえって来れば問題ありません。nameなどは立ち上げるたびに変わるので・・
$ curl http://localhost:9200/ { "name" : "Aliyah Bishop", "cluster_name" : "elasticsearch", "version" : { "number" : "2.3.2", "build_hash" : "b9e4a6acad4008027e4038f6abed7f7dba346f94", "build_timestamp" : "2016-04-21T16:03:47Z", "build_snapshot" : false, "lucene_version" : "5.5.0" }, "tagline" : "You Know, for Search" }
kibanaの起動確認は以下の通り、こちらも公式サイトから取得しましょう。
$ ./bin/kibana log [23:43:01.165] [info][status][plugin:sense] Status changed from uninitialized to green - Ready log [23:43:01.171] [info][status][plugin:kibana] Status changed from uninitialized to green - Ready log [23:43:01.193] [info][status][plugin:elasticsearch] Status changed from uninitialized to yellow - Waiting for Elasticsearch log [23:43:01.207] [info][status][plugin:kbn_vislib_vis_types] Status changed from uninitialized to green - Ready log [23:43:01.213] [info][status][plugin:markdown_vis] Status changed from uninitialized to green - Ready log [23:43:01.224] [info][status][plugin:metric_vis] Status changed from uninitialized to green - Ready
tutorialの設定
$ go get github.com/sensorbee/tutorial/ml $ cp -r $GOPATH/src/github.com/sensorbee/tutorial/ml/config/* /path/to/sbml/ $ cp -r $GOPATH/src/github.com/sensorbee/tutorial/ml/config/* ./sbml/ $ cd sbml/
fluentd
最後にfluentdです。(ここはLogstashではないのか・・・)
まず、初めにbundlerが入っていことを確認しましょう。versionがコンソールに表示されていなければ
$gem list | grep bundler
入っていなければ、以下のコマンドを実行しましょう。
$sudo gem install bundler
最後にbundle installを使って、fluentdを実行します。
$ bundle install --path vendor/bundle $ bundle exec fluentd --version fluentd 0.12.23
fluentdの起動確認をしましょう。以下のような表示がコンソールに出れば成功です。
$ bundle exec fluentd -c fluent.conf 2016-05-04 23:50:17 +0900 [info]: reading config file path="fluent.conf" 2016-05-04 23:50:17 +0900 [info]: starting fluentd-0.12.23 2016-05-04 23:50:17 +0900 [info]: gem 'fluentd' version '0.12.23' 2016-05-04 23:50:17 +0900 [info]: gem 'fluent-plugin-elasticsearch' version '1.4.0' 2016-05-04 23:50:17 +0900 [info]: adding match pattern="sensorbee.tweets" type="elasticsearch" 2016-05-04 23:50:17 +0900 [info]: adding source type="forward" 2016-05-04 23:50:17 +0900 [info]: using configuration file: <ROOT> <source> @type forward @id forward_input </source> <match sensorbee.tweets> @type elasticsearch host localhost port 9200 include_tag_key true tag_key @log_name logstash_format true flush_interval 1s </match> </ROOT> 2016-05-04 23:50:17 +0900 [info]: listening fluent socket on 0.0.0.0:24224 ^C2016-05-04 23:50:34 +0900 [info]: shutting down fluentd 2016-05-04 23:50:34 +0900 [info]: shutting down input type="forward" plugin_id="forward_input" 2016-05-04 23:50:34 +0900 [info]: shutting down output type="elasticsearch" plugin_id="object:3fc04d87f990" 2016-05-04 23:50:34 +0900 [info]: process finished code=0
今回はtwitterを解析するので、api_keyの設定をします。
api_keyはtwitterの公式サイトより、取得することができます。
公式サイトに掲載されている以下の雛形にしたがって、api_key.yamlを作成しましょう。
$ go get gopkg.in/sensorbee/sensorbee.v0/... $ build_sensorbee sensorbee_main.go $ ./sensorbee run -c sensorbee.yaml INFO[0000] Setting up the server context config={"logging":{"log_dropped_tuples":false,"min_log_level":"info","summarize_dropped_tuples":false,"target":"stderr"},"network":{"listen_on":":15601"},"storage":{"uds":{"params":{"dir":"uds"},"type":"fs"}},"topologies":{"twitter":{"bql_file":"twitter.bql"}}} INFO[0000] Setting up the topology topology=twitter INFO[0007] Starting the server on :15601
この時に立ち上がっていれば、kibana上で以下の画面を見ることができます。
まずは、kibana上で可視化したいelasticsearchのindexを指定します。
indexを指定すると以下の画面を見ることができます。
最後にDiscoveryをクリックするとデータが投入されている様子がわかります。
トラブルが発生している場合は・・・
sensorbee shell -t twitter
まずは、以下のコマンドを入力し、データが取得できているかを確認します。
twitter > SELECT RSTREAM * FROM public_tweets [RANGE 1 TUPLES]; twitter > SELECT RSTREAM * FROM labeled_tweets [RANGE 1 TUPLES];
データが取得できている場合は更に以下のコマンドを実行し、ストリーム生成処理が成功しているかを確認します。
CREATE SOURCE public_tweets TYPE twitter_public_stream WITH key_file = "api_key.yaml";
以下、暫くはBQLの紹介なのでスキップし、機械学習部分に行きます。
機械学習
まずは、既存にある機械学習のモデルを読み込みます。
twitter> LOAD STATE age_model TYPE jubaclassifier_arow OR CREATE IF NOT SAVED WITH label_field = "age", regularization_weight = 0.001; twitter> LOAD STATE gender_model TYPE jubaclassifier_arow OR CREATE IF NOT SAVED WITH label_field = "gender", regularization_weight = 0.001;
評価はEVAL Statementを使うことで実施可能です。
twitter> EVAL jubaclassify("gender_model", { "text": {"i": 1, "wanna": 1, "eat":1, "sushi":1}, "description": {"i": 1, "need": 1, "sushi": 1} });
maleかfemaleのどちらかであることを評価するためにはjuba_classified_labelを使用します。
twitter> EVAL juba_classified_label({ "male":0.021088751032948494,"female":-0.020287269726395607});
機械学習のトレーニングに躓いているので、こちらは余裕があればやることにします。
Go言語を触ったことのない人間がSensorBeeを使ってみた Part1
本日はさくっとSensorBeeを使ってみました。
皆さんこんにちは
お元気ですか。連休でほっとしています。
今回はSensorBeeと呼ばれるライブラリを紹介します。
Machine Learningまでは流石に長過ぎるので、word countまでやってみました。
What is SensorBee
SensorBeeは特徴として以下の内容を兼ね揃えます。
Stateful
機械学習に有用な構造化されていない情報を取得し、ユーザが定義した機械学習のモデルを動作させることができます。
また、ChainerやJubatusに加え、その他SensorBeeで記載できるQueryによっても作成することができます。
Expressive
命令やクエリはBQLで書かれています。BQLはパワフルな言語で簡単に習得でき、SQLに似ています(確かに)。
BQLはスキーマレスで、JSONにかなり近い、データ構造となってます。
LightWeight
SensorBeeはLightweightで軽量です。30MBも必要ないので、Raspberry Piのような
小型であっても動作します。 しかしながら、very smallなデバイスには搭載するには十分ではありません。
将来的には、このようなデバイスにも動作させたいんだそうな。
Install
goを持ってない人はgoからのインストールが必要となります。
Go(Mac)
Go自体のインストールと環境変数となります。
$ brew install go $ export GOROOT=/usr/local/opt/go/libexec $ export GOPATH=$HOME/go $ export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
SensorBeeのインストール
SensorBeeのインストールは簡単です。
$ go get gopkg.in/sensorbee/sensorbee.v0/...
Tutorial
これだけではなんのことかまるでわからないので、Tutorialを実施してみます。
まずは、データの取得と初期化を行います。
データの取得と初期化
$ go get github.com/sensorbee/tutorial/wordcount $ mkdir wordcount $ cp $GOPATH/src/github.com/sensorbee/tutorial/wordcount/config/* ./wordcount/ $ build.yaml sensorbee.yaml wordcount.bql
ビルド用のコマンドとしてbuild_sensorbeeを使う必要があります。
$ go get gopkg.in/sensorbee/sensorbee.v0/cmd/build_sensorbee
$ cd wordcount/
$ build_sensorbee
build.yamlの内容は以下のようになります。
$ cat build.yaml plugins: - github.com/sensorbee/tutorial/wordcount/plugin
サーバの起動
これでSensorBeeを使う準備ができました。
早速、SensorBeeのサーバを起動してみましょう。
$ ./sensorbee run INFO[0000] Setting up the server context config={"logging":{"log_dropped_tuples":false,"min_log_level":"info","summarize_dropped_tuples":false,"target":"stderr"},"network":{"listen_on":":15601"},"storage":{"uds":{"params":{},"type":"in_memory"}},"topologies":{}} INFO[0000] Starting the server on :15601
試しにcurlを投げてみましょう。以下のようなレスポンスが返ってくるはずです。
$ curl http://localhost:15601/api/v1/runtime_status {"gomaxprocs":4,"goroot":"/usr/local/opt/go/libexec","goversion":"go1.5.3","hostname":"{host name}-Pro.local","num_cgo_call":1,"num_cpu":4,"num_goroutine":13,"pid":44076,"user":"Tereka","working_directory":"/Users/Tereka/Programing/Software/SensorBee/wordcount"}
まずは、topologyと呼ばれるものが必要になります。topologyは
RDBMSのデータベースに近いそうです。まずは、これを作成しましょう。
./sensorbee topology create wordcount
出力されているStreaming情報はBQLと呼ばれる文法を使うことで様々なことをすることができます。
まずは、stream(ストリーム)からデータを取得してみましょう。
wordcount> CREATE SOURCE sentences TYPE wc_sentences; wordcount> SELECT RSTREAM * FROM sentences [RANGE 1 TUPLES];
BQN
はじめに
BQNはストリーム間の関連性のデータ命令と関係性を示した命令があります。(あってる?)
ストリームの処理単位を決定することができます。
ストリームの処理単位は以下のような構文で実施することができます。
[RANGE n TUPLES] or [RANGE n SECONDS]. [RANGE n TUPLES]
例えば、以下のように書けます。
SELECT RSTREAM * FROM sentences [RANGE 1 TUPLES];
STREAMは3種類あります。
Stream | 説明 |
RSTREAM | 新しいtupleが到着した時に結果を更新する。(処理をする) |
ISTREAM | 到着したtupleのみ更新し、以前までの時刻は更新しない。(処理をしない) |
DSTREAM | 解説plz |
SELECT文
まずは、SELECT文 SQLと殆ど同じ書き方です。
wordcount> SELECT RSTREAM name FROM sentences [RANGE 1 TUPLES]; {"name":"isabella"} {"name":"isabella"} {"name":"isabella"} {"name":"jacob"} {"name":"sophia"}
WHERE文
これも殆ど同じではないだろうか。
WHERE name = "sophia"の部分で、フィルタリングをかけています。
wordcount> SELECT RSTREAM * FROM sentences [RANGE 1 TUPLES] WHERE name = "sophia"; {"name":"sophia","text":"in velit commodo cillum cillum consequat proident dolore ut"} {"name":"sophia","text":"in aute aliqua irure anim sit et"} {"name":"sophia","text":"mollit sunt commodo id id commodo esse sit"} {"name":"sophia","text":"cillum magna aute tempor eu velit"}
GROUP BY
SQLのGROUP BYと似たような使い方です。出力は名前が以前+今回で何回出てきたかをcountで出力しているようですね。
wordcount> SELECT ISTREAM name, count(*) FROM sentences [RANGE 60 SECONDS] GROUP BY name; {"count":1,"name":"jacob"} {"count":1,"name":"sophia"} {"count":2,"name":"sophia"} {"count":1,"name":"isabella"} {"count":2,"name":"isabella"}
ストリームの作成
既にあるストリームから、新しいストリームを作成することができます。
sentencesを処理して新しいwordsと呼ばれるストリームを作成しています。
wordcount> CREATE STREAM words AS SELECT RSTREAM name, text AS word FROM wc_tokenizer("sentences", "text") [RANGE 1 TUPLES]; wordcount> SELECT RSTREAM * FROM words [RANGE 1 TUPLES]; {"name":"isabella","word":"proident"} {"name":"isabella","word":"id"} {"name":"isabella","word":"eu"} {"name":"isabella","word":"laboris"} {"name":"isabella","word":"sunt"}
これを使うと、以下のようにしてword countを実施することができます。
wordcount> SELECT ISTREAM word, count(*) FROM words [RANGE 60 SECONDS] GROUP BY word; {"count":1,"word":"culpa"} {"count":1,"word":"sunt"} {"count":1,"word":"occaecat"} {"count":1,"word":"ullamco"} {"count":1,"word":"ut"} {"count":1,"word":"consequat"} {"count":1,"word":"minim"} {"count":1,"word":"aute"}
それぞれのワードのカウント最大数と最小数を求めています。
また、以下のBQNによって、出現ワードの最大回数、最小回数を算出することができます。
wordcount> CREATE STREAM word_counts AS SELECT ISTREAM word, count(*) FROM words [RANGE 60 SECONDS] GROUP BY word; wordcount> SELECT RSTREAM max(count), min(count) FROM word_counts [RANGE 60 SECONDS]; {"max":8,"min":8} {"max":8,"min":5} {"max":8,"min":5} {"max":11,"min":5} {"max":11,"min":5}
これで、ワードのカウントをSensorBeeで実施するチュートリアルを完走しました。
チュートリアルが半分残っているので時間に余裕があれば、Part2やります。
間違ってたら後で修正かけます。。
Kaggleのコンペティションで公開されている手法・ソースコードのリンクをまとめてみた Part2
皆さんこんにちは
お元気ですか。私は元気です。
今日は前回の以下のページからだいぶ更新が立ち、Kaggleのコンペ的にも多くの開催がありました。
そこで、新しいページでリンクを纏めてみました。
中にはインタビューやフォーラム、githubなど様々なものが混合しているのはお許し下さい。
Prudential Life Insurance Assessment
1st - 1st place solution - Prudential Life Insurance Assessment | Kaggle
2nd - Solution -- 2nd place - Prudential Life Insurance Assessment | Kaggle
Homesite Quote Conversion
Santa's Stolen Sleigh
2nd-GitHub - woshialex/SantaStolenSleigh: Santa's Stolen Sleigh competition
7th-GitHub - nagadomi/kaggle-santas-stolen-sleigh: Code for Santa's Stolen Sleigh. 7th place.
9th-Ninth place solution (12404781212) - Santa's Stolen Sleigh | Kaggle
Airbnb New User Bookings
2nd-GitHub - Keiku/kaggle-airbnb-recruiting-new-user-bookings: 2nd Place Solution in Kaggle Airbnb New User Bookings competition
こちらは日本人の方でKaggle Meetupでの発表資料があります。
sssslide.com
Rossmann Store Sales
1st-Model documentation 1st place - Rossmann Store Sales | Kaggle
3rd-GitHub - entron/entity-embedding-rossmann
Grasp-and-Lift EEG Detection
2nd-GitHub - stupiding/kaggle_EEG
3rd-GitHub - bitsofbits/kaggle_grasp_and_lift_eeg_detection: Code for Team HEDJs submission for Kaggle's Grasp and Lift EEG Detection Contest
Avito Context Ad Clicks
2nd-GitHub - Gzsiceberg/kaggle-avito: https://www.kaggle.com/c/avito-context-ad-clicks/forums
Diabetic Retinopathy Detection
1st-GitHub - sveitser/kaggle_diabetic: Team o_O solution for the Kaggle Diabetic Retinopathy Detection Challenge
3rd-3rd Place Solution Report - Diabetic Retinopathy Detection | Kaggle
6th-Diagnosing diabetic retinopathy with deep learning | deepsense.io
Crowdflower Search Results Relevance
1st-GitHub - ChenglongChen/Kaggle_CrowdFlower: 1st Place Solution for Search Results Relevance Competition on Kaggle (https://www.kaggle.com/c/crowdflower-search-relevance)
2nd-GitHub - geffy/kaggle-crowdflower
3rd-CrowdFlower Winners’ Interview: 3rd place, Team Quartet | no free hunch
Otto Group Product Classification Challenge
1st-1st PLACE - WINNER SOLUTION - Gilberto Titericz & Stanislav Semenov - Otto Group Product Classification Challenge | Kaggle
2nd-Otto Product Classification Winner’s Interview: 2nd place, Alexander Guschin ¯\_(ツ)_/¯ | no free hunch
4th-GitHub - diefimov/otto_2015
Coupon Purchase Prediction
5th-GitHub - nagadomi/kaggle-coupon-purchase-prediction: Code for RECRUIT Challenge. 5th place.
Walmart Recruiting II: Sales in Stormy Weather
Neural Networkでの失敗経験やアンチパターンを語る
皆さんこんにちは
お元気ですか。私は元気です。
今日は珍しくNeural Networkを使っていく上での失敗経験について語ります。
学習の時に案外、失敗するのですが、だいたい原因は決まっています。そう大体は・・・
ということで、今回は失敗の経験、アンチパターンのようなものを書こうと思います。
- Trouble1:学習時にNanを叩き出す。
- Trouble2:収束しない
- Trouble3:Validation Scoreが低い
- Trouble4:正しい入力を与えたはずなのに、ライブラリから変なエラーを吐かれる場合
- まとめ
Trouble1:学習時にNanを叩き出す。
こんな経験よくあるのでは無いでしょうか?
なぜかよくわからないけれども学習していると気がついたらNanになっていることがあります。
原因1 cross-entropy誤差を使っている。
まずは、cross-entropy誤差関数を見てみましょう。
(今回はTheanoのbinary cross entropyを取り上げます)
実はこの数式、nanを出す要因があります。対数に着目してみます。
対数は0を入力するとnanが返ってきて、計算不可能な値となります。
何らかの原因で、対数に0が入力され、計算がおかしくなっています。
この場合はsigmoid関数やnp.log1pの関数を使い、関数に一工夫が必要になります。
しかし、sigmoid関数についても、nanが出力される場合があります。
原因2 結果が小さすぎて、0と認識される。
原因1の事象はsigmoid関数を使っている場合でも発生します。
sigmoid関数は∞に大きくなれば0や1を計算することが可能です。
Neural Networkの計算において、sigmoid関数はfloat32の場合において、小さすぎて0と算出されます。
これが原因になっていることがあります。
以下のコードを書いて検証してみました。
import numpy as np def sigmoid(z): return 1/(1+np.exp(-z)) sigmoid(-500) #7.1245764067412845e-218 sigmoid(-500).astype(np.float32) #0.0
原因3 重みがあらぬ方向へ学習する。
回帰式を計算した時によくあることなのですが、
重みが凄い方向へ学習してそのままinfを叩き出し、nanになることがあります。
Trouble2:収束しない
作った関数が収束しない、これもよくあることです。
大体原因は決まっている気がします。
原因1 学習率が高すぎる
学習率が高過ぎると重みがぶれ、学習ができません。
あまりにも遅ければ上げてみる、もしくはAdamなど、自動的に学習してくれる
学習法を使ってみると良いと思います。
chainerのMNISTのexample(
chainer/train_mnist.py at master · pfnet/chainer · GitHub)
に対して学習方法をSGDにして、学習率1000000000.0とした場合の標準出力
正当率があがらず、誤差もnanが出続けています。
epoch 1 graph generated train mean loss=nan, accuracy=0.0988166666403 test mean loss=nan, accuracy=0.0979999999329 epoch 2 train mean loss=nan, accuracy=0.0987166666767 test mean loss=nan, accuracy=0.0979999999329 epoch 3 train mean loss=nan, accuracy=0.0987166667202 test mean loss=nan, accuracy=0.0979999999329
原因2 学習率が低すぎる
学習率が低すぎると、学習が遅くなります。
対策としては原因1と同じです。見なおしてみてください。
chainerのMNISTのexampleに対して学習方法をSGDにして、学習率0.0000001とした場合は以下になります。
縦軸が誤差、横軸がepoch数、で学習が殆ど進んでいないことが見てわかります。
対して学習率を0.1とした場合の誤差は以下のようになります。
個人的にこのパラメータは0.01周りを使っていればトラブルが少ないと考えています。
原因3 適切な誤差関数ではない
誤差関数がよくないといった失敗をやったことがあります。
基本的に誤差関数は、誤っている場合の誤差が大きければ、大きいほど、学習の進みがよくなります。
マルチラベルの場合最小二乗誤差ではなく、cross-entropyを使わなければ、収束がすごく遅いです。
因みにこれを私はcross-entropyと最小二乗誤差でやりました。
原因4 活性化関数を誤った
昔、回帰の問題を解いていました(100,300などを予測)が
盛大な誤差関数を出力するが、誤差落ちなかったことがありました。
モデルを調べた結果、なぜかsigmoid関数を使っていたことがありました。
全然減らないと思った時は最後の出力の活性化関数を見直すのも良いでしょう。
因みに負の値の予測が必要な時にReLuを使うのもよろしくありません。式を見れば一目瞭然ですが・・・
原因5 そもそも入力が誤っている
画像に変な処理をかけたことで、入力が誤っていることがあります。
例えばuint8に対してintの処理をすることで期待と異なる結果が返る場合があります。
2 / 100 #0 2 / 100.0 #0.02
Trouble3:Validation Scoreが低い
Neural Networkを作ったけれども精度が出ない、そんな失敗もあります。
原因1 過学習しているにも関わらず、気づかなかった。
Early Stoppingを実施しなかった時によく起こる問題だと思います。
Early Stoppingを実施しない場合は、一定の間は普通ですが、
あるときから、Validation Scoreが低下していきます。
原因2 与えるデータとラベルの1対1が誤っている
与えるデータとラベルを何らかの処理で取得している場合
1対1が間違っている可能性があります。
例えば、与えるデータとラベルをうっかりValidationの時に各々でシャッフルするなどあります。
あまりにも学習データと乖離しているときは、与えているデータが違っていないか疑ってみるのもよいでしょう。
Trouble4:正しい入力を与えたはずなのに、ライブラリから変なエラーを吐かれる場合
これは、どちらかというとライブラリ周りの話です。
原因1 モデル構築誤り
この場合はだいたい、入力誤りです。
連結している部分のfor文あたりが間違っている事が多いです。
例えば、連結が途切れているなどはこの場合に含まれるでしょう。
原因2 入力データのデータ形式誤り
ライブラリによって異なりますが、regressionとclassificationでは大体入力の方法が異なっています。
これに気づかずにやるとデータの形式にハマります。
時々、ConvolutionやDense Layer(Liner Layer)の対応マップが誤って出ることもあります。
Theano関連のライブラリだと以下の様な結果が出ることでしょう。
ValueError: Input dimension mis-match. (input[0].shape[1] = 2, input[1].shape[1] = 1) Apply node that caused the error: Elemwise{sub,no_inplace}(Elemwise{Composite{tanh((i0 + i1))}}[(0, 0)].0, <TensorType(float64, matrix)>) Inputs types: [TensorType(float64, matrix), TensorType(float64, matrix)] Inputs shapes: [(50, 2), (50, 1)] Inputs strides: [(16, 8), (8, 8)]
Python: keras shape mismatch error - Stack Overflowより
因みに大体のライブラリで回帰問題とクラス分類問題によって決まっており、
以下の入力をすれば、特段問題はないと思います。
[[1],[3],[4]] #regression [1,2,3,4] #classification
まとめ
大体上記4つのトラブルに失敗の経験は含まれると思います。(私はそうでした)
皆さんの失敗経験がこれで減りますように。
他に失敗経験があったらぜひ教えて下さい。