TensorFlow (Python)で学習したモデルを用いてフロント上で推論を実装しようと考えたのですが、その際に考えたことや実装に当たってのtipsについて備忘録としてまとめておきたいと思います。
システムの構成案
TensorFlowで学習したモデルを利用する方法として以下の3通りを検討しました。
実装方法 | メリット | デメリット |
サーバサイドでTensorFlowを実装 | モデル構造・モデルの重み等の情報を公開する必要がない。 | TensorFlowを実行するためにメモリをかなり食い、複数接続時の負荷が懸念される |
AWS LambdaでAPIを立てる | モデル構造・モデルの重み等の情報を公開する必要がない。 TensorFlowとサーバサイドを分けているため、メモリを気にする必要が無い。 | コールドスタート時にTensorFlowのロードに時間がかかる。 |
フロント上でTensorFlow.jsを実装 | サーバを介さないため応答時間は短く済む。 | モデル構造・モデルの重み等の情報を公開してしまう。 |
上記に加えて推論結果を得るまでの応答時間なども考慮して構成を考える必要があります。
今回はサーバ側の負荷やLambda上でのTensorFlowの起動時間の懸念からフロントでのTensorFlow.jsによる実装を行いたいと思います。
TensorFlow.js + Reactjs
Python上で学習したモデルをReact上で使いたい場合、次の流れで開発することになると思います。
- Python上でモデルを作成し、パラメータチューニングし、学習済みモデルを作成
- 学習済みモデルをTensorFlowjsで読み込める形式に変換
- React上でモデルを読み込み、推論
以下では2,3のやり方について説明したいと思います。
学習済みモデルをTensorflowjsで読み込める形式に変換
学習済みモデルを変換する方法は
- Python内で作成した学習済みの
tf.keras.models.Model
のインスタンスをtfjs.converters.save_keras_model
で変換 - コマンドで
tensorflowjs_converter
を実行
の2通りがあります。どちらの方法を取るにせよPythonにtensorflowjsをインストールします。
pip install tensorflowjs
tf.keras.models.Model
のインスタンスをtfjs.converters.save_keras_model
で変換import tensorflowjs as tfjs
tfjs.converters.save_keras_model(model, 'tfjs')
これにより、学習したmodel
からtfjsフォルダにTensorFlowjsで読み込むのに必要な形式のファイルが作成されます。
- コマンドで
tensorflowjs_converter
を実行
コマンドによる変換のやり方はこちらに説明があります。
tensorflowjs_converter --input_format=keras /tmp/model.h5 /tmp/tfjs_model
TensorFlowjs変換時の注意
以上二通りのやり方を説明しましたが、TensorFlowjs用に変換する際は、Python側でのモデルインスタンスの作成方法に注意しないと変換後のmodel.json
でモデルのアーキテクチャーが書き出されないというトラップがあります!(最初ここではまりました)
以下のようにtf.keras.models.Model
を継承したクラスを作成してモデルの学習を行っていました。
# not suitable way for TensorFlowjs conversion
class MyModel(tf.keras.models.Model):
def __init__(self):
self.dense_layer = Dense(1)
def call(self, inputs):
out = self.dense_layer(inputs[0])
return out
しかしながら、このような形式でモデルを作成すると、model.save()時にアーキテクチャーが保存されないことから、TensorFlowjsへの変換時でもアーキテクチャー部分(modelTopology
)が空になってしまうのです。
TensorFlowjsしたいモデルを作成する際はSequential APIやFunctional APIでモデルを作成するのがよいでしょう。
React上でモデルを読み込み、推論
index.html の <head>に以下のソースを追加する。これによってReact上でwindow.tfとしてTensorFlow.jsを使うことが出来ます。(npm installでも)
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs/dist/tf.min.js"></script>
import React, { useEffect, useState } from 'react';
import * as tf from '@tensorflow/tfjs';
const TFJS = (props) => {
const [tfModel, setTfModel] = useState(null)
const [predicted, setPredicted] = useState(null)
const clickPredict = async () => {
if (tfModel !== null){
let X_tensor = tf.tensor([1,1,1,1,1,1,1]) // sample tensor which does not make sense
let predict = await tfModel.predict(X_tensor)
let predicted_value = await predict.data().then(v=>{ return v[0] })
setPredicted(predicted_value)
}
}
useEffect(()=>{
if (tfModel === null){
window.tf.loadLayersModel('/static/tfjs/model.json')
.then(model=>{
setTfModel(model)
})
}
})
return (
<div>
<div>{predicted === null ? '推定' : predicted}</div>
<button onClick={clickPredict}>Predict</button>
</div>
)
}
export default TFJS
ポイントは、useEffect内で学習済みのモデルをロードすること、推論時にはmodel.predictを実行し、dataメソッドで取り出すというところです。
ロードするモデルは私の場合はサーバサイドがDjangoのため、staticフォルダに置いてあります。
コメント