ホーム » MNIST

MNIST」カテゴリーアーカイブ

TensorFlow : Tutorials : TF Layers へのガイド : CNN を構築する

TensorFlow : Tutorials : TF Layers へのガイド : CNN を構築する (翻訳/解説)

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

* Getting Started / Programmer’s Guide が再構成されましたが、Tutorials でも数編が新規追加されています。
* 本ページは、TensorFlow 本家サイトの Tutorials – A Guide to TF Layers: Building a Convolutional Neural Network
を翻訳した上で適宜、補足説明したものです:

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

 

本文

TensorFlow layers (層) モジュール はニューラルネットワークを構築することを容易にする高位 API を提供します。それは dense (完全結合) 層と畳込み層の作成を容易にし、活性化関数を追加して、そして dropout 正則化を適用するメソッドを提供します。このチュートリアルでは、MNIST データセットの手書き数字を認識するために畳み込みニューラルネットワーク・モデルを layers を使用してどのように構築するかを学習します。

MNIST データセット は手書き数字 0-9 の 60,000 訓練サンプルと 10,000 テスト・サンプルから成り、28×28-ピクセルのモノクローム画像としてフォーマットされています。

 

Getting Started

私達の TensorFlow プログラムのためにスケルトンをセットアップしましょう。cnn_mnist.py と呼ばれるファイルを作成して、次のコードを追加します :

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

# Imports
import numpy as np
import tensorflow as tf

tf.logging.set_verbosity(tf.logging.INFO)

# Our application logic will be added here

if __name__ == "__main__":
  tf.app.run()

チュートリアルを通してワークするとき、畳み込みニューラルネットワークを構築し、訓練し、そして評価するためのコードを追加するでしょう。完全な、最終的なコードは ここで見つかります

 

畳み込みニューラルネットワークへのイントロ

畳み込みニューラルネットワークは画像分類タスクのための現在の最先端モデル・アーキテクチャです。CNN は (モデルが分類のために使用できる) より高位の特徴を抽出して学習するために画像の生ピクセルデータにフィルタのシリーズを適用します。CNN は3つのコンポーネントを含みます :

  • 畳み込み層、これは指定された数の畳み込みフィルタを画像に適用します。各部分領域に対して、層は出力特徴マップの単一の値を生成するために数学演算のセットを遂行します。畳み込み層はそれからモデルに非線形性を導入するために典型的には ReLU 活性化関数 を出力に適用します。
  • プーリング層、これは畳み込み層により抽出された画像データを処理時間を減少させるために特徴マップの次元を削減して ダウンサンプリング します。一般的に使用されるプーリング・アルゴリズムはマックス・プーリングで、これは特徴マップの部分領域 (e.g., 2×2-ピクセル・タイル) を抽出し、それらの最大値を保持して、他の総ての値を捨てます。
  • Dense (完全結合) 層、これは畳み込み層により抽出されてプーリング層によりダウンサンプリングされた特徴上で分類を遂行します。dense 層では、層の総てのノードは前の層の総てのノードに接続されています。

典型的には、CNN は特徴抽出を遂行する畳み込みモジュールのスタックから成ります。各モジュールはプーリング層が続く畳み込み層から成ります。最後の畳み込みモジュールには分類を遂行する一つまたはそれ以上の dense 層が続きます。CNN の最後の dense 層はモデルの各ターゲットクラス (モデルが予測できる可能な総てのクラス) のために単一のノードを含み、各ノードのために 0-1 の間の値を生成するための softmax 活性化関数を持ちます (これらの softmax 値の総計は 1 に等しいです)。与えられた画像に対する softmax 値を画像が各ターゲットクラスに収まる尤度の相対尺度として解釈できます。

Note: CNN アーキテクチャのより包括的なウォークスルーのためには、Visual Recognition コース・マテリアルのための Stanford University の畳み込みニューラルネットワーク を見てください。

 

CNN MNIST 分類器を構築する

次の CNN アーキテクチャを使用して MNIST データセットの画像を分類するためのモデルを構築してみましょう :

  1. Convolutional Layer #1: 32 5×5 フィルタを適用します (5×5-ピクセル部分領域を抽出), with ReLU 活性化関数
  2. Pooling Layer #1: 2×2 フィルタと 2 のストライド (これはプールされる領域がオーバーラップしないことを指定します) を持つマックス・プーリングを遂行します。
  3. Convolutional Layer #2: 64 5×5 フィルタを適用します、with ReLU 活性化関数
  4. Pooling Layer #2: 再度、2×2 フィルタと 2 のストライドを持つマックス・プーリングを遂行します。
  5. Dense Layer #1: 1,024 ニューロン、with dropout 正則化 0.4 のレート (0.4 の確率で任意の与えられた要素が訓練の間にドロップされます)。
  6. Dense Layer #2 (ロジット層): 10 ニューロン、一つが各数字ターゲットクラス (0-9)。

tf.layers モジュールは上の3つの層タイプの各々を作成するためのメソッドを含みます :

  • conv2d(). 2-次元畳み込み層を構築します。引数としてフィルタ数、フィルタ・カーネルサイズ、パディング、そして活性化関数を取ります。
  • max_pooling2d(). マックスプーリング・アルゴリズムを使用する 2-次元プーリング層を構築します。引数としてプーリング・フィルタサイズとストライドを取ります。
  • dense(). dense 層を構築します。引数としてニューロン数と活性化関数を取ります。

これらのメソッドの各々は入力として tensor を受け取って出力として変換された tensor を返します。これは一つの層を他に接続することを容易にします : 一つの層作成メソッドから単に出力を取りそしてそれを他の一つの入力として供給します。

cnn_mnist.py をオープンして次の cnn_model_fn function 関数を追加します、これは TensorFlow の Estimator API (これについては後で詳述) により想定されるインターフェイスに準拠しています。cnn_mnist.py は MNIST 特徴データ、ラベル、そして モデル・モード (TRAIN, EVAL, PREDICT) を引数として取ります ; CNN を構成します ; そして予測、損失、そして訓練演算を返します :

def cnn_model_fn(features, labels, mode):
  """Model function for CNN."""
  # Input Layer
  input_layer = tf.reshape(features["x"], [-1, 28, 28, 1])

  # Convolutional Layer #1
  conv1 = tf.layers.conv2d(
      inputs=input_layer,
      filters=32,
      kernel_size=[5, 5],
      padding="same",
      activation=tf.nn.relu)

  # Pooling Layer #1
  pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)

  # Convolutional Layer #2 and Pooling Layer #2
  conv2 = tf.layers.conv2d(
      inputs=pool1,
      filters=64,
      kernel_size=[5, 5],
      padding="same",
      activation=tf.nn.relu)
  pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)

  # Dense Layer
  pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 64])
  dense = tf.layers.dense(inputs=pool2_flat, units=1024, activation=tf.nn.relu)
  dropout = tf.layers.dropout(
      inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)

  # Logits Layer
  logits = tf.layers.dense(inputs=dropout, units=10)

  predictions = {
      # Generate predictions (for PREDICT and EVAL mode)
      "classes": tf.argmax(input=logits, axis=1),
      # Add `softmax_tensor` to the graph. It is used for PREDICT and by the
      # `logging_hook`.
      "probabilities": tf.nn.softmax(logits, name="softmax_tensor")
  }

  if mode == tf.estimator.ModeKeys.PREDICT:
    return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)

  # Calculate Loss (for both TRAIN and EVAL modes)
  loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)

  # Configure the Training Op (for TRAIN mode)
  if mode == tf.estimator.ModeKeys.TRAIN:
    optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
    train_op = optimizer.minimize(
        loss=loss,
        global_step=tf.train.get_global_step())
    return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)

  # Add evaluation metrics (for EVAL mode)
  eval_metric_ops = {
      "accuracy": tf.metrics.accuracy(
          labels=labels, predictions=predictions["classes"])}
  return tf.estimator.EstimatorSpec(
      mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)

以下のセクション (上の各コードブロックに対応する見出しとともに) では各層を作成するために使用される tf.layers コードに加えて、どのように損失を計算するか、訓練 op を構成するか、そして予測を生成するかについて深く潜ります。貴方が既に CNN と TensorFlow Estimator を経験していて、上のコードを直感的であると見い出すのであれば、これらのセクションは拾い読みして単に (最後のセクションの) “Training and Evaluating the CNN MNIST Classifier” へとスキップしても良いでしょう。

 

入力層

2-次元画像データのための畳み込みとプーリング層を作成する層モジュールのメソッドは入力 tensor がデフォルトでは [batch_size, image_height, image_width, channels] の shape を持つことを想定します。この挙動はdata_format パラメータを使用して変更できます ; 次のように定義されます :

  • batch_size. 訓練の間に勾配降下を遂行するとき使用するサンプルのサブセットのサイズ。
  • image_height. サンプル画像の高さ。
  • image_width. サンプル画像の幅。
  • channels. サンプル画像のカラーチャネル数。カラー画像については、チャネル数は 3 (赤、緑、青)。モノクローム画像については、丁度 1 チャネル (黒) があります。
  • data_format. channels_last (デフォルト) か channels_first の一つの文字列。channels_last は shape (batch, …, channels) を持つ入力に対応する一方で channels_first は shape (batch, channels, …) を持つ入力に対応します。

ここで、MNIST データセットはモノクローム 28×28 ピクセル画像から成りますので、入力層のために望まれる shape は [batch_size, 28, 28, 1] です。

入力特徴マップ (features) をこの shape に変換するためには、次の reshape 演算を遂行できます :

input_layer = tf.reshape(features["x"], [-1, 28, 28, 1])

バッチサイズとして -1 を示したことに注意してください、これはこの次元が (他の次元の定数の総てのサイズを保持しながら) features[“x”] の入力値の数に基づいて動的に計算されるべきであることを指定します。これは batch_size を調整可能なハイパーパラメータとして扱うことを可能にします。例えば、サンプルをモデルにバッチ 5 で供給する場合、features[“x”] は 3,920 値 (各画像の各ピクセルのために 1 値) を含み、そして input_layer は [5, 28, 28, 1] の shape を持つでしょう。同様に、バッチ 100 でサンプルを供給する場合、features[“x”] は 78,400 値を含み、そして input_layer は [100, 28, 28, 1] の shape を持つでしょう。

 

Convolutional Layer #1

最初の畳込み層で、入力層に 32 5×5 フィルタを適用することを望みます、ReLU 活性化関数とともに。この層を作成するために層モジュールの conv2d() メソッドを次のように使用できます。

conv1 = tf.layers.conv2d(
    inputs=input_layer,
    filters=32,
    kernel_size=[5, 5],
    padding="same",
    activation=tf.nn.relu)

入力引数は入力 tensor を指定します、これは shape [batch_size, image_height, image_width, channels] を持たなければなりません。ここで、最初の畳み込み層を入力層に接続しています、これは shape [batch_size, 28, 28, 1] を持ちます。

Note: conv2d() は引数 data_format=channels_first が渡されたときには代わりに [batch_size, channels, image_height, image_width] の shape を受け取るでしょう。

filters 引数は適用するフィルタの数を指定します (ここでは、32)、そして kernel_size はフィルタの次元を [height, width] として指定します (ここでは、[5, 5])。

TIP: フィルタの高さと幅が同じ値を持つ場合、kernel_size のために代わりに単一の整数を指定できます —e.g., kernel_size=5。

padding 引数は2つの列挙値 (case-insensitive) の一つを指定します : valid (デフォルト値) か same です。出力 tensor が入力 tensor と同じ高さと幅を持つことを指定するためには、ここで padding=same を設定します、これは TensorFlow に 28 の高さと幅を保存するために入力 tensor のエッジに 0 値を追加することを命令します。(padding なしでは、28×28 tensor に渡る 5×5 畳み込みは 24×24 tensor を生成します、何故ならば 28×28 グリッドから 5×5 タイルを抽出する 24×24 位置があるからです。)

activation 引数は畳み込みの出力に適用する活性化関数を指定します。ここでは、tf.nn.relu で ReLU 活性を指定します。

conv2d() により生成される出力 tensor は [batch_size, 28, 28, 32] の shape を持ちます : 入力と同じ高さと幅の次元ですが、今ではフィルタの各々からの 32 チャネルが出力を保持しています。

 

Pooling Layer #1

次に、作成したばかりの畳込み層に最初のプーリング層を接続します。2×2 フィルタと 2 のストライドを持つマックスプーリングを遂行する層を構築するために layers の max_pooling2d() メソッドを使用できます :

pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2)

再び、inputs は [batch_size, image_height, image_width, channels] の shape を持つ入力 tensor を指定します。ここで、入力 tensor は conv1、最初の畳み込み層からの出力で、これは [batch_size, 28, 28, 32] の shape を持ちます。

Note: conv2d() と同様に、引数 data_format=channels_first が渡されたとき max_pooling2d() は代わりに [batch_size, channels, image_height, image_width] の shape を受け取ります。

pool_size 引数はマックスプーリング・フィルタのサイズを [height, width] (ここでは、[2, 2]) として指定します。もし両者の次元が同じ値を持つ場合には、代わりに単一の整数 (e.g., pool_size=2) を指定できます。

strides 引数はストライドのサイズを指定します。ここでは、2 のストライドを設定します、これは高さと幅の次元の両者でフィルタで抽出される部分領域が 2 ピクセル隔てられることを示します (2×2 フィルタについては、これは抽出された領域のいずれもがオーバーラップしないことを意味します)。高さと幅のために異なるストライド値を設定することを望む場合、代わりにタプルかリスト (e.g., stride=[3, 6]) を指定できます。

max_pooling2d() (pool1) により生成された出力 tensor は [batch_size, 14, 14, 32] の shape を持ちます : 2×2 フィルタは高さと幅をそれぞれ 50 % 削減します。

 

Convolutional Layer #2 と Pooling Layer #2

前のように conv2d() と max_pooling2d() を使用して2 番目の畳み込みとプーリング層を私達の CNN に接続できます。convolutional layer #2 については、ReLU 活性を伴う 64 5×5 フィルタを構成し、pooling layer #2 については、pooling layer #1 と同じ仕様を使用します (2 のストライドを持つ 2×2 マックスプーリング・フィルタ) :

conv2 = tf.layers.conv2d(
    inputs=pool1,
    filters=64,
    kernel_size=[5, 5],
    padding="same",
    activation=tf.nn.relu)

pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2)

convolutional layer #2 は入力として最初のプーリング層 (pool1) の出力 tensor を取り、出力として tensor conv2 を生成することに注意してください。conv2 は [batch_size, 14, 14, 64] の shape を持ち、pool1 と同じ高さと幅、そして 64 フィルタが適用されるために 64 チャネルです。

Pooling layer #2 は入力として conv2 を取り、出力として pool2 を生成します。pool2 は shape [batch_size, 7, 7, 64] を持ちます (conv2 から高さと幅の 50 % 削減)。

 

Dense Layer

次に、convolution/pooling 層で抽出された特徴上で分類を遂行するために私達の CNN に dense 層 (with 1,024 ニューロンと ReLU 活性) を追加することを望みます。層に接続する前に、けれども、tensor が2つの次元だけを持つように shape [batch_size, features] に特徴マップ (pool2) を平坦化します :

pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 64])

上の reshape() 演算で、-1 は batch_size 次元は入力データのサンプルの数を基に動的に計算されることを表します。各サンプルは 7 (pool2 高さ) * 7 (pool2 幅) * 64 (pool2 チャネル) 特徴を持ちますので、特徴次元に 7 * 7 * 64 (総計で 3136) の値を持つことを望みます。出力 tensor, pool2_flat, は shape [batch_size, 3136] を持ちます。

今では、dense 層に接続するために次のように layers の dense() メソッドを使用できます :

dense = tf.layers.dense(inputs=pool2_flat, units=1024, activation=tf.nn.relu)

inputs 引数は入力 tensor を指定します : 平坦化された特徴マップ, pool2_flat です。units 引数は dense 層のニューロン数を指定します (1,024)。activation 引数は活性化関数を取ります ; 再び、ReLU 活性を追加するために tf.nn.relu を使用します。

モデルの結果を改善する手助けをするために、layers の dropout メソッドを使用して、dense 層に dropout 正則化もまた適用します :

dropout = tf.layers.dropout(
    inputs=dense, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)

再び、inputs は入力 tensor を指定し、これは dense 層 (dense) からの出力 tensor です。

rate 引数は dropout 率を指定します ; ここでは、0.4 を使用します、これは訓練の間に要素の 40 % がランダムにドロップアウトされることを意味します。

training 引数はモデルが現在訓練モードで実行されているか否かを指定する boolean を取ります ; dropout は training が True の場合に遂行されるだけです。ここでは、モデル関数 cnn_model_fn に渡される mode が TRAIN モードであるかをチェックします。

出力 tensor dropout は shape [batch_size, 1024] を持ちます。

 

Logits Layer

私達のニューラルネットワークの最終層は logits 層です、これは予測のために生の値を返します。10 ニューロン (各ターゲットクラス 0-9 のために一つ) で dense 層を作成します、linear 活性 (デフォルト) を伴います。

logits = tf.layers.dense(inputs=dropout, units=10)

CNN の最後の出力 tensor, logits, は shape [batch_size, 10] を持ちます。

 

予測を生成する

モデルの logits 層は [batch_size, 10]-次元 tensor の生の値として予測を返します。これらの生の値をモデル関数が返すことができる2つの異なるフォーマットに変換しましょう :

  • 各サンプルのための 予測されるクラス : 0-9 の数字。
  • 各サンプルのための各可能なターゲットクラスのための 確率 : サンプルが 0 である、1 である、2 である, etc. の確率です。

与えられたサンプルに対して、予測されるクラスは最も高い生の値を持つ logits tensor の対応する行の要素です。tf.argmax 関数を使用してこの要素のインデックスを見つけることができます :

tf.argmax(input=logits, axis=1)

input 引数はそこから最大値を抽出する tensor を指定します — ここでは logits です。axis 引数はそれに沿って最大値を見つける入力 tensor の軸を指定します。ここでは、1 のインデックスを持つ次元に沿った最大値を見つけることを望みます、これは予測に対応します (私達の logits tensor は shape [batch_size, 10] を持つことを思い出してください)。

tf.nn.softmax を使用して softmax 活性を適用することにより logits 層から確率を導出できます :

tf.nn.softmax(logits, name="softmax_tensor")

Note: この演算を softmax_tensor と明示的に命名するために name 引数を使用しますので、後でそれを参照できます (“Set Up a Logging Hook” で softmax 値のために logging をセットアップします)。

予測を辞書にコンパイルして、EstimatorSpec オブジェクトを返します :

predictions = {
    "classes": tf.argmax(input=logits, axis=1),
    "probabilities": tf.nn.softmax(logits, name="softmax_tensor")
}
if mode == tf.estimator.ModeKeys.PREDICT:
  return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)

 

損失を計算する

訓練と評価の両者のために、モデルの予測がターゲット・クラスにどのくらい近いかを測定する 損失関数を定義する必要がありますMNIST のようなマルチクラス分類のためには、典型的には 交差エントロピー が損失メトリックとして使用されます。次のコードはモデルが TRAIN か EVAL モードのいずれかで実行されるとき交差エントロピーを計算します :

onehot_labels = tf.one_hot(indices=tf.cast(labels, tf.int32), depth=10)
loss = tf.losses.softmax_cross_entropy(
    onehot_labels=onehot_labels, logits=logits)

上で何が起きているかをより密接に見てみましょう。

ラベル tensor はサンプル, e.g. [1, 9, …] のための予測のリストを含みます。交差エントロピーを計算するために、最初にラベルを対応する one-hot エンコーディング に変換する必要があります :

[[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
 ...]

この変換を遂行するために tf.one_hot 関数を使用します。tf.one_hot() は2つの必要な引数を持ちます :

  • indices. “on values” を持つ one-hot tensor 内の位置 — i.e., 上で示された tensor 内で 1 値の位置。
  • depth. one-hot tensor の深さ — i.e., ターゲット・クラスの数。ここでは、depth は 10 です。

次のコードは私達のラベル、onehot_labels のための one-hot tensor を作成します :

onehot_labels = tf.one_hot(indices=tf.cast(labels, tf.int32), depth=10)

ラベルは 0-9 からの値のシリーズを含みますので、indices は 整数にキャストされた値を持つ単に私達の labels tensor です。depth は 10 です、何故ならば 10 の可能なターゲット・クラスを持つからです、各数字のために1つ。

次に、onehot_labels と logits 層からの予測の softmax の交差エントロピーを計算します。tf.losses.softmax_cross_entropy() は引数として onehot_labels と logits を取り、logits 上の softmax 活性を遂行し、交差エントロピーを計算し、そして損失をスカラー Tensor として返します :

loss = tf.losses.softmax_cross_entropy(
    onehot_labels=onehot_labels, logits=logits)

 

訓練 Op を構成する

前のセクションでは、CNN のための損失を logits 層とラベルの softmax 交差エントロピーとして定義しました。訓練の間のこの損失値を最適化するモデルを構成しましょう。0.001 の学習率と最適化アルゴリズムとして確率的勾配降下を使用します :

if mode == tf.estimator.ModeKeys.TRAIN:
  optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001)
  train_op = optimizer.minimize(
      loss=loss,
      global_step=tf.train.get_global_step())
  return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)

 

評価メトリクスを追加する

モデルに accuracy メトリックを追加するために、次のように EVAL モードで eval_metric_ops 辞書を定義します :

eval_metric_ops = {
    "accuracy": tf.metrics.accuracy(
        labels=labels, predictions=predictions["classes"])}
return tf.estimator.EstimatorSpec(
    mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)

 

CNN MNIST 分類器を訓練して評価する

MNIST CNN モデル関数をコーディングしました ; 今ではそれを訓練して評価する準備ができています。

 

訓練とテストデータをロードする

最初に、訓練とテストデータをロードしましょう。cnn_mnist.py に次のコードで main() 関数を追加します :

def main(unused_argv):
  # Load training and eval data
  mnist = tf.contrib.learn.datasets.load_dataset("mnist")
  train_data = mnist.train.images # Returns np.array
  train_labels = np.asarray(mnist.train.labels, dtype=np.int32)
  eval_data = mnist.test.images # Returns np.array
  eval_labels = np.asarray(mnist.test.labels, dtype=np.int32)

訓練特徴データ (手書き数字の 55,000 画像のための生ピクセル値) と訓練ラベル (各画像のための 0-9 の対応する値) をそれぞれ train_data と train_labels に numpy 配列 としてストアします。同様に、評価特徴データ (10,000 画像) と評価ラベルをそれぞれ eval_data と eval_labels にストアします。

 

Estimator を作成する

次に、モデルのための Estimator (高位モデル訓練、評価、そして推論を遂行するための TensorFlow クラス) を作成します。main() に次のコードを追加します :

# Create the Estimator
mnist_classifier = tf.estimator.Estimator(
    model_fn=cnn_model_fn, model_dir="/tmp/mnist_convnet_model")

model_fn は訓練、評価、そして予測のために使用するモデル関数を指定します ; それに前のセクションで作成した cnn_model_fn を渡します。model_dir 引数はモデルデータ (チェックポイント) がセーブされるディレクトリを指定します (個々では、temp ディレクトリ /tmp/mnist_convnet_model を指定します、しかし貴方の選択した他のディレクトリに自由に変更してください)。

 

Logging フックをセットアップします

CNN は訓練するのにしばらくかかるかもしれないので、訓練の間に進捗を追跡できるようにあるロギングをセットアップしましょう。CNN の softmax 層からの確率値をログを取る tf.train.LoggingTensorHook を作成するために TensorFlow の tf.train.SessionRunHook を使用できます。次を main() に追加してください :

# Set up logging for predictions
  tensors_to_log = {"probabilities": "softmax_tensor"}
  logging_hook = tf.train.LoggingTensorHook(
      tensors=tensors_to_log, every_n_iter=50)

ログを取りたい tensor の辞書を tensors_to_log にストアします。各キーは選択したラベルでこれはログ出力にプリントされます、そして対応するラベルは TensorFlow グラフの Tensor の名前です。ここでは probabilities は softmax_tensor で見つかります、名前は cnn_model_fn で probabilities を生成したとき softmax 演算子に前に与えています。

Note: name 引数を通して演算子に名前を明示的に割り当てない場合、TensorFlow はデフォルト名を割り当てます。演算子に適用される名前を発見する 2, 3 の簡単な方法は TensorFlow 上でグラフを可視化するか、TensorFlow Debugger (tfdbg) を有効にすることです。

次に、LoggingTensorHook を作成して、tensors_to_log を tensor 引数に渡します。every_n_iter=50 を設定します、これは probabilities が訓練の 50 ステップ毎後にログされるべきであることを指定しています。

 

モデルを訓練する

さてモデルを訓練する準備ができました、これは train_input_fn を作成して mnist_classifier 上で train() を呼び出すことにより行なうことができます。次のコードを main() に追加します :

# Train the model
train_input_fn = tf.estimator.inputs.numpy_input_fn(
    x={"x": train_data},
    y=train_labels,
    batch_size=100,
    num_epochs=None,
    shuffle=True)
mnist_classifier.train(
    input_fn=train_input_fn,
    steps=20000,
    hooks=[logging_hook])

numpy_input_fn 呼び出し内で、訓練特徴データとラベルをそれぞれ (辞書として) x と y として渡します。100 の batch_size を設定します (これはモデルは各ステップで 100 サンプルのミニバッチ上で訓練されることを意味します)。num_epochs=None はモデルは指定されたステップ数に達するまで訓練されることを意味します。訓練データをシャッフルするために shuffle=True も設定します。train 呼び出しでは、steps=20000 を設定します (これはモデルが総計 20,000 ステップのために訓練されることを意味します)。logging_hook を hooks 引数に渡します、訓練の間にそれがトリガーされるように。

 

モデルを評価する

ひとたび訓練が完了したら、MNIST テストセット上でその精度を決定するためにモデルを評価することを望みます。evaluate メソッドを呼び出します、これは model_fn の eval_metric_ops 引数で指定されたメトリクスを評価します。main() に以下を追加します :

# Evaluate the model and print results
eval_input_fn = tf.estimator.inputs.numpy_input_fn(
    x={"x": eval_data},
    y=eval_labels,
    num_epochs=1,
    shuffle=False)
eval_results = mnist_classifier.evaluate(input_fn=eval_input_fn)
print(eval_results)

eval_input_fn を作成するために、num_epochs=1 を設定します、その結果モデルはデータの 1 エポックに渡るメトリクスを評価して結果を返します。データをシーケンシャルに iterate するために shuffle=False も設定します。

 

モデルを実行する

CNN モデル関数、Estimator、そして訓練/評価ロジックをコーディングしました ; 今は結果を見てみましょう。cnn_mnist.py を実行します。

Note: CNN の訓練は非常に計算的に集中的 (= intensive) です。cnn_mnist.py の見積もられる完了時間は貴方のプロセッサに依存して様々ですが、おそらく CPU 上で 1 時間以上でしょう。より迅速に訓練するために、train() に渡される steps の数を減らすことができますが、これは精度に影響することに注意してください。

モデルを訓練するにつれて、次のようなログ出力を見るでしょう :

INFO:tensorflow:loss = 2.36026, step = 1
INFO:tensorflow:probabilities = [[ 0.07722801  0.08618255  0.09256398, ...]]
...
INFO:tensorflow:loss = 2.13119, step = 101
INFO:tensorflow:global_step/sec: 5.44132
...
INFO:tensorflow:Loss for final step: 0.553216.

INFO:tensorflow:Restored model from /tmp/mnist_convnet_model
INFO:tensorflow:Eval steps [0,inf) for training step 20000.
INFO:tensorflow:Input iterator is exhausted.
INFO:tensorflow:Saving evaluation summary for step 20000: accuracy = 0.9733, loss = 0.0902271
{'loss': 0.090227105, 'global_step': 20000, 'accuracy': 0.97329998}

ここで、テストデータセット上で 97.3 % の精度を獲得しました。

 
以上



deeplearn.js : チュートリアル : TensorFlow モデルの移植


deeplearn.js : チュートリアル : TensorFlow モデルの移植

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

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

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

 

本文

このチュートリアルでは訓練と TensorFlow モデルの deeplearn.js への移植をデモします。このチュートリアルで使用されるコードとすべての必要なリソースは demos/mnist にストアされています。

(訳注: 画像はデモ実行時のブラウザ画面のスナップショットです)


MNIST データセットから手書き数字を予想する完全結合ニューラルネットワークを使用します。コードは公式 TensorFlow MNIST チュートリアル から fork されています。

NOTE : deeplearn.js repo のベース・ディレクトリを $BASE として参照します。

最初に、deeplearn.js レポジトリを clone して TensorFlow がインストールされていることを確認します。$BASE 内に cd して以下を実行することでモデルを訓練します :

python demos/mnist/fully_connected_feed.py

訓練は ~1 分かかりそしてモデル・チェックポイントを /tmp/tensorflow/mnist/tensorflow/mnist/logs/fully_connected_feed/ にストアするでしょう。

次に、TensorFlow チェックポイントから deeplearn.js へ重みを移植する必要があります。これを行なうスクリプトを提供しています。それを $BASE ディレクトリから実行します :

python scripts/dump_checkpoint_vars.py --output_dir=demos/mnist/ \
  --checkpoint_file=/tmp/tensorflow/mnist/logs/fully_connected_feed/model.ckpt-1999

(訳注: 以下は dump_checkpoint_vars.py 実行時のコンソールログです : )

Writing variable softmax_linear/biases...
Writing variable softmax_linear/weights...
Writing variable hidden2/weights...
Writing variable hidden1/weights...
Writing variable hidden2/biases...
Writing variable hidden1/biases...
Ignoring global_step
Writing manifest to demos/mnist/manifest.json
Done!

スクリプトはファイルのセット (variable 毎に一つのファイル、そして manifest.json) を demos/mnist ディレクトリに保存します。manifest.json は単なる辞書で variable 名をファイルにそして shape を map します :

{
  ...,
  "hidden1/weights": {
    "filename": "hidden1_weights",
    "shape": [784, 128]
  },
  ...
}

コーディングを開始する前の最後の一つのこと – $BASE ディレクトリから静的 HTTP サーバを実行する必要があります :

npm run prep
./node_modules/.bin/http-server
>> Starting up http-server, serving ./
>> Available on:
>>   http://127.0.0.1:8080
>> Hit CTRL-C to stop the server

ブラウザで http://localhost:8080/demos/mnist/manifest.json を見ることにより HTTP 経由で manifest.json にアクセスできることを確認してください。

幾つかの deeplearn.js コードを書くための準備ができました!

NOTE : TypeScript で書くことを選択した場合、コードを JavaScript にコンパイルして静的 HTTP サーバ経由でそれをサーブすることを確認しましょう。

重みを読みためには、CheckpointLoader を作成してそれが manifest ファイルを指すようにする必要があります。そして loader.getAllVariables() を呼び出します、これは variable 名を NDArray にマップする辞書を返します。その時点で、私たちのモデルを書く準備ができます。CheckpointLoader の使用方法を示すスニペットがここにあります :

import {CheckpointLoader, Graph} from 'deeplearnjs';
// manifest.json is in the same dir as index.html.
const reader = new CheckpointReader('.');  // 訳注: 原文のコード行は誤り、正しくは new CheckpointLoader('.');
reader.getAllVariables().then(vars => {
  // Write your model here.
  const g = new Graph();
  const input = g.placeholder('input', [784]);
  const hidden1W = g.constant(vars['hidden1/weights']);
  const hidden1B = g.constant(vars['hidden1/biases']);
  const hidden1 = g.relu(g.add(g.matmul(input, hidden1W), hidden1B));
  ...
  ...
  const math = new NDArrayMathGPU();
  const sess = new Session(g, math);
  math.scope(() => {
    const result = sess.eval(...);
    console.log(result.getValues());
  });
});

完全なモデル・コードについての詳細は demos/mnist/mnist.ts を見てください。デモは、3つの異なる API を使用する MNIST モデルの正確な実装を提供します :

  • buildModelGraphAPI() は Graph API を使用します、これは TensorFlow API を模倣していて、feed と fetch による遅延実行 (lazy execution) を提供します。ユーザは入力データ以外の GPU 関連のメモリリークを心配する必要はありません。
  • buildModelLayerAPI() は Graph.layers と連動する Graph API を使用します、これは Keras layers API を模倣しています。
  • buildModelMathAPI() は Math API を使用します。これは deeplearn.js の低位 API でユーザに最大限の制御を与えます。Math コマンドは直ちに実行されます、numpy のように。Math コマンドは math.scope() でラップされその結果、中間的な math コマンドで作成された NDArray は自動的にクリーンアップされます。

mnist デモを実行するために、watch-demo スクリプトを提供しています、これは typescript コードを監視してそれが変更された時にリコンパイルします。更に、スクリプトは単純な HTTP サーバを 8080 上で実行します、これは静的な html/js ファイルをサーブします。watch-demo を実行する前に、チュートリアルの前の方で起動した HTTP サーバを 8080 ポートを開放するために必ず kill してください。それから $BASE から web app デモのエントリ・ポイント、demos/mnist/mnist.ts を指すように watch-demo を実行します :

./scripts/watch-demo demos/mnist/mnist.ts
>> Starting up http-server, serving ./
>> Available on:
>>   http://127.0.0.1:8080
>>   http://192.168.1.5:8080
>> Hit CTRL-C to stop the server
>> 1410084 bytes written to demos/mnist/bundle.js (0.91 seconds) at 5:17:45 PM

http://localhost:8080/demos/mnist/ を見てください、demos/mnist/sample_data.json にストアされた 50 mnist 画像のテストセットを使用して計測されたテスト精度 ~90% を示す単純なページを見るはずです。デモで自由に遊んでください (e.g. それを対話的にするとか)、そして pull リクエストを私たちに送ってください!

(訳注 : demos/mnist の実行結果のスナップショットです : )
 

 

以上



TensorFlow: Network-In-Network で CIFAR-10 精度 90%

TensorFlow: Network-In-Network で CIFAR-10 精度 90%
作成 : (株)クラスキャット セールスインフォメーション
日時 : 05/08/2017

 

Network In Network

マイクロ・ネットワークで有名な Network in Network (NiN) は、より小さいモデルでより高速に訓練することを可能とし、over-fitting も比較的起きにくいとされます。多大な影響を与えた epoch-making なモデルです。

その基本アイデアは MLP 畳込み層 (mlpconv) – マイクロ・ネットワーク – の導入とグローバル平均プーリングによる完全結合層の代用ですが、特に前者については広く利用され、類似のアイデアは Inception や ResNet にも見られます。後者は解釈を容易にして over-fitting を起きにくくします。

Network In Network 全体の構成としては mlpconv 層のスタックになり、そのトップにグローバル平均プーリング、更に目的コスト層が存在することになります。イメージと違い、意外にシンプルなモデルです。

参照されることが多いわりにはオリジナル・モデルがそのまま使われることは (知る限りでは) 少ないように思われますが、実装は簡単ですので定番のデータセットで威力を試しておきます。
MNIST、CIFAR-10 及び CIFAR-100 について原論文の結果に匹敵、あるいは凌駕する結果が得られました。CIFAR-10 では精度 90 % に到達します。

Network In Network の原論文は以下です :

  • Network In Network
    Min Lin, Qiang Chen, Shuicheng Yan
    (Submitted on 16 Dec 2013 (v1), last revised 4 Mar 2014 (this version, v3))

Abstract のみ翻訳しておきますが、基本的にはここに書かれていることが全てです :

受容野内のローカルパッチのモデル識別性を強化するために “Network in Network” (NIN) と呼ばれる、新しい深層ネットワーク構造を提案します。従来の畳込み層は入力をスキャンするために、非線形活性化関数が続く線形フィルタを使用します。代わりに、受容野内のデータを抽象化するためにより複雑な構造でマイクロ・ニューラルネットワークを構築します。そのマイクロ・ニューラルネットワークは潜在的な関数近似器である多層パーセプトロンでインスタンス化します。特徴マップは CNN と同様の流儀で入力に渡ってマイクロ・ネットワークをスライドさせることで得られます; そしてそれらは次の層に供給されます。深層 NIN は上で記述された構造を多層化することで実装されます。マイクロ・ネットワークを通したローカルモデリングの強化により、分類層の特徴マップに渡るグローバル平均プーリングを利用することが可能で、これは伝統的な完全結合層よりも解釈がより容易で過剰適合しにくいです。私たちは CIFAR-10 と CIFAR-100 上の NIN で state-of-the-art な分類性能を示し、SVHN と MNIST データセットで合理的な性能を示しました。

実装

実装は簡単ですが、以下の Caffe 実装を参考にしました (というか後者を殆どそのまま TensorFlow に流用しました) :

 

MNIST

手始めに MNIST です。取り敢えず 80 epochs 実行してみましたが、最後の 10 epochs の平均エラー率は 0.393 % で、state of the art に近い精度が出ました (ちなみに原論文のエラー率は 0.47 % ですので、僅かばかり良い結果が得られたことになります)。

 

CIFAR-10

原論文では 91.2 % のようですが、そこまでは出ませんでしたが、400 epochs で 90 % に到達します :

念のため更に 100 epochs 再調整します :

最後の 10 epochs の平均精度は 90.204 でした。時間をかければ 91 % に近い精度は出る感じですが、超えるのは難しそうです。

 

CIFAR-100

続いて CIAR-100 ですが、スクラッチからの訓練ではなく上記の CIFAR-10 の訓練済みのモデルを流用しました。この方法だと 66 % は出ます。原論文の結果は 64.32% です :

 
以上

TensorFlowOnSpark GetStarted EC2 (翻訳・解説)

TensorFlowOnSpark GetStarted EC2 (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
日時 : 02/17/2017

* 本ページは、github TensorFlowOnSpark の GetStarted_EC2 : Running TensorFlowOnSpark on EC2 をベースに実際に実験した上で翻訳して解説を加えたものです :
    https://github.com/yahoo/TensorFlowOnSpark/wiki/GetStarted_EC2

 

EC2 上で TensorFlowOnSpark を実行する

このガイドは 既存の AMI イメージを us-west-2 リージョンで使用して TensorFlowOnSpark を適用するための基本ステップの概要を説明します。

1. standalone Spark クラスタを EC2 上でセットアップ

TFoS AMI で p2.xlarge (1 GPU, 4 vCPUs) 上、 3 スレーブで Spark クラスタを起動するために scripts/spark-ec2 を実行します。TFoS _HOME は TensorFlowOnSpark ソースコードのホームディレクトリを参照することを仮定しています。

* 以下のスクリプトを実行する前に TFoS_HOME の他にも、EC2_KEY(キー名)と EC2_PEM_FILE 変数を設定して export しておきましょう。

export AMI_IMAGE=ami-f6d25596
export EC2_REGION=us-west-2
export EC2_ZONE=us-west-2a
export SPARK_WORKER_INSTANCES=3
export EC2_INSTANCE_TYPE=p2.xlarge  
export EC2_MAX_PRICE=0.8
${TFoS_HOME}/scripts/spark-ec2 \
    --key-pair=${EC2_KEY} --identity-file=${EC2_PEM_FILE} \
        --region=${EC2_REGION} --zone=${EC2_ZONE} \
        --ebs-vol-size=50 \
        --instance-type=${EC2_INSTANCE_TYPE} \
        --master-instance-type=${EC2_INSTANCE_TYPE} \
        --ami=${AMI_IMAGE}  -s ${SPARK_WORKER_INSTANCES} \
        --spot-price ${EC2_MAX_PRICE} \
        --copy-aws-credentials \
        --hadoop-major-version=yarn --spark-version 1.6.0 \
        --no-ganglia \
        --user-data ${TFoS_HOME}/scripts/ec2-cloud-config.txt \
        launch TFoSdemo

上のスクリプトを実行すると、以下のように直ちにクラスタの構築が開始されます :

Warning: Unrecognized EC2 instance type for instance-type: p2.xlarge
Warning: Unrecognized EC2 instance type for master-instance-type: p2.xlarge
Setting up security groups...
Searching for existing cluster TFoSdemo in region us-west-2...
Launching instances...
Requesting 3 slaves as spot instances with price $0.800
Waiting for spot instances to be granted...
All 3 slaves granted
Launched master in us-west-2a, regid = r-0963a9d66d2d84831
Waiting for AWS to propagate instance metadata...
Waiting for cluster to enter 'ssh-ready' state....

* p2.xlarge を Unrecognized EC2 instance type とする警告が出ますが、実際には問題なく p2.xlarge インスタンスが起動されました。
* ssh-ready ステート待ちで 5 分ほど時間がかかります。最終的に 10 分ほどで作業が完了しました。

最後に次の例のような行が見られます、これは Spark マスタのホスト名を含みます。

Spark standalone cluster started at http://ec2-52-49-81-151.us-west-2.compute.amazonaws.com:8080
Done!

2. Spark マスタ上への ssh

ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i ${EC2_PEM_FILE} root@<SPARK_MASTER_HOST>

実際にログインして OS を確認してみたところ、Ubuntu 16.04.1 LTS が使用されていました :

# cat /etc/os-release 
NAME="Ubuntu"
VERSION="16.04.1 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.1 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial

3. MNIST ファイルを TensorFlow Record フォーマットに変換する

次の Spark コマンドを、MNIST データファイルを TensorFlow Record フォーマットに変換して HDFS ファイルシステムにストアするために実行します。
* ${TFoS_HOME} は “/root/TensorFlowOnSpark” に設定されています。

pushd ${TFoS_HOME}
spark-submit --master local[4] \
--jars ${TFoS_HOME}/tensorflow-hadoop-1.0-SNAPSHOT.jar \
--conf spark.executorEnv.LD_LIBRARY_PATH="/usr/local/cuda/lib64" \
--driver-library-path="/usr/local/cuda/lib64" \
${TFoS_HOME}/examples/mnist/mnist_data_setup.py \
--output mnist/tfr \
--format tfr
popd
hadoop fs -ls mnist/tfr

3m40.774s で変換完了しました、HDFS 上のファイルを確認しておきましょう :

# hadoop fs -ls mnist/tfr
Found 2 items
drwxr-xr-x   - root supergroup          0 2017-02-16 16:55 mnist/tfr/test
drwxr-xr-x   - root supergroup          0 2017-02-16 16:54 mnist/tfr/train

# hadoop fs -ls mnist/tfr/train
Found 11 items
-rw-r--r--   3 root supergroup          0 2017-02-16 16:54 mnist/tfr/train/_SUCCESS
-rw-r--r--   3 root supergroup    4865957 2017-02-16 16:53 mnist/tfr/train/part-r-00000
-rw-r--r--   3 root supergroup    5853920 2017-02-16 16:53 mnist/tfr/train/part-r-00001
-rw-r--r--   3 root supergroup    5844694 2017-02-16 16:53 mnist/tfr/train/part-r-00002
-rw-r--r--   3 root supergroup    5851485 2017-02-16 16:53 mnist/tfr/train/part-r-00003
-rw-r--r--   3 root supergroup    5844411 2017-02-16 16:54 mnist/tfr/train/part-r-00004
-rw-r--r--   3 root supergroup    5824177 2017-02-16 16:54 mnist/tfr/train/part-r-00005
-rw-r--r--   3 root supergroup    5843674 2017-02-16 16:54 mnist/tfr/train/part-r-00006
-rw-r--r--   3 root supergroup    5835612 2017-02-16 16:54 mnist/tfr/train/part-r-00007
-rw-r--r--   3 root supergroup    5833012 2017-02-16 16:54 mnist/tfr/train/part-r-00008
-rw-r--r--   3 root supergroup    5444489 2017-02-16 16:54 mnist/tfr/train/part-r-00009

# hadoop fs -ls mnist/tfr/test
Found 11 items
-rw-r--r--   3 root supergroup          0 2017-02-16 16:55 mnist/tfr/test/_SUCCESS
-rw-r--r--   3 root supergroup     944145 2017-02-16 16:55 mnist/tfr/test/part-r-00000
-rw-r--r--   3 root supergroup     941762 2017-02-16 16:55 mnist/tfr/test/part-r-00001
-rw-r--r--   3 root supergroup     944395 2017-02-16 16:55 mnist/tfr/test/part-r-00002
-rw-r--r--   3 root supergroup     944966 2017-02-16 16:55 mnist/tfr/test/part-r-00003
-rw-r--r--   3 root supergroup     944537 2017-02-16 16:55 mnist/tfr/test/part-r-00004
-rw-r--r--   3 root supergroup     956450 2017-02-16 16:55 mnist/tfr/test/part-r-00005
-rw-r--r--   3 root supergroup     961667 2017-02-16 16:55 mnist/tfr/test/part-r-00006
-rw-r--r--   3 root supergroup     964471 2017-02-16 16:55 mnist/tfr/test/part-r-00007
-rw-r--r--   3 root supergroup     964857 2017-02-16 16:55 mnist/tfr/test/part-r-00008
-rw-r--r--   3 root supergroup     955109 2017-02-16 16:55 mnist/tfr/test/part-r-00009

4. MNIST モデルをトレーニングする

HDFS フォルダ /user/root/mnist/tfr/train にある mnist データセットを使用して DNN モデルをトレーニングしてテストします。

pushd ${TFoS_HOME}/src
zip -r ${TFoS_HOME}/tfspark.zip *
popd

#adjust these setting per instance types
#Instance type: p2.8xlarge
#export NUM_GPU=8
#export CORES_PER_WORKER=32
#Instance type: p2.xlarge
export NUM_GPU=1
export CORES_PER_WORKER=4

export SPARK_WORKER_INSTANCES=3
export TOTAL_CORES=$((${CORES_PER_WORKER}*${SPARK_WORKER_INSTANCES}))
export MASTER=spark://$(hostname):7077

spark-submit --master ${MASTER} \
--conf spark.cores.max=${TOTAL_CORES} \
--conf spark.task.cpus=${CORES_PER_WORKER} \
--py-files ${TFoS_HOME}/tfspark.zip,${TFoS_HOME}/examples/mnist/tf/mnist_dist.py \
--conf spark.executorEnv.LD_LIBRARY_PATH="/usr/local/cuda/lib64:$JAVA_HOME/jre/lib/amd64/server:$HADOOP_HOME/lib/native" \
--conf spark.executorEnv.JAVA_HOME="$JAVA_HOME" \
--conf spark.executorEnv.HADOOP_HDFS_HOME=”$HADOOP_HOME” \
--conf spark.executorEnv.CLASSPATH=$($HADOOP_HOME/bin/hadoop classpath --glob) \
--driver-library-path="/usr/local/cuda/lib64" \
${TFoS_HOME}/examples/mnist/tf/mnist_spark.py \
--cluster_size ${SPARK_WORKER_INSTANCES} \
--images mnist/tfr/train --format tfr \
--mode train --model mnist_model --tensorboard

トレーニングされたモデルとそのチェックポイントは HDFS 上に置かれます。

4m22.633s でトレーニングが完了しました。他のクラスタ環境と比較してみないと妥当な数字かは判断つきませんが、チェックポイントは作成されています :

# hadoop fs -ls /user/root/mnist_model
Found 17 items
-rw-r--r--   3 root supergroup        265 2017-02-16 17:02 /user/root/mnist_model/checkpoint
-rw-r--r--   3 root supergroup     142712 2017-02-16 17:00 /user/root/mnist_model/graph.pbtxt
-rw-r--r--   3 root supergroup     814164 2017-02-16 17:02 /user/root/mnist_model/model.ckpt-385.data-00000-of-00001
-rw-r--r--   3 root supergroup        372 2017-02-16 17:02 /user/root/mnist_model/model.ckpt-385.index
-rw-r--r--   3 root supergroup      56854 2017-02-16 17:02 /user/root/mnist_model/model.ckpt-385.meta
-rw-r--r--   3 root supergroup     814164 2017-02-16 17:02 /user/root/mnist_model/model.ckpt-512.data-00000-of-00001
-rw-r--r--   3 root supergroup        372 2017-02-16 17:02 /user/root/mnist_model/model.ckpt-512.index
-rw-r--r--   3 root supergroup      56854 2017-02-16 17:02 /user/root/mnist_model/model.ckpt-512.meta
-rw-r--r--   3 root supergroup     814164 2017-02-16 17:02 /user/root/mnist_model/model.ckpt-634.data-00000-of-00001
-rw-r--r--   3 root supergroup        372 2017-02-16 17:02 /user/root/mnist_model/model.ckpt-634.index
-rw-r--r--   3 root supergroup      56854 2017-02-16 17:02 /user/root/mnist_model/model.ckpt-634.meta
-rw-r--r--   3 root supergroup     814164 2017-02-16 17:02 /user/root/mnist_model/model.ckpt-762.data-00000-of-00001
-rw-r--r--   3 root supergroup        372 2017-02-16 17:02 /user/root/mnist_model/model.ckpt-762.index
-rw-r--r--   3 root supergroup      56854 2017-02-16 17:02 /user/root/mnist_model/model.ckpt-762.meta
-rw-r--r--   3 root supergroup     814164 2017-02-16 17:02 /user/root/mnist_model/model.ckpt-889.data-00000-of-00001
-rw-r--r--   3 root supergroup        372 2017-02-16 17:02 /user/root/mnist_model/model.ckpt-889.index
-rw-r--r--   3 root supergroup      56854 2017-02-16 17:02 /user/root/mnist_model/model.ckpt-889.meta

Spark の UI ももちろん確認できます :

4. MNIST モデルを使用して Image 推論を実行する

次のコマンドを実行するだけです、環境変数はトレーニング時と同じです。

spark-submit --master ${MASTER} \
--conf spark.cores.max=${TOTAL_CORES} \
--conf spark.task.cpus=${CORES_PER_WORKER} \
--py-files ${TFoS_HOME}/tfspark.zip,${TFoS_HOME}/examples/mnist/tf/mnist_dist.py \
--conf spark.executorEnv.LD_LIBRARY_PATH="/usr/local/cuda/lib64:$JAVA_HOME/jre/lib/amd64/server:$HADOOP_HOME/lib/native" \
--conf spark.executorEnv.JAVA_HOME="$JAVA_HOME" \
--conf spark.executorEnv.HADOOP_HDFS_HOME=”$HADOOP_HOME” \
--conf spark.executorEnv.CLASSPATH=$($HADOOP_HOME/bin/hadoop classpath --glob) \
--driver-library-path="/usr/local/cuda/lib64" \
${TFoS_HOME}/examples/mnist/tf/mnist_spark.py \
--cluster_size ${SPARK_WORKER_INSTANCES} \
--images mnist/tfr/test \
--mode inference \
--model mnist_model \
--output predictions

1m10.731s で完了です。
ここで予測結果を吟味できます: 元のラベル vs. 予測です。

# hadoop fs -ls  /user/root/predictions/
Found 2 items
-rw-r--r--   3 root supergroup      20000 2017-02-16 17:11 /user/root/predictions/part-00001
-rw-r--r--   3 root supergroup      20000 2017-02-16 17:11 /user/root/predictions/part-00002

# hadoop fs -cat  /user/root/predictions/* | head -n 20
7 7
2 2
1 1
0 0
4 4
1 1
4 4
9 9
5 6
9 9
0 0
6 6
9 9
0 0
1 1
5 5
9 9
7 7
3 3
4 4

5. Jupyter Notebook による対話的な学習

IPython Notebook に必要な追加のソフトウェアをインストールします。

pip install jupyter jupyter[notebook] 

マスター・ノードで IPython notebook を起動します。

pushd ${TFoS_HOME}/examples/mnist
PYSPARK_DRIVER_PYTHON="jupyter" \
PYSPARK_DRIVER_PYTHON_OPTS="notebook --no-browser --ip=`hostname`" \
pyspark  --master ${MASTER} \
--conf spark.cores.max=${TOTAL_CORES} \
--conf spark.task.cpus=${CORES_PER_WORKER} \
--py-files ${TFoS_HOME}/tfspark.zip,${TFoS_HOME}/examples/mnist/tf/mnist_dist.py \
--conf spark.executorEnv.LD_LIBRARY_PATH="/usr/local/cuda/lib64:$JAVA_HOME/jre/lib/amd64/server:$HADOOP_HOME/lib/native" \
--conf spark.executorEnv.JAVA_HOME="$JAVA_HOME" \
--conf spark.executorEnv.HADOOP_HDFS_HOME=”$HADOOP_HOME” \
--conf spark.executorEnv.CLASSPATH=$($HADOOP_HOME/bin/hadoop classpath --glob) \
--driver-library-path="/usr/local/cuda/lib64" 

サンプルノートブックを上の pyspark コマンドで与えられたセキュリティトークンと一緒に起動します :

http://<MASTER_HOST>:8888/notebooks/TFOS_demo.ipynb

以下は実際に接続した Jupyter notebook の画面です。
一応全部のセルを通して実行してみましたが、特に問題なく完了しました。
 

 
以下は全体画面です :

6. Spark クラスタを Destroy する

以下のコマンドでクラスタは terminate されます。

${TFoS_HOME}/scripts/spark-ec2 \
        --key-pair=${EC2_KEY} --identity-file=${EC2_PEM_FILE} \
        --region=${EC2_REGION} --zone=${EC2_ZONE} \
        destroy TFoSdemo
 

以上

TensorFlow で CNN AutoEncoder – MNIST –

TensorFlow で CNN AutoEncoder – MNIST –

AutoEncoder はモデルの事前トレーニングをはじめとして様々な局面で必要になりますが、基本的には Encoder となる積層とそれを逆順に積み重ねた Decoder を用意するだけですので TensorFlow で簡単に実装できます。

今回は MNIST を題材として最初に MLP ベースの AutoEncoder を復習した後に、畳込み AutoEncoder (Convolutional AutoEncoder) を実装し、encode された特徴マップを視覚化し、decode された画像を元画像と比較してみます。

TensorFlow で MLP AutoEncoder

MLP ベースの AutoEncoder の実装は非常に簡単です。
完全結合層を並べて encoder とし、逆順の積層を decoder とするだけです。

以下の例では単純化のために encoder を1層のみとし、元画像と decode された画像を比較してみます :

【元サンプル画像】
サンプル画像は MNIST のテスト用画像を頭から 40 個集めたものです :
ae_mlp_mnist_list_samples.01

【1 epoch】
1 epoch 後の decode された画像。
一応それらしい画像は出力されていますが、薄ぼんやりしていて分かりにくいです :
ae_mlp_mnist_list_decoded.01

【1 epoch(明るさ・輝度調整)】
明るさと輝度を調整してみました。元画像と比べると数字を構成する骨格自体が異なっているものも目立ちます :
ae_mlp_mnist_list_decoded.01b

【5 epochs(明るさ・輝度調整)】
やはり raw 出力では見て取れないので、明るさ・輝度を調整した後の画像を掲示しています :
ae_mlp_mnist_list_decoded.05b

【10 epochs(明るさ・輝度調整)】
だいぶ一致してきましたが細部が表現できていません :
ae_mlp_mnist_list_decoded.10b

TensorFlow で Convolutional Autoencoder

単層 MLP では十分な表現力が得られないので Convolutional Autoencoder にしてみます。
基本的な考え方は同じで、畳込み層を3層とする、ConvNet の基本モデルを使用しました。
但し、encode された画像を見やすくするために encoder 最終層の出力サイズは大きくなるように調整しています。

最初は MLP の場合と同様に decode した画像を元画像と比較してみます :

【元サンプル画像】
元サンプル画像は MLP と同じものを使います :
ae_mnist_list_samples.01

【1 epoch】
1 epoch で既に十分 decode できています。明るさ・輝度の調整も必要ありません :
ae_mnist_list_decoded.01

【50 epochs】
50 epochs トレーニングした後の decode された画像では細部がよりクリアになっています :
ae_mnist_list_decoded.50

念のために単一のサンプル画像と decode された画像をトレーニング epochs で比較してみましたが、微細な違いはあるもののほぼ完璧に decode できています :

元サンプル画像

1 epoch

ae_mnist_sample.01.03

ae_mnist_decoded.01.03

10 epochs

50 epochs

ae_mnist_decoded.10.03

ae_mnist_decoded.50.03

Convolutional Autoencoder で encode された画像

次に encode された画像をやはり epochs 数別に比較してみます。
以下は上の “0” の画像を encode した画像 (= encoder の特徴出力マップ) です。
トレーニングが進むにつれて特徴の掴みかたがより的確になっています :

【1 epoch】
ae_mnist_encoded.01.03

【10 epochs】
ae_mnist_encoded.10.03

【50 epochs】
ae_mnist_encoded.50.03

他の数字でも確認しておきます。
元サンプル画像、50 epochs 後の decode された画像、そして 50 epochs 後の encode された画像群の順です :

ae_mnist_sample.50.00

ae_mnist_decoded.50.00

ae_mnist_encoded.50.00

ae_mnist_sample.50.04

ae_mnist_decoded.50.04

ae_mnist_encoded.50.04

ae_mnist_sample.50.61

ae_mnist_decoded.50.61

ae_mnist_encoded.50.61

ae_mnist_sample.50.02

ae_mnist_decoded.50.02

ae_mnist_encoded.50.02

 
以上

TensorFlow 畳込み層のフィルタの可視化 – MNIST –

TensorFlow 畳込み層のフィルタの可視化 – MNIST –

mnist_convnetTensorFlow ベースの ConvNet (CNN) における畳込み層とプーリングの出力、あるいは特徴マップの可視化については TensorFlow 畳込み層の特徴マップの可視化 – MNIST – で扱いました。

次に同じ ConvNet モデルで畳込み層のフィルタを TensorFlow で可視化してみました。モデルは右図のように単純なもので、畳込み層2つと(マックス)プーリング層から成り、テスト精度は 99 % 超まであげてあります。

畳込み層の1つ目と2つ目のフィルタを可視化していますが、サイズとフィルタ数は2通りで試しています。

フィルタの視覚化

1-0) ConvLayer 0 : まず最初の畳込み層で、サイズ 3×3 が 32 個のフィルタです :
mnist_filters_conv0.3x3

1-1) ConvLayer 1 : 2つ目の畳込み層も、サイズ 3×3 が 32 個のフィルタです :
mnist_filters_conv2.3x3

次に畳込み層のフィルタ構成を変更して視覚化しました。

2-0) ConvLayter 0 : サイズ 5 x 5 が 32 個のフィルタです :
mnist_filters2_conv0.5x5

2-2) ConvLayer 1 : サイズ 3×3 が 64 個のフィルタです :
mnist_filters2_conv2.3x3

以上

TensorFlow 畳込み層の特徴マップの可視化 – MNIST – (2)

TensorFlow 畳込み層の特徴マップの可視化 (2)

TensorFlow 畳込み層の特徴マップの可視化 – MNIST – の続きです。
MNIST サンプル画像ラベル 5 ~9 までの特徴マップの可視化です。

視覚化、特徴マップ

サンプル画像 : 以下の例では 5 か 6 か見た目で迷いますが、ラベルは 5 です
(こういうサンプル画像を見ると精度が 100 % にならないのも仕方がない気がします) :
mnist_sample.5

conv1 層の出力 :
mnist_conv1out.5

conv2 層の出力 :
mnist_conv2out.5

max pooling 2 層の出力 :
mnist_maxpool2out.5

サンプル画像 :
mnist_sample.6

conv1 層の出力 :
mnist_conv1out.6

conv2 層の出力 :
mnist_conv2out.6

max pooling 2 層の出力 :
mnist_maxpool2out.6

サンプル画像 :
mnist_sample.7

conv1 層の出力 :
mnist_conv1out.7

conv2 層の出力 :
mnist_conv2out.7

max pooling 2 層の出力 :
mnist_maxpool2out.7

サンプル画像 :
mnist_sample.8

conv1 層の出力 :
mnist_conv1out.8

conv2 層の出力 :
mnist_conv2out.8

max pooling 2 層の出力 :
mnist_maxpool2out.8

サンプル画像 :
mnist_sample.9

conv1 層の出力 :
mnist_conv1out.9

conv2 層の出力 :
mnist_conv2out.9

max pooling 2 層の出力 :
mnist_maxpool2out.9

以上

TensorFlow 畳込み層の特徴マップの可視化 – MNIST –

TensorFlow 畳込み層の特徴マップの可視化 – MNIST –

mnist_convnet
TensorFlow を利用した基本的な技術の紹介を続けていますが、特徴マップの視覚化については (AutoEncoder や RBM で扱いはしたものの)基本的な ConvNet (CNN) についてはまだ紹介していませんでした。

そこで TensorFlow の ConvNet モデルで畳込み層とプーリング層の出力を可視化してみました。モデルは右図のように単純なもので、畳込み層2つと(マックス)プーリング層から成り、テスト精度は 99 % 超まであげてあります。3つの層からの出力を可視化しましたが、最上位層(図では bottom)からの出力は特に特徴マップとも呼ばれます。

フィルタの可視化については こちら を参照してください。

視覚化、特徴マップ

せっかくなので 0 ~ 9 までの数字それぞれについての画像を掲載しておきます。最初はサンプル画像から始まります。

サンプル画像 : training sample の最初の方からピックアップしています。
以後の特徴マップ出力はこのサンプル画像を元にしています :
mnist_sample.0

conv1 層の出力 : 最初の畳込み層の活性後の出力の可視化です :
mnist_conv1out.0

conv2 層の出力 : 続く2つ目の畳込み層の活性後の可視化です :
mnist_conv2out.0

max pooling 2 層の出力 : そしてマックスプーリング層の出力。特徴マップです :
mnist_maxpool2out.0

サンプル画像 :
mnist_sample.1

conv1 層の出力 :
mnist_conv1out.1

conv2 層の出力 :
mnist_conv2out.1

max pooling 2 層の出力 :
mnist_maxpool2out.1

サンプル画像 :
mnist_sample.2

conv1 層の出力 :
mnist_conv1out.2

conv2 層の出力 :
mnist_conv2out.2

max pooling 2 層の出力 :
mnist_maxpool2out.2

サンプル画像 :
mnist_sample.3

conv1 層の出力 :
mnist_conv1out.3

conv2 層の出力 :
mnist_conv2out.3

max pooling 2 層の出力 :
mnist_maxpool2out.3

サンプル画像 :
mnist_sample.4

conv1 層の出力 :
mnist_conv1out.4

conv2 層の出力 :
mnist_conv2out.4

max pooling 2 層の出力 :
mnist_maxpool2out.4

少し長くなったので、ラベル 5 ~ 9 までの画像は別記事にまとめました :
TensorFlow 畳込み層の特徴マップの可視化 – MNIST – (2)

以上

Google Cloud Machine Learning : 入門編 (3) – 予測

Google Cloud Machine Learning : 入門編 (3) – 予測

Google Cloud ML 入門編 (1) では Google Cloud ML パブリック Beta のクライアント環境のセットアップと MNIST のシングル・ワーカー・ジョブの投入までを試しました。
入門編 (2) では Cloud ML の TensorFlow 分散訓練の方法から始めてハイパーパラメータ調整を行ないました。

本記事 – 入門編 (3) では以下のドキュメントに従って :

Prediction Quickstart | Google Cloud Machine Learning

予測 (prediction) を主題として Cloud ML 上で TensorFlow モデルをサービス提供する方法を扱います。Training クイックスタートでトレーニングしたものと同様なモデルに対してオンラインとバッチ予測リクエストの両方を送ることができます。

* あくまでベータですので仕様が変更される可能性はありますのでご注意ください

Prediction クイックスタート

クラウド上で予測のためにモデルをアップデートする

クラウド上で予測を有効にするためには、Training クイックスタートで使用した TensorFlow MNIST サンプル・コードに小さな変更を行なう必要があります。

これらの変更については Exporting and Deploying Your Model for Prediction how-to に記述されていますが、このクイックスタートのためには既に変更を加えています; 単に作業ディレクトリを ~/google-cloud-ml/samples/mnist/deployable/ に移してください :

cd ~/google-cloud-ml/samples/mnist/deployable/

クラウドでアップデートしたモデルをトレーニングする

最初に、モデルがローカルでトレーニングできることを一応確認しておきます :

# Clear the output from any previous local run.
rm -f data/{checkpoint,events,export}*
# Train locally.
python -m trainer.task

トレーニングの最後に、export された最終的なモデルは data/export と data/export.meta ファイル群に置かれます :

$ ls -1 data/
checkpoint
checkpoint-1999
checkpoint-1999.meta
checkpoint-999
checkpoint-999.meta
eval_sample.tensor.json
events.out.tfevents.1477226741.cs-6860-devshell-vm-e1e01071-54f6-495c-bcec-d79c9d38047f-114
export
export.meta
predict_sample.tensor.json

次に、トレーニング・ジョブのための名前を選択します、e.g. “mnist_deployable_yourusername”.
英字で始まり、英数字とアンダースコアを含みます。

JOB_NAME=<your job name>

そしてトレーニング・スクリプトをクラウドに submit します :

$ PROJECT_ID=`gcloud config list project --format "value(core.project)"`
$ echo $PROJECT_ID
classcat-tensorflow

$ TRAIN_BUCKET=gs://${PROJECT_ID}-ml
$ echo $TRAIN_BUCKET
gs://classcat-tensorflow-ml

$ TRAIN_PATH=${TRAIN_BUCKET}/${JOB_NAME}
$ echo $TRAIN_PATH
gs://classcat-tensorflow-ml/mnist_deployable_classcat

# Clear the output from any previous cloud run.
$ gsutil rm -rf ${TRAIN_PATH}

$gcloud beta ml jobs submit training ${JOB_NAME} \
  --package-path=trainer \
  --module-name=trainer.task \
  --staging-bucket="${TRAIN_BUCKET}" \
  --region=us-central1 \
  -- \
  --train_dir="${TRAIN_PATH}/train" \
  --model_dir="${TRAIN_PATH}/model"

実行直後です :

createTime: '2016-10-23T12:57:33Z'
jobId: mnist_deployable_classcat
state: QUEUED
trainingInput:
  args:
  - --train_dir=gs://classcat-tensorflow-ml/mnist_deployable_classcat/train
  - --model_dir=gs://classcat-tensorflow-ml/mnist_deployable_classcat/model
  packageUris:
  - gs://classcat-tensorflow-ml/cloudmldist/1477227451/trainer-0.0.0.tar.gz
  pythonModule: trainer.task
  region: us-central1
masao_cc@classcat-tensorflow:~/google-cloud-ml/samples/mnist/deployable$ gcloud beta ml jobs describe --project ${PROJECT_ID} 
${JOB_NAME}
createTime: '2016-10-23T12:57:33Z'
jobId: mnist_deployable_classcat
state: PREPARING
trainingInput:
  args:
  - --train_dir=gs://classcat-tensorflow-ml/mnist_deployable_classcat/train
  - --model_dir=gs://classcat-tensorflow-ml/mnist_deployable_classcat/model
  packageUris:
  - gs://classcat-tensorflow-ml/cloudmldist/1477227451/trainer-0.0.0.tar.gz
  pythonModule: trainer.task
  region: us-central1

最後に、ジョブの進行をチェックして終了を待ちます :

gcloud beta ml jobs describe --project ${PROJECT_ID} ${JOB_NAME}

クラウドにモデルを配備する

最初に、モデルの名前を選択します、e.g. “mnist_yourusername”。
英字で始まり、英数字とアンダースコアを含みます。

MODEL_NAME=<your model name>

そして予測のための Cloud ML モデルとバージョンを作成します :

gcloud beta ml models create ${MODEL_NAME}
gcloud beta ml models versions create \
  --origin=${TRAIN_PATH}/model/ \
  --model=${MODEL_NAME} \
  v1
gcloud beta ml models versions set-default --model=${MODEL_NAME} v1

alternative として、GCP コンソールでもモデルとバージョンを作成できます :

  1. “モデルを作成” をクリックします(または既に一つ以上のモデルがある場合には “+ モデルを作成”)。
  2. モデル名を入力します、 e.g. mnist_yourusername。
  3. “作成” をクリックします。
  4. 新しいモデルの名前をクリックします。
  5. “バージョンを作成する” または “+ バージョンを作成する” をクリックします。
  6. 次の情報を入力します :
    • 名前 : v1
    • ソース : ${TRAIN_PATH}/model/ の値 (ブラウズで選択できます)。
  7. “作成” をクリックします。
  8. モデルバージョン “v1” の隣の「デフォルトに設定」をクリックします(但し、1個だけの時は自動的にデフォルトに設定される感じです)。

クラウドで新しいインスタンスを予測する

これでモデルに予測リクエストを送ることができます。各インスタンスは JSON オブジェクトで、その属性は事前に宣言してあるテンソル・エイリアスです (“image”, “key”)。”image” 属性は float のリストとしての手書き数字画像データ(i.e. モデルに予測させたいもの)を含み、一方で “key” (i.e. JSON ファイルの画像のインデックス)は単一の integer です :

head -n2 data/predict_sample.tensor.json

以下と同様の出力が見れるはずです :

{"image": [0.0,..., 0.0, 0.0], "key": 0}
{"image": [0.0,..., 0.0, 0.0], "key": 1}
オンライン予測サービスを使用する

【注意】Cloud ML オンライン予測サービスは現時点で(製品の他の機能は Beta ですが)Alpha フィーチャーです。オンライン予測は特に制限なく利用可能ですが、Cloud ML の他の機能よりもステーブルではなく信頼性が低いかもしれません。

次のスクリプトはファイルからインスタンスを読んでそれらを Cloud ML オンライン予測サービスに送ります :

gcloud beta ml predict --model=${MODEL_NAME} \
  --instances=data/predict_sample.tensor.json

以下は出力結果です :

predictions:
- key: 0
  prediction: 3
  scores:
  - 0.0203564
  - 0.000128082
  - 0.00255795
  - 0.619445
  - 3.96154e-05
  - 0.335909
  - 0.000672323
  - 0.00473043
  - 0.0136186
  - 0.00254196
- key: 1
  prediction: 0
  scores:
  - 0.997337
  - 7.48403e-09
  - 3.81023e-05
  - 8.05008e-05
  - 3.44861e-07
  - 0.00245502
  - 2.90748e-05
  - 1.94155e-05
  - 3.20863e-05
  - 8.17647e-06
- key: 2
  prediction: 4
  scores:
  - 0.00338854
  - 0.00223743
  - 0.0289303
  - 0.0399133
  - 0.672126
  - 0.0051319
  - 0.0154283
  - 0.0249293
  - 0.0218912
  - 0.186024
- key: 3
  prediction: 1
  scores:
  - 3.44334e-06
  - 0.962688
  - 0.00933552
  - 0.00441769
  - 0.000420508
  - 0.000595645
  - 0.000220079
  - 0.000721661
  - 0.0209434
  - 0.000654054
- key: 4
  prediction: 9
  scores:
  - 1.9798e-05
  - 0.000375617
  - 6.38733e-05
  - 0.000149535
  - 0.100276
  - 0.000647383
  - 0.000101338
  - 0.0209089
  - 0.00366108
  - 0.873796
- key: 5
  prediction: 2
  scores:
  - 0.0048439
  - 0.000105955
  - 0.810874
  - 0.00665644
  - 0.000815119
  - 0.00121918
  - 0.00100165
  - 0.0151151
  - 0.0751259
  - 0.0842431
- key: 6
  prediction: 1
  scores:
  - 5.99334e-08
  - 0.987748
  - 0.00203607
  - 0.00626478
  - 5.05617e-05
  - 0.000297003
  - 6.14583e-05
  - 0.000487078
  - 0.0024817
  - 0.00057279
- key: 7
  prediction: 3
  scores:
  - 0.000191433
  - 1.08367e-06
  - 0.00137237
  - 0.984816
  - 1.26182e-05
  - 0.00102288
  - 6.42889e-07
  - 5.89483e-05
  - 0.0122277
  - 0.000295992
- key: 8
  prediction: 1
  scores:
  - 5.161e-06
  - 0.971483
  - 0.00174534
  - 0.00532335
  - 0.000445978
  - 0.00363754
  - 0.000348157
  - 0.00521967
  - 0.00764051
  - 0.00415152
- key: 9
  prediction: 4
  scores:
  - 0.000359493
  - 0.000114784
  - 0.000876791
  - 0.000155708
  - 0.95885
  - 0.00325834
  - 0.0195464
  - 0.00022779
  - 0.00797938
  - 0.00863121

 

バッチ予測サービスを使用する

Cloud ML バッチ予測サービスも使用できます。

最初に、バッチ予測ジョブのための名前を選択します、”predict_mnist_yourusername”。
英文字から始まり英数字とアンダースコアを含みます。

JOB_NAME=<your job name>

次に、バッチ予測ジョブを submit します :

gsutil cp data/predict_sample.tensor.json ${TRAIN_PATH}/data/
gcloud beta ml jobs submit prediction ${JOB_NAME} \
    --model=${MODEL_NAME} \
    --data-format=TEXT \
    --input-paths=${TRAIN_PATH}/data/predict_sample.tensor.json \
    --output-path=${TRAIN_PATH}/output \
    --region=us-central1

実行直後 :

createTime: '2016-10-23T13:20:35Z'
jobId: predict_mnist_classcat
predictionInput:
  dataFormat: TEXT
  inputPaths:
  - gs://classcat-tensorflow-ml/mnist_deployable_classcat/data/predict_sample.tensor.json
  modelName: projects/classcat-tensorflow/models/mnist_classcat
  outputPath: gs://classcat-tensorflow-ml/mnist_deployable_classcat/output
  region: us-central1
predictionOutput:
  outputPath: gs://classcat-tensorflow-ml/mnist_deployable_classcat/output
state: QUEUED

実行中 :

$ gcloud beta ml jobs describe --project ${PROJECT_ID} ${JOB_NAME}
createTime: '2016-10-23T13:20:35Z'
jobId: predict_mnist_classcat
predictionInput:
  dataFormat: TEXT
  inputPaths:
  - gs://classcat-tensorflow-ml/mnist_deployable_classcat/data/predict_sample.tensor.json
  modelName: projects/classcat-tensorflow/models/mnist_classcat
  outputPath: gs://classcat-tensorflow-ml/mnist_deployable_classcat/output
  region: us-central1
predictionOutput:
  outputPath: gs://classcat-tensorflow-ml/mnist_deployable_classcat/output
startTime: '2016-10-23T13:20:35Z'
state: RUNNING

終了を待ちます :

gcloud beta ml jobs describe --project ${PROJECT_ID} ${JOB_NAME}

最終的に、出力を読みます :

gsutil cat ${TRAIN_PATH}/output/prediction.results-00000-of-00001

以下は実際に確認できた出力です :

$ gsutil cat ${TRAIN_PATH}/output/prediction.results-00
000-of-00001
{u'prediction': 3, u'key': 0, u'scores': [0.020356435328722, 0.00012808165047317743, 0.002557950560003519, 0.6194452047348022,
 3.9615388232050464e-05, 0.3359093964099884, 0.0006723233964294195, 0.004730433691293001, 0.013618593104183674, 0.002541961381
211877]}
{u'prediction': 0, u'key': 1, u'scores': [0.9973371624946594, 7.484025843496056e-09, 3.8102345570223406e-05, 8.05008239694871e
-05, 3.4486083677620627e-07, 0.0024550205562263727, 2.9074832127662376e-05, 1.9415505448705517e-05, 3.208634370821528e-05, 8.1
76466508302838e-06]}
{u'prediction': 4, u'key': 2, u'scores': [0.003388544311746955, 0.0022374324034899473, 0.028930312022566795, 0.039913255721330
64, 0.6721255779266357, 0.005131898447871208, 0.015428278595209122, 0.024929305538535118, 0.02189120277762413, 0.1860242187976
8372]}
{u'prediction': 1, u'key': 3, u'scores': [3.443341711317771e-06, 0.9626880884170532, 0.009335516951978207, 0.00441769091412425
, 0.0004205082659609616, 0.0005956447566859424, 0.00022007898951414973, 0.0007216611411422491, 0.020943380892276764, 0.0006540
539907291532]}
{u'prediction': 9, u'key': 4, u'scores': [1.979799708351493e-05, 0.0003756166552193463, 6.387331086443737e-05, 0.0001495352771
5988457, 0.10027632117271423, 0.0006473834509961307, 0.00010133774776477367, 0.020908894017338753, 0.003661080962046981, 0.873
7961053848267]}
{u'prediction': 2, u'key': 5, u'scores': [0.004843897186219692, 0.00010595522326184437, 0.8108737468719482, 0.0066564441658556
46, 0.000815118954051286, 0.0012191830901429057, 0.0010016539599746466, 0.01511511579155922, 0.07512589544057846, 0.0842430591
583252]}
{u'prediction': 1, u'key': 6, u'scores': [5.993342000465418e-08, 0.9877484440803528, 0.0020360725466161966, 0.0062647750601172
45, 5.056171357864514e-05, 0.0002970028144773096, 6.145832594484091e-05, 0.0004870775737799704, 0.002481696894392371, 0.000572
7899260818958]}
{u'prediction': 3, u'key': 7, u'scores': [0.00019143284589517862, 1.0836668025149265e-06, 0.0013723709853366017, 0.98481637239
45618, 1.2618214896065183e-05, 0.0010228765895590186, 6.428894607779512e-07, 5.8948346122633666e-05, 0.012227668426930904, 0.0
002959921257570386]}
{u'prediction': 1, u'key': 8, u'scores': [5.1609990805445705e-06, 0.9714827537536621, 0.0017453399486839771, 0.005323346704244
614, 0.00044597769738174975, 0.0036375385243445635, 0.0003481570165604353, 0.005219669546931982, 0.007640512194484472, 0.00415
1524044573307]}
{u'prediction': 4, u'key': 9, u'scores': [0.000359493336873129, 0.00011478372471174225, 0.0008767909603193402, 0.0001557076757
3080957, 0.9588501453399658, 0.00325834471732378, 0.0195463877171278, 0.00022778974380344152, 0.00797937996685505, 0.008631209
842860699]}

前述のオンライン予測サービスと比較すると、このサービスは :

  • インスタンスの小さい数に対してはより遅いです(しかし大量のインスタンスに対してはより適しています)。
  • 入力とは異なる順序で出力が返されるかもしれません。
 

以上

Google Cloud Machine Learning : 入門編 (2) – 分散訓練 & ハイパーパラメータ調整

Google Cloud Machine Learning : 入門編 (2) – 分散訓練 & ハイパーパラメータ調整

Google Cloud ML 入門編 (1) の続編です。先の入門編 (1) では Google Cloud ML パブリック Beta のクライアント環境のセットアップと MNIST のシングル・ワーカー・ジョブの投入までを試しました。

本記事 – 入門編 (2) では Cloud ML の TensorFlow 分散訓練の方法から始めてハイパーパラメータ調整を行ないます。予備知識として TensorFlow : How To : 分散 TensorFlow に目を通しておくと良いでしょう。

* あくまでベータですので仕様が変更される可能性はありますのでご注意ください

(続) Training クイックスタート

クラウド上でトレーニングする : 分散

Training Quickstart の以下の項目から始めます :

Train on the cloud: distributed | Training Quickstart | Google Cloud Machine Learning

Cloud ML においてマルチワーカー上で TensorFlow モデルのトレーニング・ジョブを実行することはシングル・ワーカー上と殆ど同じくらい簡単です。先に利用した TensorFlow MNIST サンプルはシングル・ワーカー上でのトレーニングのみが可能ですが、TensorFlow : How To : 分散 TensorFlow でアドバイスされている方法によって分散トレーニングを可能にするため、アップデートします。

備考 : Cloud ML のオンライン & バッチ予測サービスをサポートするためにもまたサンプルをアップデートしています。これらについては( Prediction Quickstart のために)予測サービスに配備するモデルを保存することになります。

アップデートされたコードは以下で見つかります :

cd ~/google-cloud-ml/samples/mnist/distributed/

 

トレーニング・コードをローカルでテストする

最初に、モデルが(シングル・ワーカー上)ローカルでトレーニングできることを確認します :

# 以前のローカル実行からの出力をクリア
rm -rf output/
# ローカルでトレーニング
python -m trainer.task \
  --train_data_paths=gs://cloud-ml-data/mnist/train.tfr.gz \
  --eval_data_paths=gs://cloud-ml-data/mnist/eval.tfr.gz \
  --output_path=output

以下は実行結果の一部です(実際はかなり長いです) :

$ python -m trainer.task \
> --train_data_paths=gs://cloud-ml-data/mnist/train.tfr.gz \
> --eval_data_paths=gs://cloud-ml-data/mnist/eval.tfr.gz \
> --output_path=output
INFO:root:Original job data: {}
INFO:tensorflow:global_step/sec: 0
INFO:tensorflow:global_step/sec: 0
INFO:root:Train [master/0], step 1: loss: 2.312, accuracy: 0.040 (0.126 sec) 7.9 global steps/s, 7.9 local steps/s
INFO:root:Eval, step 1: loss: 2.298, accuracy: 0.094
INFO:root:Train [master/0], step 145: loss: 1.997, accuracy: 0.386 (3.407 sec) 43.9 global steps/s, 43.9 local steps/s
INFO:root:Eval, step 145: loss: 1.683, accuracy: 0.550
INFO:root:Adjusting eval interval from 1.00s to 1.39s
INFO:root:Train [master/0], step 288: loss: 1.697, accuracy: 0.528 (5.804 sec) 59.7 global steps/s, 59.7 local steps/s
INFO:root:Train [master/0], step 341: loss: 1.592, accuracy: 0.569 (6.189 sec) 137.6 global steps/s, 137.6 local steps/s
INFO:root:Eval, step 341: loss: 0.908, accuracy: 0.816
INFO:root:Train [master/0], step 482: loss: 1.362, accuracy: 0.642 (8.503 sec) 60.9 global steps/s, 60.9 local steps/s
INFO:root:Train [master/0], step 536: loss: 1.286, accuracy: 0.665 (8.889 sec) 140.1 global steps/s, 140.1 local steps/s
INFO:root:Eval, step 536: loss: 0.601, accuracy: 0.857

(... 略 ...)

INFO:root:Train [master/0], step 4908: loss: 0.428, accuracy: 0.882 (245.001 sec) 26.9 global steps/s, 26.9 local steps/s
INFO:root:Train [master/0], step 4934: loss: 0.427, accuracy: 0.882 (246.208 sec) 21.5 global steps/s, 21.5 local steps/s
INFO:root:Train [master/0], step 4944: loss: 0.427, accuracy: 0.883 (246.484 sec) 36.3 global steps/s, 36.3 local steps/s
INFO:root:Eval, step 4944: loss: 0.236, accuracy: 0.935
INFO:root:Train [master/0], step 4969: loss: 0.426, accuracy: 0.883 (253.471 sec) 3.6 global steps/s, 3.6 local steps/s
INFO:root:Train [master/0], step 4991: loss: 0.425, accuracy: 0.883 (254.472 sec) 22.0 global steps/s, 22.0 local steps/s
INFO:root:Exporting prediction graph to output/model
INFO:root:Final metrics after 5000 steps, loss: 0.236, accuracy: 0.934

 

トレーニング・ジョブを submit する

トレーニング・ジョブのための名前を選択します、e.g. “mnist_distributed_yourusername”。
英字で始まり英数字とアンダースコアのみを含めることができます。

JOB_NAME=<your job name>

以前のクラウド実行からの出力をクリアしておきます :

PROJECT_ID=`gcloud config list project --format "value(core.project)"`
TRAIN_BUCKET=gs://${PROJECT_ID}-ml
TRAIN_PATH=${TRAIN_BUCKET}/${JOB_NAME}
gsutil rm -rf ${TRAIN_PATH}

単純な config ファイルを作成します、これは Cloud ML STANDARD_1 scale tier(= 多くのワーカーと2、3 (= a few) のパラメータ・サーバ)を指定するものです :

cat << EOF > config.yaml
trainingInput:
  # Use a cluster with many workers and a few parameter servers.
  scaleTier: STANDARD_1
EOF

そして最後にトレーニング・ジョブを submit します :

gcloud beta ml jobs submit training ${JOB_NAME} \
  --package-path=trainer \
  --module-name=trainer.task \
  --staging-bucket="${TRAIN_BUCKET}" \
  --region=us-central1 \
  --config=config.yaml \
  -- \
  --train_data_paths="gs://cloud-ml-data/mnist/train.tfr.gz" \
  --eval_data_paths="gs://cloud-ml-data/mnist/eval.tfr.gz" \
  --output_path="${TRAIN_PATH}/output"

実際に実行してみます :

$ gcloud beta ml jobs submit training ${JOB_NAME} \
>   --package-path=trainer \
>   --module-name=trainer.task \
>   --staging-bucket="${TRAIN_BUCKET}" \
>   --region=us-central1 \
>   --config=config.yaml \
>   -- \
>   --train_data_paths="gs://cloud-ml-data/mnist/train.tfr.gz" \
>   --eval_data_paths="gs://cloud-ml-data/mnist/eval.tfr.gz" \
>   --output_path="${TRAIN_PATH}/output"
createTime: '2016-10-17T09:05:49Z'
jobId: mnist_distributed_classcat
state: QUEUED
trainingInput:
  args:
  - --train_data_paths=gs://cloud-ml-data/mnist/train.tfr.gz
  - --eval_data_paths=gs://cloud-ml-data/mnist/eval.tfr.gz
  - --output_path=gs://classcat-tensorflow-ml/mnist_distributed_classcat/output
  packageUris:
  - gs://classcat-tensorflow-ml/cloudmldist/1476695147/trainer-0.0.0.tar.gz
  pythonModule: trainer.task
  region: us-central1
  scaleTier: STANDARD_1

ステータス確認。もちろん Cloud Platform コンソールからも確認できます :

$ gcloud beta ml jobs describe --project ${PROJECT_ID} ${JOB_NAME}
createTime: '2016-10-17T09:05:49Z'
jobId: mnist_distributed_classcat
startTime: '2016-10-17T09:06:25Z'
state: RUNNING
trainingInput:
  args:
  - --train_data_paths=gs://cloud-ml-data/mnist/train.tfr.gz
  - --eval_data_paths=gs://cloud-ml-data/mnist/eval.tfr.gz
  - --output_path=gs://classcat-tensorflow-ml/mnist_distributed_classcat/output
  packageUris:
  - gs://classcat-tensorflow-ml/cloudmldist/1476695147/trainer-0.0.0.tar.gz
  pythonModule: trainer.task
  region: us-central1
  scaleTier: STANDARD_1

成功しました :

$ gcloud beta ml jobs describe --project ${PROJECT_ID} ${JOB_NAME}
createTime: '2016-10-17T09:05:49Z'
endTime: '2016-10-17T09:13:17Z'
jobId: mnist_distributed_classcat
startTime: '2016-10-17T09:06:25Z'
state: SUCCEEDED
trainingInput:
  args:
  - --train_data_paths=gs://cloud-ml-data/mnist/train.tfr.gz
  - --eval_data_paths=gs://cloud-ml-data/mnist/eval.tfr.gz
  - --output_path=gs://classcat-tensorflow-ml/mnist_distributed_classcat/output
  packageUris:
  - gs://classcat-tensorflow-ml/cloudmldist/1476695147/trainer-0.0.0.tar.gz
  pythonModule: trainer.task
  region: us-central1
  scaleTier: STANDARD_1

 

出力を inspect する

この例では出力は ${TRAIN_PATH}/output に保存されていますので、リストを取るには ”
gsutil ls ${TRAIN_PATH}/output” を実行します :

$ gsutil ls $TRAIN_PATH/output
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/checkpoint
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/events.out.tfevents.1476695558.master-63d9-0-ytvx3
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/events.out.tfevents.1476695559.master-63d9-0-ytvx3
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/events.out.tfevents.1476695560.master-63d9-0-ytvx3
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/events.out.tfevents.1476695562.master-63d9-0-ytvx3
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/events.out.tfevents.1476695564.master-63d9-0-ytvx3
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/events.out.tfevents.1476695566.master-63d9-0-ytvx3
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/events.out.tfevents.1476695568.master-63d9-0-ytvx3
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/events.out.tfevents.1476695571.master-63d9-0-ytvx3
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/events.out.tfevents.1476695573.master-63d9-0-ytvx3
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/events.out.tfevents.1476695575.master-63d9-0-ytvx3
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/events.out.tfevents.1476695578.master-63d9-0-ytvx3
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/events.out.tfevents.1476695580.master-63d9-0-ytvx3
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/events.out.tfevents.1476695583.master-63d9-0-ytvx3
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/events.out.tfevents.1476695585.master-63d9-0-ytvx3
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/export
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/export.meta
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/graph.pbtxt
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/model.ckpt-2496
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/model.ckpt-2496.meta
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/model.ckpt-3117
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/model.ckpt-3117.meta
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/model.ckpt-4018
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/model.ckpt-4018.meta
gs://classcat-tensorflow-ml/mnist_distributed_classcat/output/model.ckpt-5006

 

Stackdriver ログを inspect する

マルチ・ワーカー上でモデルがトレーニングされたことを確認するために Stackdriver ロギングが使用できます。

ジョブのログを見つける最も簡単な方法は(シングル・ワーカー上の場合と同じように)Cloud Platform コンソールで「ログを表示」をクリックすることです。「すべてのログ」ドロップダウンの中から master-replica-0 をクリックすると、以下のようなログが閲覧できます :
gcml_distributed_log_master0b

次に master-replicat-0 の代わりに worker-replica-0 を選択すると、次のようなログが閲覧できます :
gcml_distributed_log_worker0b

alternative として、コマンドライン上でもログを読むことができます :

gcloud beta logging read --project ${PROJECT_ID} --format=json \
  "labels.\"ml.googleapis.com/task_name\"=\"master-replica-0\" AND \
   labels.\"ml.googleapis.com/job_id\"=\"${JOB_NAME}\""

以下は実行例です :

$ gcloud beta logging read --project ${PROJECT_ID} --format=json   "labels.\"ml.googleapis
.com/task_name\"=\"master-replica-0\" AND \
   labels.\"ml.googleapis.com/job_id\"=\"${JOB_NAME}\"" | head -40
[
  {
    "insertId": "15cxtb6f1ae12i",
    "jsonPayload": {
      "created": 1476695587.16638,
      "levelname": "INFO",
      "lineno": 690,
      "message": "Task completed successfully.",
      "pathname": "/runcloudml.py"
    },
    "labels": {
      "compute.googleapis.com/resource_id": "6857495858232852682",
      "compute.googleapis.com/resource_name": "master-63d9-0-ytvx3",
      "compute.googleapis.com/resource_type": "instance",
      "ml.googleapis.com/job_id": "mnist_distributed_classcat",
      "ml.googleapis.com/job_id/log_area": "root",
      "ml.googleapis.com/task_name": "master-replica-0",
      "ml.googleapis.com/trial_id": ""
    },
    "logName": "projects/classcat-tensorflow/logs/master-replica-0",
    "resource": {
      "labels": {
        "job_id": "mnist_distributed_classcat",
        "task_name": "master-replica-0"
      },
      "type": "ml_job"
    },
    "severity": "INFO",
    "timestamp": "2016-10-17T09:13:07.166379928Z"
  },
  {
    "insertId": "15cxtb6f1ae12h",
    "jsonPayload": {
      "created": 1476695587.16607,
      "levelname": "INFO",
      "lineno": 688,
      "message": "Clean up finished.",
      "pathname": "/runcloudml.py"
    },
    "labels": {

 

要約ログを inspect する

この例のために TensorBoard を実行するには、”–logdir=${TRAIN_PATH}/output” を指定すれば良いです :

$ echo ${TRAIN_PATH}
gs://classcat-tensorflow-ml/mnist_distributed_classcat
$ tensorboard --logdir=${TRAIN_PATH}/output --port 8080

以下は損失グラフ :
gcml_distributed_tb_loss2

そして精度グラフです :
gcml_distributed_tb_accu2

 

クラウド上でトレーニングする : ハイパーパラメータ調整

最後に、(この場合は)以下のより良い値を自動的に見つけることによりモデル精度をあげるためにハイパーパラメータ調整を利用できます :

  • 2つの隠れ層のサイズ
  • 学習率

ハイパーパラメータ調整を有効にするためには、前のセクションで使用したサンプルコードに小さな変更を行なう必要があります。興味があれば、これらの変更は Increasing Model Accuracy with Hyperparameter Tuning how-to に記述されていますが、このクイックスタートのためには既に変更を行なっています; 単に作業ディレクトリを ~/google-cloud-ml/samples/mnist/hptuning/ に移してください :

cd ~/google-cloud-ml/samples/mnist/hptuning/

 

トレーニング・コードをローカルでテストする

最初に、モデルを(ハイパーパラメータ調整なし、シングルワーカー上の)ローカルでトレーニング可能なことを確認します :

# Clear the output from any previous local run.
rm -rf output/
# Train locally.
python -m trainer.task \
  --train_data_paths=gs://cloud-ml-data/mnist/train.tfr.gz \
  --eval_data_paths=gs://cloud-ml-data/mnist/eval.tfr.gz \
  --output_path=output

上記の分散トレーニングのためのローカル実行からの出力と同様の出力を見るはずです。
実際の出力は以下のような感じです :

INFO:root:Original job data: {}
INFO:tensorflow:global_step/sec: 0
INFO:tensorflow:global_step/sec: 0
INFO:root:Train [master/0], step 1: loss: 2.322, accuracy: 0.100 (0.117 sec) 8.5 global steps/s, 8.5 local steps/s
INFO:root:Eval, step 1: loss: 2.312, accuracy: 0.108
INFO:root:Train [master/0], step 1352: loss: 0.973, accuracy: 0.742 (12.467 sec) 109.4 global steps/s, 109.4 local steps/s
INFO:root:Eval, step 1352: loss: 0.593, accuracy: 0.846
INFO:root:Train [master/0], step 2626: loss: 0.775, accuracy: 0.801 (24.021 sec) 110.3 global steps/s, 110.3 local steps/s
INFO:root:Eval, step 2626: loss: 0.512, accuracy: 0.887
INFO:root:Train [master/0], step 3914: loss: 0.687, accuracy: 0.830 (35.433 sec) 112.9 global steps/s, 112.9 local steps/s
INFO:root:Eval, step 3914: loss: 0.479, accuracy: 0.899
INFO:root:Exporting prediction graph to output/model
INFO:root:Final metrics after 5000 steps, loss: 0.455, accuracy: 0.908

 

トレーニング・ジョブを submit する

トレーニング・ジョブのための名前を選択します、e.g. “mnist_hptuning_yourusername”。
英字から始まり英数字とアンダースコアを含みます。

JOB_NAME=<your job name>

以前のクラウド実行からの出力をクリアしておきます :

PROJECT_ID=`gcloud config list project --format "value(core.project)"`
TRAIN_BUCKET=gs://${PROJECT_ID}-ml  # gs://ccml-beta-ml
TRAIN_PATH=${TRAIN_BUCKET}/${JOB_NAME}  # gs://ccml-beta-ml/mnist_hptunint_classcat
gsutil rm -rf ${TRAIN_PATH}

最適化したい ハイパーパラメータscale tier を指定する config ファイルを作成します :

cat << EOF > config.yaml
trainingInput:
  # Use a cluster with many workers and a few parameter servers.
  scaleTier: STANDARD_1
  # Hyperparameter-tuning specification.
  hyperparameters:
    # Maximize the objective value.
    goal: MAXIMIZE
    # Run at most 10 trials with different hyperparameters.
    maxTrials: 10
    # Run two trials at a time.
    maxParallelTrials: 2
    params:
      # Allow the size of the first hidden layer to vary between 40 and 400.
      # One value in this range will be passed to each trial via the
      # --hidden1 command-line flag.
      - parameterName: hidden1
        type: INTEGER
        minValue: 40
        maxValue: 400
        scaleType: UNIT_LINEAR_SCALE
      # Allow the size of the second hidden layer to vary between 5 and 250.
      # One value in this range will be passed to each trial via the
      # --hidden2 command-line flag.
      - parameterName: hidden2
        type: INTEGER
        minValue: 5
        maxValue: 250
        scaleType: UNIT_LINEAR_SCALE
      # Allow the learning rate to vary between 0.0001 and 0.5.
      # One value in this range will be passed to each trial via the
      # --learning_rate command-line flag.
      - parameterName: learning_rate
        type: DOUBLE
        minValue: 0.0001
        maxValue: 0.5
        scaleType: UNIT_LOG_SCALE
EOF

最後に、トレーニング・ジョブを submit します :

gcloud beta ml jobs submit training ${JOB_NAME} \
  --package-path=trainer \
  --module-name=trainer.task \
  --staging-bucket="${TRAIN_BUCKET}" \
  --region=us-central1 \
  --config=config.yaml \
  -- \
  --train_data_paths="gs://cloud-ml-data/mnist/train.tfr.gz" \
  --eval_data_paths="gs://cloud-ml-data/mnist/eval.tfr.gz" \
  --output_path="${TRAIN_PATH}/output"

このコマンドは、ハイパーパラメータ調整の指定を追加した点を除けば、上述の分散トレーニングのために使ったものと同じです。

実行直後です :

createTime: '2016-10-22T14:03:36Z'
jobId: mnist_hptunint_classcat
state: QUEUED
trainingInput:
  args:
  - --train_data_paths=gs://cloud-ml-data/mnist/train.tfr.gz
  - --eval_data_paths=gs://cloud-ml-data/mnist/eval.tfr.gz
  - --output_path=gs://ccml-beta-ml/mnist_hptunint_classcat/output
  hyperparameters:
    goal: MAXIMIZE
    maxParallelTrials: 2
    maxTrials: 10
    params:
    - maxValue: 400.0
      minValue: 40.0
      parameterName: hidden1
      scaleType: UNIT_LINEAR_SCALE
      type: INTEGER
    - maxValue: 250.0
      minValue: 5.0
      parameterName: hidden2
      scaleType: UNIT_LINEAR_SCALE
      type: INTEGER
    - maxValue: 0.5
      minValue: 0.0001
      parameterName: learning_rate
      scaleType: UNIT_LOG_SCALE
      type: DOUBLE
  packageUris:
  - gs://ccml-beta-ml/cloudmldist/1477145014/trainer-0.0.0.tar.gz
  pythonModule: trainer.task
  region: us-central1
  scaleTier: STANDARD_1

 

トレーニング・ジョブの終了を待つ

ジョブの進行をチェックして終了することを待ちます :

gcloud beta ml jobs describe --project ${PROJECT_ID} ${JOB_NAME}

ジョブが完了すればステート SUCCEEDED が確認できます。
ドキュメントにはおよそ 20 分かかるとありましたが、実際のジョブ実行時間は 27 分かかりました。以下は成功後の出力です :

$ gcloud beta ml jobs describe --project ${PROJECT_ID} ${JOB_NAME}
createTime: '2016-10-22T14:03:36Z'
endTime: '2016-10-22T14:30:40Z'
jobId: mnist_hptunint_classcat
startTime: '2016-10-22T14:03:38Z'
state: SUCCEEDED
trainingInput:
  args:
  - --train_data_paths=gs://cloud-ml-data/mnist/train.tfr.gz
  - --eval_data_paths=gs://cloud-ml-data/mnist/eval.tfr.gz
  - --output_path=gs://ccml-beta-ml/mnist_hptunint_classcat/output
  hyperparameters:
    goal: MAXIMIZE
    maxParallelTrials: 2
    maxTrials: 10
    params:
    - maxValue: 400.0
      minValue: 40.0
      parameterName: hidden1
      scaleType: UNIT_LINEAR_SCALE
      type: INTEGER
    - maxValue: 250.0
      minValue: 5.0
      parameterName: hidden2
      scaleType: UNIT_LINEAR_SCALE
      type: INTEGER
    - maxValue: 0.5
      minValue: 0.0001
      parameterName: learning_rate
      scaleType: UNIT_LOG_SCALE
      type: DOUBLE
  packageUris:
  - gs://ccml-beta-ml/cloudmldist/1477145014/trainer-0.0.0.tar.gz
  pythonModule: trainer.task
  region: us-central1
  scaleTier: STANDARD_1
trainingOutput:
  completedTrialCount: '10'
  trials:
  - finalMetric:
      objectiveValue: 1.0
      trainingStep: '801'
    hyperparameters:
      hidden1: '400'
      hidden2: '243'
      learning_rate: '0.35743598509131963'
    trialId: '2'
  - finalMetric:
      objectiveValue: 1.0
      trainingStep: '155'
    hyperparameters:
      hidden1: '400'
      hidden2: '78'
      learning_rate: '0.46075871302559684'
    trialId: '4'
  - finalMetric:
      objectiveValue: 1.0
      trainingStep: '59'
    hyperparameters:
      hidden1: '318'
      hidden2: '156'
      learning_rate: '0.49635208597915981'
    trialId: '7'
  - finalMetric:
      objectiveValue: 1.0
      trainingStep: '77'
    hyperparameters:
      hidden1: '400'
      hidden2: '171'
      learning_rate: '0.40330855230836954'
    trialId: '9'
  - finalMetric:
      objectiveValue: 0.9635
      trainingStep: '57'
    hyperparameters:
      hidden1: '202'
      hidden2: '250'
      learning_rate: '0.062366331313038155'
    trialId: '10'
  - finalMetric:
      objectiveValue: 0.9632
      trainingStep: '53'
    hyperparameters:
      hidden1: '400'
      hidden2: '199'
      learning_rate: '0.028588163150300036'
    trialId: '5'
  - finalMetric:
      objectiveValue: 0.9573
      trainingStep: '65'
    hyperparameters:
      hidden1: '169'
      hidden2: '24'
      learning_rate: '0.47690789477002721'
    trialId: '8'
  - finalMetric:
      objectiveValue: 0.9515
      trainingStep: '47'
    hyperparameters:
      hidden1: '68'
      hidden2: '175'
      learning_rate: '0.49684846231717211'
    trialId: '6'
  - finalMetric:
      objectiveValue: 0.7194
      trainingStep: '687'
    hyperparameters:
      hidden1: '134'
      hidden2: '87'
      learning_rate: '0.000949340820855901'
    trialId: '1'
  - finalMetric:
      objectiveValue: 0.3354
      trainingStep: '254'
    hyperparameters:
      hidden1: '399'
      hidden2: '19'
      learning_rate: '0.00010892698020942698'
    trialId: '3'

この出力は 10 試行の各々に使用されたハイパーパラメータと、目的値 (= objective value) (この場合は精度)を含みます。目的値によりソートされています。

 

出力を inspect する

このサンプルでは、出力は ${TRAIN_PATH}/output に保存されます :

gsutil ls ${TRAIN_PATH}/output

各試行のための 10 個の出力ディレクトリが見てとれます :

$ gsutil ls ${TRAIN_PATH}/output/
gs://ccml-beta-ml/mnist_hptunint_classcat/output/1/
gs://ccml-beta-ml/mnist_hptunint_classcat/output/10/
gs://ccml-beta-ml/mnist_hptunint_classcat/output/2/
gs://ccml-beta-ml/mnist_hptunint_classcat/output/3/
gs://ccml-beta-ml/mnist_hptunint_classcat/output/4/
gs://ccml-beta-ml/mnist_hptunint_classcat/output/5/
gs://ccml-beta-ml/mnist_hptunint_classcat/output/6/
gs://ccml-beta-ml/mnist_hptunint_classcat/output/7/
gs://ccml-beta-ml/mnist_hptunint_classcat/output/8/
gs://ccml-beta-ml/mnist_hptunint_classcat/output/9/

$ gsutil ls ${TRAIN_PATH}/output/10
gs://ccml-beta-ml/mnist_hptunint_classcat/output/10/checkpoint
gs://ccml-beta-ml/mnist_hptunint_classcat/output/10/events.out.tfevents.1477146511.master-f3ea-0-5rb4e
gs://ccml-beta-ml/mnist_hptunint_classcat/output/10/events.out.tfevents.1477146512.master-f3ea-0-5rb4e
gs://ccml-beta-ml/mnist_hptunint_classcat/output/10/events.out.tfevents.1477146523.master-f3ea-0-5rb4e
gs://ccml-beta-ml/mnist_hptunint_classcat/output/10/events.out.tfevents.1477146524.master-f3ea-0-5rb4e
gs://ccml-beta-ml/mnist_hptunint_classcat/output/10/events.out.tfevents.1477146534.master-f3ea-0-5rb4e
gs://ccml-beta-ml/mnist_hptunint_classcat/output/10/events.out.tfevents.1477146535.master-f3ea-0-5rb4e
gs://ccml-beta-ml/mnist_hptunint_classcat/output/10/export
gs://ccml-beta-ml/mnist_hptunint_classcat/output/10/export.meta
gs://ccml-beta-ml/mnist_hptunint_classcat/output/10/graph.pbtxt
gs://ccml-beta-ml/mnist_hptunint_classcat/output/10/model.ckpt-1
gs://ccml-beta-ml/mnist_hptunint_classcat/output/10/model.ckpt-1.meta
gs://ccml-beta-ml/mnist_hptunint_classcat/output/10/model.ckpt-1771
gs://ccml-beta-ml/mnist_hptunint_classcat/output/10/model.ckpt-1771.meta
gs://ccml-beta-ml/mnist_hptunint_classcat/output/10/model.ckpt-5007

 

要約ログを inspect する

例えば –logdir=${TRAIN_PATH}/output/1 で TensorBoard が利用できます。
以下はまとめて閲覧したところです :

gcml_hyperparameter_tuning0

gcml_hyperparameter_tuning0b

以下は結果の良かった Id 2 のグラフです :

gcml_hyperparameter_tuning2b

 

ここまでで Training クイックスタートを通して動作確認したことになります。

 

以上

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