ホーム » TensorFlow.js

TensorFlow.js」カテゴリーアーカイブ

TensorFlow.js : ガイド : Keras ユーザのための TensorFlow.js 層 API


TensorFlow.js : ガイド : Keras ユーザのための TensorFlow.js 層 API (翻訳/解説)

作成 : (株)クラスキャット セールスインフォメーション
日時 : 04/14/2018

* 本ページは、TensorFlow.js サイトの Guides – TensorFlow.js Layers API for Keras Users を翻訳した上で
適宜、補足説明したものです:

* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

TensorFlow.js の層 API は Keras に追随してモデル化されています。貴方がチュートリアルとサンプルから気が付いているかもしれないように、層 API を (JavaScript と Python の間の違いが与えられらたもとで) 合理的に Keras に似せる努力をしています。これは Python で Keras モデルを開発した経験を持つユーザに JavaScript の TensorFlow.js 層へマイグレートすることを容易にします。例えば、次の Keras コードは JavaScript へと翻訳されます :

# Python:
import keras
import numpy as np

# Build and compile model.
model = keras.Sequential()
model.add(keras.layers.Dense(units=1, input_shape=[1]))
model.compile(optimizer='sgd', loss='mean_squared_error')

# Generate some synthetic data for training.
xs = np.array([[1], [2], [3], [4]])
ys = np.array([[1], [3], [5], [7]])

# Train model with fit().
model.fit(xs, ys, epochs=1000)

# Run inference with predict().
print(model.predict(np.array([[5]])))
// JavaScript:
import * as tf from '@tensorlowjs/tfjs';

// Build and compile model.
const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [1]}));
model.compile({optimizer: 'sgd', loss: 'meanSquaredError'});

// Generate some synthetic data for training.
const xs = tf.tensor2d([[1], [2], [3], [4]], [4, 1]);
const ys = tf.tensor2d([[1], [3], [5], [7]], [4, 1]);

// Train model with fit().
await model.fit(xs, ys, {epochs: 1000});

// Run inference with predict().
model.predict(tf.tensor2d([[5]], [1, 1])).print();

けれども、このドキュメントで集めて説明したい幾つかの違いはあります。ひとたびこれらの違いとそれらの背後の理論的根拠を理解すれば、貴方の Python-to-JavaScript マイグレーション (あるいは逆方向のマイグレーション) は比較的スムースな経験になるはずです。

 

コンストラクタは JavaScript オブジェクトをコンフィギュレーションとして取る

上のサンプルからの次の Python と JavaScript 行を比較してください : それらは両者とも Dense 層を作成します。

# Python:
keras.layers.Dense(units=1, inputShape=[1])
// JavaScript:
tf.layers.dense({units: 1, inputShape: [1]});

JavaScript 関数は Python 関数のキーワード引数と同等のものを持ちません。私達はコンストラクタ・オプションを JavaScript の位置引数として実装することは回避したいです、これらは巨大な数のキーワード引数 (e.g., LSTM) を伴うコンストラクタのためには覚えて使用することは特に扱いにくいでしょう。これが JavaScript コンフィギュレーション・オブジェクトを使用する理由です。そのようなオブジェクトは Python キーワード引数と同じレベルの位置普遍性と柔軟性を提供します。

Model クラスの幾つかのメソッド、e.g., Model.compile(), もまた入力として JavaScript コンフィギュレーション・オブジェクトを取ります。けれども、Model.fit(), Model.evaluate() と Model.predict() は少し異なることに留意してください。何故ならばこれらのメソッドは入力として必須の x (特徴) と y (ラベルかターゲット) データを取るからです ; x と y は、キーワード引数の役割を果たすすぐ次のコンフィギュレーション・オブジェクトとは別の位置引数です。例えば :

// JavaScript:
await model.fit(xs, ys, {epochs: 1000});

 

Model.fit() は async

Model.fit() は主要なメソッドで、それを用いてユーザは TensorFlow.js でモデル訓練を遂行します。このメソッドはしばしば長時間実行の可能性があり、数秒または数分間続きます。それ故に、この関数がブラウザで実行されるときにメイン UI スレッドをブロックしない方法で使用されるように JavaScript 言語の async 特徴を活用します。これは async fetch のような、JavaScript の他の潜在的に長時間実行される関数と同様です、async は Python には存在しない構成物であることに注意してください。Keras の fit() メソッドが History オブジェクトを返す一方で、JavaScript における fit() メソッドの相対物は History の Promise を返します、これは (上のサンプル内のように) await されるか then() メソッドで使用されます。

 

TensorFlow.js のために NumPy はありません

Python Keras ユーザは上のサンプルで 2D tensor を生成するような、基本的な数値と配列演算を遂行するためにしばしば NumPy を使用します。

# Python:
xs = np.array([[1], [2], [3], [4]])

TensorFlow.js では、この種の基本的な数値演算はパッケージそれ自身で成されます。例えば :

// JavaScript:
const xs = tf.tensor2d([[1], [2], [3], [4]], [4, 1]);

tf.* 名前空間は配列と行列操作のような線形代数演算のための多数の関数もまた提供します。更なる情報のためには TensorFlow.js Core ドキュメント を見てください。

 

コンストラクタではなく、ファクトリメソッドを使用します

(上のサンプルからの) Python のこの行はコンストラクタ呼び出しです :

# Python:
model = keras.Sequential()

厳密に JavaScript に翻訳された場合、同等なコンストラクタ呼び出しは次のように見えるでしょう :

// JavaScript:
const model = new tf.Sequential();  // !!! DON'T DO THIS !!!

けれども、私達は “new” コンストラクタを使用しないことを決定しました、何故ならば 1) “new” キーワードはコードをより膨らませまて 2) “new” コンストラクタは JavaScript の「バッド・パート」と見做され、潜在的な落とし穴です。

TensorFlow.js でモデルと層を作成するためには、lowerCamelCase 名を持つファクトリメソッドを呼び出します、例えば :

// JavaScript:
const model = tf.sequential();

const layer = tf.layers.batchNormalization({axis: 1});

 

オプション文字列値は lowerCamelCase です、snake_case ではありません

snake case が一般的な (e.g., Keras で) Python と比べて、JavaScript では、シンボル名のために camel case を使用することがより一般的です (e.g., Google JavaScript Style Guide を見てください)。そのようなものとして、次を含むオプションの文字列値のために lowerCamelCase を使用することを決定しました :

  • データフォーマット, e.g., channels_first の代わりに channelsFirst
  • Initializer, e.g., glorot_normal の代わりに glorotNormal
  • 損失とメトリクス, e.g., mean_squared_error の代わりに meanSquaredError, categorical_crossentropy の代わりに categoricalCrossentropy。

例えば、上のサンプル内のように :

// JavaScript:
model.compile({optimizer: 'sgd', loss: 'meanSquaredError'});

モデル・シリアライゼーション デシリアライゼーションについて、安心してください。TensorFlow の内部メカニズムは JSON オブジェクトの snake case が正しく処理されることを保証します、 e.g., Python Keras から事前学習されたモデルをロードするとき。

 

層オブジェクトは apply() で実行します、それらを関数としては呼び出しません

Keras では、層オブジェクトは定義された __call__ メソッドを持ちます。そのためユーザはオブジェクトを関数として呼び出すことにより層のロジックを起動できます、e.g.,

# Python:
my_input = keras.Input(shape=[2, 4])
flatten = keras.layers.Flatten()

print(flatten(my_input).shape)

この Python シンタックス・シュガーは TensorFlow.js では apply() メソッドとして実装されます :

// JavaScript:
const myInput = tf.input{shape: [2, 4]});
const flatten = tf.layers.flatten();

console.log(flatten.apply(myInput).shape);

 

Layer.apply() は具体的な tensor 上で命令型 (eager) 評価をサポートします

現在、Keras では、call メソッドは (Python) TensorFlow の Tensor オブジェクト上で作用するだけで (TensorFlow バックエンドを仮定してます)、これはシンボリックで実際の数値は保持しません。けれども、TensorFlow.js では、層の apply() メソッドはシンボリックと命令型モードの両者で作用できます。apply() が SymbolicTensor (tf.Tesnor の密接な類推) で呼び起こされる場合、戻り値は SymbolicTensor です。これは典型的にはモデル構築の間に起こります。しかし apply() が実際の具体的な Tensor 値で呼び起こされた場合には、それは具体的な Tensor を返します。例えば :

// JavaScript:
const flatten = tf.layers.flatten();

flatten.apply(tf.ones([2, 3, 4])).print();

この特徴は (Python) TensorFlow の Eager Execution の想起 (= reminiscent) です。それは動的ニューラルネットワークを構成するためのドアを開けることに加えて、モデル開発の間より偉大な対話性とデバッグの容易さを与えます。

 

Optimizer は train. 下、optimizers ではありません

Keras では、Optimizer オブジェクトのコンストラクタは keras.optimizers.* 名前空間のもとにあります。TensorFlow.js 層では、Optimizer のファクトリメソッドは tf.train.* 名前空間のもとにあります。
例えば :

# Python:
my_sgd = keras.optimizers.sgd(lr=0.2)
// JavaScript:
const mySGD = tf.train.sgd({lr: 0.2});

 

loadModel() は URL からロードします、HDF5 ファイルではありません

Keras では、モデルは通常は HDF5 (.h5) ファイルとしてセーブされ、これは keras.models.load_model() メソッドを使用して後でロード可能です。メソッドは .h5 ファイルへのパスを取ります。HDF5 はブラウザ-friendly なファイル・フォーマットではありませんので、tf.loadModel() は TensorFlow.js-specific フォーマットを取ります。tf.loadModel() はその入力引数として model.json ファイルを取ります。model.json は tensorflowjs pip パッケージを使用して Keras HDF5 ファイルから変換されます。

// JavaScript:
const model = await tf.loadModel('https://foo.bar/model.json');

tf.loadModel() は tf.Model の Promise を返すことにも注意してください。

 

以上




TensorFlow.js : チュートリアル : TensorFlow SavedModel を TensorFlow.js にインポートする


TensorFlow.js : チュートリアル : TensorFlow SavedModel を TensorFlow.js にインポートする (翻訳/解説)

作成 : (株)クラスキャット セールスインフォメーション
日時 : 04/12/2018

* 本ページは、TensorFlow.js サイトの Tutorials – How to import a TensorFlow SavedModel into TensorFlow.js を翻訳した上で適宜、補足説明したものです:

* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

TensorFlow.js コンバータは事前訓練された TensorFlow SavedModel をブラウザにロードして TensorFlow.js を通して推論を実行するためのオープンソース・ライブラリです。

貴方のモデルをインポートする 2-段階プロセスです :

  1. TensorFlow SavedModel を web friendly フォーマットに変換するために python pip パッケージ。貴方が変換されたモデルを既に持つか、既にホストされたモデル (e.g. MobileNet) を使用している場合には、このステップはスキップしてください。
  2. ロードして推論を実行するための Javascript API (訳注: リンク切れ、おそらくは こちら)。

 

Step 1: SavedModel を web-friendly フォーマットに変換する

TensorFlow.js pip パッケージをインストールします :

  $ pip install tensorflowjs

pip パッケージにより提供されるコンバータ・スクリプトを実行します :

使用方法:

$ tensorflowjs_converter \
    --input_format=tf_saved_model \
    --output_node_names='MobilenetV1/Predictions/Reshape_1' \
    --saved_model_tags=serve
    /mobilenet/saved_model \
    /mobilenet/web_model
位置変数 説明
input_path セーブされたモデル・ディレクトリの完全パス。
output_dir 総ての出力生成物のためのパス。
オプション 説明
–input_format 入力モデルのフォーマット。SavedModel のためには tf_saved_model を使用します。
–output_node_names 出力ノードの名前、カンマで区切られます。
–saved_model_tags ロードする MetaGraphDef のタグ、カンマ区切り形式。デフォルトは serve です。

 

Web-friendly フォーマット

上の変換スクリプトは 3 タイプのファイルを生成します :

  • web_model.pb (the dataflow graph)
  • weights_manifest.json (weight manifest file)
  • group1-shard\*of\* (collection of binary weight files)

例えば、ここに変換されて次の位置でサービス提供されている MobileNet があります。

  https://storage.cloud.google.com/tfjs-models/savedmodel/mobilenet_v1_1.0_224/optimized_model.pb
  https://storage.cloud.google.com/tfjs-models/savedmodel/mobilenet_v1_1.0_224/weights_manifest.json
  https://storage.cloud.google.com/tfjs-models/savedmodel/mobilenet_v1_1.0_224/group1-shard1of5
  ...
  https://storage.cloud.google.com/tfjs-models/savedmodel/mobilenet_v1_1.0_224/group1-shard5of5

 

Step 2: ブラウザ内でロードして実行する

  1. tfjs-converter npm パッケージをインストールします。
    yarn add @tensorflow/tfjs-converter or npm install @tensorflow/tfjs-converter
    
  2. FrozenModel クラス をインスタンス化して推論を実行します。
    import * as tfc from '@tensorflow/tfjs-core';
    import {loadFrozenModel} from '@tensorflow/tfjs-converter';
    
    const MODEL_URL = 'https://.../mobilenet/web_model.pb';
    const WEIGHTS_URL = 'https://.../mobilenet/weights_manifest.json';
    
    const model = await loadFrozenModel(MODEL_URL, WEIGHTS_URL);
    const cat = document.getElementById('cat');
    model.execute({input: tfc.fromPixels(cat)});
    

私達の動作する MobileNet デモ を確かめてください。

貴方のサーバがモデル・ファイルにアクセスするための credentials をリクエストする場合は、オプションの RequestOption param を提供できます。

const model = await loadFrozenModel(MODEL_URL, WEIGHTS_URL,
    {credentials: 'include'});

詳細は fetch() ドキュメント を見てください。

 

サポートされる演算

現在のところ TensorFlow.js は TensorFlow Ops の限定的なセットをサポートするだけです。完全なリスト を見てください。もし貴方のモデルがサポートされていない ops を使用しているのであれば、tensorflowjs_converter スクリプトは失敗して貴方のモデル内のサポートされていない ops のリストを生成します。

 

FAQ

  1. コンバータはどの TensorFlow モデルを現在サポートしていますか?

    画像ベースのモデル (MobileNet, SqueezeNet, 貴方がテストすれば更に追加します) が最もサポートされています。制御フロー ops (e.g. RNNs) を伴うモデルはまだサポートされていません。tensorflowjs_converter スクリプトは貴方が持つモデルを検証してモデル内でサポートされていない ops のリストを示します。どの ops が現在サポートされているかのためには このリスト を見てください。

  2. 巨大な重みを持つモデルは動作しますか?

    ブラウザが 100-500MB モデルのロードをサポートする一方で、ページ・ロード時間、推論時間そしてユーザ経験は素晴らしいものではないでしょう。エッジデバイス (e.g. 電話) のためにデザインされたモデルを使用することを推奨します。これらのモデルは通常は 30 MB よりも小さいです。

  3. モデルと重みファイルはブラウザ内にキャッシュされますか?

    はい、私達は重みを 4 MB チャンクのファイルに分割し、これはブラウザにそれらを自動的にキャッシュすることを可能にします。モデル・アーキテクチャが 4 MB 未満 (殆どのモデルがそうです) である場合、それもまたキャッシュされるでしょう。

  4. それは量子化を伴うモデルをサポートしますか?

    まだです。量子化サポートをまもなく追加することを計画しています。

  5. 推論のための predict() メソッドの最初の呼び出しは、続く呼び出しよりも何故非常に遅いのでしょう?

    最初の呼び出し時はまたモデルのための WebGL シェーダー・プログラムのコンパイル時間も含みます。最初の呼び出し後にはシェーダー・プログラムはキャッシュされ、これは続く呼び出しを遥かに高速にします。モデル・ローディングの完了のすぐ後に、predict メソッドを総てゼロの入力で呼び出すことによりキャッシュをウォームアップすることができます。

 

開発

TensorFlow.js コンバータをソースからビルドするには、プロジェクトを clone して dev 環境を準備する必要があります :

$ git clone https://github.com/tensorflow/tfjs-converter.git
$ cd tfjs-converter
$ yarn # Installs dependencies.

開発のために Visual Studio Code を使用することを推奨します。TSLint VSCode エクステンション と npm clang-format 1.2.2 またそれ以上を自動フォーマッティングのための Clang-Format VSCode と共に確実にインストールしてください。

pull リクエストを提出する前に、コードが総てのテストをパスして lint エラーがないことを確認してください :

$ yarn test
$ yarn lint

テストのサブセットを and/or 特定のブラウザ上で実行するには :

$ yarn test --browsers=Chrome --grep='execute'
 
> ...
> Chrome 64.0.3282 (Linux 0.0.0): Executed 39 of 39 SUCCESS (0.129 secs / 0 secs)

テストを一度実行して karma プロセスを抜けるためには (Windows 上で有用です) :

$ yarn test --single-run
 

以上




TensorFlow.js : チュートリアル : Keras モデルを TensorFlow.js にインポートする


TensorFlow.js : チュートリアル : Keras モデルを TensorFlow.js にインポートする (翻訳/解説)

作成 : (株)クラスキャット セールスインフォメーション
日時 : 04/11/2018

* 本ページは、TensorFlow.js サイトの Tutorials – Importing a Keras model into TensorFlow.js を翻訳した上で
適宜、補足説明したものです:

* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

Keras モデル (典型的には Python API を通して作成されます) は 幾つかのフォーマットの一つ でセーブされます。”whole model” フォーマットは TensorFlow.js 層フォーマットに変換可能で、これは推論や更なる訓練のために TensorFlow.js に直接ロードできます。

ターゲット TensorFlow.js 層フォーマットは model.json ファイルとバイナリ形式のシャードされた重みファイルのセットを含むディレクトリです。model.json ファイルはモデル・トポロジー (aka “architecture” または “graph” : 層とそれらがどのように接続されているかの記述) と重みファイルのマニフェストの両者を含みます。

 

Requirements

変換手続きは Python 環境を必要とします ; 貴方は pipenvvirtualenv を使用して隔離された一つを保持することを望むかもしれません。変換器 (= converter) をインストールするためには pip install tensorflowjs を使用してください。

Keras モデルを TensorFlow.js にインポートすることは 2 段階のプロセスです。最初に、既存の Keras モデルを TF.js 層フォーマットに変換し、それから TensorFlow.js にロードします。

 

Step 1. 既存の Keras モデルを TF.js 層フォーマットに変換する

Keras モデルは通常は model.save(filepath) を通してセーブされます、これはモデル・トポロジーと重みの両者を含む単一の HDF5 (.h5) ファイルです。そのようなファイルを TF.js 層フォーマットに変換するためには、次のコマンドを実行します、ここで path/to/my_model.h5 はソース Keras .h5 ファイルで path/to/tfjs_target_dir は TF.js ファイルのためのターゲット出力ディレクトリです :

tensorflowjs_converter --input_format keras \
                       path/to/my_model.h5 \
                       path/to/tfjs_target_dir

 

Alternative : TF.js 層フォーマットに直接エクスポートするために Python API を使用する

もし貴方が Keras モデルを Python で持つのであれば、それを次のように TensorFlow.js 層フォーマットに直接的にエクスポートできます :

# Python

import tensorflowjs as tfjs

def train(...):
    model = keras.models.Sequential()   # for example
    ...
    model.compile(...)
    model.fit(...)
    tfjs.converters.save_keras_model(model, tfjs_target_dir)

 

Step 2: モデルを TensorFlow.js にロードする

Step 1 で生成した変換されたモデルファイルをサービス提供するためには web サーバを使用します。JavaScript でファイルを取得することを可能にするために、Cross-Origin リソース共有 (Resource Sharing, CORS) が有効になるように貴方のサーバを構成する必要があるかもしれないことに注意してください。

それから model.json ファイルへの URL を提供することによりモデルを TensorFlow.js にロードします :

// JavaScript

import * as tf from '@tensorflow/tfjs';

const model = await tf.loadModel('https://foo.bar/tfjs_artifacts/model.json');

今はモデルは推論、評価、あるいは再訓練のために準備ができています。例えば、ロードされたモデルは予測を行なうために直ちに利用できます :

// JavaScript

const example = tf.fromPixels(webcamElement);  // for example
const prediction = model.predict(example);

TensorFlow.js Examples の多くはこのアプローチを取り、変換されて Google Cloud Storage 上でホストされる事前訓練されたモデルを使用します。

model.json filepath を使用してモデル全体を参照することに注意してください。loadModel(…) は model.json を取得してそれから model.json weight マニフェストで参照されるシャードされた重みファイルを得るために追加の HTTP(S) リクエストを行ないます。このアプローチはこれらのファイルにブラウザ (そして多分インターネット上の追加のキャッシング・サーバ) によりキャッシュされることを可能にします、何故ならば model.json と重みシャードは典型的なキャッシュ・ファイルサイズ制限よりもそれぞれより小さいからです。こうして次の機会にはモデルは多分より迅速にロードされるでしょう。

 

サポートされる特徴

現在 TensorFlow.js 層は標準的な Keras 構成部品を使用する Keras モデルをサポートするだけです。サポートされていない ops や 層 — e.g. カスタム層、Lambda 層、カスタム損失、あるいはカスタム・メトリクス — を使用するモデルは自動的にはインポートできません、何故ならばそれらは確実には JavaScript に翻訳できない Python コードに依存するからです。

 

以上



TensorFlow.js : チュートリアル : MNIST – 畳み込みニューラルネットで手書き数字認識


TensorFlow.js : チュートリアル : MNIST – 畳み込みニューラルネットで手書き数字認識 (翻訳/解説)

作成 : (株)クラスキャット セールスインフォメーション
日時 : 04/04/2018

* 本ページは、TensorFlow.js サイトの Tutorials – Training on Images: Recognizing Handwritten Digits with a Convolutional Neural Network を翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

このチュートリアルでは、手書き数字を畳み込みニューラルネットワークで分類するために TensorFlow.js モデルを構築します。最初に、分類器をそれに何千もの手書き数字画像とそれらのラベルを「見させる」ことによって訓練します。それからそのモデルが決して見ていないテストデータを使用して分類器の精度を評価します。

 

データ

このチュートリアルのためには MNIST 手書きデータセット を使用します。私達が分類するために学習する手書き MNIST 数字はこのように見えます :

データを処理するために、data.js を書きました、これは便宜のために私達が提供する MNIST データセットのホストされたバージョンから MNIST 画像のランダム・バッチを取得するクラス MnistData を含んでいます。

MnistData はデータセット全体を訓練データとテストデータに分割します。モデルを訓練するとき、分類器は訓練セットだけを見るでしょう。モデルを評価するとき、モデルの予測が真新しいデータにどのくらい上手く一般化されるかを見るために、モデルがまだ見ていない、テストセットのデータだけを使用します。

MnistData は2つの public メソッドを持ちます :

  • nextTrainBatch(batchSize): 訓練セットから画像とそれらのラベルのランダム・バッチを返します。
  • nextTestBatch(batchSize): テストセットから画像とそれらのラベルのバッチを返します。

NOTE : MNIST 分類器を訓練するとき、データをランダムにシャッフルすることは重要です、その結果モデルの予測はそれに画像を供給する順序の影響を受けません。例えば、この訓練段階の間にもしモデルに総ての数字 1 を最初に供給したならば、モデルは単純に 1 を予測するように学習するかもしれません (これは損失を最小化するからです)。そしてモデルに 2 だけを供給した場合には、それは単純に 2 だけを予測するように切り替えて決して 1 を予測しないかもしれません (何故ならば、再度、これは画像の新しいセットのために損失を最小化するでしょうから)。モデルは、数字の代表的なサンプルに渡り正確な予測を行なうような学習は決してしないでしょう。

 

モデルを構築する

このセクションでは、畳み込み画像分類器モデルを構築します。それを行なうために、Sequential モデル (モデルの最も単純なタイプ) を使用します、そこでは tensor は一つの層から次へと連続的に渡されます。

最初に、私達の Sequential モデルを tf.sequential でインスタンス化しましょう :

const model = tf.sequential();

モデルを作成した今、それに層を追加しましょう。

 

最初の層を追加する

私達が追加する最初の層は 2-次元畳み込み層です。畳み込みは空間的に不変な変換 (つまり、画像の異なる部分のパターンやオブジェクトが同じように扱われます) を学習するためにフィルタ・ウィンドウを画像に渡りスライドします 。畳み込みについての更なる情報については、この記事 を見てください。

tf.layers.conv2d を使用して 2-D 畳み込み層を作成することができます、これは層の構造を定義する configuration オブジェクトを受け取ります :

model.add(tf.layers.conv2d({
  inputShape: [28, 28, 1],
  kernelSize: 5,
  filters: 8,
  strides: 1,
  activation: 'relu',
  kernelInitializer: 'VarianceScaling'
}));

configuration オブジェクトの各引数を分解しましょう :

  • inputShape. モデルの最初の層に流れ込むデータの shape です。この場合、MNIST サンプルは 28×28-ピクセルの白黒画像です。画像データについての典型的なフォーマットは [row, column, depth] ですので、ここでは [28, 28, 1] の shape を構成することを望みます — 各次元についてのピクセル数のための 28 行と列、そして私達の画像は 1 カラーチャネルだけを持ちますから 1 depth です。
  • kernelSize. 入力データに適用されるスライディング畳み込みフィルタ・ウィンドウのサイズです。ここでは、5 の kernelSize を設定します、これは正方形の、5×5 畳み込みウィンドウを指定します。
  • filters. 入力データに適用するサイズ kernelSize のフィルタ・ウィンドウの数。ここでは、データに 8 フィルタを適用します。
  • strides. スライディング・ウィンドウの「ステップ・サイズ」です — i.e. フィルタが画像に渡り移動するたびに幾つのピクセルをシフトするかです。ここでは、1 のストライドを指定します、これはフィルタが画像に渡り 1 ピクセルのステップでスライドすることを意味します。
  • activation. 畳み込みが完了した後でデータに適用される 活性化関数 です。この場合、Rectified Linear Unit (ReLU) 関数を適用しています、これは ML モデルにおいて非常に一般的な活性化関数です。
  • kernelInitializer. モデル重みをランダムに初期化するために使用されるメソッドで、これは訓練ダイナミクスに非常に重要です。初期化の詳細についてはここでは深入りしませんが、VarianceScaling (ここで使用されます) は一般に良い initializer 選択です。

 

2番目の層を追加する

モデルに2番目の層を追加しましょう : マックスプーリング層で、これは tf.layers.maxPooling2d を使用して作成します。この層は畳み込みからの結果 (活性としても知られます) を各スライディング・ウィンドウについて最大値を計算することによりダウンサンプリングします :

model.add(tf.layers.maxPooling2d({
  poolSize: [2, 2],
  strides: [2, 2]
}));

引数を分解しましょう :

  • poolSize. 入力データに適用されるスライディング・プーリング・ウィンドウのサイズです。ここでは、[2, 2] の poolSize を設定します、これはプーリング層が入力データに 2×2 ウィンドウを適用することを意味します。
  • strides. スライディング・プーリング・ウィンドウの「ステップ・サイズ」です — i.e. ウィンドウが入力データに渡り移動するたびに幾つのピクセルをシフトするかです。ここでは、[2, 2] のストライドを指定します、これはフィルタが水平と垂直方向の両者で画像に渡り 2 ピクセルのステップでスライドすることを意味します。

NOTE: poolSize と strides の両者が 2×2 ですから、プーリング・ウィンドウは完全に非オーバーラッピングです。これはプーリング層が前の層からの活性のサイズを半分にカットすることを意味します。

 

残りの層を追加する

層構造の繰り返しはニューラルネットワークの一般的なパターンです。私達のモデルに2番目の畳み込み層、続いてもう一つのプーリング層を追加しましょう。私達の2番目の畳み込み層ではフィルタの数を 8 から 16 に 2 倍していることに注意してください。また inputShape を指定していないことにも注意しましょう、何故ならばそれは前の層からの出力の shape から推論できるからです :

model.add(tf.layers.conv2d({
  kernelSize: 5,
  filters: 16,
  strides: 1,
  activation: 'relu',
  kernelInitializer: 'VarianceScaling'
}));

model.add(tf.layers.maxPooling2d({
  poolSize: [2, 2],
  strides: [2, 2]
}));

次に、前の層の出力をベクトルに平坦化するために flatten 層を追加しましょう :

model.add(tf.layers.flatten());

最後に、dense 層 (完全結合層としても知られています) を追加しましょう、これは最後の分類を遂行します。dense 層の前の畳み込み + プーリング層のペアの出力を平坦化することはニューラルネットワークのもう一つの一般的なパターンです :

model.add(tf.layers.dense({
  units: 10,
  kernelInitializer: 'VarianceScaling',
  activation: 'softmax'
}));

dense 層に渡される引数を分解してみましょう。

  • units. 出力活性のサイズです。これは最終層で、そして私達は 10-クラス分類タスク (数字 0-9) を行なっていますので、ここでは 10 units を使用します (時に units はニューロン数として参照されますが、その用語は回避します)。
  • kernelInitializer. dense 層のために、畳み込み層のために使用したのと同じ VarianceScaling 初期化ストラテジーを使用します。
  • activation. 分類タスクのための最後の層の活性化関数は通常は softmax です。Softmax は私達の 10-次元出力ベクトルを確率分布に正規化します、その結果 10 クラスの各々のための確率を得ます。

 

モデルを訓練する

実際にモデルの訓練を駆動するためには、optimizer を構築して損失関数を定義する必要があります。また私達のモデルがデータ上でどのくらい上手く遂行するかを計測するために評価メトリックを定義します。

 

Optimizer を定義する

私達の畳み込みニューラルネットワークのためには、確率的勾配降下法 (SGD, stochastic gradient descent) optimizer を 0.15 の学習率で使用します :

const LEARNING_RATE = 0.15;
const optimizer = tf.train.sgd(LEARNING_RATE);

 

損失を定義する

損失関数としては、交差エントロピー (categoricalCrossentropy) を使用します、これは分類タスクを最適化するために一般的に使用されます。categoricalCrossentropy は、私達のモデルの最終層により生成された確率分布と (正しいクラス・ラベルで 1 (100%) を持つ分布となる) ラベルにより与えられる確率分布の間の誤差を測定します。例えば、数字 7 のサンプルに対して次のラベルと予測値が与えられた場合 :

|class | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |----------|---|---|---|---|---|---|---|---|---|---||label | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | |prediction|.1 |.01|.01|.01|.20|.01|.01|.60|.03|.02|

categoricalCrossentropy はもし予測が数字が 7 である高い確率であればより低い損失値を、予測が 7 の低い確率であればより高い損失値を与えます。訓練の間、データセット全体に渡る categoricalCrossentropy を最小化するためにモデルはその内部パラメータを更新します。

 

評価メトリックを定義する

評価メトリックとしては、accuracy を使用します、これは総ての予測から正しい予測のパーセンテージを測定します。

 

モデルをコンパイルする

モデルをコンパイルするためには、optimizer、損失関数そして評価メトリックのリスト (ここでは、単に ‘accuracy’ です) を持つ configuration オブジェクトをそれに渡します :

model.compile({
  optimizer: optimizer,
  loss: 'categoricalCrossentropy',
  metrics: ['accuracy'],
});

 

バッチサイズを configure する

訓練を始める前に、バッチサイズに関連する 2,3 の更なるパラメータを定義する必要があります :

// How many examples the model should "see" before making a parameter update.
const BATCH_SIZE = 64;
// How many batches to train the model for.
const TRAIN_BATCHES = 100;

// Every TEST_ITERATION_FREQUENCY batches, test accuracy over TEST_BATCH_SIZE examples.
// Ideally, we'd compute accuracy over the whole test set, but for performance
// reasons we'll use a subset.
const TEST_BATCH_SIZE = 1000;
const TEST_ITERATION_FREQUENCY = 5;

 

更にバッチ処理とバッチサイズについて

計算を並列化して GPU の能力を完全に利用するために、私達は単一の feed-forward 呼び出しを使用して複数の入力をまとめてバッチ処理してそれらをネットワークを通して供給することを望みます。

私達の計算をバッチ処理するもう一つの理由は最適化の間、幾つかのサンプルからの勾配を平均した後にはじめて内部パラメータを更新することです。これは外れ値のサンプル (e.g., 誤ってラベル付けられた数字) により間違った方向にステップを取ることを回避する助けになります。

入力データをバッチ処理するとき、rank D+1 の tensor を導入します、ここで D は単一の入力の次元です。

前に議論したように、MNIST データセットの単一の画像の次元は [28, 28, 1] です。64 の BATCH_SIZE を設定したとき、一度に 64 画像をバッチ処理しています、これは私達のデータの実際の shape は [64, 28, 28, 1] であることを意味します (バッチは常に最も外側の次元です) 。

NOTE : 最初の conv2d の config の inputShape はバッチサイズ (64) を指定していないことを思い出してください。Configs はバッチサイズ不可知論として書かれていて、その結果それらは任意のサイズのバッチを受け取ることができます。

 

訓練ループをコーディングする

ここに訓練ループのためのコードがあります :

for (let i = 0; i < TRAIN_BATCHES; i++) {
  const batch = data.nextTrainBatch(BATCH_SIZE);
 
  let testBatch;
  let validationData;
  // Every few batches test the accuracy of the mode.
  if (i % TEST_ITERATION_FREQUENCY === 0) {
    testBatch = data.nextTestBatch(TEST_BATCH_SIZE);
    validationData = [
      testBatch.xs.reshape([TEST_BATCH_SIZE, 28, 28, 1]), testBatch.labels
    ];
  }
 
  // The entire dataset doesn't fit into memory so we call fit repeatedly
  // with batches.
  const history = await model.fit(
      batch.xs.reshape([BATCH_SIZE, 28, 28, 1]),
      batch.labels,
      {
        batchSize: BATCH_SIZE,
        validationData,
        epochs: 1
      });

  const loss = history.history.loss[0];
  const accuracy = history.history.acc[0];

  // ... plotting code ...
}

コードを分析してみましょう。最初に、訓練サンプルのバッチを取得します。GPU 並列化を活用してパラメータ更新を行なう前に多くのサンプルからのエビデンスを平均するためにサンプルをバッチ処理することを上から思い出してください :

const batch = data.nextTrainBatch(BATCH_SIZE);

5 ステップ (TEST_ITERATION_FREQUENCY) 毎に、テストセットからの MNIST 画像とそれらの対応するラベルのバッチを含む 2 つの要素の配列、validationData を構築します。このデータをモデルの精度を評価するために使用します :

if (i % TEST_ITERATION_FREQUENCY === 0) {
  testBatch = data.nextTestBatch(TEST_BATCH_SIZE);
  validationData = [
    testBatch.xs.reshape([TEST_BATCH_SIZE, 28, 28, 1]),
    testBatch.labels
  ];
}

model.fit はモデルが訓練されてパラメータが実際に更新される場所です。

NOTE : データセット全体の上で一度に model.fit() を呼び出すことはデータセット全体を GPU にアップロードする結果になるでしょう、これはアプリケーションをフリーズさせかねません。GPU に多すぎるデータをアップロードすることを回避するために、下で示されるように、model.fit() を for ループ内で呼び出し、一度にデータの単一のバッチを渡すことを推奨します :

// The entire dataset doesn't fit into memory so we call fit repeatedly
// with batches.
  const history = await model.fit(
      batch.xs.reshape([BATCH_SIZE, 28, 28, 1]), batch.labels,
      {batchSize: BATCH_SIZE, validationData: validationData, epochs: 1});

引数を再度分解してみましょう :

  • x. 入力画像データです。サンプルをバッチで供給していますので、fit 関数に私達のバッチがどのくらい大きいかを知らせなければならないことを忘れないでください。MnistData.nextTrainBatch は shape [BATCH_SIZE, 784] を持つ画像を返します — 長さ 784 (28 * 28) の 1-D ベクトルにある画像のための総てのデータです。けれども、私達のモデルは shape [BATCH_SIZE, 28, 28, 1] の画像データを想定していますので、それに従って reshape します。
  • y. ラベルです ; 各画像のための正しい数字分類です。
  • batchSize. 各訓練バッチに幾つの画像が含まれるかです。ここで使用するために先に 64 の BATCH_SIZE を設定しています。
  • validationData. TEST_ITERATION_FREQUENCY (ここでは, 5) バッチ毎に構築する検証セットです。このデータは shape [TEST_BATCH_SIZE, 28, 28, 1] にあります。先に、1000 の TEST_BATCH_SIZE を設定しています。評価メトリック (accuracy) はこのデータセットに渡り計算されます。
  • epochs. バッチ上で遂行される訓練実行の数です。fit にバッチを反復的に供給していますので、それに一度にこのバッチから訓練することを望むだけです。

fit を呼び出すたびに、それはメトリクスのログを含む豊かなオブジェクトを返し、これは history にストアしています。各訓練反復のために loss と accuracy を抽出し、グラフ上にそれらをプロットすることができます :

const loss = history.history.loss[0];
const accuracy = history.history.acc[0];

 

結果を見ます!

完全なコードを実行する場合、貴方はこのような出力を見るはずです
(訳注 : 以下の画像は実際の実行結果のスナップショットです) :

画像の殆どについてモデルは正しい数字を予測しているようです。Great work!

 

以上



TensorFlow.js : チュートリアル : 訓練の最初の一歩 : 合成データに曲線をフィットさせる


TensorFlow.js : チュートリアル : 訓練の最初の一歩 : 合成データに曲線をフィットさせる (翻訳/解説)

作成 : (株)クラスキャット セールスインフォメーション
日時 : 04/03/2018

* 本ページは、TensorFlow.js サイトの Tutorials – Training First Steps: Fitting a Curve to Synthetic Data を翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

入力データ

私達の合成データセットは x- と y-座標から成り、これはデカルト平面上でプロットした時に次のように見えます :

このデータは形式 y = ax3 + bx2 + cx + d の3次関数を使用して生成されました。

私達のタスクはこの関数の係数を学習することです : データに最善にフィットする a, b, c, そして d の値です。TensorFlow.js 演算を使用してそれらの値をどのように学習するのかを見てみましょう。

 

Step 1 : Variable をセットアップする

最初に、モデル訓練の各ステップにおけるこれらの値の現在の最善の推定を保持するために幾つか variable を作成しましょう。手始めに、これらの varilable の各々にランダム数を割り当てましょう :

const a = tf.variable(tf.scalar(Math.random()));
const b = tf.variable(tf.scalar(Math.random()));
const c = tf.variable(tf.scalar(Math.random()));
const d = tf.variable(tf.scalar(Math.random()));

 

Step 2: モデルを構築する

TensorFlow.js で私達の多項式関数 y = ax3 + bx2 + cx + d を数学的演算のシリーズを連鎖することにより表わすことができます : 加算 (add), 乗算 (mul), そしてべき乗 (powsquare) です。

次のコードは入力として x を取り y を返す predict 関数を構築します :

function predict(x) {
  // y = a * x ^ 3 + b * x ^ 2 + c * x + d
  return tf.tidy(() => {
    return a.mul(x.pow(tf.scalar(3))) // a * x^3
      .add(b.mul(x.square())) // + b * x ^ 2
      .add(c.mul(x)) // + c
      .add(d);
  });
}

先に進んで私達の多項式関数を Step 1 で設定した a, b, cd のためのランダム値を使用してプロットしましょう。プロットは多分このようなものに見えるでしょう :

ランダム値で開始しましたので、私達の関数はデータセットに対して非常に劣ったフィットになりがちです。モデルはまだ係数についてより良い値を学習しなければなりません。

 

Step 3: モデルを訓練する

私達の最後のステップは係数のために良い値を学習するためにモデルを訓練することです。私達のモデルを訓練するために、3つのことを定義する必要があります :

  • 損失関数、これは与えられた多項式がデータにどのくらい上手くフィットするかを測定します。損失値が低くなればなるほど、多項式はデータにより良くフィットします。
  • optimizer、これは損失関数の出力に基づいて係数値を更新するためのアルゴリズムを実装します。optimizer の目的は損失関数の出力値を最小化することです。
  • 訓練ループ、これは損失を最小化するために optimizer を反復的に実行するでしょう。

 

損失関数を定義する

このチュートリアルのためには、私達の損失関数として平均二乗誤差 (MSE, mean squared error) を使用します。MSE は、データセットの各 x 値に対する実際の y 値と予測された y 値の間の差を二乗し、そして総ての結果の項の平均を取ることで計算されます。

TensorFlow.js では MSE 損失関数は次のように定義できます :

function loss(predictions, labels) {
  // Subtract our labels (actual values) from predictions, square the results,
  // and take the mean.
  const meanSquareError = predictions.sub(labels).square().mean();
  return meanSquareError;
}

 

Optimizer を定義する

私達の optimizer のためには、確率的勾配降下法 (SGD, Stochastic Gradient Descent) を使用します。SGD は、データセットのランダムポイントの 勾配 を取りそしてその値をモデル係数の値を増加させるか減少させるかを伝えるために使用することで動作します。

TensorFlow.js は SGD を遂行するために便利な関数を提供します、そのためこれら総ての数学的演算を貴方自身で遂行する心配する必要はありません。tf.train.sdg は入力として望ましい学習率を取り、そして SGDOptimizer オブジェクトを返します、これは損失関数の値を最適化するために呼び起こされます。

学習率は (モデルの) 予測を改良するときモデルの調整がどのくらい大きいかを制御します。
低い学習率は学習プロセスをよりゆっくりにします (良い係数を学習するためにはより多くの訓練反復が必要とされます)、その一方で高い学習率は学習をスピードアップしますがモデルが正しい値のまわりで振動する、常に過剰修正 (= overcorrecting) する結果になるかもしれません。

次のコードは SGD optimizer を 0.5 の学習率で構築します :

const learningRate = 0.5;
const optimizer = tf.train.sgd(learningRate);

 

訓練ループを定義する

損失関数と optimizer を定義した今、私達は訓練ループを構築できます、これは損失 (MSE) を最小化して私達のモデル係数を洗練するために反復的に SGD を遂行します。私達のループがどのように見えるかがここにあります :

function train(xs, ys, numIterations = 75) {

  const learningRate = 0.5;
  const optimizer = tf.train.sgd(learningRate);

  for (let iter = 0; iter < numIterations; iter++) {
    optimizer.minimize(() => {
      const predsYs = predict(xs);
      return loss(predsYs, ys);
    });
  }
}

コードをより密接に見てみましょう、一歩ずつです。最初に、入力としてデータセットの xy 値、そして指定された反復数を取る訓練関数を定義します :

function train(xs, ys, numIterations) {
...
}

次に、前のセクションで議論したように学習率と SGD optimizer を定義します :

const learningRate = 0.5;
const optimizer = tf.train.sgd(learningRate);

最後に、numIterations 訓練反復を実行する for ループをセットアップします。各反復では、optimizer 上の minimize を呼び起こし、ここが魔法が起こるところです :

for (let iter = 0; iter < numIterations; iter++) {
  optimizer.minimize(() => {
    const predsYs = predict(xs);
    return loss(predsYs, ys);
  });
}

minimize は2つのことを行なう関数を取ります :

  • それは Step 2 で先に定義した predict モデル関数を使用して総ての x 値のために y 値 (predYs) を予測します。
  • それは「損失関数を定義する」で先に定義した損失関数を使用してそれらの予測に対する平均二乗誤差損失を返します。

それから minimize はこの関数で使用される任意の変数 (ここでは、係数 a, b, c, と d) を戻り値 (損失) を最小化するために自動的に調整します。

訓練ループの実行後、a, b, c, と d は SGD の 75 反復後のモデルにより学習された係数値を含みます。

 

結果を見ます!

プログラムの実行がひとたび終了すれば、変数 a, b, c, と d の最終値を取り曲線をプロットするためにそれらを使用できます :

結果は係数のために元々はランダム値を使用してプロットした曲線よりも遥かに良い結果です。

 

以上


TensorFlow.js : チュートリアル : TensorFlow.js の中心概念


TensorFlow.js : チュートリアル : TensorFlow.js の中心概念 (翻訳/解説)

作成 : (株)クラスキャット セールスインフォメーション
日時 : 04/03/2018

* 本ページは、TensorFlow.js サイトの Tutorials – Core Concepts in TensorFlow.js を翻訳した上で
適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

TensorFlow.js は機械知能のためのオープンソースの WebGL で高速化される JavaScripit ライブラリです。それは高性能な機械学習ビルディングブロックを貴方の手元にもたらし、ニューラルネットワークをブラウザで訓練したり事前訓練したモデルを推論モードで実行することを可能にします。

TensorFlow.js は機械学習のための下位ビルディングブロックとニューラルネットワークを構築するための高位の、Keras にインスピレーションを得た API を提供します。ライブラリの中心コンポーネントの幾つかを見てみましょう。

 

Tensor

TensorFlow.js のデータの中心的なユニットは tensor です : 一つまたはそれ以上の次元の配列へ shape された数値のセットです。Tensor インスタンスは配列 shape を定義する shape 属性を持ちます (i.e, 配列の各次元にどれだけの値があるか)。

主要な Tensor コンストラクタは tf.tensor 関数です :

// 2x3 Tensor
const shape = [2, 3]; // 2 rows, 3 columns
const a = tf.tensor([1.0, 2.0, 3.0, 10.0, 20.0, 30.0], shape);
a.print(); // print Tensor values
// Output: [[1 , 2 , 3 ],
//          [10, 20, 30]]

// The shape can also be inferred:
const b = tf.tensor([[1.0, 2.0, 3.0], [10.0, 20.0, 30.0]]);
b.print();
// Output: [[1 , 2 , 3 ],
//          [10, 20, 30]]

けれども、low-rank tensor を構築するためには、コードの可読性を高めるために次の関数を使用することを推奨します : tf.scalar, tf.tensor1d, tf.tensor2d, tf.tensor3dtf.tensor4d

次のサンプルは tf.tensor2d を使用して上の一つと同値な tensor を作成します :

const c = tf.tensor2d([[1.0, 2.0, 3.0], [10.0, 20.0, 30.0]]);
c.print();
// Output: [[1 , 2 , 3 ],
//          [10, 20, 30]]

TensorFlow.js はまた総ての値が 0 に設定されるか (tf.zeros) 総ての値が 1 に設定される (tf.ones) tensor を作成するための便利な関数も提供します :

// 3x5 Tensor with all values set to 0
const zeros = tf.zeros([3, 5]);
// Output: [[0, 0, 0, 0, 0],
//          [0, 0, 0, 0, 0],
//          [0, 0, 0, 0, 0]]

TensorFlow.js では、tensor はイミュータブルです ; ひとたび作成されれば、それらの値を変更することはできません。代わりにそれらの上で新しい tensor を生成する演算を遂行します。

 

Variables (変数)

Variable は tensor の値で初期化されます。けれども Tensor と違い、それらの値はミュータブルです。assign メソッドを使用して既存の variable に新しい tensor を割り当てることができます :

const initialValues = tf.zeros([5]);
const biases = tf.variable(initialValues); // initialize biases
biases.print(); // output: [0, 0, 0, 0, 0]

const updatedValues = tf.tensor1d([0, 1, 0, 1, 0]);
biases.assign(updatedValues); // update values of biases
biases.print(); // output: [0, 1, 0, 1, 0]

Variable は主としてモデル訓練の間に値をストアしてから更新するために使用されます。

 

演算 (Ops)

tensor がデータをストアすることを可能にする一方で、演算 (ops) はそのデータを操作することを可能にします。TensorFlow.js は、tensor 上で遂行可能な、線形代数と機械学習に適切な多種多様の ops を提供します。tensor はイミュータブルですから、これらの ops はそれらの値を変更しません ; 代わりに、ops は新しい tensor を返します。

利用可能な ops は square のような単項 ops を含みます :


const d = tf.tensor2d([[1.0, 2.0], [3.0, 4.0]]);
const d_squared = d.square();
d_squared.print();
// Output: [[1, 4 ],
//          [9, 16]]

そして add, sub, と mul のような二項 ops です :

const e = tf.tensor2d([[1.0, 2.0], [3.0, 4.0]]);
const f = tf.tensor2d([[5.0, 6.0], [7.0, 8.0]]);

const e_plus_f = e.add(f);
e_plus_f.print();
// Output: [[6 , 8 ],
//          [10, 12]]

TensorFlow.js has a chainable API; you can call ops
on the result of ops:

```js
const sq_sum = e.add(f).square();
sq_sum.print();
// Output: [[36 , 64 ],
            [100, 144]]

// All operations are also exposed as functions in the main namespace,
// so you could also do the following:
const sq_sum = tf.square(tf.add(e, f));

 

Model と Layer

概念的には、モデルは、与えられた何某かの入力が何某かの望まれる出力を生成する関数です。

TensorFlow.js ではモデルを作成する2つの方法があります。モデルが行なうワークを表わすために ops を直接的に利用できます。例えば :

/ Define function
function predict(input) {
  // y = a * x ^ 2 + b * x + c
  // More on tf.tidy in the next section
  return tf.tidy(() => {
    const x = tf.scalar(input);

    const ax2 = a.mul(x.square());
    const bx = b.mul(x);
    const y = ax2.add(bx).add(c);

    return y;
  });
}

// Define constants: y = 2x^2 + 4x + 8
const a = tf.scalar(2);
const b = tf.scalar(4);
const c = tf.scalar(8);

// Predict output for input of 2
const result = predict(2);
result.print() // Output: 24

貴方はまた layers (層) からモデルを構築するために高位 API tf.model を利用することもできます、これは深層学習のポピュラーな抽象です。次のコードは tf.sequential モデルを構築します :

const model = tf.sequential();
model.add(
  tf.layers.simpleRNN({
    units: 20,
    recurrentInitializer: 'GlorotNormal',
    inputShape: [80, 4]
  })
);

const optimizer = tf.train.sgd(LEARNING_RATE);
model.compile({optimizer, loss: 'categoricalCrossentropy'});
model.fit({x: data, y: labels)});

TensorFlow.js で利用可能な多くの異なるタイプの layers があります。2, 3 のサンプルは tf.layers.simpleRNN, tf.layers.grutf.layers.lstm を含みます。

 

メモリ管理 : dispose と tf.tidy

TensorFlow.js は数学演算をアクセラレートするために GPU を使用しますので、tensor と variable で作業するとき GPU メモリを管理する必要があります。

TensorFlow.js はこれを手助けするために2つの関数を提供します : dispose と tf.tidy です。

 

dispose

tensor または variable 上でそれをパージしてその GPU メモリを解放するために dispose を呼び出すことができます。

const x = tf.tensor2d([[0.0, 2.0], [4.0, 6.0]]);
const x_squared = x.square();

x.dispose();
x_squared.dispose();

 

tf.tidy

dispose の使用は多くの tensor 演算を行なうときには扱いにくいかもしれません。TensorFlow.js はもう一つの関数, tf.tidy を提供します、これは JavaScript の通常のスコープに対して同様の役割を果たしますが、GPU-backed tensor のためです。

tf.tidy は関数を実行して作成された任意の中間的な tensor をパージし、それらの GPU メモリを解放します。それは内部関数の戻り値はパージしません。

// tf.tidy takes a function to tidy up after
const average = tf.tidy(() => {
  // tf.tidy will clean up all the GPU memory used by tensors inside
  // this function, other than the tensor that is returned.
  //
  // Even in a short sequence of operations like the one below, a number
  // of intermediate tensors get created. So it is a good practice to
  // put your math ops in a tidy!
  const y = tf.tensor1d([1.0, 2.0, 3.0, 4.0]);
  const z = tf.ones([4]);

  return y.sub(z).square().mean();
});

average.print() // Output: 3.5

tf.tidy の使用は貴方のアプリケーションでメモリリークを回避する助けとなるでしょう。それはまたメモリが再利用されるときにより注意深く制御するためにも使用できます。

 

2つの重要なノート

  • tf.tidy に渡される関数は同期的であるべきで Promise を返すべきでもありません。UI の更新やリモート・リクエストを行なうコードは tf.tidy の外側で保持することを提案します。
  • tf.tidy は variable をクリーンアップしないでしょう。Variable は典型的には機械学習モデルのライフサイクル全体を通して存続しますので、TensorFlow.js はそれらが tidy 内で作成された場合でさえもそれらをクリーンアップしません ; けれども、それらの上で dispose を手動で呼び出すことはできます。
 

以上


AI導入支援 #2 ウェビナー

スモールスタートを可能としたAI導入支援   Vol.2
[無料 WEB セミナー] [詳細]
「画像認識 AI PoC スターターパック」の紹介
既に AI 技術を実ビジネスで活用し、成果を上げている日本企業も多く存在しており、競争優位なビジネスを展開しております。
しかしながら AI を導入したくとも PoC (概念実証) だけでも高額な費用がかかり取組めていない企業も少なくないようです。A I導入時には欠かせない PoC を手軽にしかも短期間で認知度を確認可能とするサービの紹介と共に、AI 技術の特性と具体的な導入プロセスに加え運用時のポイントについても解説いたします。
日時:2021年10月13日(水)
会場:WEBセミナー
共催:クラスキャット、日本FLOW(株)
後援:働き方改革推進コンソーシアム
参加費: 無料 (事前登録制)
人工知能開発支援
◆ クラスキャットは 人工知能研究開発支援 サービスを提供しています :
  • テクニカルコンサルティングサービス
  • 実証実験 (プロトタイプ構築)
  • アプリケーションへの実装
  • 人工知能研修サービス
◆ お問合せ先 ◆
(株)クラスキャット
セールス・インフォメーション
E-Mail:sales-info@classcat.com