はじめに
諸事情により、Pythonで学習させたモデルのCコード化をする必要が出てきたので、まとめる。
とりあえずこのページでは、以下で紹介したLSTMモデルをCコード化するときの過程を紹介する。
前準備
Pythonで学習したモデルをCコード化する場合は、
事前にkeras2cというライブラリをインストールしておく必要がある。
keras2cは、Pythonの他のライブラリと違って、「pip install ~」のノリで取得する感じではないらしい。
インストールしたい場合は、以下のコマンドをコマンドラインで入力しましょう。
git clone https://github.com/f0uriest/keras2c
cd keras2c
pip install -r requirements.txt
↑のコマンドを実行すると、カレントディレクトリに「keras2c」というフォルダが作成されます。この中にkeras2cライブラリの情報がいろいろ入ってると思われます。
で、、、ちょっとめんどくさいんだけど、
実際にこのライブラリを使う際は、毎回、以下のような感じでライブラリのおいてある場所のパスを設定してあげると、使えるようになります。
(使うたびに、↓のおまじないのコードを書いてください。以下の設定は、ちょっと別のことをやるとリセットされます。たぶん、もっといいやり方があるんだと思います。)
# ライブラリのおいてある場所のパスを設定
import sys
sys.path.append('C:\\Python\\Library\\keras2c') #「C:\\Python\\Library\\keras2c」のところは、先ほど作った「keras2c」というフォルダがおいてある場所のパスを設定してください。
※上記コードの「C:\Python\Library\keras2c」のところは、先ほど作った「keras2c」というフォルダがおいてある場所のパスを設定してください。
先日のLSTMモデルをCコード化してみる
では、実際に先日に作ったLSTMモデルをCコード化してみます。
以下のコードを実行すれば、先日のLSTMモデルをCコード化できます。
今回追加した内容は、下のほうにあります。
# 必要なライブラリをインポートする
import numpy as np # 数値計算を効率的に行うためのライブラリ
import matplotlib.pyplot as plt # グラフ描画のためのライブラリ
from keras.models import Sequential # KerasのSequentialモデルを使用するためのインポート
from keras.layers import LSTM, Dense # LSTMとDense層を使用するためのインポート
# データ生成
# 0から100までの等間隔な数列を生成し、サイン関数でデータを生成する
data = np.sin(np.linspace(0, 100, 1000)) # np.linspaceは0から100まで1000分割した数列を生成し、np.sinでその数列のサイン値を計算する
sequence_length = 10 # 一つの入力シーケンスの長さを定義する
# データ準備関数
# 与えられたデータから、LSTMモデルの入力となるシーケンスを準備する
def prepare_sequences(data, sequence_length):
x, y = [], [] # 入力シーケンスと出力値を格納するためのリストを初期化する
# シーケンスの長さだけデータをスライスし、入力と出力を準備する
for i in range(len(data) - sequence_length):
x.append(data[i:i + sequence_length]) # i番目からsequence_length分のデータを取り出し、入力シーケンスとしてxに追加する
y.append(data[i + sequence_length]) # i番目からsequence_lengthを足した位置のデータを取り出し、出力値としてyに追加する
return np.array(x), np.array(y) # xとyをNumPy配列に変換して返す
# 関数を使ってデータを準備する
x, y = prepare_sequences(data, sequence_length) # 上で定義した関数を使って、入力シーケンスと出力値を準備する
# データ分割
# データの80%を訓練用、残りの20%をテスト用に分割する
split_fraction = 0.8 # 分割する割合を定義する
split = int(split_fraction * len(x)) # 実際に分割する位置を計算する
# 訓練データとテストデータに分割する
x_train, x_test = x[:split], x[split:] # 入力シーケンスを訓練用とテスト用に分割する
y_train, y_test = y[:split], y[split:] # 出力値を訓練用とテスト用に分割する
# モデル構築
# Sequentialモデルを使用し、LSTM層とDense層を追加してモデルを構築する
model = Sequential() # Sequentialモデルのインスタンスを作成する
model.add(LSTM(50, activation='relu', input_shape=(sequence_length, 1))) # LSTM層を追加する。50はユニット数、activationは活性化関数、input_shapeは入力の形状を指定する
model.add(Dense(1)) # 出力層としてDense層を追加する。1は出力の次元数を指定する
model.compile(optimizer='adam', loss='mse') # モデルをコンパイルする。optimizerは最適化アルゴリズム、lossは損失関数を指定する
# モデル訓練
# 訓練データを使ってモデルを100エポックで訓練する
model.fit(x_train, y_train, epochs=100, validation_data=(x_test, y_test)) # モデルを訓練する。epochsは訓練の回数、validation_dataは検証用データを指定する
########################ここからが今回追加した内容################################################################################################
# 既存のKerasモデルを保存する
model.save('lstm_model.keras')
# ライブラリのおいてある場所のパスを設定
import sys
sys.path.append('C:\\Python\\Library\\keras2c') #「C:\\Python\\Library\\keras2c」のところは、先ほど作った「keras2c」というフォルダがおいてある場所のパスを設定してください。
# ライブラリのインポート処理
from keras2c import k2c
from keras.models import load_model
# モデルをロード
model = load_model('lstm_model.keras')
# モデルをC言語のコードに変換
k2c(model, 'lstm_c_model', malloc=False, num_tests=10, verbose=True)
結果
実行したら、以下のようなファイルが生成されました。やったね。
とりあえずCコードは生成されましたが、まじで何が書いてあるのかよくわからん。
参考にしたページ