Kerasによる時系列データ処理 ~その1~
はじめに
こんにちは、がんがんです。無事に年が明けましたね。
2018年も終わり、2019年がやってきました。
2019年は開幕早々自身が起きたり、インフルにかかったりと大変でした…
インフルも治ったので、2018年に勉強していた本を今一度勉強しようと思いました。
今回はこちらの本を再学習していきます。
詳解 ディープラーニング ~TensorFlow・Kerasによる時系列データ処理~
- 作者: 巣籠悠輔
- 出版社/メーカー: マイナビ出版
- 発売日: 2017/05/30
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (5件) を見る
今後、何回かに分けて備忘録をまとめていきます。
参考記事
改めてAmazonのリンクを記載しておきます。
詳解 ディープラーニング ~TensorFlow・Kerasによる時系列データ処理~
- 作者: 巣籠悠輔
- 出版社/メーカー: マイナビ出版
- 発売日: 2017/05/30
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (5件) を見る
また、公式が挙げられているGitHubのリンクについても貼っておきます。
コードのリンクはその都度貼っていきます。
deeplearning-tensorflow-keras/5 at master · yusugomori/deeplearning-tensorflow-keras · GitHub
時系列モデルについてはこちらがまとまっています。
deepage.net
問題提起・環境について
今回の実験では簡単な時系列データであるsin波を用いていきます。
検証するモデルは以下の通りです。
・simple RNN ・LSTM ・GRU
また、実験環境としては以下を用いました。なお、TensorFlowについての実験はこちらでは扱っていないのでご了承ください。
・Windows 10 ・Python 3.6.4 ・Keras 2.1.5
LSTM
LSTM
はRNNの欠点を改良したモデルです。LSTMを初めて見たときのイメージは「フリップフロップみたい」でした(笑)
モデルの詳細については以下が参考になります。
LSTMのモデルについては様々な方がまとめられているのでそちらも参考にしてください。
qiita.com
実験の結果は以下のようになりました。
GRU
実行結果は以下のようになりました。
GRUは使用したコードも載せておきます。
#------------------------------------------------------------ # # chap5. # kerasを用いてsin波のRNNを行う。GRUを使用 # #------------------------------------------------------------ # coding: utf-8 #------------------------------------------------------------ import numpy as np import matplotlib.pyplot as plt from keras.models import Sequential from keras.layers import Dense, Activation from keras.optimizers import Adam from keras.initializers import TruncatedNormal # 切断正規分布を使用 from keras.layers.recurrent import GRU from keras.callbacks import EarlyStopping from sklearn.model_selection import train_test_split from sklearn.utils import shuffle """ Deep NN クラス """ class DNN(object): # 初期化処理 def __init__( self, n_in, n_hidden, n_out, epochs, batch_size, maxlen ): self.n_in = n_in self.n_hidden = n_hidden self.n_out = n_out self.epochs = epochs self.batch_size = batch_size self.maxlen = maxlen """ モデルの構築関数 """ def inference( self ): # LSTM model.add( GRU( self.n_hidden, kernel_initializer=TruncatedNormal(stddev=0.01), input_shape = ( self.maxlen, self.n_in)) ) # 出力層 model.add( Dense( self.n_out, kernel_initializer=TruncatedNormal(stddev=0.01)) ) model.add( Activation('linear') ) model.compile( loss='mean_squared_error', optimizer=Adam(lr=0.001, beta_1=0.9, beta_2=0.999) ) """ 学習関数 """ def training( self, X_train, Y_train, X_validation, Y_validation ): early_stopping = EarlyStopping( monitor='val_loss', patience=10, verbose=1 ) # モデルの学習 hist = model.fit( X_train, Y_train, epochs = self.epochs, batch_size = self.batch_size, validation_data = ( X_validation, Y_validation), callbacks = [early_stopping] ) # sin波の生成 def sin( x, T=100 ): return np.sin( 2.0 * np.pi * x / T ) # Toy Problem def toy_problem( T=100, ampl=0.05 ): x = np.arange( 0, 2 * T + 1 ) noise = ampl * np.random.uniform( low=-1.0, high=1.0, size=len(x) ) return sin(x) + noise if __name__ == '__main__': """ データの設定 """ np.random.seed(0) T = 100 f = toy_problem(T) length_of_sequences = 2 * T # 全時系列の長さ maxlen = 25 # 1つの時系列のデータ長 data = [] target = [] for i in range( 0, length_of_sequences - maxlen + 1 ): data.append( f[i: i + maxlen] ) target.append( f[i + maxlen] ) X = np.array(data).reshape( len(data), maxlen, 1 ) Y = np.array(target).reshape( len(data), 1 ) # データの分割 N_train = int(len(data) * 0.9) N_validation = len(data) - N_train X_train, X_validation, Y_train, Y_validation = \ train_test_split( X, Y, test_size=N_validation ) # モデル設定 n_in = len(X[0][0]) # 1 n_hidden = 20 n_out = len(Y[0]) # 1 epochs = 500 batch_size = 10 # インスタンス定義 DNN = DNN( n_in, n_hidden, n_out , epochs, batch_size, maxlen ) model = Sequential() DNN.inference() # モデル学習 DNN.training( X_train, Y_train, X_validation, Y_validation ) # sin波の出力 truncate = maxlen Z = X[:1] # 元データの最初の一部だけ切り出し original = [f[i] for i in range(maxlen)] predicted = [None for i in range(maxlen)] for i in range(length_of_sequences - maxlen + 1): # 最後の時系列データから未来を予測 z_ = Z[-1:] y_ = model.predict(z_) # 予測結果かを用いて新しい時系列データを生成 sequence_ = np.concatenate( ( z_.reshape(maxlen, n_in)[1:], y_), axis=0).reshape( 1, maxlen, n_in ) Z = np.append( Z, sequence_, axis=0 ) predicted.append( y_.reshape(-1) ) # グラフの描画 plt.rc('font', family='serif') plt.figure() plt.plot( toy_problem( T, ampl=0), linestyle='dotted', color='#aaaaaa' ) plt.plot( original, linestyle='dashed', color='blue' ) plt.plot( predicted, color='black' ) plt.show()
まとめ
Kerasの時系列モデルは非常に簡単に使えるので、ほかにもいろいろな実験をしていきます。
今後も自身の勉強のために頑張ります。