こんにちは、ヒガシです。
TensorflowやPytorchの環境下でAIモデルを構築しても、実際に運用する際にそれらの環境を準備できないことってよくありますよね。
そんな状況に対応するために以前の記事にて、単純な多層パーセプトロン(MLP)モデルや時系列データ扱うのが得意なLSTMモデルをnumpyの行列計算のみで再現する方法をご紹介しました。
◆MLPモデルの場合
【AI】活性化関数付MLPモデルの計算を行列計算で再現する方法!
◆LSTMモデルの場合
【AI】学習済みLSTMモデルの内部計算をnumpyのみで再現する方法
今回もこれらと同じことをRNNモデルに適用してみようと思います。
それではさっそくやっていきましょう!
KerasでRNNモデルを構築する
RNNの内部計算を再現しようにも、まずは学習済みのモデルがないと話になりません。
というわけでまずは簡易的なRNNモデルを構築するところから始めます。
今回は以下のデータを用います。
RNNのLook Back数を4にとり、X1,X2,X3を一つの時刻における入力、Yをその時刻における出力としてモデルを構築していきます。
なので以下のように7つのデータを学習させることになります。
★1つ目のデータ
★2つ目のデータ
★7つ目のデータ
今回はモデルを作ることが目的ではなく、あくまでもRNNモデルの内部計算を行列計算だけで実施することが目的ですので、このような簡易的なデータを用いていきます。
それでは上記データが入ったcsvファイルがプログラム実行フォルダに【RNN_sample.csv】という名前で保存されていることを前提に、RNNモデルを構築していきましょう。
以下がそのコードです。
#ライブラリインポート
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation
from tensorflow.keras.layers import SimpleRNN
from tensorflow.keras.optimizers import Adam
#csvファイルの読み込み
data_file='RNN_sample.csv'
data=pd.read_csv(data_file).values
#学習用データセットの構築
Xdata=[]
Ydata=[]
look_back=4
for i in range(data.shape[0]-look_back+1):
Xdata.append(data[i:i+look_back,:-1])
Ydata.append(data[i+look_back-1,-1])
Xdata=np.array(Xdata)
Ydata=np.array(Ydata)
#RNNモデルの構築
hl_unit=3
model = Sequential()
model.add(SimpleRNN(hl_unit, input_shape=(look_back,Xdata.shape[2])))
model.add(Dense(1))
model.compile(loss="mean_absolute_error", optimizer=Adam(lr=0.01))
model.summary()
history=model.fit(Xdata,Ydata,batch_size=4,epochs=2000)
これで変数modelの中にLSTMモデルが構築できます。
RNNの内部パラメータはどこで使われているのか?
RNNの内部計算をnumpyで再現するうえで、まずはRNNの構造および内部パラメータがどこで使われているのかを理解しておきましょう。
以下がその概要図です。
Keras-RNNモデルの内部パラメーターを取得する
モデルが構築できたら、次はRNNモデルが学習した内部のパラメータを取得していきましょう。
以下がそのコードです。
#LSTM内部の重み、バイアスを取得
W,U,b,Wout,bout=model.get_weights()
これで各変数の中にRNN内部で使用する重み、バイアスが格納されます。
ここまでがKeras環境で実施する内容になります。
RNNの内部計算をnumpyだけで実行する方法
事前準備はここまで。
それでは本題であるRNNの内部計算のnumpyで再現していきましょう。
numpyの行列計算およびKrasのPredictでそれぞれ内部計算を再現し、それらの結果を散布図として表示します。
以下がそのコードです。
result=[]
for index in range(Xdata.shape[0]):
h=np.zeros(hl_unit)
#RNN計算開始----------------------------------------
for i in range(Xdata.shape[1]):
x=Xdata[index][i]
h=np.tanh(np.dot(x,W)+np.dot(h,U)+b)
manual_result=np.dot(h,Wout)+bout
#RNNの計算終了--------------------------------------
keras_result=model.predict(np.array([Xdata[index]]))
result.append([keras_result,manual_result])
#結果の可視化
result=np.array(result)
plt.scatter(result[:,0],result[:,1])
plt.xlabel('Keras_Predic',fontsize=14)
plt.ylabel('Manual_Calc',fontsize=14)
numpy計算とKerasの結果を比較した結果
それでは先ほどのコードで実施した、numpyでのRNNモデルの再現と、Kerasを使って計算した結果を比較してみましょう。
以下がその結果です。
両者のデータは直線上に並んでいますね。
手計算とKerasの結果が一致していることが確認できました。
おわりに
というわけで今回は時系列データを取り扱うのが得意なRNNモデルの内部計算をnumpy行列計算のみで再現する方法をご紹介しました。
ライブラリが活用できない環境下でのAI運用の際などにぜひご活用ください。
このように、私のブログでは様々なスキルを紹介しています。
今は仕事中で時間がないかもしれませんが、ぜひ通勤時間中などに他の記事も読んでいただけると嬉しいです。
⇒興味をもった方は【ヒガサラ】で検索してみてください。
確実にスキルアップできるはずです。
最後に、この記事が役に立ったという方は、ぜひ応援よろしくお願いします。
↓ 応援ボタン
にほんブログ村
それではまた!
Follow @HigashiSalary
コメント