TensorFlow.js + Reactjs でディープラーニングモデルを実装するときのtips

技術備忘録

TensorFlow (Python)で学習したモデルを用いてフロント上で推論を実装しようと考えたのですが、その際に考えたことや実装に当たってのtipsについて備忘録としてまとめておきたいと思います。

スポンサーリンク

システムの構成案

TensorFlowで学習したモデルを利用する方法として以下の3通りを検討しました。

実装方法メリットデメリット
サーバサイドでTensorFlowを実装モデル構造・モデルの重み等の情報を公開する必要がない。TensorFlowを実行するためにメモリをかなり食い、複数接続時の負荷が懸念される
AWS LambdaでAPIを立てる モデル構造・モデルの重み等の情報を公開する必要がない。
TensorFlowとサーバサイドを分けているため、メモリを気にする必要が無い。
コールドスタート時にTensorFlowのロードに時間がかかる。
フロント上でTensorFlow.jsを実装サーバを介さないため応答時間は短く済む。 モデル構造・モデルの重み等の情報を公開してしまう。

上記に加えて推論結果を得るまでの応答時間なども考慮して構成を考える必要があります。

今回はサーバ側の負荷やLambda上でのTensorFlowの起動時間の懸念からフロントでのTensorFlow.jsによる実装を行いたいと思います。

スポンサーリンク

TensorFlow.js + Reactjs

Python上で学習したモデルをReact上で使いたい場合、次の流れで開発することになると思います。

  1. Python上でモデルを作成し、パラメータチューニングし、学習済みモデルを作成
  2. 学習済みモデルをTensorFlowjsで読み込める形式に変換
  3. 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フォルダに置いてあります。

    コメント

    タイトルとURLをコピーしました