TensorFlow.js: Python SavedModel を TensorFlow.js 形式に変換する

1. はじめに

ここまでで、TensorFlow.js で最初の一歩を踏み出し、既製のモデルを試したり、独自のモデルを作成したりすることができました。しかし、Python で最先端の研究が発表され、これがウェブブラウザで実行され、拡張可能な方法で多くの人々の目に触れるようになるのではないかと心配しています。皆様も心当たりはありませんか。もしそうなら、この Codelab がおすすめです。

TensorFlow.js チームは、コマンドライン コンバータを介して SavedModel 形式のモデルを TensorFlow.js に変換する便利なツールを用意しています。これにより、ウェブのリーチとスケールでモデルを楽しむことができます。

学習内容

この Codelab では、TensorFlow.js コマンドライン コンバータを使用して、Python で生成された SavedModel をウェブブラウザでクライアントサイドで実行するために必要な model.json 形式に移植する方法を学びます。

詳細は以下のとおりです。

  • シンプルな Python ML モデルを作成し、TensorFlow.js コンバータが必要とする形式で保存する方法。
  • Python からエクスポートした SavedModel に TensorFlow.js コンバータをインストールして使用する方法。
  • 変換後のファイルを取得し、JS ウェブ アプリケーションで使用する。
  • 問題が発生した場合の対処方法(すべてのモデルが変換されない)と、利用可能なオプションを把握します。

新しくリリースされた研究を活用して、世界中の何百万人もの JS デベロッパーがそのモデルを利用できるようにすることを想像してみてください。あるいは、自分でこれを使用して自分で作成するという人もいるでしょう。複雑な依存関係や環境設定が不要なので、世界中の誰でも、ウェブブラウザで実行すればそれを体験できます。さっそくハッキングを始めましょう。始める

コンバージョンを達成したデータを Google と共有します。

本日学習した内容を使用して、お気に入りのモデルの一部を Python から変換できます。これが成功し、モデルの実際のデモウェブサイトを作成できたら、ソーシャル メディアで #MadeWithTFJS ハッシュタグを付けて Google にタグ付けしてください。あなたのプロジェクトが TensorFlow ブログや、今後のショーと発表のイベントで紹介されるチャンスがあります。もっと素晴らしい研究がウェブに移植され、より多くの人々がそのようなモデルを革新的で創造的な方法で使用できるようになることを願っています。こちらの素晴らしい例をご覧ください。

2. TensorFlow.js とは

1aee0ede85885520.png

TensorFlow.js は、JavaScript が実行可能な場所であればどこでも実行できるオープンソースの ML ライブラリです。Python で記述された元の TensorFlow ライブラリをベースとし、このデベロッパー エクスペリエンスと JavaScript エコシステム用の API セットを再構築することを目的としています。

使用できる場所

JavaScript のポータビリティにより、1 つの言語で記述して、以下のすべてのプラットフォームで簡単に ML を実行できるようになりました。

  • 標準の JavaScript を使用するウェブブラウザのクライアントサイド
  • Node.js を使用したサーバーサイドのデバイスや IoT デバイス(Raspberry Pi など)
  • Electron を使用したデスクトップ アプリ
  • React Native を使用したネイティブ モバイルアプリ

TensorFlow.js は、これらの各環境(CPU や WebGL など、内部で実行できる実際のハードウェアベースの環境)内の複数のバックエンドもサポートしています。「バックエンド」このコンテキストでは、サーバー側の環境を意味するわけではありません。たとえば、実行のバックエンドは WebGL のクライアント側の場合があります)。これは、互換性を確保し、動作の高速化を維持するためです。現在、TensorFlow.js は次のものをサポートしています。

  • デバイスのグラフィック カード(GPU)での WebGL の実行 - GPU アクセラレーションを利用して、より大規模なモデル(サイズが 3 MB 超)を実行する最も高速な方法です。
  • CPU でのウェブ アセンブリ(WASM)の実行 - 古い世代のスマートフォンなど、さまざまなデバイスの CPU パフォーマンスを向上させます。これは小さいモデル(サイズが 3 MB 未満)に適しています。グラフィック プロセッサにコンテンツをアップロードするオーバーヘッドがあるため、WASM では WebGL よりも CPU での実行速度が速くなります。
  • CPU の実行 - 他のどの環境も使用できない場合にフォールバックします。これは 3 つのうち最も遅い方法ですが、常に役立ちます。

注: どのデバイスで実行するかがわかっている場合は、これらのバックエンドのいずれかを強制的に適用するか、指定しない場合は単に TensorFlow.js に処理を任せることもできます。

クライアントサイドの強み

クライアント マシンのウェブブラウザで TensorFlow.js を実行すると、検討に値するいくつかのメリットがあります。

プライバシー

サードパーティのウェブサーバーにデータを送信することなく、クライアント マシン上でデータのトレーニングと分類を行うことができます。GDPR など地域の法律への準拠が求められる場合や、ユーザーが自分のマシンに保存し、第三者に送信してはならないデータを処理する際に、こうした要件が生じる場合もあります。

速度

データをリモート サーバーに送信する必要がないため、推論(データを分類する作業)を高速化できます。さらに、ユーザーがアクセスを許可すれば、デバイスのセンサー(カメラ、マイク、GPS、加速度計など)に直接アクセスできるようになります。

リーチと規模

世界中の誰もが、送信したリンクをワンクリックでクリックし、ブラウザでウェブページを開き、あなたが作成したものを利用できます。CUDA ドライバを使用した複雑なサーバーサイドの Linux セットアップは不要で、ML システムを使用するだけで十分です。

費用

サーバーがないということは、HTML、CSS、JS、モデルファイルをホストするための CDN さえあれば有料です。CDN の費用は、サーバー(場合によってはグラフィック カードが接続されている)を 24 時間 365 日稼働させるよりもはるかに安価です。

サーバーサイドの機能

TensorFlow.js の Node.js 実装を利用すると、次の機能が有効になります。

CUDA のフルサポート

サーバー側でグラフィック カード アクセラレーションを使用するには、NVIDIA CUDA ドライバをインストールして、TensorFlow がグラフィック カードと連携できるようにする必要があります(WebGL を使用するブラウザとは異なり、インストールは不要です)。ただし、CUDA を完全にサポートすることで、グラフィック カードの下位レベルの機能をフルに活用でき、トレーニングと推論にかかる時間を短縮できます。両方とも同じ C++ バックエンドを共有しているため、パフォーマンスは Python TensorFlow 実装と同等です。

モデルサイズ

研究段階の最先端モデルの場合、ギガバイト規模の非常に大規模なモデルを扱っている可能性があります。ブラウザのタブごとのメモリ使用量の制限により、現在、これらのモデルをウェブブラウザで実行することはできません。このような大規模なモデルを実行するには、このようなモデルを効率的に実行するために必要なハードウェア仕様を備えた独自のサーバーで Node.js を使用できます。

IoT

Node.js は Raspberry Pi などの一般的なシングルボード コンピュータでサポートされているため、このようなデバイスでも TensorFlow.js モデルを実行できます。

速度

Node.js は JavaScript で記述されているため、ジャストインタイム コンパイルが有効です。つまり、Node.js を使用すると、実行時に最適化されるため、パフォーマンスが向上することがよくあります。これは特に前処理を行う場合に顕著です。その好例が、こちらのケーススタディで紹介されています。Hugging Face が Node.js を使用して自然言語処理モデルのパフォーマンスを 2 倍に高めた事例が紹介されています。

TensorFlow.js の基本や実行できる場所とメリットについて理解できたところで、実際に TensorFlow.js を使ってみましょう。

3. システムの設定

このチュートリアルでは、Ubuntu を使用します。Ubuntu は、多くの人々に広く使用されている人気の Linux ディストリビューションで、クラウドベースの仮想マシンを使用する場合に、Google Cloud Compute Engine でベースイメージとして利用できます。

執筆時点では、新しい標準 Compute Engine インスタンスを作成するときに Ubuntu 18.04.4 LTS のイメージを選択できます。これが使用するイメージです。もちろん、ご自身のマシンを使用することも、必要に応じて別のオペレーティング システムを使用することもできますが、インストール手順や依存関係はシステムによって異なる場合があります。

TensorFlow をインストールする(Python 版)

さて、あなたは発見した、または作成する予定の既存の Python ベースのモデルを変換しようとしているのではないでしょうか。「SavedModel」をエクスポートする前に、で「SavedModel」を使用できない場合は、インスタンスに Python バージョンの TensorFlow を設定しておく必要があります。はまだダウンロードできません。

上で作成したクラウドマシンに SSH で接続し、ターミナル ウィンドウで次のように入力します。

ターミナル ウィンドウ:

sudo apt update
sudo apt-get install python3

これにより、マシンに Python 3 がインストールされていることを確認できます。TensorFlow を使用するには、Python 3.4 以降をインストールする必要があります。

正しいバージョンがインストールされていることを確認するには、次のコマンドを入力します。

ターミナル ウィンドウ:

python3 --version

Python 3.6.9 などのバージョン番号を示す出力が表示されます。正しく出力され、3.4 を上回っていれば、続行できます。

次に、Python のパッケージ マネージャーである Python 3 用の PIP をインストールして更新します。タイプ:

ターミナル ウィンドウ:

sudo apt install python3-pip
pip3 install --upgrade pip

ここでも、以下を使用して pip3 のインストールを確認できます。

ターミナル ウィンドウ:

pip3 --version

執筆時点では、このコマンドを実行すると pip 20.2.3 がターミナルに出力されます。

TensorFlow をインストールする前に、Python パッケージ「setuptools」が必要です。41.0.0 以降である必要があります次のコマンドを実行して、最新バージョンに更新されていることを確認します。

ターミナル ウィンドウ:

pip3 install -U setuptools

これで、TensorFlow for Python をインストールできます。

ターミナル ウィンドウ:

pip3 install tensorflow

完了するまでにしばらく時間がかかることがあるため、処理が完了するまでお待ちください。

TensorFlow が正しくインストールされているか確認しましょう。現在のディレクトリに test.py という名前の Python ファイルを作成します。

ターミナル ウィンドウ:

nano test.py

nano が開いたら、Python コードを記述して、インストールされている TensorFlow のバージョンを出力します。

test.py:

import tensorflow as tf
print(tf.__version__)

CTRL + O を押してディスクに変更を書き込み、CTRL + X を押して nano エディタを終了します。

この Python ファイルを実行すると、画面に出力される TensorFlow のバージョンを確認できます。

ターミナル ウィンドウ:

python3 test.py

執筆時点では、インストールされている TensorFlow Python のバージョンを示す 2.3.1 がコンソールに出力されています。

4. Python モデルの作成

この Codelab の次のステップでは、シンプルな Python モデルを作成し、このトレーニング済みモデルを「SavedModel」に保存する方法を説明します。TensorFlow.js コマンドラインコンバータで使用できます。この原則は変換しようとしているどの Python モデルでもほぼ同じですが、誰もが理解できるようにこのコードはシンプルに保ちます。

最初のセクションで作成した test.py ファイルを編集し、コードを次のように更新しましょう。

test.py:

import tensorflow as tf
print(tf.__version__)

# Import NumPy - package for working with arrays in Python.
import numpy as np

# Import useful keras functions - this is similar to the
# TensorFlow.js Layers API functionality.
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense

# Create a new dense layer with 1 unit, and input shape of [1].
layer0 = Dense(units=1, input_shape=[1])
model = Sequential([layer0])

# Compile the model using stochastic gradient descent as optimiser
# and the mean squared error loss function.
model.compile(optimizer='sgd', loss='mean_absolute_error')

# Provide some training data! Here we are using some fictional data 
# for house square footage and house price (which is simply 1000x the 
# square footage) which our model must learn for itself.
xs = np.array([800.0, 850.0, 900.0, 950.0, 980.0, 1000.0, 1050.0, 1075.0, 1100.0, 1150.0, 1200.0, 1250.0, 1300.0, 1400.0, 1500.0, 1600.0, 1700.0, 1800.0, 1900.0, 2000.0], dtype=float)

ys = np.array([800000.0, 850000.0, 900000.0, 950000.0, 980000.0, 1000000.0, 1050000.0, 1075000.0, 1100000.0, 1150000.0, 1200000.0,  1250000.0, 1300000.0, 1400000.0, 1500000.0, 1600000.0, 1700000.0, 1800000.0, 1900000.0, 2000000.0], dtype=float)

# Train the model for 500 epochs.
model.fit(xs, ys, epochs=500, verbose=0)

# Test the trained model on a test input value
print(model.predict([1200.0]))

# Save the model we just trained to the "SavedModel" format to the
# same directory our test.py file is located.
tf.saved_model.save(model, './')

このコードは、非常にシンプルな線形回帰をトレーニングして、提供された x(入力)と y(出力)の関係を推定することを学習します。そして、結果として得られたトレーニング済みモデルをディスクに保存します。各行の機能の詳細については、インライン コメントを確認してください。

このプログラムを実行した後(python3 test.py を呼び出して)ディレクトリを確認すると、現在のディレクトリに新しいファイルとフォルダが作成されているはずです。

  • test.py
  • saved_model.pb
  • アセット
  • variables

これで、モデルをブラウザで実行できるように変換するために TensorFlow.js コンバータで使用する必要があるファイルを生成しました。

5. SavedModel から TensorFlow.js 形式に変換する

TensorFlow.js コンバータをインストールする

コンバータをインストールするには、次のコマンドを実行します。

ターミナル ウィンドウ:

pip3 install tensorflowjs

簡単だったね。

上記のウィザード バージョンではなく、コマンドライン コンバータ(tensorflowjs_converter)を使用している場合、次のコマンドを呼び出して、作成した保存済みモデルを変換し、パラメータを明示的にコンバータに渡すことができます。

ターミナル ウィンドウ:

tensorflowjs_converter \
    --input_format=keras_saved_model \
    ./ \
    ./predict_houses_tfjs

何が起きているのでしょうか。まず、インストールした tensorflowjs_converter バイナリを呼び出し、Keras 保存済みモデルを変換するよう指定します。

上記のコード例では、Keras をインポートし、その上位レイヤ API を使用してモデルを作成しています。Python コードで keras を使用しなかった場合は、別の入力形式を使用できます。

  • keras - keras 形式(HDF5 ファイル形式)を読み込む
  • tf_saved_model - keras ではなく TensorFlow Core API を使用するモデルを読み込みます。
  • tf_frozen_model - 固定された重みを含むモデルを読み込みます。
  • tf_hub - TensorFlow Hub から生成されたモデルを読み込みます。

その他のフォーマットについて詳しくは、こちらをご覧ください。

次の 2 つのパラメータで、保存済みモデルが配置されているフォルダを指定します。上のデモでは、現在のディレクトリを指定します。最後に、変換の出力先となるディレクトリを指定します。上記では「predict_houses_tfjs」というフォルダを指定します。確認できます。

上記のコマンドを実行すると、現在のディレクトリに predict_houses_tfjs という名前の新しいフォルダが作成されます。このフォルダには : が含まれています。

  • model.json
  • Group1-shard1of1.bin

これらは、ウェブブラウザでモデルを実行するために必要なファイルです。次のセクションで使用するため、これらのファイルを保存します。

6. 変換したモデルをブラウザで使用する

変換されたファイルをホストする

まず、ウェブサーバー上で生成した model.json ファイルと *.bin ファイルを配置して、ウェブページからアクセスできるようにします。このデモでは、参照しやすいように Glitch.com を使用します。ただし、ウェブ エンジニアリングの経験がある方は、現在の Ubuntu サーバー インスタンスでシンプルな HTTP サーバーを起動して、代わりに簡単な http サーバーを起動することもできます。お好きな声を選んでくださいね。

Glitch にファイルをアップロードする

  1. Glitch.com にログインします。
  2. こちらのリンクを使用して、ボイラープレート TensorFlow.js プロジェクトのクローンを作成します。このファイルには、TensorFlow.js ライブラリをインポートするスケルトン html、css、js ファイルが含まれています。
  3. [アセット] をクリックします。[フォルダ] を選択します。
  4. [アセットをアップロード] をクリックします[group1-shard1of1.bin] を選択して、このフォルダにアップロードします。アップロードが完了すると、25a2251c7f165184.png のようになります。
  5. 先ほどアップロードした group1-shard1of1.bin ファイルをクリックすると、URL をその場所にコピーできます。次に示すように、このパスをコピーします。92ded8d46442c404.png
  6. 次に、ローカルマシン上の任意のテキスト エディタを使用して model.json を編集し、(Ctrl+F キーを使用して)そのどこかに言及されている group1-shard1of1.bin ファイルを検索します。

このファイル名を手順 5 でコピーした URL に置き換えますが、コピーしたパスから不具合が生成される先頭の https://cdn.glitch.com/ は削除します。

編集後は次のようになります(先頭のサーバーパスが削除されているので、アップロードされたファイル名のみが保持されます)。d5a338f2dc1f31d4.png 7.グリッチするには、編集したこの model.json ファイルを保存してアップロードします。アセットをクリックし、[アセットをアップロード] をクリックしてアップロードします。ボタン(重要)。物理的なボタンとドラッグ&ドロップを使わないファイルは、CDN ではなく編集可能なファイルとしてアップロードされます。CDN ファイルは同じフォルダに存在せず、TensorFlow.js が特定のモデルのバイナリ ファイルをダウンロードする際に相対パスが想定されます。正しく設定されていれば、assets フォルダに 51a6dbd5d3097ffc.png の 2 つのファイルが表示されます。

これでこれで、保存したファイルをブラウザで実際のコードとともに使用できるようになりました。

モデルの読み込み

変換されたファイルがホストされたので、これらのファイルを読み込み、それらを使用して予測を行うシンプルなウェブページを作成します。Glitch プロジェクト フォルダで script.js を開き、Glitch でアップロードした model.json ファイルの Glitch.com リンクを指すように const MODEL_URL を変更したら、このファイルの内容を次のように置き換えます。

script.js:

// Grab a reference to our status text element on the web page.
// Initially we print out the loaded version of TFJS.
const status = document.getElementById('status');
status.innerText = 'Loaded TensorFlow.js - version: ' + tf.version.tfjs;

// Specify location of our Model.json file we uploaded to the Glitch.com CDN.
const MODEL_URL = YOUR MODEL.JSON URL HERE! CHANGE THIS!';
// Specify a test value we wish to use in our prediction.
// Here we use 950, so we expect the result to be close to 950,000.
const TEST_VALUE = 950.0

// Create an asynchronous function.
async function run() {
    // Load the model from the CDN.
    const model = await tf.loadLayersModel(MODEL_URL);

    // Print out the architecture of the loaded model.
    // This is useful to see that it matches what we built in Python.
    console.log(model.summary());

    // Create a 1 dimensional tensor with our test value.
    const input = tf.tensor1d([TEST_VALUE]);

    // Actually make the prediction.
    const result = model.predict(input);

    // Grab the result of prediction using dataSync method
    // which ensures we do this synchronously.
    status.innerText = 'Input of ' + TEST_VALUE + 
        'sqft predicted as $' + result.dataSync()[0];
}

// Call our function to start the prediction!
run();

model.json パスを指すように MODEL_URL 定数を変更した後、上記のコードを実行すると、次のような出力が表示されます。

c5e8457213058ec3.png

ウェブブラウザのコンソールを調べる(F12 キーを押してブラウザでデベロッパー ツールを表示する)と、読み込まれたモデルのモデルの説明も確認できます。この説明が出力されます。

35e79d70dbd66f27.png

これを、この Codelab の冒頭で記述した Python コードと比較すると、1 つの密の入力と 1 つのノードを持つ 1 つの Dense レイヤで作成したのと同じネットワークであることを確認できます。

これで、変換済みの Python でトレーニングされたモデルをウェブブラウザで実行しました。

7. 変換されないモデル

場合によっては、あまり一般的でない演算を使用するようにコンパイルされる、より複雑なモデルが変換でサポートされないことがあります。ブラウザベースの TensorFlow.js は TensorFlow を完全に書き換えたものであり、現時点では TensorFlow C++ API が備える低レベルの演算(1,000 程度)をすべてサポートしているわけではありません。ただし、今後成長し、コア演算が安定するにつれて、さらに多くの演算が追加されます。

執筆時点では、保存されたモデルとしてエクスポートされたときにサポートされていない演算を生成する TensorFlow Python の関数として linalg.diag があります。これを使用する保存済みモデルを Python(生成する結果の op をサポートしている)で変換しようとすると、次のようなエラーが表示されます。

5df94fc652393e00.png

赤色でハイライト表示されているのは、linalg.diag 呼び出しがコンパイルされ、MatrixDiagV3 という名前の演算を生成していることです。この演算は、この Codelab の執筆時点では、ウェブブラウザの TensorFlow.js でサポートされていません。

対応方法

方法は次の 2 つです。

  1. TensorFlow.js に欠落している演算を実装します。TensorFlow はオープンソース プロジェクトであり、新しい演算などへのコントリビューションを歓迎します。TensorFlow.js 用の新しいオペレーションの記述に関するこちらのガイドをご覧ください。その場合は、コマンドライン コンバータで Skip_op_check フラグを使用して、このエラーを無視し、どうにかして変換を続けます(この op は、不足している op がサポートされている、作成した TensorFlow.js ビルドの新しいビルドで利用できると想定されます)。
  2. エクスポートした savedmodel ファイルで、Python コードのどの部分でサポートされていないオペレーションが発生しているかを確認します。小さなコードセットでは簡単に特定できますが、より複雑なモデルでは、特定の op を一度 savedmodel ファイル形式で生成した高レベルの Python 関数呼び出しを特定するメソッドがないため、かなりの調査が必要になることがあります。ただし、見つかったら、サポートされている別の方法を使用するように変更できます。

8. 完了

これで、ウェブブラウザで TensorFlow.js を介して Python モデルを使用することができました。

内容のまとめ

この Codelab では、次の方法を学びました。

  1. Python ベースの TensorFlow をインストールする Linux 環境をセットアップする
  2. Python「SavedModel」をエクスポートする
  3. TensorFlow.js コマンドライン コンバータをインストールする
  4. TensorFlow.js コマンドライン コンバータを使用して、必要なクライアント側ファイルを作成します。
  5. 生成されたファイルを実際のウェブ アプリケーションで使用する
  6. コンバージョンに至らないモデルを特定し、今後コンバージョンできるようにするために何を実装する必要があるかを特定します。

次のステップ

#MadeWithTFJS を使って作成したものには必ず Google のタグを付けてください。ソーシャル メディアで紹介されたり、今後の TensorFlow イベントで紹介されたりする可能性があります。何を変換していただけるか、ブラウザでクライアントサイドをお使いいただけることを願っています。

TensorFlow.js のその他の Codelab: 理解を深める

おすすめのウェブサイト