LoginSignup
0
1

More than 1 year has passed since last update.

Google Colaboratoryを使ったRNNの動作確認その2(2022年3月30日)

Last updated at Posted at 2022-03-30

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')

image.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"]])

image.png

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)

image.png
 GPU無しで2分程度です。

4.1 推論用プログラム

 次のコードで推論を実行し、真値データと比較します。

 # 予測
predicted = model.predict(X_test)

 # 描写
dataf =  pd.DataFrame(predicted[:200])
dataf.columns = ["predict"]
dataf["input"] = y_test[:200]
dataf.plot()

image.png
 振幅がやや少ないですが、概ね推定に成功していると言えます。

5. おわりに

 オリジナル記事からの変更箇所は、modelのfitメソッドにおけるエポックの変数名です(nb_epoch → epochs)。オリジナル記事を書いて下さったkazukiiiさんに感謝致します。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1