1. はじめに
YOLO・CNNといったニューラルネットワークを使った機械学習を勉強中の者です。この手のコモディティ化以前のテクノロジーの学習で障害となるのは、プラットフォームやソフトウェアライブラリ等がどんどんアップデートされているので、ほんのちょっと前に書かれた記事であっても、書かれた通りに動かすことができないという点です(筆者も度々遭遇して難儀しています)。
つい昨晩、RNNに挑戦したところ、やはり参考にさせて頂いたサイト記事の通りには実行できず、いろいろとネット上を調べまわった結果、何とか動かすことができましたので、自分用の備忘録を兼ねて記録しておきたいと思います。その第2弾です。
2. 参考にさせて頂いたサイト記事
今度こそわかるぞRNN, LSTM編
https://qiita.com/kazukiii/items/df809d6cd5d7d1f57be3
更新日 2019年05月05日
3. テスト用データの作成プログラム
今回もGoogle Chrome上でGoogle Colaboratoryを使います。
オリジナルの記事では、乱数によりノイズを乗せたサインカーブをテストデータとして用い、それをRNNで学習させています。
3.0 ノイズ入りサインカーブ
まずは、今回の動作確認に使用するノイズ入りサインカーブを作成するプログラムコードを入力し、試しに実行します。
import pandas as pd
import numpy as np
import math
import random
import matplotlib.pyplot as plt
import seaborn as sns
# サイクルあたりのステップ数
steps_per_cycle = 80
# 生成するサイクル数
number_of_cycles = 50
df = pd.DataFrame(np.arange(steps_per_cycle * number_of_cycles + 1),
columns=["t"])
# 一様乱数でノイズを発生させたsin波を生成
df["sin_t"] = df.t.apply(lambda x: math.sin(x * (2 * math.pi /
steps_per_cycle)+ random.uniform(-0.1, +0.1) ))
# 2サイクルだけ抽出してプロット
df[["sin_t"]].head(steps_per_cycle * 2).plot()
# 画像を保存
plt.savefig('sinecurveWithNoise.png')
わかりやすくするために、オリジナルの記事より大きめのノイズを与えています。直感的にノイズの入ったサインカーブであることがわかるかと思います。
3.1 トレーニングデータ・テストデータの作成プログラム
続いて、RNNプログラムに入力するデータを作成するプログラムです。30ステップを入力し、31ステップ目を推定するように、トレーニングデータとテストデータを作成するプログラムを入力し、実行します。サインカーブなので、ノイズの無いサインカーブが真値(正解)となります。
def _load_data(data, n_prev=30):
docX, docY = [], []
for i in range(len(data) - n_prev):
docX.append(data.iloc[i:i + n_prev].values)
docY.append(data.iloc[i + n_prev].values)
alsX = np.array(docX)
alsY = np.array(docY)
return alsX, alsY
def train_test_split(df, test_size=0.1, n_prev=30):
ntrn = round(len(df) * (1 - test_size))
ntrn = int(ntrn)
X_train, y_train = _load_data(df.iloc[0:ntrn], n_prev)
X_test, y_test = _load_data(df.iloc[ntrn:], n_prev)
return (X_train, y_train), (X_test, y_test)
(X_train, y_train), (X_test, y_test) = train_test_split(df[["sin_t"]])
4. 推論用RNNプログラムの実装と学習
4.1 トレーニング用プログラム
次のコードを入力し実行すると学習が行われます。
from keras.models import Sequential
from keras.layers.core import Dense, Activation
from keras.layers.recurrent import LSTM
# パラメータ
in_out_neurons = 1
hidden_neurons = 300
length_of_sequences = 30
model = Sequential()
model.add(LSTM(hidden_neurons, batch_input_shape=(None, length_of_sequences,
in_out_neurons), return_sequences=False))
model.add(Dense(in_out_neurons))
model.add(Activation("linear"))
model.compile(loss="mean_squared_error", optimizer="rmsprop")
model.fit(X_train, y_train, batch_size=600, epochs=15, validation_split=0.05)
4.1 推論用プログラム
次のコードで推論を実行し、真値データと比較します。
# 予測
predicted = model.predict(X_test)
# 描写
dataf = pd.DataFrame(predicted[:200])
dataf.columns = ["predict"]
dataf["input"] = y_test[:200]
dataf.plot()
5. おわりに
オリジナル記事からの変更箇所は、modelのfitメソッドにおけるエポックの変数名です(nb_epoch → epochs)。オリジナル記事を書いて下さったkazukiiiさんに感謝致します。