Pythonと機械学習スマートフォン用の表示で見るPythonと機械学習Pythonも機械学習も初心者ですが、頑張ってこのブログで勉強してこうと思います。RNNブロック順伝播の時間ループ逆伝播の時間ループDense中の時間ループネットワーク全体作成クラス実行結果return_sequences=Truereturn_sequences=Falseはじめにここでは、前回勉強したRNNをPythonで実装してみようと思います。前回の記事はこちらを参照。実はかなり前にコードを書いてたのですが、放置状態になっていました。勉強のログをブログに残しておくと、頭の中で考えが整理されて記憶に残るので、更新はゆっくりでも頑張って続けていきたいですね。学習させる事を考えていきます。グラフの青い線が元のsin波で、オレンジと緑が位相が遅れてノイズが乗ったsin波です。オレンジと緑の5この時間データをサンプルデータ、青の同じ時刻の5個の時間データをターゲットデータとして学習させます。式で書くと以下のようになってます。時間データ数5個、特徴量数2個のデータをRNNに入力して、時間データ数5個、クラス数1個のデータを出力させるようにします。上のグラフですが、各サンプルとターゲットが5個の時間データを持っており、そのままグラフにプロットするのは難しいので、最終時間のデータだけプロットしています。kerasを使ってどんな感じになるのか見ていきましょう。kerasには、SimpleRNNというクラスがあるのでそれを使います。return_sequences=TrueSimpleRNNの引数にreturn_sequencesというのがあります。return_sequencesをTrueに設定すると、時間データを全部出力します。Falseにすると最後の時間だけしか出力されません。ユニット数)の2階のテンソルになります。デフォルトではreturn_sequences=Falseになっています。今回はターゲットデータも5個の時間を持つようにしたいのでTrueにしておきます。SimpleRNNの後ろには出力とターゲットのユニット数を合わせるために、調整用のDenseを入れておきます。全部で100個あるサンプルデータの最初の80個をトレーニングデータ、後の20個を評価データとして学習させます。以下lossの履歴と、学習後のprediction結果です。以降が評価データですが、中々いい感じで予測できてますね。return_sequences=Falsereturn_sequences=Falseにした場合は、最終時間しか出力されないので、SimpleRNNの出力の形は時間インデックスが無くなり2階のテンソルになります。その後のDenseレイヤーでも2階のテンソルとして演算されるので、ターゲットデータもそれに合わせて、最終時間のみにしてやります。以下lossの履歴と、学習後のprediction結果です。return_sequences=True時と比較してみました。return_sequences=False時は、True時よりもlossがちょっと下がっていますね。学習後の予測結果では、最終時間だけ見るとreturn_sequences=FalseとTrueでそんなに違いはないみたいですね。RNNの実装では実際にRNNを実装していきたいと思います。出力の全部で4層のネットワークを作成していきます。基本的な構成は、以前多層パーセプトロンを実装した時と同じです。多層パーセプトロンの実装に関してはこちら。kerasに合わせてreturn_sequencesの切り替え機能も付けたいと思います。追加と、順伝播関数forward_propと逆伝播関数back_propで時間ループを回していることです。順伝播の時間ループ以下の順伝播の式を全ての時間で計算するため、時間でforループを回す必要があります。forward_prop関数内の以下の55~60行目の記述が相当します。self.act_func.forward_prop(Z[:,t,:])戻り値は、return_sequencesで場合分けしてFalseの時は最終時間のみを出力させてます。Phi_next[:,-1,:]逆伝播の時間ループ以下逆伝播の式です。こちらも全ての時間で算出してやります。時間に関しても逆伝播するので、未来から過去に向かってforループを回してやります。back_prop関数内の87~92行目が相当する処理です。self.W.T)以下は重み勾配の計算式です。こちらは全ての時間について足し込んでやります。94~98行目の処理が相当します。Delta[:,t,:])/n_samplesreturn_sequences=False時は、逆伝播してくる2階のテンソルを、最終時間のみだけ値が入り、後の時間は全部ゼロになる様に3階のテンソルに変形しています。75~79行目が相当します。全部ゼロになっているというわけです。Dense中の時間ループreturn_sequence=True時は時間データも含めた3階のテンソルで処理する必要があるので、全結合演算でも、forward_propとback_prop関数内で時間ループを回す必要があります。Denseを継承して、TimeSeriesDenseというクラスを作成し、時間ループの演算をするforward_propとback_prop関数をオーバーライドしておきます。出力の4層ネットワークの作成と学習をまとめたクラスです。レイヤー作成のcreate_layers関数では、return_sequensesの値によって全結合クラスを変えています。True時はTimeSeriesDenseが呼ばれ、False時はDenseが呼ばれる様にしています。72~75行目の処理です。input_dim=self.rnn_units)順伝播関数forward_propと逆伝播関数back_propでは、各レイヤークラスのforward_propとback_prop関数をレイヤー順に呼ぶだけです。lossに平均2乗誤差を用いるので、mean_square_error関数を用意しています。2))/n_samples実行結果return_sequences=True以下、自作版RNNの学習実行スクリプトです。学習後はlossの履歴とpredicton結果をグラフに出力してkeras版の結果と比較しています。以下lossの履歴です。自作版の方はlossの収束値が少し大きいですが、まあ許容範囲でしょう。以下prediction結果です。思ったよりkeras版と一致してますね。return_sequences=False以下が自作版のreturn_sequences=Falseにした時の学習実施スクリプトです。こちらも学習後はloss履歴とprediction結果をグラフに出力してkeras版と比較しています。以下loss履歴です。自作版の方がkeras版よりlossがちょっと小さくなりました。以下prediction結果です。こちらもまあまあの一致。(13)はてなブログをはじめよう!dardenさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。