ホーム » 分散訓練

分散訓練」カテゴリーアーカイブ

Sonnet 2.0 : Tutorials : snt.distribute で分散訓練 (CIFAR-10)

Sonnet 2.0 : Tutorials : snt.distribute で分散訓練 (翻訳/解説)

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

* 本ページは、Sonnet の以下のドキュメントを翻訳した上で適宜、補足説明したものです:

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

 

snt.distribute で分散訓練

イントロダクション

このチュートリアルは Sonnet 2 “Hello, world!” サンプル (MLP on MNIST) を既に完了していることを仮定しています。

このチュートリアルでは、より大きなモデルとより大きなデータセットで物事をスケールアップしていきます、そして計算をマルチデバイスに渡り分散していきます。

 

import sys
assert sys.version_info >= (3, 6), "Sonnet 2 requires Python >=3.6"
!pip install dm-sonnet tqdm
import sonnet as snt
import tensorflow as tf
import tensorflow_datasets as tfds
print("TensorFlow version: {}".format(tf.__version__))
print("    Sonnet version: {}".format(snt.__version__))

最後に利用可能な GPU を素早く見ましょう :

!grep Model: /proc/driver/nvidia/gpus/*/information | awk '{$1="";print$0}'

 

分散ストラテジー

幾つかのデバイスに渡り計算を分散するためのストラテジーが必要です。Google Colab は単一 GPU を提供するだけですのでそれを 4 つの仮想 GPU に分割します :

physical_gpus = tf.config.experimental.list_physical_devices("GPU")
physical_gpus
[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
tf.config.experimental.set_virtual_device_configuration(
    physical_gpus[0],
    [tf.config.experimental.VirtualDeviceConfiguration(memory_limit=2000)] * 4
)
gpus = tf.config.experimental.list_logical_devices("GPU")
gpus
[LogicalDevice(name='/job:localhost/replica:0/task:0/device:GPU:0', device_type='GPU'),
 LogicalDevice(name='/job:localhost/replica:0/task:0/device:GPU:1', device_type='GPU'),
 LogicalDevice(name='/job:localhost/replica:0/task:0/device:GPU:2', device_type='GPU'),
 LogicalDevice(name='/job:localhost/replica:0/task:0/device:GPU:3', device_type='GPU')]

Sonnet optimizer を使用するとき、snt.distribute からの Replicator か TpuReplicator を利用しなければあんりません、あるいは tf.distribute.OneDeviceStrategy を利用できます。Replicator は MirroredStrategy と等値でそして TpuReplicator は TPUStrategy と等値です。

strategy = snt.distribute.Replicator(
    ["/device:GPU:{}".format(i) for i in range(4)],
    tf.distribute.ReductionToOneDevice("GPU:0"))

 

データセット

基本的には MNIST サンプルと同じですが、今回は CIFAR-10 を使用しています。CIFAR-10 は 10 の異なるクラス (飛行機、自動車、鳥、猫、鹿、犬、蛙、馬、船そしてトラック) にある 32×32 ピクセルカラー画像を含みます。

# NOTE: This is the batch size across all GPUs.
batch_size = 100 * 4

def process_batch(images, labels):
  images = tf.cast(images, dtype=tf.float32)
  images = ((images / 255.) - .5) * 2.
  return images, labels

def cifar10(split):
  dataset = tfds.load("cifar10", split=split, as_supervised=True)
  dataset = dataset.map(process_batch)
  dataset = dataset.batch(batch_size)
  dataset = dataset.prefetch(tf.data.experimental.AUTOTUNE)
  dataset = dataset.cache()
  return dataset

cifar10_train = cifar10("train").shuffle(10)
cifar10_test = cifar10("test")

 

モデル & Optimizer

都合良く、snt.nets にこのデータセットのために特に設計された事前ビルドされたモデルがあります。

作成された任意の変数が正しく分散されることを確実にするために、モデルと optimizer は strategy スコープ内で構築しなければなりません。代わりに、tf.distribute.experimental_set_strategy を使用してプログラム全体のためのスコープに入ることもでできるでしょう。

learning_rate = 0.1

with strategy.scope():
  model = snt.nets.Cifar10ConvNet()
  optimizer = snt.optimizers.Momentum(learning_rate, 0.9)

 

モデルを訓練する

Sonnet optimizer はできる限り綺麗でそして単純であるように設計されています。それらは分散実行を扱うためのどのようなコードも含みません。従ってそれはコードの 2, 3 の追加行を必要とします。

異なるデバイス上で計算された勾配を集めなければなりません。これは ReplicaContext.all_reduce を使用して成されます。

Replicator / TpuReplicator を使用するとき values が総てのレプリカで同一で在り続けることを確かなものにすることはユーザの責任であることに注意してください。

def step(images, labels):
  """Performs a single training step, returning the cross-entropy loss."""
  with tf.GradientTape() as tape:
    logits = model(images, is_training=True)["logits"]
    loss = tf.reduce_mean(
        tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels,
                                                       logits=logits))

  grads = tape.gradient(loss, model.trainable_variables)

  # Aggregate the gradients from the full batch.
  replica_ctx = tf.distribute.get_replica_context()
  grads = replica_ctx.all_reduce("mean", grads)

  optimizer.apply(grads, model.trainable_variables)
  return loss

@tf.function
def train_step(images, labels):
  per_replica_loss = strategy.run(step, args=(images, labels))
  return strategy.reduce("sum", per_replica_loss, axis=None)

def train_epoch(dataset):
  """Performs one epoch of training, returning the mean cross-entropy loss."""
  total_loss = 0.0
  num_batches = 0

  # Loop over the entire training set.
  for images, labels in dataset:
    total_loss += train_step(images, labels).numpy()
    num_batches += 1

  return total_loss / num_batches

cifar10_train_dist = strategy.experimental_distribute_dataset(cifar10_train)

for epoch in range(20):
  print("Training epoch", epoch, "...", end=" ")
  print("loss :=", train_epoch(cifar10_train_dist))

 

モデルを評価する

バッチ次元に渡り削減するために strategy.reduce による axis パラメータの使用方法に注意してください。

num_cifar10_test_examples = 10000

def is_predicted(images, labels):
  logits = model(images, is_training=False)["logits"]
  # The reduction over the batch happens in `strategy.reduce`, below.
  return tf.cast(tf.equal(labels, tf.argmax(logits, axis=1)), dtype=tf.int32)

cifar10_test_dist = strategy.experimental_distribute_dataset(cifar10_test)

@tf.function
def evaluate():
  """Returns the top-1 accuracy over the entire test set."""
  total_correct = 0

  for images, labels in cifar10_test_dist:
    per_replica_correct = strategy.run(is_predicted, args=(images, labels))
    total_correct += strategy.reduce("sum", per_replica_correct, axis=0)

  return tf.cast(total_correct, tf.float32) / num_cifar10_test_examples

print("Testing...", end=" ")
print("top-1 accuracy =", evaluate().numpy())
 

以上






TensorFlow 2.0 : 上級 Tutorials : 分散訓練 :- 分散ストラテジーを使用してモデルをセーブとロードする

TensorFlow 2.0 : 上級 Tutorials : 分散訓練 :- 分散ストラテジーを使用してモデルをセーブとロードする (翻訳/解説)

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

* 本ページは、TensorFlow org サイトの TF 2.0 – Advanced Tutorials – Distributed training の以下のページを翻訳した上で
適宜、補足説明したものです:

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

 

無料セミナー開催中 クラスキャット主催 人工知能 & ビジネス Web セミナー

人工知能とビジネスをテーマにウェビナー (WEB セミナー) を定期的に開催しています。スケジュールは弊社 公式 Web サイト でご確認頂けます。
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
  • Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/
Facebook: https://www.facebook.com/ClassCatJP/

 

分散訓練 :- 分散ストラテジーを使用してモデルをセーブとロードする

概要

訓練の間にモデルをセーブしてロードすることは一般的です。keras モデルをセーブしてロードするために API の 2 つのセットがあります: 高位 API、そして低位 API です。このチュートリアルは tf.distribute.Strategy を使用するとき SavedModel API をどのように使用できるかを実演します。一般に SavedModel とシリアライゼーションについて学習するためには、saved model ガイド、そして Keras モデル・シリアライゼーション・ガイド を読んでください。単純なサンプルで始めましょう。

依存性をインポートします :

from __future__ import absolute_import, division, print_function, unicode_literals

import tensorflow_datasets as tfds

import tensorflow as tf
tfds.disable_progress_bar()

tf.distribute.Strategy を使用してデータとモデルを準備します :

mirrored_strategy = tf.distribute.MirroredStrategy()

def get_data():
  datasets, ds_info = tfds.load(name='mnist', with_info=True, as_supervised=True)
  mnist_train, mnist_test = datasets['train'], datasets['test']

  BUFFER_SIZE = 10000

  BATCH_SIZE_PER_REPLICA = 64
  BATCH_SIZE = BATCH_SIZE_PER_REPLICA * mirrored_strategy.num_replicas_in_sync

  def scale(image, label):
    image = tf.cast(image, tf.float32)
    image /= 255

    return image, label

  train_dataset = mnist_train.map(scale).cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
  eval_dataset = mnist_test.map(scale).batch(BATCH_SIZE)

  return train_dataset, eval_dataset

def get_model():
  with mirrored_strategy.scope():
    model = tf.keras.Sequential([
        tf.keras.layers.Conv2D(32, 3, activation='relu', input_shape=(28, 28, 1)),
        tf.keras.layers.MaxPooling2D(),
        tf.keras.layers.Flatten(),
        tf.keras.layers.Dense(64, activation='relu'),
        tf.keras.layers.Dense(10, activation='softmax')
    ])

    model.compile(loss='sparse_categorical_crossentropy',
                  optimizer=tf.keras.optimizers.Adam(),
                  metrics=['accuracy'])
    return model

モデルを訓練します :

model = get_model()
train_dataset, eval_dataset = get_data()
model.fit(train_dataset, epochs=2)
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
Downloading and preparing dataset mnist (11.06 MiB) to /home/kbuilder/tensorflow_datasets/mnist/1.0.0...

/home/kbuilder/.local/lib/python3.5/site-packages/urllib3/connectionpool.py:1004: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
/home/kbuilder/.local/lib/python3.5/site-packages/urllib3/connectionpool.py:1004: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
/home/kbuilder/.local/lib/python3.5/site-packages/urllib3/connectionpool.py:1004: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
/home/kbuilder/.local/lib/python3.5/site-packages/urllib3/connectionpool.py:1004: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,

WARNING:tensorflow:From /home/kbuilder/.local/lib/python3.5/site-packages/tensorflow_datasets/core/file_format_adapter.py:209: tf_record_iterator (from tensorflow.python.lib.io.tf_record) is deprecated and will be removed in a future version.
Instructions for updating:
Use eager execution and: 
`tf.data.TFRecordDataset(path)`

WARNING:tensorflow:From /home/kbuilder/.local/lib/python3.5/site-packages/tensorflow_datasets/core/file_format_adapter.py:209: tf_record_iterator (from tensorflow.python.lib.io.tf_record) is deprecated and will be removed in a future version.
Instructions for updating:
Use eager execution and: 
`tf.data.TFRecordDataset(path)`

Dataset mnist downloaded and prepared to /home/kbuilder/tensorflow_datasets/mnist/1.0.0. Subsequent calls will reuse this data.
Epoch 1/2
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

938/938 [==============================] - 14s 14ms/step - loss: 0.1997 - accuracy: 0.9430
Epoch 2/2
938/938 [==============================] - 2s 3ms/step - loss: 0.0674 - accuracy: 0.9801

<tensorflow.python.keras.callbacks.History at 0x7f1450dc75c0>

 

モデルをセーブしてロードする

作業するための単純なモデルを持った今、セーブ/ロード API を見てみまよう。利用可能な API の 2 つのセットがあります :

 

Keras API

ここに Keras API でモデルをセーブしてロードするサンプルがあります :

keras_model_path = "/tmp/keras_save"
model.save(keras_model_path)  # save() should be called out of strategy scope
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.5/site-packages/tensorflow_core/python/ops/resource_variable_ops.py:1781: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.

WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.5/site-packages/tensorflow_core/python/ops/resource_variable_ops.py:1781: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.

INFO:tensorflow:Reduce to /replica:0/task:0/device:CPU:0 then broadcast to ('/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /replica:0/task:0/device:CPU:0 then broadcast to ('/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /replica:0/task:0/device:CPU:0 then broadcast to ('/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /replica:0/task:0/device:CPU:0 then broadcast to ('/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Assets written to: /tmp/keras_save/assets

INFO:tensorflow:Assets written to: /tmp/keras_save/assets

tf.distribute.Strategy なしでモデルを復旧します :

restored_keras_model = tf.keras.models.load_model(keras_model_path)
restored_keras_model.fit(train_dataset, epochs=2)
Epoch 1/2
938/938 [==============================] - 10s 11ms/step - loss: 0.0491 - accuracy: 0.9851
Epoch 2/2
938/938 [==============================] - 3s 3ms/step - loss: 0.0339 - accuracy: 0.9900

<tensorflow.python.keras.callbacks.History at 0x7f14502d00f0>

モデルを復旧した後、その上で訓練を継続できます、compile() を再度呼び出す必要さえなく、何故ならばそれはセーブ前に既にコンパイルされているからです。モデルは TensorFlow の標準 SavedModel proto 形式でセーブされます。より多くの情報については、guide to saved_model format を参照してください。

tf.distribute.strategy のスコープの外から model.save() メソッドを呼び出すことだけは重要です。スコープ内でそれを呼び出すことはサポートされません。

今はモデルをロードしてそれを訓練するために tf.distribute.Strategy を使用します :

another_strategy = tf.distribute.OneDeviceStrategy("/cpu:0")
with another_strategy.scope():
  restored_keras_model_ds = tf.keras.models.load_model(keras_model_path)
  restored_keras_model_ds.fit(train_dataset, epochs=2)
Epoch 1/2
938/938 [==============================] - 15s 16ms/step - loss: 0.0486 - accuracy: 0.9852
Epoch 2/2
938/938 [==============================] - 11s 12ms/step - loss: 0.0345 - accuracy: 0.9897

見れるように、ロードは tf.distribute.Strategy とともに期待されたように動作します。 ここで使用されるストラテジーはセービングの前に使用されたのと同じストラテジーでなくてもかまいません。

 

tf.saved_model API

今は低位 API を見てみましょう。モデルのセービングは keras API に類似しています :

model = get_model()  # get a fresh model
saved_model_path = "/tmp/tf_save"
tf.saved_model.save(model, saved_model_path)
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Assets written to: /tmp/tf_save/assets

INFO:tensorflow:Assets written to: /tmp/tf_save/assets

ロードは tf.saved_model.load() で行なうことができます。けれども、それは低位上の API です (そしてそれ故により広範囲のユースケースを持ちます) から、それは Keras モデルを返しません。代わりに、それは推論を行なうために使用できる関数を含むオブジェクトを返します。例えば :

DEFAULT_FUNCTION_KEY = "serving_default"
loaded = tf.saved_model.load(saved_model_path)
inference_func = loaded.signatures[DEFAULT_FUNCTION_KEY]

ロードされたオブジェクトは複数の関数を含むかもしれません、各々はキーと関連付けられています。”serving_default” はセーブされた Keras モデルによる推論関数のためのデフォルトキーです。この関数で推論を行なうためには :

predict_dataset = eval_dataset.map(lambda image, label: image)
for batch in predict_dataset.take(1):
  print(inference_func(batch))
{'dense_3': <tf.Tensor: id=163719, shape=(64, 10), dtype=float32, numpy=
array([[0.10728385, 0.10047228, 0.10261484, 0.11404606, 0.10439669,
        0.09272724, 0.09213927, 0.10215139, 0.11169203, 0.07247637],
       [0.10643671, 0.09905838, 0.09364076, 0.11701185, 0.10924707,
        0.09127147, 0.09204151, 0.10397962, 0.10052412, 0.08678856],
       [0.10438395, 0.10305102, 0.09159523, 0.12274157, 0.1077928 ,
        0.09475194, 0.0791743 , 0.11037502, 0.09112864, 0.09500553],
       [0.10716499, 0.09490513, 0.10168986, 0.11599538, 0.10473887,
        0.08412197, 0.09422952, 0.10134438, 0.10640062, 0.08940925],
       [0.10903514, 0.10466785, 0.09625442, 0.09959863, 0.10513363,
        0.08701214, 0.09148837, 0.10629265, 0.10480279, 0.09571434],
       [0.10791405, 0.0994103 , 0.08700535, 0.11203778, 0.10917093,
        0.09215206, 0.09492003, 0.10987404, 0.10913727, 0.07837823],
       [0.10487697, 0.1086623 , 0.09380413, 0.11928336, 0.11513475,
        0.08585147, 0.0855743 , 0.10447548, 0.09436136, 0.08797587],
       [0.11953841, 0.10592035, 0.09351776, 0.10883537, 0.11183759,
        0.08616813, 0.08055402, 0.1016137 , 0.10553744, 0.08647724],
       [0.1001956 , 0.09496056, 0.10120489, 0.11922734, 0.09466279,
        0.08841368, 0.09372198, 0.10862154, 0.10443942, 0.0945522 ],
       [0.10173271, 0.10577305, 0.10043491, 0.10811324, 0.09887545,
        0.10345043, 0.09138881, 0.10311095, 0.10145498, 0.08566544],
       [0.10915802, 0.09801247, 0.09486966, 0.11884604, 0.10890727,
        0.09173197, 0.08757571, 0.1097801 , 0.09345251, 0.08766618],
       [0.12305965, 0.10477802, 0.10122419, 0.10920276, 0.10642693,
        0.0803097 , 0.089819  , 0.10291311, 0.09739247, 0.08487416],
       [0.11381779, 0.10931753, 0.09873011, 0.11637557, 0.11114289,
        0.08807714, 0.07799057, 0.09821263, 0.10721567, 0.07912013],
       [0.11134263, 0.09600631, 0.09837915, 0.12407107, 0.10555959,
        0.09594846, 0.08290008, 0.10883261, 0.10144335, 0.07551681],
       [0.11251914, 0.10554384, 0.09913144, 0.10999293, 0.10561096,
        0.07938422, 0.08732757, 0.10422582, 0.1096524 , 0.08661176],
       [0.1071265 , 0.10107235, 0.10104455, 0.12165232, 0.09664022,
        0.09286968, 0.0891385 , 0.10249172, 0.10644917, 0.08151497],
       [0.10819855, 0.10904767, 0.10180869, 0.11292984, 0.09951544,
        0.08959039, 0.09180361, 0.10376687, 0.0935899 , 0.089749  ],
       [0.10038829, 0.09874914, 0.09890129, 0.11915599, 0.10857335,
        0.09699985, 0.08979851, 0.10805573, 0.09952758, 0.07985032],
       [0.10805429, 0.10442685, 0.099279  , 0.11294735, 0.1079711 ,
        0.08618448, 0.08894631, 0.10854797, 0.11077981, 0.07286283],
       [0.11217733, 0.10181618, 0.09626949, 0.1101595 , 0.09953736,
        0.08308611, 0.1039778 , 0.11402612, 0.09844285, 0.08050729],
       [0.1175424 , 0.10847426, 0.09683861, 0.10149902, 0.10666198,
        0.08579018, 0.09005664, 0.10190959, 0.10221969, 0.08900762],
       [0.11500932, 0.10343985, 0.09347771, 0.12577702, 0.10971518,
        0.08523733, 0.08214136, 0.10528794, 0.09671546, 0.08319884],
       [0.11175612, 0.10435012, 0.0984369 , 0.1191108 , 0.09581577,
        0.08925212, 0.09045488, 0.10521886, 0.09986348, 0.08574096],
       [0.11444057, 0.10850222, 0.09963862, 0.10142051, 0.10838775,
        0.08676049, 0.08990512, 0.10423999, 0.09729694, 0.0894078 ],
       [0.10881206, 0.11097988, 0.09718787, 0.11925952, 0.09623734,
        0.08606921, 0.09177926, 0.09912794, 0.09836774, 0.09217919],
       [0.10792447, 0.11186771, 0.10025145, 0.1140421 , 0.10892291,
        0.08941509, 0.09012905, 0.09400386, 0.10047787, 0.08296548],
       [0.10844032, 0.09806747, 0.0961417 , 0.11372101, 0.09871072,
        0.09228362, 0.09338211, 0.10678563, 0.10351523, 0.08895217],
       [0.10387842, 0.09575935, 0.10545119, 0.10064226, 0.1034956 ,
        0.09042715, 0.09294212, 0.11890968, 0.11319113, 0.07530304],
       [0.1227584 , 0.10466544, 0.0841779 , 0.09771729, 0.11111001,
        0.08448302, 0.0934371 , 0.11048996, 0.10305537, 0.08810547],
       [0.12329397, 0.09496878, 0.103743  , 0.11139977, 0.10066491,
        0.08561404, 0.09533388, 0.11039741, 0.09291557, 0.08166874],
       [0.12045516, 0.10910697, 0.10111618, 0.09754261, 0.10887689,
        0.08471666, 0.09063336, 0.10426611, 0.09986193, 0.08342412],
       [0.11602842, 0.11101867, 0.10563238, 0.10994542, 0.10256457,
        0.0871765 , 0.0918168 , 0.10208733, 0.09566812, 0.0780618 ],
       [0.10475811, 0.10498275, 0.09951681, 0.10977667, 0.10362052,
        0.09762244, 0.0898955 , 0.10377637, 0.09997776, 0.08607301],
       [0.10318095, 0.10635176, 0.10179733, 0.11117157, 0.105158  ,
        0.09139618, 0.09156478, 0.09806094, 0.10203766, 0.08928081],
       [0.09828327, 0.10664824, 0.09477657, 0.12164301, 0.10451195,
        0.0932444 , 0.08256079, 0.10863042, 0.09929656, 0.09040477],
       [0.10853811, 0.11033206, 0.0940258 , 0.1113859 , 0.10713692,
        0.08983784, 0.0831388 , 0.10531119, 0.1047819 , 0.08551157],
       [0.11990581, 0.12092119, 0.1031604 , 0.11084578, 0.10152177,
        0.08251272, 0.08635441, 0.10541882, 0.09153688, 0.07782226],
       [0.10128036, 0.10670947, 0.10337903, 0.11031315, 0.1019455 ,
        0.09146291, 0.09584799, 0.09672082, 0.10148021, 0.09086055],
       [0.10947275, 0.10200524, 0.09993119, 0.10882212, 0.10303847,
        0.08627772, 0.09159538, 0.09889076, 0.10446595, 0.0955004 ],
       [0.10939393, 0.09627976, 0.10602371, 0.1142818 , 0.10102987,
        0.09605702, 0.08749614, 0.10808735, 0.10765684, 0.07369358],
       [0.10504688, 0.10167556, 0.10281529, 0.1192755 , 0.10568851,
        0.08670694, 0.08155579, 0.11723237, 0.09987677, 0.08012642],
       [0.10824965, 0.09176606, 0.09443861, 0.11798903, 0.11201838,
        0.09821461, 0.08609   , 0.11264105, 0.09485514, 0.0837375 ],
       [0.09964753, 0.10516388, 0.09635878, 0.1263353 , 0.10689379,
        0.09252935, 0.08307378, 0.10495035, 0.10201847, 0.08302879],
       [0.10292235, 0.10445141, 0.10405432, 0.11601374, 0.09692912,
        0.09204514, 0.08684668, 0.10418826, 0.1005675 , 0.09198151],
       [0.10444795, 0.09730533, 0.10376438, 0.12015738, 0.09772504,
        0.09089442, 0.08984255, 0.10278826, 0.11849745, 0.07457713],
       [0.10438851, 0.10686149, 0.10246357, 0.10493152, 0.10348819,
        0.08775381, 0.09083097, 0.09938617, 0.11093659, 0.08895922],
       [0.10544944, 0.09818077, 0.09329084, 0.11733873, 0.11078161,
        0.09766933, 0.09083114, 0.10782209, 0.0947513 , 0.08388472],
       [0.10703585, 0.10091925, 0.09355933, 0.11673613, 0.10551108,
        0.0878339 , 0.08623412, 0.10723548, 0.09952866, 0.09540622],
       [0.10752242, 0.10790183, 0.10093197, 0.11127086, 0.09987544,
        0.08419652, 0.09178086, 0.09874151, 0.10740087, 0.09037771],
       [0.10816085, 0.09434848, 0.09469503, 0.11608687, 0.10236199,
        0.0936012 , 0.09178096, 0.11500423, 0.10858335, 0.0753771 ],
       [0.10754462, 0.09610054, 0.10465137, 0.11755015, 0.09690968,
        0.0879105 , 0.09588192, 0.11404539, 0.10285615, 0.07654973],
       [0.11241148, 0.08882284, 0.09405247, 0.10950889, 0.10673883,
        0.08781228, 0.09985832, 0.1141803 , 0.10457499, 0.08203958],
       [0.1091413 , 0.10412721, 0.10478941, 0.10395776, 0.09535929,
        0.08805153, 0.09860662, 0.10201051, 0.10118678, 0.09276962],
       [0.10605051, 0.09701546, 0.0949271 , 0.11232355, 0.1087898 ,
        0.1004519 , 0.08760285, 0.11227378, 0.10104988, 0.07951519],
       [0.10381093, 0.09920877, 0.08820166, 0.12324253, 0.11016691,
        0.09974337, 0.08212494, 0.11035147, 0.106262  , 0.07688744],
       [0.11215791, 0.10010476, 0.10120094, 0.11671812, 0.10982783,
        0.08855668, 0.08435183, 0.11731754, 0.08742444, 0.08233997],
       [0.10245907, 0.10029367, 0.10221576, 0.10540797, 0.09739272,
        0.09511559, 0.09776582, 0.10032315, 0.101548  , 0.09747829],
       [0.10604411, 0.1033968 , 0.10131188, 0.10618415, 0.09859092,
        0.08605155, 0.09868422, 0.10696511, 0.10429069, 0.08848058],
       [0.10748281, 0.11348563, 0.09736608, 0.1156299 , 0.10006159,
        0.09052482, 0.08917169, 0.10554566, 0.0933612 , 0.08737059],
       [0.1029908 , 0.09412522, 0.09733023, 0.12130862, 0.10755724,
        0.0986068 , 0.08982269, 0.1031662 , 0.10753588, 0.0775563 ],
       [0.1047086 , 0.09500396, 0.09726457, 0.11584704, 0.10728658,
        0.0957251 , 0.09239414, 0.11417031, 0.09799711, 0.07960259],
       [0.11915238, 0.09845953, 0.09652468, 0.1032242 , 0.11258449,
        0.08078464, 0.09128478, 0.10983384, 0.10177512, 0.08637629],
       [0.11451644, 0.09615005, 0.09332057, 0.12316085, 0.11431079,
        0.08255224, 0.08722318, 0.11545283, 0.09139941, 0.08191368],
       [0.11015461, 0.10917749, 0.0990641 , 0.1019919 , 0.1069501 ,
        0.0880907 , 0.08974147, 0.1048572 , 0.10007656, 0.08989589]],
      dtype=float32)>}

分散マナーでロードして推論を行なうこともできます :

another_strategy = tf.distribute.MirroredStrategy()
with another_strategy.scope():
  loaded = tf.saved_model.load(saved_model_path)
  inference_func = loaded.signatures[DEFAULT_FUNCTION_KEY]

  dist_predict_dataset = another_strategy.experimental_distribute_dataset(
      predict_dataset)

  # Calling the function in a distributed manner
  for batch in dist_predict_dataset:
    another_strategy.experimental_run_v2(inference_func, 
                                         args=(batch,))
WARNING:tensorflow:Using MirroredStrategy eagerly has significant overhead currently. We will be working on improving this in the future, but for now please wrap `call_for_each_replica` or `experimental_run` or `experimental_run_v2` inside a tf.function to get the best performance.

WARNING:tensorflow:Using MirroredStrategy eagerly has significant overhead currently. We will be working on improving this in the future, but for now please wrap `call_for_each_replica` or `experimental_run` or `experimental_run_v2` inside a tf.function to get the best performance.

WARNING:tensorflow:Using MirroredStrategy eagerly has significant overhead currently. We will be working on improving this in the future, but for now please wrap `call_for_each_replica` or `experimental_run` or `experimental_run_v2` inside a tf.function to get the best performance.

WARNING:tensorflow:Using MirroredStrategy eagerly has significant overhead currently. We will be working on improving this in the future, but for now please wrap `call_for_each_replica` or `experimental_run` or `experimental_run_v2` inside a tf.function to get the best performance.

WARNING:tensorflow:Using MirroredStrategy eagerly has significant overhead currently. We will be working on improving this in the future, but for now please wrap `call_for_each_replica` or `experimental_run` or `experimental_run_v2` inside a tf.function to get the best performance.

WARNING:tensorflow:Using MirroredStrategy eagerly has significant overhead currently. We will be working on improving this in the future, but for now please wrap `call_for_each_replica` or `experimental_run` or `experimental_run_v2` inside a tf.function to get the best performance.

WARNING:tensorflow:Using MirroredStrategy eagerly has significant overhead currently. We will be working on improving this in the future, but for now please wrap `call_for_each_replica` or `experimental_run` or `experimental_run_v2` inside a tf.function to get the best performance.

WARNING:tensorflow:Using MirroredStrategy eagerly has significant overhead currently. We will be working on improving this in the future, but for now please wrap `call_for_each_replica` or `experimental_run` or `experimental_run_v2` inside a tf.function to get the best performance.

WARNING:tensorflow:Using MirroredStrategy eagerly has significant overhead currently. We will be working on improving this in the future, but for now please wrap `call_for_each_replica` or `experimental_run` or `experimental_run_v2` inside a tf.function to get the best performance.

WARNING:tensorflow:Using MirroredStrategy eagerly has significant overhead currently. We will be working on improving this in the future, but for now please wrap `call_for_each_replica` or `experimental_run` or `experimental_run_v2` inside a tf.function to get the best performance.

復旧された関数の呼び出しはセーブされたモデル上の forward パス (予測) です。ロードされた関数で訓練を続けることを望む場合はどうでしょう?あるいはロードされた関数をより大きなモデルに埋め込には?一般的な実践はこれを成すためにロードされたオブジェクトを Keras 層にラップすることです。幸い、ここで示されるように、TF Hub はこの目的のために hub.KerasLayer を持ちます :

import tensorflow_hub as hub

def build_model(loaded):
  x = tf.keras.layers.Input(shape=(28, 28, 1), name='input_x')
  # Wrap what's loaded to a KerasLayer
  keras_layer = hub.KerasLayer(loaded, trainable=True)(x)
  model = tf.keras.Model(x, keras_layer)
  return model

another_strategy = tf.distribute.MirroredStrategy()
with another_strategy.scope():
  loaded = tf.saved_model.load(saved_model_path)
  model = build_model(loaded)

  model.compile(loss='sparse_categorical_crossentropy',
                optimizer=tf.keras.optimizers.Adam(),
                metrics=['accuracy'])
  model.fit(train_dataset, epochs=2)
Epoch 1/2
938/938 [==============================] - 10s 10ms/step - loss: 0.1881 - accuracy: 0.9451
Epoch 2/2
938/938 [==============================] - 3s 3ms/step - loss: 0.0638 - accuracy: 0.9812

見れるように、hub.KerasLayer は tf.saved_model.load() でロードし戻された結果を (もう一つのモデルを構築するために使用できる) Keras 層にラップします。これは転移学習のために非常に有用です。

 

どの API を使用するべきでしょう?

セーブについては、keras モデルで作業している場合、Keras の model.save() API を使用することが殆ど常に推奨されます。貴方がセーブしているものが Keras モデルでないのであれば、低位レベルが貴方の唯一の選択肢です。

ロードについては、貴方がどの API を使用するかはロードする API から何を得ることを望むかに依拠します。Keras モデルを得ることができない (あるいは望まない) 場合にはtf.saved_model.load() を使用します。そうでないなら、tf.keras.models.load_model() を使用します。Keras モデルでセーブした場合に限り Keras モデルを戻して得ることができることに注意してください。

API を混在させて適合させることは可能です。model.save で Keras モデルをセーブできて、低位 API, tf.saved_model.load で非 Keras モデルをロードできます。

model = get_model()

# Saving the model using Keras's save() API
model.save(keras_model_path) 

another_strategy = tf.distribute.MirroredStrategy()
# Loading the model using lower level API
with another_strategy.scope():
  loaded = tf.saved_model.load(keras_model_path)
INFO:tensorflow:Assets written to: /tmp/keras_save/assets

INFO:tensorflow:Assets written to: /tmp/keras_save/assets

 

Caveats (注意事項)

特別なケースは well-defined な入力を持たない Keras モデルを持つときです。例えば、Sequential モデルは任意の入力 shape なしに作成できます (Sequential([Dense(3), …])。Subclassed モデルもまた初期化後 well-defined な入力を持ちません。この場合、セーブとロードの両方で低位 API に固執するべきです。

貴方のモデルが well-defined な入力を持つかどうか確認するには、単に model.inputs が None であるか確認します。それが None でないならば、総て問題ありません。モデルが .fit, .evaluate, .predict やモデルを呼び出す (model(inputs)) とき入力 shape は自動的に定義されます。

ここのサンプルがあります :

class SubclassedModel(tf.keras.Model):

  output_name = 'output_layer'

  def __init__(self):
    super(SubclassedModel, self).__init__()
    self._dense_layer = tf.keras.layers.Dense(
        5, dtype=tf.dtypes.float32, name=self.output_name)

  def call(self, inputs):
    return self._dense_layer(inputs)

my_model = SubclassedModel()
# my_model.save(keras_model_path)  # ERROR! 
tf.saved_model.save(my_model, saved_model_path)
WARNING:tensorflow:Skipping full serialization of Keras model <__main__.SubclassedModel object at 0x7f15017bfa90>, because its inputs are not defined.

WARNING:tensorflow:Skipping full serialization of Keras model <__main__.SubclassedModel object at 0x7f15017bfa90>, because its inputs are not defined.

WARNING:tensorflow:Skipping full serialization of Keras layer , because it is not built.

WARNING:tensorflow:Skipping full serialization of Keras layer , because it is not built.

INFO:tensorflow:Assets written to: /tmp/tf_save/assets

INFO:tensorflow:Assets written to: /tmp/tf_save/assets
 

以上






TensorFlow 2.0 : 上級 Tutorials : 分散訓練 :- Keras でマルチワーカー訓練

TensorFlow 2.0 : 上級 Tutorials : 分散訓練 :- Keras でマルチワーカー訓練 (翻訳/解説)

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

* 本ページは、TensorFlow org サイトの TF 2.0 – Advanced Tutorials – Distributed training の以下のページを翻訳した上で
適宜、補足説明したものです:

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

 

無料セミナー開催中 クラスキャット主催 人工知能 & ビジネス Web セミナー

人工知能とビジネスをテーマにウェビナー (WEB セミナー) を定期的に開催しています。スケジュールは弊社 公式 Web サイト でご確認頂けます。
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
  • Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/
Facebook: https://www.facebook.com/ClassCatJP/

 

分散訓練 :- Keras でマルチワーカー訓練

概要

このチュートリアルは tf.distribute.Strategy API を使用して Keras モデルによるマルチワーカー分散訓練を実演します。マルチワーカー訓練のために特に設計されたストラテジーの助けにより、シングルワーカー上で動作するために設計された Keras モデルは最小限のコード変更で複数ワーカーでシームレスに動作できます。

Distributed Training in TensorFlow ガイドは TensorFlow がサポートする分散ストラテジーの概要について tf.distribute.Strategy API のより深い理解に感心がある人達のために利用可能です。

 

セットアップ

最初に、TensorFlow と必要なインポートをセットアップします。

from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow_datasets as tfds
import tensorflow as tf
tfds.disable_progress_bar()

 

データセットを準備する

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

BUFFER_SIZE = 10000
BATCH_SIZE = 64

def make_datasets_unbatched():
  # Scaling MNIST data from (0, 255] to (0., 1.]
  def scale(image, label):
    image = tf.cast(image, tf.float32)
    image /= 255
    return image, label

  datasets, info = tfds.load(name='mnist',
                            with_info=True,
                            as_supervised=True)

  return datasets['train'].map(scale).cache().shuffle(BUFFER_SIZE)

train_datasets = make_datasets_unbatched().batch(BATCH_SIZE)
Downloading and preparing dataset mnist (11.06 MiB) to /home/kbuilder/tensorflow_datasets/mnist/1.0.0...

/usr/lib/python3/dist-packages/urllib3/connectionpool.py:860: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
/usr/lib/python3/dist-packages/urllib3/connectionpool.py:860: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
/usr/lib/python3/dist-packages/urllib3/connectionpool.py:860: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
/usr/lib/python3/dist-packages/urllib3/connectionpool.py:860: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)

WARNING:tensorflow:From /home/kbuilder/.local/lib/python3.6/site-packages/tensorflow_datasets/core/file_format_adapter.py:209: tf_record_iterator (from tensorflow.python.lib.io.tf_record) is deprecated and will be removed in a future version.
Instructions for updating:
Use eager execution and: 
`tf.data.TFRecordDataset(path)`

WARNING:tensorflow:From /home/kbuilder/.local/lib/python3.6/site-packages/tensorflow_datasets/core/file_format_adapter.py:209: tf_record_iterator (from tensorflow.python.lib.io.tf_record) is deprecated and will be removed in a future version.
Instructions for updating:
Use eager execution and: 
`tf.data.TFRecordDataset(path)`

Dataset mnist downloaded and prepared to /home/kbuilder/tensorflow_datasets/mnist/1.0.0. Subsequent calls will reuse this data.

 

Keras モデルを構築する

ここではMNIST データセットで訓練するために単純な畳み込みニューラルネットワーク Keras モデルを構築してコンパイルするために tf.keras.Sequential API を使用します。

def build_and_compile_cnn_model():
  model = tf.keras.Sequential([
      tf.keras.layers.Conv2D(32, 3, activation='relu', input_shape=(28, 28, 1)),
      tf.keras.layers.MaxPooling2D(),
      tf.keras.layers.Flatten(),
      tf.keras.layers.Dense(64, activation='relu'),
      tf.keras.layers.Dense(10, activation='softmax')
  ])
  model.compile(
      loss=tf.keras.losses.sparse_categorical_crossentropy,
      optimizer=tf.keras.optimizers.SGD(learning_rate=0.001),
      metrics=['accuracy'])
  return model

最初に小さい数のエポックの間モデルを訓練してみて総てが正しく動作するかを確実にするためにシングル・ワーカーで結果を観察しましょう。エポックが進むにつれて損失が落ちて精度が 1.0 に近づくことを見ることを期待できるはずです。

single_worker_model = build_and_compile_cnn_model()
single_worker_model.fit(x=train_datasets, epochs=3)
Epoch 1/3
938/938 [==============================] - 11s 12ms/step - loss: 2.0667 - accuracy: 0.4719
Epoch 2/3
938/938 [==============================] - 2s 3ms/step - loss: 1.1673 - accuracy: 0.7724
Epoch 3/3
938/938 [==============================] - 2s 3ms/step - loss: 0.6323 - accuracy: 0.8469

<tensorflow.python.keras.callbacks.History at 0x7fc3b85f7978>

 

マルチワーカー Configuration

さて、マルチワーカー訓練の世界に入りましょう。TensorFlow では、複数マシン上の訓練のために TF_CONFIG 環境変数が必要です、それらの各々は多分異なる役割りを持ちます。TF_CONFIG はクラスタの一部である各ワーカー上クラスタ構成を指定するために使用されます。

TF_CONFIG の 2 つのコンポーネントがあります: cluster と task です。cluster は訓練クラスタについての情報を提供します、これは worker のようなジョブの異なる型から成る dict です。マルチワーカー訓練では、通常のワーカーが行なうものに加えて、チェックポイントをセーブして TensorBoard のために要約ファイルを書くような少し多くの責任を追う 1 つのワーカーが通常はあります。そのようなワーカーは ‘chief’ ワーカーとして参照され、インデックス 0 を持つワーカーが chief ワーカーとして任命されるのが習慣です (実際にこれは tf.distribute.Strategy がどのように実装されるかです)。他方、task は現在のタスクの情報を提供します。

このサンプルでは、タスクタイプを “worker” にそしてタスクインデックスを 0 に設定します。これはそのような設定を持つマシンが最初のワーカーであることを意味します、これはチーフ・ワーカーとして指定されて他のワーカーよりも多くの作業を行ないます。他のマシンもまた TF_CONFIG 環境変数を持つ必要があることに注意してください、そしてそれは同じ cluster dict を、しかしそれらのマシンの役割りが何であるかに依拠して異なるタスクタイプあるいはタスクインデックスを持つはずです。

説明目的で、このチュートリアルはローカルホスト上の 2 ワーカーで TF_CONFIG をどのように設定して良いかを示します。実際には、ユーザは外部 IP アドレス/ポート上でマルチワーカーを作成し、そして各ワーカー上で TF_CONFIG を適切に設定します。

警告: 次のコードを Colab で実行しないでください。TensorFlow のランタイムは指定された IP アドレスとポートで gRPC サーバを作成することを試みて、それは失敗しがちです。

 

os.environ['TF_CONFIG'] = json.dumps({
    'cluster': {
        'worker': ["localhost:12345", "localhost:23456"]
    },
    'task': {'type': 'worker', 'index': 0}
})

このサンプルでは学習率は固定される一方で、一般にはグローバルバッチサイズに基づいて学習率を調整する必要があるかもしれません。

 

正しいストラテジーを選択する

TensorFlow では、分散訓練は同期訓練、そこでは訓練ステップはワーカーとレプリカに渡り同期されます、そして非同期訓練、そこでは訓練ステップは厳密には同期されません、から成ります。

MultiWorkerMirroredStrategy、これは同期マルチワーカー訓練のために推奨されるストラテジーです、はこのガイドで実演されます。モデルを訓練するために、tf.distribute.experimental.MultiWorkerMirroredStrategy のインスタンスを使用します。MultiWorkerMirroredStrategy は総てのワーカーに渡り各デバイス上でモデルの層の総ての変数のコピーを作成します。それは勾配を累積して変数を同期して保持するために CollectiveOps、collective な通信のための TensorFlow op を使用します。tf.distribute.Strategy ガイド はこのストラテジーについてより詳細を持ちます。

strategy = tf.distribute.experimental.MultiWorkerMirroredStrategy()
WARNING:tensorflow:Collective ops is not configured at program startup. Some performance features may not be enabled.

WARNING:tensorflow:Collective ops is not configured at program startup. Some performance features may not be enabled.

INFO:tensorflow:Single-worker CollectiveAllReduceStrategy with local_devices = ('/device:GPU:0',), communication = CollectiveCommunication.AUTO

INFO:tensorflow:Single-worker CollectiveAllReduceStrategy with local_devices = ('/device:GPU:0',), communication = CollectiveCommunication.AUTO

Note: MultiWorkerMirroredStrategy.init() が呼び出されるときに TF_CONFIG はパースされて TensorFlow の GRPC は開始されますので、TF_CONFIG 環境変数は tf.distribute.Strategy インスタンスが作成される前に設定されなければなりません。

MultiWorkerMirroredStrategy は CollectiveCommunication パラメータを通して複数の実装を提供します。RING は gRPC を使用して ring-based collective を cross-ホスト通信層として実装します。NCCL は collective を実装するために Nvidia の NCCL を使用します。AUTO は選択をランタイムに任せます。collective 実装の最善の選択は GPU の数と種類、そしてクラスタのネットワーク相互接続に依拠します。

 

モデルを MultiWorkerMirroredStrategy で訓練する

tf.distribute.Strategy API の tf.keras への統合では、訓練をマルチワーカーに分散するために行なう唯一の変更はモデル構築と model.compile() 呼び出しを strategy.scope() 内に包み込むことです。分散ストラテジーのスコープは変数がどのようにそしてどこで作成されるかを指示します、そして MultiWorkerMirroredStrategy の場合には、作成される変数は MirroredVariable で、それらはワーカーの各々で複製されます。

Note: 現在 MultiWorkerMirroredStrategy には制限があり、そこでは TensorFlow ops は strategy のインスタンスが作成された後に作成される必要があります。RuntimeError: Collective ops must be configured at program startup を見る場合、MultiWorkerMirroredStrategy のインスタンスをプログラムの最初で作成してみてください、そして ops を作成するかもしれないコードを strategy がインスタンス化された後に置きます。

Note: この Colab では、次のコードは期待される結果とともに動作できますが、けれどもこれは効果的なシングルワーカー訓練です、何故ならば TF_CONFIG が設定されていないからです。貴方自身のサンプルで TF_CONFIG をひとたび設定すれば、複数のマシン上の訓練によるスピードアップを期待できるはずです。

NUM_WORKERS = 2
# Here the batch size scales up by number of workers since 
# `tf.data.Dataset.batch` expects the global batch size. Previously we used 64, 
# and now this becomes 128.
GLOBAL_BATCH_SIZE = 64 * NUM_WORKERS
with strategy.scope():
  # Creation of dataset, and model building/compiling need to be within 
  # `strategy.scope()`.
  train_datasets = make_datasets_unbatched().batch(GLOBAL_BATCH_SIZE)
  multi_worker_model = build_and_compile_cnn_model()
multi_worker_model.fit(x=train_datasets, epochs=3)
Epoch 1/3
469/469 [==============================] - 9s 18ms/step - loss: 2.2174 - accuracy: 0.2142
Epoch 2/3
469/469 [==============================] - 1s 3ms/step - loss: 1.9502 - accuracy: 0.5165
Epoch 3/3
469/469 [==============================] - 1s 3ms/step - loss: 1.4742 - accuracy: 0.7417

<tensorflow.python.keras.callbacks.History at 0x7fc3a0123e48>

 

Dataset シャーディングとバッチサイズ

マルチワーカー訓練では、収束とパフォーマンスを確実にするためにデータを複数のパートにシャーディングすることが必要です。けれども、上のコードスニペットでは、データセットはシャーディングする必要なく model.fit() に直接送られていることに注意してください ; これは tf.distribute.Strategy API がマルチワーカー訓練でデータセットのシャーディングを自動的に対処するからです。

貴方の訓練のために手動のシャーディングを好むのであれば、自動シャーディングは tf.data.experimental.DistributeOptions api を通して無効にできます。具体的には、

options = tf.data.Options()
options.experimental_distribute.auto_shard = False
train_datasets_no_auto_shard = train_datasets.with_options(options)

注意すべきもう一つのことはデータセットのためのバッチサイズです。上のコードスニペットでは、GLOBAL_BATCH_SIZE = 64 * NUM_WORKERS を使用しています、これはそれがシングルワーカーのためのケースほどの大きさの NUM_WORKERS 倍です、何故ならば効果的なワーカー毎バッチサイズはワーカー数で除算されたグローバルバッチサイズです、そしてこの変更により前と同じワーカー毎バッチサイズを保持しています。

 

パフォーマンス

今は MultiWorkerMirroredStrategy によりマルチワーカーで動作するように総てセットアップされた Keras モデルを持ちます。マルチワーカー訓練のパフォーマンスを微調整するために次のテクニックを試すことができます。

  • MultiWorkerMirroredStrategy は複数の collective 通信実装 を提供します。RING は gRPC を使用して ring-based collectives を cross-ホスト通信層として実装します。NCCL は collective を実装するために Nvidia の NCCL を使用します。AUTO は選択をランタイムに任せます。collective 実装の最善の選択は GPU の数と種類、そしてクラスタのネットワーク相互接続に依拠します。自動選択をオーバーライドするには、MultiWorkerMirroredStrategy のコンストラクタの communication パラメータに正当な値を指定します、e.g. communication=tf.distribute.experimental.CollectiveCommunication.NCCL。
  • 可能であれば変数を tf.float にキャストします。公式の ResNet モデルはこれがどのように成されるかの サンプル を含みます。

 

フォールトトレランス

同期訓練では、ワーカーの一つが失敗して障害復旧メカニズムが存在しないのであれば、クラスタは失敗するでしょう。tf.distribute.Strategy で Keras を使用するとワーカーが予期せぬ停止をするかそうでないなら安定していない場合にフォールトトレランスの優位点を装備します。これを訓練状態を貴方が選択する分散ファイルシステムに保存することにより行ないます、その結果前に失敗したか無効にされたインスタンスの再開始時に訓練状態がリカバーされます。

総てのワーカーは訓練エポックとステップの観点から同期的に保持されますので、他のワーカーは失敗したか無効にされたワーカーが続行するために再開始されるのを待つ必要があります。

 

ModelCheckpoint コールバック

マルチワーカー訓練でフォールトトレランスを利用するために、tf.keras.Model.fit() 呼び出しで tf.keras.callbacks.ModelCheckpoint のインスタンスを提供します。コールバックは ModelCheckpoint の filepath 引数に対応するディレクトリにチェックポイントと訓練状態をストアします。

# Replace the `filepath` argument with a path in the file system
# accessible by all workers.
callbacks = [tf.keras.callbacks.ModelCheckpoint(filepath='/tmp/keras-ckpt')]
with strategy.scope():
  multi_worker_model = build_and_compile_cnn_model()
multi_worker_model.fit(x=train_datasets, epochs=3, callbacks=callbacks)
Epoch 1/3
    469/Unknown - 8s 18ms/step - loss: 2.2049 - accuracy: 0.2318WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_core/python/ops/resource_variable_ops.py:1781: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.

WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_core/python/ops/resource_variable_ops.py:1781: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.

INFO:tensorflow:Assets written to: /tmp/keras-ckpt/assets

INFO:tensorflow:Assets written to: /tmp/keras-ckpt/assets

469/469 [==============================] - 9s 19ms/step - loss: 2.2049 - accuracy: 0.2318
Epoch 2/3
451/469 [===========================>..] - ETA: 0s - loss: 1.9195 - accuracy: 0.5715INFO:tensorflow:Assets written to: /tmp/keras-ckpt/assets

INFO:tensorflow:Assets written to: /tmp/keras-ckpt/assets

469/469 [==============================] - 2s 4ms/step - loss: 1.9113 - accuracy: 0.5767
Epoch 3/3
450/469 [===========================>..] - ETA: 0s - loss: 1.4175 - accuracy: 0.7550INFO:tensorflow:Assets written to: /tmp/keras-ckpt/assets

INFO:tensorflow:Assets written to: /tmp/keras-ckpt/assets

469/469 [==============================] - 2s 4ms/step - loss: 1.4078 - accuracy: 0.7561

<tensorflow.python.keras.callbacks.History at 0x7fc38fdfee80>

ワーカーが無効にされる場合、クラスタ全体は無効にされたワーカーが再開始されるまで一時的に停止します。ひとたびワーカーがクラスタに再び加われば、他のワーカーも再開始します。今は、総てのワーカーは前にセーブされたチェックポイント・ファイルを読みそして前の状態をピックアップし、従ってクラスタに同期的に戻ることを可能にします。そして訓練は続行します。

ModelCheckpoint で指定した filepath を含むディレクトリを調べると、幾つかの一時的に生成されたチェックポイント・ファイルに気付くかもしれません。それらのファイルは前に失われたインスタンスをリカバーするために必要です、そしてそれらはマルチワーカー訓練の成功的な exit の時に tf.keras.Model.fit() の最後でライブラリにより削除されます。

 

See also

  1. Distributed Training in TensorFlow ガイドは利用可能な分散ストラテジーの概要を提供します。
  2. MirroredStrategy か MultiWorkerMirroredStrategy を使用して訓練できる、公式の ResNet50 モデル。
 

以上






TensorFlow 2.0 : 上級 Tutorials : 分散訓練 :- Estimator でマルチワーカー訓練

TensorFlow 2.0 : 上級 Tutorials : 分散訓練 :- Estimator でマルチワーカー訓練 (翻訳/解説)

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

* 本ページは、TensorFlow org サイトの TF 2.0 – Advanced Tutorials – Distributed training の以下のページを翻訳した上で
適宜、補足説明したものです:

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

 

無料セミナー開催中 クラスキャット主催 人工知能 & ビジネス Web セミナー

人工知能とビジネスをテーマにウェビナー (WEB セミナー) を定期的に開催しています。スケジュールは弊社 公式 Web サイト でご確認頂けます。
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
  • Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/
Facebook: https://www.facebook.com/ClassCatJP/

 

分散訓練 :- Estimator でマルチワーカー訓練

概要

Note: Estimator で tf.distribute API を利用できる一方で、代わりに tf.distribute で Keras を使用することを貴方に勧めます (Multi-worker Training with Keras を見てください)。tf.distribute.Strategy を伴う Estimator 訓練は現時点では制限されたサポートを持ちます。

このチュートリアルは tf.distribute.Strategy が tf.estimator で分散マルチワーカー訓練のためにどのように使用できるかを実演します。貴方のコードを tf.estimator を使用して書いて、そして高パフォーマンスで単一マシンを越えてスケーリングすることに関心がある場合、このチュートリアルは貴方のためにあります。

始める前に、tf.distribute.Strategy ガイド を読んでください。マルチ GPU 訓練ガイド もまた関連があります、何故ならばこのチュートリアルは同じモデルを使用するからです。

 

セットアップ

最初に、TensorFlow と必要なインポートをセットアップします。

from __future__ import absolute_import, division, print_function, unicode_literals 
import tensorflow_datasets as tfds
import tensorflow as tf
tfds.disable_progress_bar()

import os, json

 

入力関数

このチュートリアルは TensorFlow Dataset から MNIST データセットを使用します。ここでのコードは一つの主要な違いとともに マルチ GPU 訓練チュートリアル に類似しています : マルチワーカー訓練のために Estimator を使用するとき、モデル収束を確実にするためにデータセットをシャードする必要があります。入力データは、各ワーカーがデータセットの 1/num_workers の異なる部分を処理するように、ワーカーインデックスでシャードされます。

BUFFER_SIZE = 10000
BATCH_SIZE = 64

def input_fn(mode, input_context=None):
  datasets, info = tfds.load(name='mnist',
                                with_info=True,
                                as_supervised=True)
  mnist_dataset = (datasets['train'] if mode == tf.estimator.ModeKeys.TRAIN else
                   datasets['test'])

  def scale(image, label):
    image = tf.cast(image, tf.float32)
    image /= 255
    return image, label

  if input_context:
    mnist_dataset = mnist_dataset.shard(input_context.num_input_pipelines,
                                        input_context.input_pipeline_id)
  return mnist_dataset.map(scale).cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE)

収束を獲得するための他の合理的なアプローチは各ワーカーで異なる seed でデータセットをシャッフルすることです。

 

マルチワーカー configuration

(マルチ GPU 訓練チュートリアル に比較して) このチュートリアルの主要な違いの一つはマルチワーカー・セットアップです。TF_CONFIG 環境変数はクラスタの一部である各ワーカーにクラスタ configuration を指定するための標準的な方法です。

TF_CONFIG の 2 つの構成要素があります : cluster と task です。cluster はクラスタ全体についての情報を提供します、つまりクラスタのワーカーとパラメータサーバです。task は現在のタスクについての情報を提供します。この例では、タスクタイプはワーカーでタスクインデックスは 0 です。

説明目的で、このチュートリアルはローカルホスト上 2 つのワーカーで TF_CONFIG をどのように設定するかを示します。実際には、貴方は外部 IP アドレスとポート上マルチワーカーを作成して各ワーカーで TF_CONFIG を適切に設定します、i.e. タスクインデックスを変更します。

警告: 次のコードを Colab で実行しないでください。TensorFlow のランタイムは指定された IP アドレスとポートで gRPC サーバを作成することを試みて、それは失敗しがちです。

 

os.environ['TF_CONFIG'] = json.dumps({
    'cluster': {
        'worker': ["localhost:12345", "localhost:23456"]
    },
    'task': {'type': 'worker', 'index': 0}
})

 

モデルを定義する

訓練のための層、optimizer と損失関数を書きます。このチュートリアルは マルチ GPU 訓練チュートリアル と同様に、Keras 層でモデルを定義します。

LEARNING_RATE = 1e-4
def model_fn(features, labels, mode):
  model = tf.keras.Sequential([
      tf.keras.layers.Conv2D(32, 3, activation='relu', input_shape=(28, 28, 1)),
      tf.keras.layers.MaxPooling2D(),
      tf.keras.layers.Flatten(),
      tf.keras.layers.Dense(64, activation='relu'),
      tf.keras.layers.Dense(10)
  ])
  logits = model(features, training=False)

  if mode == tf.estimator.ModeKeys.PREDICT:
    predictions = {'logits': logits}
    return tf.estimator.EstimatorSpec(labels=labels, predictions=predictions)

  optimizer = tf.compat.v1.train.GradientDescentOptimizer(
      learning_rate=LEARNING_RATE)
  loss = tf.keras.losses.SparseCategoricalCrossentropy(
      from_logits=True, reduction=tf.keras.losses.Reduction.NONE)(labels, logits)
  loss = tf.reduce_sum(loss) * (1. / BATCH_SIZE)
  if mode == tf.estimator.ModeKeys.EVAL:
    return tf.estimator.EstimatorSpec(mode, loss=loss)

  return tf.estimator.EstimatorSpec(
      mode=mode,
      loss=loss,
      train_op=optimizer.minimize(
          loss, tf.compat.v1.train.get_or_create_global_step()))

Note: このサンプルでは学習率は固定されますが、一般にはグローバルバッチサイズに基づいて学習率を調整する必要があるかもしれません。

 

MultiWorkerMirroredStrategy

モデルを訓練するために、tf.distribute.experimental.MultiWorkerMirroredStrategy のインスタンスを使用します。MultiWorkerMirroredStrategy は総てのワーカーに渡り各デバイス上モデルの層で総ての変数のコピーを作成します。それは勾配を累積して変数を同期して保持するために CollectiveOps、collective 通信のための TensorFlow op を使用します。tf.distribute.Strategy guide ガイド はこのストラテジーについてより詳細を持ちます。

strategy = tf.distribute.experimental.MultiWorkerMirroredStrategy()
INFO:tensorflow:Single-worker CollectiveAllReduceStrategy with local_devices = ('/device:GPU:0',), communication = CollectiveCommunication.AUTO

 

モデルを訓練して評価する

次に、estimator のために RunConfig で分散ストラテジーを指定し、そして tf.estimator.train_and_evaluate を呼び出して訓練と評価をします。このチュートリアルは train_distribute を通してストラテジーを指定することにより訓練だけを分散します。eval_distribute を通して評価を分散することも可能です。

config = tf.estimator.RunConfig(train_distribute=strategy)

classifier = tf.estimator.Estimator(
    model_fn=model_fn, model_dir='/tmp/multiworker', config=config)
tf.estimator.train_and_evaluate(
    classifier,
    train_spec=tf.estimator.TrainSpec(input_fn=input_fn),
    eval_spec=tf.estimator.EvalSpec(input_fn=input_fn)
)
INFO:tensorflow:Initializing RunConfig with distribution strategies.
INFO:tensorflow:Not using Distribute Coordinator.
INFO:tensorflow:Using config: {'_master': '', '_save_checkpoints_steps': None, '_num_ps_replicas': 0, '_is_chief': True, '_evaluation_master': '', '_service': None, '_train_distribute': <tensorflow.python.distribute.collective_all_reduce_strategy.CollectiveAllReduceStrategy object at 0x7fea2d0fb828>, '_global_id_in_cluster': 0, '_save_summary_steps': 100, '_experimental_max_worker_delay_secs': None, '_keep_checkpoint_every_n_hours': 10000, '_distribute_coordinator_mode': None, '_log_step_count_steps': 100, '_task_type': 'worker', '_keep_checkpoint_max': 5, '_num_worker_replicas': 1, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_device_fn': None, '_session_creation_timeout_secs': 7200, '_tf_random_seed': None, '_save_checkpoints_secs': 600, '_model_dir': '/tmp/multiworker', '_experimental_distribute': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x7fea2d0fb9b0>, '_protocol': None, '_task_id': 0, '_eval_distribute': None}
INFO:tensorflow:Not using Distribute Coordinator.
INFO:tensorflow:Running training and evaluation locally (non-distributed).
INFO:tensorflow:Start train and evaluate loop. The evaluate will happen after every checkpoint. Checkpoint frequency is determined based on RunConfig arguments: save_checkpoints_steps None or save_checkpoints_secs 600.
INFO:tensorflow:The `input_fn` accepts an `input_context` which will be given by DistributionStrategy
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.5/site-packages/tensorflow_core/python/ops/resource_variable_ops.py:1630: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.

WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.5/site-packages/tensorflow_core/python/ops/resource_variable_ops.py:1630: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Create CheckpointSaverHook.

INFO:tensorflow:Create CheckpointSaverHook.

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Saving checkpoints for 0 into /tmp/multiworker/model.ckpt.

INFO:tensorflow:Saving checkpoints for 0 into /tmp/multiworker/model.ckpt.

INFO:tensorflow:loss = 2.3090205, step = 0

INFO:tensorflow:loss = 2.3090205, step = 0

INFO:tensorflow:global_step/sec: 137.125

INFO:tensorflow:global_step/sec: 137.125

INFO:tensorflow:loss = 2.2972226, step = 100 (0.732 sec)

INFO:tensorflow:loss = 2.2972226, step = 100 (0.732 sec)

INFO:tensorflow:global_step/sec: 145.665

INFO:tensorflow:global_step/sec: 145.665

INFO:tensorflow:loss = 2.2918024, step = 200 (0.686 sec)

INFO:tensorflow:loss = 2.2918024, step = 200 (0.686 sec)

INFO:tensorflow:global_step/sec: 137.544

INFO:tensorflow:global_step/sec: 137.544

INFO:tensorflow:loss = 2.305677, step = 300 (0.727 sec)

INFO:tensorflow:loss = 2.305677, step = 300 (0.727 sec)

INFO:tensorflow:global_step/sec: 137.924

INFO:tensorflow:global_step/sec: 137.924

INFO:tensorflow:loss = 2.2915964, step = 400 (0.725 sec)

INFO:tensorflow:loss = 2.2915964, step = 400 (0.725 sec)

INFO:tensorflow:global_step/sec: 137.804

INFO:tensorflow:global_step/sec: 137.804

INFO:tensorflow:loss = 2.2914124, step = 500 (0.725 sec)

INFO:tensorflow:loss = 2.2914124, step = 500 (0.725 sec)

INFO:tensorflow:global_step/sec: 142.391

INFO:tensorflow:global_step/sec: 142.391

INFO:tensorflow:loss = 2.2710123, step = 600 (0.703 sec)

INFO:tensorflow:loss = 2.2710123, step = 600 (0.703 sec)

INFO:tensorflow:global_step/sec: 138.232

INFO:tensorflow:global_step/sec: 138.232

INFO:tensorflow:loss = 2.272681, step = 700 (0.723 sec)

INFO:tensorflow:loss = 2.272681, step = 700 (0.723 sec)

INFO:tensorflow:global_step/sec: 160.382

INFO:tensorflow:global_step/sec: 160.382

INFO:tensorflow:loss = 2.2810445, step = 800 (0.623 sec)

INFO:tensorflow:loss = 2.2810445, step = 800 (0.623 sec)

INFO:tensorflow:global_step/sec: 643.312

INFO:tensorflow:global_step/sec: 643.312

INFO:tensorflow:loss = 2.2849498, step = 900 (0.154 sec)

INFO:tensorflow:loss = 2.2849498, step = 900 (0.154 sec)

INFO:tensorflow:Saving checkpoints for 938 into /tmp/multiworker/model.ckpt.

INFO:tensorflow:Saving checkpoints for 938 into /tmp/multiworker/model.ckpt.

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Starting evaluation at 2019-10-01T01:21:23Z

INFO:tensorflow:Starting evaluation at 2019-10-01T01:21:23Z

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Restoring parameters from /tmp/multiworker/model.ckpt-938

INFO:tensorflow:Restoring parameters from /tmp/multiworker/model.ckpt-938

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Evaluation [10/100]

INFO:tensorflow:Evaluation [10/100]

INFO:tensorflow:Evaluation [20/100]

INFO:tensorflow:Evaluation [20/100]

INFO:tensorflow:Evaluation [30/100]

INFO:tensorflow:Evaluation [30/100]

INFO:tensorflow:Evaluation [40/100]

INFO:tensorflow:Evaluation [40/100]

INFO:tensorflow:Evaluation [50/100]

INFO:tensorflow:Evaluation [50/100]

INFO:tensorflow:Evaluation [60/100]

INFO:tensorflow:Evaluation [60/100]

INFO:tensorflow:Evaluation [70/100]

INFO:tensorflow:Evaluation [70/100]

INFO:tensorflow:Evaluation [80/100]

INFO:tensorflow:Evaluation [80/100]

INFO:tensorflow:Evaluation [90/100]

INFO:tensorflow:Evaluation [90/100]

INFO:tensorflow:Evaluation [100/100]

INFO:tensorflow:Evaluation [100/100]

INFO:tensorflow:Finished evaluation at 2019-10-01-01:21:25

INFO:tensorflow:Finished evaluation at 2019-10-01-01:21:25

INFO:tensorflow:Saving dict for global step 938: global_step = 938, loss = 2.2761376

INFO:tensorflow:Saving dict for global step 938: global_step = 938, loss = 2.2761376

INFO:tensorflow:Saving 'checkpoint_path' summary for global step 938: /tmp/multiworker/model.ckpt-938

INFO:tensorflow:Saving 'checkpoint_path' summary for global step 938: /tmp/multiworker/model.ckpt-938

INFO:tensorflow:Loss for final step: 1.138028.

INFO:tensorflow:Loss for final step: 1.138028.

({'global_step': 938, 'loss': 2.2761376}, [])

 

訓練パフォーマンスを最適化する

今ではモデルと tf.distribute.Strategy を装備したマルチワーカー capable Estimator を持ちます。マルチワーカー訓練のパフォーマンスを最適化するために次のテクニックを試すことができます :

  • バッチサイズを増やす: ここで指定されるバッチサイズは GPU 毎です。一般に、GPU メモリに収まる最大のバッチサイズが賢明です。
  • 変数をキャストする: 可能であれば変数を tf.float にキャストします。公式 ResNet モデルはこれがどのように成されるかの サンプル を含みます。
  • collective 通信を使用する: MultiWorkerMirroredStrategy は複数の collective 通信実装 を提供します。
    • RING は gRPC を使用して ring-based collective を cross-ホスト通信層として実装します。
    • NCCL は collective を実装するために Nvidia の NCCL を使用します。
    • AUTO は選択をランタイムに任せます。

     

    collective 実装の最善の選択は GPU の数と種類、そしてクラスタのネットワーク相互作用に依拠します。自動選択をオーバーライドするには、MultiWorkerMirroredStrategy のコンストラクタの communication パラメータに正当な値を指定することです、e.g., communication=tf.distribute.experimental.CollectiveCommunication.NCCL。

 

他のコードサンプル

  1. Kubernetes テンプレートを使用する tensorflow/ecosystem のマルチワーカー訓練のための end-to-end サンプル。このサンプルは Keras モデルで始めてそれを tf.keras.estimator.model_to_estimator API を使用して Estimator に変換します。
  2. 公式 ResNet50 モデル、これは MirroredStrategy または MultiWorkerMirroredStrategy を使用して訓練できます。
 

以上






TensorFlow 2.0 : 上級 Tutorials : 分散訓練 :- tf.distribute.Strategy でカスタム訓練

TensorFlow 2.0 : 上級 Tutorials : 分散訓練 :- tf.distribute.Strategy でカスタム訓練 (翻訳/解説)

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

* 本ページは、TensorFlow org サイトの TF 2.0 – Advanced Tutorials – Distributed training の以下のページを翻訳した上で
適宜、補足説明したものです:

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

 

無料セミナー開催中 クラスキャット主催 人工知能 & ビジネス Web セミナー

人工知能とビジネスをテーマにウェビナー (WEB セミナー) を定期的に開催しています。スケジュールは弊社 公式 Web サイト でご確認頂けます。
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
  • Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/
Facebook: https://www.facebook.com/ClassCatJP/

 

分散訓練 :- tf.distribute.Strategy でカスタム訓練

このチュートリアルはカスタム訓練ループで tf.distribute.Strategy をどのように使用するかを実演します。fashion MNIST データセット上で単純な CNN モデルを訓練します。fashion MNIST データセットはサイズ 28 x 28 の 60000 訓練画像とサイズ 28 x 28 の 10000 テスト画像を含みます。

モデルを訓練するためにカスタム訓練ループを使用しています、何故ならばそれらは訓練の上で柔軟性とより良い制御を与えてくれるからです。更に、モデルと訓練ループをデバッグすることを容易にします。

from __future__ import absolute_import, division, print_function, unicode_literals

# Import TensorFlow
import tensorflow as tf

# Helper libraries
import numpy as np
import os

print(tf.__version__)
2.0.0

 

fashion mnist データセットをダウンロードする

fashion_mnist = tf.keras.datasets.fashion_mnist

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

# Adding a dimension to the array -> new shape == (28, 28, 1)
# We are doing this because the first layer in our model is a convolutional
# layer and it requires a 4D input (batch_size, height, width, channels).
# batch_size dimension will be added later on.
train_images = train_images[..., None]
test_images = test_images[..., None]

# Getting the images in [0, 1] range.
train_images = train_images / np.float32(255)
test_images = test_images / np.float32(255)

 

変数とグラフを分散するためのストラテジーを作成する

tf.distribute.MirroredStrategy ストラテジーはどのように動作するのでしょう?

  • 総ての変数とモデル・グラフはレプリカ上で複製されます。
  • 入力はレプリカに渡り均等に分散されます。
  • 各レプリカはそれが受け取った入力のための損失と勾配を計算します。
  • 勾配はそれらを合計することにより総てのレプリカに渡り同期されます。
  • 同期後、同じ更新が各レプリカ上の変数のコピーに行われます。

Note: 下の総てのコードを単一のスコープの内側に配置できます。説明目的でそれを幾つかのコードセルに分割しています。

# If the list of devices is not specified in the
# `tf.distribute.MirroredStrategy` constructor, it will be auto-detected.
strategy = tf.distribute.MirroredStrategy()
print ('Number of devices: {}'.format(strategy.num_replicas_in_sync))
Number of devices: 1

 

入力パイプラインをセットアップする

グラフと変数をプラットフォーム不可知な SavedModel フォーマットにエクスポートします。モデルがセーブされた後、スコープとともに、あるいはスコープなしでそれをロードできます。

BUFFER_SIZE = len(train_images)

BATCH_SIZE_PER_REPLICA = 64
GLOBAL_BATCH_SIZE = BATCH_SIZE_PER_REPLICA * strategy.num_replicas_in_sync

EPOCHS = 10

データセットを作成してそれらを分散します :

train_dataset = tf.data.Dataset.from_tensor_slices((train_images, train_labels)).shuffle(BUFFER_SIZE).batch(GLOBAL_BATCH_SIZE) 
test_dataset = tf.data.Dataset.from_tensor_slices((test_images, test_labels)).batch(GLOBAL_BATCH_SIZE) 

train_dist_dataset = strategy.experimental_distribute_dataset(train_dataset)
test_dist_dataset = strategy.experimental_distribute_dataset(test_dataset)

 

モデル作成

tf.keras.Sequential を使用してモデルを作成します。これを行なうために Model Subclassing API を使用することもできます。

def create_model():
  model = tf.keras.Sequential([
      tf.keras.layers.Conv2D(32, 3, activation='relu'),
      tf.keras.layers.MaxPooling2D(),
      tf.keras.layers.Conv2D(64, 3, activation='relu'),
      tf.keras.layers.MaxPooling2D(),
      tf.keras.layers.Flatten(),
      tf.keras.layers.Dense(64, activation='relu'),
      tf.keras.layers.Dense(10, activation='softmax')
    ])

  return model
# Create a checkpoint directory to store the checkpoints.
checkpoint_dir = './training_checkpoints'
checkpoint_prefix = os.path.join(checkpoint_dir, "ckpt")

 

損失関数を定義する

通常は、1 GPU/CPU を持つ単一マシン上では、損失は入力のバッチのサンプル数により除算されます。

それでは、tf.distribute.Strategy を使用するとき損失はどのように計算されるべきでしょう?

  • 例えば、貴方は 4 GPU と 64 のバッチサイズを持つとしましょう。入力の一つのバッチはレプリカ (4 GPU) に渡り分散され、各レプリカはサイズ 16 の入力を得ます。
  • 各レプリカ上のモデルはそれぞれの入力で forward パスを行ないそして損失を計算します。今は、損失をそれぞれの入力のサンプル数 (BATCH_SIZE_PER_REPLICA = 16) で除算する代わりに、損失は GLOBAL_BATCH_SIZE (64) で除算されるべきです。

何故これを行なうのでしょう?

  • これが行われるのは各レプリカ上で勾配が計算された後、それらを総計することによりそれらはレプリカに渡り同期されるからです。

TensorFlow でこれをどのようにに処理しますか? * カスタム訓練ループを書いている場合、このチュートリアルでのように、サンプル毎損失を合計して GLOBAL_BATCH_SIZE で合計を除算するべきです: scale_loss = tf.reduce_sum(loss) * (1. / GLOBAL_BATCH_SIZE) あるいは tf.nn.compute_average_loss を使用できます、これは引数としてサンプル毎損失、オプションのサンプル重み、そして GLOBAL_BATCH_SIZE を取りそしてスケールされた損失を返します。

  • 貴方のモデルで regularization 損失を使用している場合には、損失値をレプリカの数でスケールする必要があります。tf.nn.scale_regularization_loss 関数を使用してこれを行なうことができます。
  • tf.reduce_mean の使用は推奨されません。それを行なうことは損失を実際のレプリカ毎バッチサイズで除算します、これはステップ毎に変化するかもしれません。
  • このリダクションとスケーリングは keras model.compile と model.fit で自動的に行なわれます。
  • (下のサンプルのように) tf.keras.losses クラスを使用する場合、損失リダクションは NONE か SUM の一つとして明示的に指定される必要があります。 tf.distribute.Strategy で使用されるとき AUTO と SUM_OVER_BATCH_SIZE は許容されません。AUTO は許容されません、何故ならば分散ケースでそれが正しいことを確実にするためにユーザはどのリダクションを望むかについて明示的に考えるべきだからです。SUM_OVER_BATCH_SIZE は許容されません、何故ならば現在それはレプリカ毎バッチサイズで除算するだけだからです、そしてレプリカ数による除算はユーザに委ねられます、これは簡単にミスしてしまうかもしれません。それで代わりにユーザが彼ら自身でリダクションを行なうかを明示的に尋ねます。
with strategy.scope():
  # Set reduction to `none` so we can do the reduction afterwards and divide by
  # global batch size.
  loss_object = tf.keras.losses.SparseCategoricalCrossentropy(
      reduction=tf.keras.losses.Reduction.NONE)
  # or loss_fn = tf.keras.losses.sparse_categorical_crossentropy
  def compute_loss(labels, predictions):
    per_example_loss = loss_object(labels, predictions)
    return tf.nn.compute_average_loss(per_example_loss, global_batch_size=GLOBAL_BATCH_SIZE)

 

損失と精度を追跡するためにメトリクスを定義する

これらのメトリクスは損失及び訓練とテスト精度を追跡します。累積された統計情報を得るためにいつでも .result() を使用できます。

with strategy.scope():
  test_loss = tf.keras.metrics.Mean(name='test_loss')

  train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(
      name='train_accuracy')
  test_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(
      name='test_accuracy')

 

訓練ループ

# model and optimizer must be created under `strategy.scope`.
with strategy.scope():
  model = create_model()

  optimizer = tf.keras.optimizers.Adam()

  checkpoint = tf.train.Checkpoint(optimizer=optimizer, model=model)
with strategy.scope():
  def train_step(inputs):
    images, labels = inputs

    with tf.GradientTape() as tape:
      predictions = model(images, training=True)
      loss = compute_loss(labels, predictions)

    gradients = tape.gradient(loss, model.trainable_variables)
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))

    train_accuracy.update_state(labels, predictions)
    return loss 

  def test_step(inputs):
    images, labels = inputs

    predictions = model(images, training=False)
    t_loss = loss_object(labels, predictions)

    test_loss.update_state(t_loss)
    test_accuracy.update_state(labels, predictions)
with strategy.scope():
  # `experimental_run_v2` replicates the provided computation and runs it
  # with the distributed input.
  @tf.function
  def distributed_train_step(dataset_inputs):
    per_replica_losses = strategy.experimental_run_v2(train_step,
                                                      args=(dataset_inputs,))
    return strategy.reduce(tf.distribute.ReduceOp.SUM, per_replica_losses,
                           axis=None)
 
  @tf.function
  def distributed_test_step(dataset_inputs):
    return strategy.experimental_run_v2(test_step, args=(dataset_inputs,))

  for epoch in range(EPOCHS):
    # TRAIN LOOP
    total_loss = 0.0
    num_batches = 0
    for x in train_dist_dataset:
      total_loss += distributed_train_step(x)
      num_batches += 1
    train_loss = total_loss / num_batches

    # TEST LOOP
    for x in test_dist_dataset:
      distributed_test_step(x)

    if epoch % 2 == 0:
      checkpoint.save(checkpoint_prefix)

    template = ("Epoch {}, Loss: {}, Accuracy: {}, Test Loss: {}, "
                "Test Accuracy: {}")
    print (template.format(epoch+1, train_loss,
                           train_accuracy.result()*100, test_loss.result(),
                           test_accuracy.result()*100))

    test_loss.reset_states()
    train_accuracy.reset_states()
    test_accuracy.reset_states()
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).
Epoch 1, Loss: 0.5149696469306946, Accuracy: 81.5250015258789, Test Loss: 0.37859389185905457, Test Accuracy: 86.23999786376953
Epoch 2, Loss: 0.33567535877227783, Accuracy: 87.95333862304688, Test Loss: 0.34586820006370544, Test Accuracy: 87.48999786376953
Epoch 3, Loss: 0.29027265310287476, Accuracy: 89.45333099365234, Test Loss: 0.3082132041454315, Test Accuracy: 89.19000244140625
Epoch 4, Loss: 0.25970742106437683, Accuracy: 90.52000427246094, Test Loss: 0.2932600975036621, Test Accuracy: 89.62000274658203
Epoch 5, Loss: 0.23640099167823792, Accuracy: 91.24833679199219, Test Loss: 0.2744646370410919, Test Accuracy: 89.93000030517578
Epoch 6, Loss: 0.21604427695274353, Accuracy: 92.07999420166016, Test Loss: 0.2818734049797058, Test Accuracy: 89.81999969482422
Epoch 7, Loss: 0.19880548119544983, Accuracy: 92.59500122070312, Test Loss: 0.2676812708377838, Test Accuracy: 90.24000549316406
Epoch 8, Loss: 0.1839067041873932, Accuracy: 93.10166931152344, Test Loss: 0.24938379228115082, Test Accuracy: 90.88999938964844
Epoch 9, Loss: 0.16903717815876007, Accuracy: 93.7733383178711, Test Loss: 0.25704431533813477, Test Accuracy: 90.75
Epoch 10, Loss: 0.15608058869838715, Accuracy: 94.10832977294922, Test Loss: 0.2633570432662964, Test Accuracy: 90.6500015258789

上のサンプルで注意すべきことは :

  • “for x in …” 構成要素を使用して train_dist_dataset と test_dist_dataset に渡り iterate しています。
  • スケールされた損失は distributed_train_step の戻り値です。この値は、tf.distribute.Strategy.reduce 呼び出しを使用してレプリカに渡り、それから tf.distribute.Strategy.reduce 呼び出しの戻り値を合計することによりバッチに渡り累積されます。
  • tf.keras.Metrics は tf.distribute.Strategy.experimental_run_v2 により実行される train_step and test_step 内で更新されるべきです。* tf.distribute.Strategy.experimental_run_v2 はストラテジーで各ローカルレプリカからの結果を返し、そしてこの結果を消費する複数の方法があります。累積値を得るために tf.distribute.Strategy.reduce を行なうことができます。ローカルレプリカ毎に一つ、結果に含まれる値のリストを得るために tf.distribute.Strategy.experimental_local_results を行なうこともできます。

 

最新のチェックポイントを復元してテストする

tf.distribute.Strategy でチェックポイントされたモデルはストラテジーとともに、またはストラテジーなしでリストアできます。

eval_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(
      name='eval_accuracy')

new_model = create_model()
new_optimizer = tf.keras.optimizers.Adam()

test_dataset = tf.data.Dataset.from_tensor_slices((test_images, test_labels)).batch(GLOBAL_BATCH_SIZE)
@tf.function
def eval_step(images, labels):
  predictions = new_model(images, training=False)
  eval_accuracy(labels, predictions)
checkpoint = tf.train.Checkpoint(optimizer=new_optimizer, model=new_model)
checkpoint.restore(tf.train.latest_checkpoint(checkpoint_dir))

for images, labels in test_dataset:
  eval_step(images, labels)

print ('Accuracy after restoring the saved model without strategy: {}'.format(
    eval_accuracy.result()*100))
Accuracy after restoring the saved model without strategy: 90.75

 

データセットに渡り iterate する別の方法

iterator を使用する

与えられた数のステップに渡り、そしてデータセット全体を通すのではなく iterate することを望む場合、iterator 上で iter 呼び出しと明示的に呼び出し next を使用して iterator を作成することができます。tf.functiuon の内側と外側の両者でデータセットに渡り iterate することを選択できます。ここにiterator を使用して tf.function の外側でデータセットの iteration を実演する小さいスニペットがあります。

with strategy.scope():
  for _ in range(EPOCHS):
    total_loss = 0.0
    num_batches = 0
    train_iter = iter(train_dist_dataset)

    for _ in range(10):
      total_loss += distributed_train_step(next(train_iter))
      num_batches += 1
    average_train_loss = total_loss / num_batches

    template = ("Epoch {}, Loss: {}, Accuracy: {}")
    print (template.format(epoch+1, average_train_loss, train_accuracy.result()*100))
    train_accuracy.reset_states()
Epoch 10, Loss: 0.13162840902805328, Accuracy: 94.53125
Epoch 10, Loss: 0.11109195649623871, Accuracy: 96.5625
Epoch 10, Loss: 0.1300327479839325, Accuracy: 94.6875
Epoch 10, Loss: 0.102020762860775, Accuracy: 96.25
Epoch 10, Loss: 0.09842313826084137, Accuracy: 97.03125
Epoch 10, Loss: 0.13631784915924072, Accuracy: 94.375
Epoch 10, Loss: 0.11527981609106064, Accuracy: 95.0
Epoch 10, Loss: 0.09563014656305313, Accuracy: 96.09375
Epoch 10, Loss: 0.13050365447998047, Accuracy: 94.6875
Epoch 10, Loss: 0.1324475109577179, Accuracy: 94.6875

 

tf.function の内側で iterate する

“for x in …” 構成要素を使用するか上で行なったように iterator を作成することにより tf.function の内側で入力 train_dist_dataset 全体に渡り iterate することもできます。下のサンプルは tf.function 内で訓練の 1 エポックをラップして関数の内側で train_dist_dataset に渡り iterate することを実演します。

with strategy.scope():
  @tf.function
  def distributed_train_epoch(dataset):
    total_loss = 0.0
    num_batches = 0
    for x in dataset:
      per_replica_losses = strategy.experimental_run_v2(train_step,
                                                        args=(x,))
      total_loss += strategy.reduce(
        tf.distribute.ReduceOp.SUM, per_replica_losses, axis=None)
      num_batches += 1
    return total_loss / tf.cast(num_batches, dtype=tf.float32)

  for epoch in range(EPOCHS):
    train_loss = distributed_train_epoch(train_dist_dataset)

    template = ("Epoch {}, Loss: {}, Accuracy: {}")
    print (template.format(epoch+1, train_loss, train_accuracy.result()*100))

    train_accuracy.reset_states()
Epoch 1, Loss: 0.14456823468208313, Accuracy: 94.57666778564453
Epoch 2, Loss: 0.1337885707616806, Accuracy: 94.8949966430664
Epoch 3, Loss: 0.12238477170467377, Accuracy: 95.37332916259766
Epoch 4, Loss: 0.11225613951683044, Accuracy: 95.75333404541016
Epoch 5, Loss: 0.10508091002702713, Accuracy: 96.11000061035156
Epoch 6, Loss: 0.09647118300199509, Accuracy: 96.38666534423828
Epoch 7, Loss: 0.09062784165143967, Accuracy: 96.57666778564453
Epoch 8, Loss: 0.08338376134634018, Accuracy: 96.91000366210938
Epoch 9, Loss: 0.07607696950435638, Accuracy: 97.0999984741211
Epoch 10, Loss: 0.06851287186145782, Accuracy: 97.46500396728516

 

レプリカに渡る訓練損失を追跡する

Note: 一般的なルールとして、サンプル毎の値を追跡してレプリカ内に累積された値を回避するために tf.keras.Metrics を使用するべきです。

実行される損失スケーリング計算ゆえに、異なるレプリカに渡る訓練損失を追跡するために tf.metrics.Mean を使用することを勧めません。

例えば、次の特性で訓練ジョブを実行する場合 : * 2 つのレプリカ * 2 つのサンプルが各レプリカで処理されます * 結果としての損失値: 各レプリカ上で [2, 3] と [4, 5] * グローバル・バッチサイズ = 4

損失スケーリングで、損失値を可算して、それからグローバル・バッチサイズで除算することにより各レプリカ上の損失のサンプル毎値を計算します。この場合、(2 + 3) / 4 = 1.25 と (4 + 5) / 4 = 2.25。

2 つのレプリカに渡り損失を追跡するために tf.metrics.Mean を使用する場合、結果は異なります。このサンプルでは、3.50 の total と 2 の count で終わり、これはメトリックで result() が呼び出されるとき total/count = 1.75 という結果になります。tf.keras.Metrics で計算される損失は同期するレプリカの数に等しい追加の因子でスケールされます。

 

サンプルとチュートリアル

ここにカスタム訓練ループで分散ストラテジーを使用する幾つかのサンプルがあります :

  1. MirroredStrategy を使用して MNIST を訓練する チュートリアル
  2. MirroredStrategy を使用する DenseNet サンプル。
  3. MirroredStrategy and TPUStrategy を使用して訓練される BERT サンプル。このサンプルはどのようにチェックポイントからロードするかそして分散訓練の間に定期的にチェックポイントを生成するか等を理解するために特に有用です。
  4. MirroredStrategy を使用して訓練される NCF サンプル、これは keras_use_ctl フラグを使用して有効にできます。
  5. MirroredStrategy を使用して訓練される NMT サンプル。

分散ストラテジー・ガイド でリストされるより多くのサンプル

 

Next steps

貴方のモデル上で tf.distribute.Strategy API を試してください。

 

以上






TensorFlow 2.0 : 上級 Tutorials : 分散訓練 :- Keras で分散訓練

TensorFlow 2.0 : 上級 Tutorials : 分散訓練 :- Keras で分散訓練 (翻訳/解説)

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

* 本ページは、TensorFlow org サイトの TF 2.0 – Advanced Tutorials – Distributed training の以下のページを翻訳した上で
適宜、補足説明したものです:

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

 

無料セミナー開催中 クラスキャット主催 人工知能 & ビジネス Web セミナー

人工知能とビジネスをテーマにウェビナー (WEB セミナー) を定期的に開催しています。スケジュールは弊社 公式 Web サイト でご確認頂けます。
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
  • Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/
Facebook: https://www.facebook.com/ClassCatJP/

 

分散訓練 :- Keras で分散訓練

概要

tf.distribute.Strategy API は複数の処理ユニットに渡り貴方の訓練を分散するための抽象を提供します。目標はユーザに既存のモデルと訓練コードを (最小限の変更で) 使用して分散訓練を可能にすることです。

このチュートリアルは tf.distribute.MirroredStrategy を使用します、これは一つのマシン上の多くの GPU 上で同期訓練を伴う in-graph リプリケーションを行ないます。本質的には、それはモデルの変数の総てを各プロセッサにコピーします。それから、それは総てのプロセッサからの勾配を結合するために all-reduce を使用して結合された値をモデルの総てのコピーに適用します。

MirroredStategy は TensorFlow コアで利用可能な幾つかの分散ストラテジーの一つです。より多くのストラテジーについて 分散ストラテジー・ガイド で読むことができます。

 

Keras API

このサンプルはモデルと訓練ループを構築するために tf.kera API を使用します。カスタム訓練ループについては、tf.distribute.Strategy with training loops チュートリアル を見てください。

 

Import 依存性

from __future__ import absolute_import, division, print_function, unicode_literals

# Import TensorFlow and TensorFlow Datasets
try:
  !pip install -q tf-nightly
except Exception:
  pass

import tensorflow_datasets as tfds
import tensorflow as tf
tfds.disable_progress_bar()

import os
print(tf.__version__)
2.1.0-dev20191004

 

データセットをダウンロードする

MNIST データセットをダウンロードしてそれを TensorFlow Dataset からロードします。これは tf.data フォーマットのデータセットを返します。

with_info を True に設定するとデータセット全体に対するメタデータを含みます、これはここでは info にセーブされます。他のものの中で、このメタデータ・オブジェクトは訓練とテストサンプルの数を含みます。

datasets, info = tfds.load(name='mnist', with_info=True, as_supervised=True)

mnist_train, mnist_test = datasets['train'], datasets['test']
Downloading and preparing dataset mnist (11.06 MiB) to /home/kbuilder/tensorflow_datasets/mnist/1.0.0...

/usr/lib/python3/dist-packages/urllib3/connectionpool.py:860: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
/usr/lib/python3/dist-packages/urllib3/connectionpool.py:860: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
/usr/lib/python3/dist-packages/urllib3/connectionpool.py:860: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
/usr/lib/python3/dist-packages/urllib3/connectionpool.py:860: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)

WARNING:tensorflow:From /home/kbuilder/.local/lib/python3.6/site-packages/tensorflow_datasets/core/file_format_adapter.py:209: tf_record_iterator (from tensorflow.python.lib.io.tf_record) is deprecated and will be removed in a future version.
Instructions for updating:
Use eager execution and: 
`tf.data.TFRecordDataset(path)`

WARNING:tensorflow:From /home/kbuilder/.local/lib/python3.6/site-packages/tensorflow_datasets/core/file_format_adapter.py:209: tf_record_iterator (from tensorflow.python.lib.io.tf_record) is deprecated and will be removed in a future version.
Instructions for updating:
Use eager execution and: 
`tf.data.TFRecordDataset(path)`

Dataset mnist downloaded and prepared to /home/kbuilder/tensorflow_datasets/mnist/1.0.0. Subsequent calls will reuse this data.

 

分散ストラテジーを定義する

MirroredStrategy オブジェクトを作成します。これは分散を処理し、そして内側で貴方のモデルを構築するためのコンテキストマネージャ (tf.distribute.MirroredStrategy.scope) を提供します。

strategy = tf.distribute.MirroredStrategy()
INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)

INFO:tensorflow:Using MirroredStrategy with devices ('/job:localhost/replica:0/task:0/device:GPU:0',)
print('Number of devices: {}'.format(strategy.num_replicas_in_sync))
Number of devices: 1

 

入力パイプラインをセットアップする

モデルがマルチ GPU で訓練されるとき、バッチサイズを増やすことにより特別な計算パワーを効果的に使用できます。一般に、GPU メモリに収まる最大のバッチサイズを使用し、そしてそれに従って学習率を調整します。

# You can also do info.splits.total_num_examples to get the total
# number of examples in the dataset.

num_train_examples = info.splits['train'].num_examples
num_test_examples = info.splits['test'].num_examples

BUFFER_SIZE = 10000

BATCH_SIZE_PER_REPLICA = 64
BATCH_SIZE = BATCH_SIZE_PER_REPLICA * strategy.num_replicas_in_sync

0-255 のピクセル値は 0-1 範囲に正規化されなければなりません。このスケールを関数で定義します。

def scale(image, label):
  image = tf.cast(image, tf.float32)
  image /= 255

  return image, label

この関数を訓練とテストデータに適用し、訓練データをシャッフルし、そして 訓練のためにそれをバッチ化します。パフォーマンスを改善するために訓練データの in-メモリ・キャッシュも保持していることに気付いてください。

train_dataset = mnist_train.map(scale).cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
eval_dataset = mnist_test.map(scale).batch(BATCH_SIZE)

 

モデルを作成する

strategy.scope のコンテキストで Keras モデルを作成してコンパイルします。

with strategy.scope():
  model = tf.keras.Sequential([
      tf.keras.layers.Conv2D(32, 3, activation='relu', input_shape=(28, 28, 1)),
      tf.keras.layers.MaxPooling2D(),
      tf.keras.layers.Flatten(),
      tf.keras.layers.Dense(64, activation='relu'),
      tf.keras.layers.Dense(10, activation='softmax')
  ])

  model.compile(loss='sparse_categorical_crossentropy',
                optimizer=tf.keras.optimizers.Adam(),
                metrics=['accuracy'])
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

 

コールバックを定義する

ここで使用されるコールバックは :

  • Tensorboard: このコールバックはグラフを可視化することを可能にする TensorBoard のためのログを書きます。
  • モデル・チェックポイント: このコールバックは総てのエポック後にモデルをセーブします。
  • 学習率スケジューラ: このコールバックを使用すると、総てのエポック/バッチ後に変化する学習率をスケジューリングできます。

説明目的で、このノートブックでは学習率を表示するための print コールバックを追加します。

# Define the checkpoint directory to store the checkpoints

checkpoint_dir = './training_checkpoints'
# Name of the checkpoint files
checkpoint_prefix = os.path.join(checkpoint_dir, "ckpt_{epoch}")
# Function for decaying the learning rate.
# You can define any decay function you need.
def decay(epoch):
  if epoch < 3:
    return 1e-3
  elif epoch >= 3 and epoch < 7:
    return 1e-4
  else:
    return 1e-5
# Callback for printing the LR at the end of each epoch.
class PrintLR(tf.keras.callbacks.Callback):
  def on_epoch_end(self, epoch, logs=None):
    print('\nLearning rate for epoch {} is {}'.format(epoch + 1,
                                                      model.optimizer.lr.numpy()))
callbacks = [
    tf.keras.callbacks.TensorBoard(log_dir='./logs'),
    tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_prefix,
                                       save_weights_only=True),
    tf.keras.callbacks.LearningRateScheduler(decay),
    PrintLR()
]

 

訓練そして評価する

今、通常の方法でモデルを訓練します、モデル上で fit を呼び出してチュートリアルの最初に作成されたデータセットを渡します。このステップは貴方が訓練を分散していてもそうでなくても同じです。

model.fit(train_dataset, epochs=12, callbacks=callbacks)
Epoch 1/12
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

    938/Unknown - 10s 10ms/step - loss: 0.1922 - accuracy: 0.9441
Learning rate for epoch 1 is 0.0010000000474974513
938/938 [==============================] - 10s 10ms/step - loss: 0.1922 - accuracy: 0.9441
Epoch 2/12
923/938 [============================>.] - ETA: 0s - loss: 0.0662 - accuracy: 0.9803
Learning rate for epoch 2 is 0.0010000000474974513
938/938 [==============================] - 3s 3ms/step - loss: 0.0658 - accuracy: 0.9804
Epoch 3/12
935/938 [============================>.] - ETA: 0s - loss: 0.0456 - accuracy: 0.9863
Learning rate for epoch 3 is 0.0010000000474974513
938/938 [==============================] - 3s 3ms/step - loss: 0.0455 - accuracy: 0.9863
Epoch 4/12
935/938 [============================>.] - ETA: 0s - loss: 0.0264 - accuracy: 0.9926
Learning rate for epoch 4 is 9.999999747378752e-05
938/938 [==============================] - 3s 3ms/step - loss: 0.0264 - accuracy: 0.9926
Epoch 5/12
932/938 [============================>.] - ETA: 0s - loss: 0.0226 - accuracy: 0.9939
Learning rate for epoch 5 is 9.999999747378752e-05
938/938 [==============================] - 3s 3ms/step - loss: 0.0225 - accuracy: 0.9940
Epoch 6/12
931/938 [============================>.] - ETA: 0s - loss: 0.0207 - accuracy: 0.9945
Learning rate for epoch 6 is 9.999999747378752e-05
938/938 [==============================] - 3s 3ms/step - loss: 0.0207 - accuracy: 0.9945
Epoch 7/12
932/938 [============================>.] - ETA: 0s - loss: 0.0191 - accuracy: 0.9951
Learning rate for epoch 7 is 9.999999747378752e-05
938/938 [==============================] - 3s 3ms/step - loss: 0.0191 - accuracy: 0.9951
Epoch 8/12
931/938 [============================>.] - ETA: 0s - loss: 0.0165 - accuracy: 0.9963
Learning rate for epoch 8 is 9.999999747378752e-06
938/938 [==============================] - 3s 3ms/step - loss: 0.0165 - accuracy: 0.9962
Epoch 9/12
922/938 [============================>.] - ETA: 0s - loss: 0.0162 - accuracy: 0.9963
Learning rate for epoch 9 is 9.999999747378752e-06
938/938 [==============================] - 3s 3ms/step - loss: 0.0162 - accuracy: 0.9963
Epoch 10/12
927/938 [============================>.] - ETA: 0s - loss: 0.0160 - accuracy: 0.9965
Learning rate for epoch 10 is 9.999999747378752e-06
938/938 [==============================] - 3s 3ms/step - loss: 0.0160 - accuracy: 0.9965
Epoch 11/12
934/938 [============================>.] - ETA: 0s - loss: 0.0158 - accuracy: 0.9965
Learning rate for epoch 11 is 9.999999747378752e-06
938/938 [==============================] - 3s 3ms/step - loss: 0.0158 - accuracy: 0.9965
Epoch 12/12
928/938 [============================>.] - ETA: 0s - loss: 0.0157 - accuracy: 0.9964
Learning rate for epoch 12 is 9.999999747378752e-06
938/938 [==============================] - 3s 3ms/step - loss: 0.0156 - accuracy: 0.9965

<tensorflow.python.keras.callbacks.History at 0x7f92ad88d278>

下で見れるように、チェックポイントはセーブされています。

# check the checkpoint directory
!ls {checkpoint_dir}
checkpoint           ckpt_4.data-00000-of-00002
ckpt_1.data-00000-of-00002   ckpt_4.data-00001-of-00002
ckpt_1.data-00001-of-00002   ckpt_4.index
ckpt_1.index             ckpt_5.data-00000-of-00002
ckpt_10.data-00000-of-00002  ckpt_5.data-00001-of-00002
ckpt_10.data-00001-of-00002  ckpt_5.index
ckpt_10.index            ckpt_6.data-00000-of-00002
ckpt_11.data-00000-of-00002  ckpt_6.data-00001-of-00002
ckpt_11.data-00001-of-00002  ckpt_6.index
ckpt_11.index            ckpt_7.data-00000-of-00002
ckpt_12.data-00000-of-00002  ckpt_7.data-00001-of-00002
ckpt_12.data-00001-of-00002  ckpt_7.index
ckpt_12.index            ckpt_8.data-00000-of-00002
ckpt_2.data-00000-of-00002   ckpt_8.data-00001-of-00002
ckpt_2.data-00001-of-00002   ckpt_8.index
ckpt_2.index             ckpt_9.data-00000-of-00002
ckpt_3.data-00000-of-00002   ckpt_9.data-00001-of-00002
ckpt_3.data-00001-of-00002   ckpt_9.index
ckpt_3.index

モデルがどのように遂行するかを見るために、最新のチェックポイントをロードしてテストデータ上で evaluate を呼び出します。

適切なデータセットを使用して前のように evaluate を呼び出します。

model.load_weights(tf.train.latest_checkpoint(checkpoint_dir))

eval_loss, eval_acc = model.evaluate(eval_dataset)

print('Eval loss: {}, Eval Accuracy: {}'.format(eval_loss, eval_acc))
INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /job:localhost/replica:0/task:0/device:CPU:0 then broadcast to ('/job:localhost/replica:0/task:0/device:CPU:0',).

    157/Unknown - 2s 14ms/step - loss: 0.0363 - accuracy: 0.9875Eval loss: 0.03630251882658607, Eval Accuracy: 0.987500011920929

出力を見るために、TensorBoard ログをダウンロードして端末で見ることができます。

$ tensorboard --logdir=path/to/log-directory
!ls -sh ./logs
total 4.0K
4.0K train

 

SavedModel にエクスポートする

グラフと変数をプラットフォーム不可知 (= agnostic) である SavedModel フォーマットにエクスポートします。モデルがセーブされた後、それをスコープとともに、あるいはスコープなしでロードし戻すことができます。

path = 'saved_model/'
model.save(path, save_format='tf')
WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_core/python/ops/resource_variable_ops.py:1781: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.

WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_core/python/ops/resource_variable_ops.py:1781: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.

INFO:tensorflow:Reduce to /replica:0/task:0/device:CPU:0 then broadcast to ('/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /replica:0/task:0/device:CPU:0 then broadcast to ('/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /replica:0/task:0/device:CPU:0 then broadcast to ('/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Reduce to /replica:0/task:0/device:CPU:0 then broadcast to ('/replica:0/task:0/device:CPU:0',).

INFO:tensorflow:Assets written to: saved_model/assets

INFO:tensorflow:Assets written to: saved_model/assets

strategy.scope なしでモデルをロードします。

unreplicated_model = tf.keras.models.load_model(path)

unreplicated_model.compile(
    loss='sparse_categorical_crossentropy',
    optimizer=tf.keras.optimizers.Adam(),
    metrics=['accuracy'])

eval_loss, eval_acc = unreplicated_model.evaluate(eval_dataset)

print('Eval loss: {}, Eval Accuracy: {}'.format(eval_loss, eval_acc))
    157/Unknown - 1s 7ms/step - loss: 0.0363 - accuracy: 0.9875Eval loss: 0.036302936971143104, Eval Accuracy: 0.987500011920929

strategy.scope とともにモデルをロードします。

with strategy.scope():
  replicated_model = tf.keras.models.load_model(path)
  replicated_model.compile(loss='sparse_categorical_crossentropy',
                           optimizer=tf.keras.optimizers.Adam(),
                           metrics=['accuracy'])

  eval_loss, eval_acc = replicated_model.evaluate(eval_dataset)
  print ('Eval loss: {}, Eval Accuracy: {}'.format(eval_loss, eval_acc))
    157/Unknown - 2s 14ms/step - loss: 0.0363 - accuracy: 0.9875Eval loss: 0.036302936971143104, Eval Accuracy: 0.987500011920929

 

サンプルとチュートリアル

ここに keras fit/compile を伴う分散ストラテジーを使用するための幾つかのサンプルがあります : 1. tf.distribute.MirroredStrategy を使用して訓練される Transformer サンプル 2. tf.distribute.MirroredStrategy を使用して訓練される NCF

分散ストラテジー・ガイド でリストされるより多くのサンプル

 

Next steps

 

以上






TensorFlow 2.0 Alpha : 上級 Tutorials : 分散訓練 :- 訓練ループで tf.distribute.Strategy

TensorFlow 2.0 Alpha : 上級 Tutorials : 分散訓練 :- 訓練ループで tf.distribute.Strategy (翻訳/解説)

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

* 本ページは、TensorFlow の本家サイトの TF 2.0 Alpha – Advanced Tutorials – Distributed training の以下のページを翻訳した上で適宜、補足説明したものです:

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

 

分散訓練 :- 訓練ループで tf.distribute.Strategy

このチュートリアルはカスタム訓練ループで tf.distribute.Strategy をどのように使用するかを実演します。
fashion MNIST データセット上で単純な CNN モデルを訓練します。fashion MNIST データセットはサイズ 28 x 28 の 60000 訓練画像とサイズ 28 x 28 の 10000 テスト画像を含みます。

モデルを訓練するためにカスタム訓練ループを使用しています、何故ならばそれらは訓練の上で柔軟性とより素晴らしい制御を与えてくれるからです。更に、モデルと訓練ループをデバッグすることを容易にします。

from __future__ import absolute_import, division, print_function, unicode_literals

# Import TensorFlow
!pip install -q tensorflow==2.0.0-alpha0
import tensorflow as tf

# Helper libraries
import numpy as np
import os

print(tf.__version__)
2.0.0-alpha0

 

fashion mnist データセットをダウンロードする

fashion_mnist = tf.keras.datasets.fashion_mnist

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

# Adding a dimension to the array -> new shape == (28, 28, 1)
# We are doing this because the first layer in our model is a convolutional 
# layer and it requires a 4D input (batch_size, height, width, channels).
# batch_size dimension will be added later on.
train_images = train_images[..., None]
test_images = test_images[..., None]

# Getting the images in [0, 1] range.
train_images = train_images / np.float32(255)
test_images = test_images / np.float32(255)
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz
32768/29515 [=================================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz
26427392/26421880 [==============================] - 1s 0us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz
8192/5148 [===============================================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz
4423680/4422102 [==============================] - 0s 0us/step

 

変数とグラフを分散するためのストラテジーを作成する

tf.distribute.MirroredStrategy ストラテジーはどのように動作するのでしょう?

  • 総ての変数とモデル・グラフはレプリカ上で複製されます。
  • 入力はレプリカに渡り均等に分散されます。
  • 各レプリカはそれが受け取った入力のための損失と勾配を計算します。
  • 勾配はそれらを総計することにより総てのレプリカに渡り同期されます。
  • 同期後、同じ更新が各レプリカ上の変数のコピーに行われます。

Note: 下の総てのコードを単一のスコープの内側に配置できます。説明のためにそれを幾つかのコードセルに分割しています。

# If the list of devices is not specified in the 
# `tf.distribute.MirroredStrategy` constructor, it will be auto-detected.
strategy = tf.distribute.MirroredStrategy()
WARNING: Logging before flag parsing goes to stderr.
W0405 15:21:07.446863 140252361586432 cross_device_ops.py:1111] Not all devices in `tf.distribute.Strategy` are visible to TensorFlow.
print ('Number of devices: {}'.format(strategy.num_replicas_in_sync))
Number of devices: 1

 

入力パイプラインをセットアップする

モデルがマルチ GPU 上で訓練されるのであれば、特別な計算パワーを効果的に利用するためにバッチサイズはそれに従って増やされるべきです。更に、学習率もそれに従って調整されるべきです。

BUFFER_SIZE = len(train_images)

BATCH_SIZE_PER_REPLICA = 64
BATCH_SIZE = BATCH_SIZE_PER_REPLICA * strategy.num_replicas_in_sync

EPOCHS = 10
train_steps_per_epoch = len(train_images) // BATCH_SIZE
test_steps_per_epoch = len(test_images) // BATCH_SIZE

strategy.experimental_make_numpy_iterator は総てのレプリカに渡りデータを均等に分散する iterator を作成します。

これは tf.data.Dataset.from_tensor_slices を直接的に使用するよりも効率的です、何故ならばそれは訓練データをグラフの定数として記録することを回避するからです。

strategy.experimental_make_numpy_iterator を使用していない場合、このように strategy.scope の内側に iterator を作成します :

train_dataset = tf.data.Dataset.from_tensor_slices( (train_images, train_labels)).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
train_iterator = strategy.make_dataset_iterator(train_dataset)

Note: この API は近い将来に変更される可能性があります。

with strategy.scope():
  train_iterator = strategy.experimental_make_numpy_iterator(
      (train_images, train_labels), BATCH_SIZE, shuffle=BUFFER_SIZE)

  test_iterator = strategy.experimental_make_numpy_iterator(
      (test_images, test_labels), BATCH_SIZE, shuffle=None)

 

モデル作成

tf.keras.Sequential を使用してモデルを作成します。これを行なうために Model Subclassing API を使用することもできます。

def create_model():
  model = tf.keras.Sequential([
      tf.keras.layers.Conv2D(32, 3, activation='relu'),
      tf.keras.layers.MaxPooling2D(),
      tf.keras.layers.Conv2D(64, 3, activation='relu'),
      tf.keras.layers.MaxPooling2D(),
      tf.keras.layers.Flatten(),
      tf.keras.layers.Dense(64, activation='relu'),
      tf.keras.layers.Dense(10, activation='softmax')
    ])

  return model
# Create a checkpoint directory to store the checkpoints.
checkpoint_dir = './training_checkpoints'
checkpoint_prefix = os.path.join(checkpoint_dir, "ckpt")

 

損失関数を定義する

通常は、1 GPU/CPU を持つ単一マシン上では、損失は入力のバッチにおけるサンプルの数により除算されます。

そこで、tf.distribute.Strategy を使用するとき損失はどのように計算されるのでしょう?

  • 例えば、貴方は 4 GPU と 64 のバッチサイズを持つとしましょう。入力の一つのバッチはレプリカ (4 GPU) に渡り分散され、各レプリカはサイズ 16 の入力を得ます。
  • 各レプリカ上のモデルはそれぞれの入力で forward パスを行ないそして損失を計算します。今は、損失をそれぞれの入力のサンプル数 (16) で除算する代わりに、損失はグローバルな入力サイズ (64) で除算されます。

何故これが行われるのでしょう?

  • これが行われるのは各レプリカ上で勾配が計算された後、それらを総計することによりそれらはレプリカに渡り同期されるからです。

TensorFlow でこれをどのようにに処理しますか?

  • tf.keras.losses がこれを自動的に処理します。
  • カスタム損失関数を分散する場合、それを tf.reduce_mean (これはローカルのバッチサイズで除算します) を使用して実装しないでください、総計をグローバルなバッチサイズで除算してください : scale_loss = tf.reduce_sum(loss) * (1. / global_batch_size)
with strategy.scope():
  loss_object = tf.keras.losses.SparseCategoricalCrossentropy()

 

損失と精度を追跡するためにメトリクスを定義する

これらのメトリクスは損失と精度を追跡します。累積された統計情報を得るためにいつでも .result() を使用できます。

with strategy.scope():
  train_loss = tf.keras.metrics.Mean(name='train_loss')
  test_loss = tf.keras.metrics.Mean(name='test_loss')

  train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(
      name='train_accuracy')
  test_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(
      name='test_accuracy')

 

訓練ループ

# model and optimizer must be created under `strategy.scope`.
with strategy.scope():
  model = create_model()

  optimizer = tf.keras.optimizers.Adam()
  
  checkpoint = tf.train.Checkpoint(optimizer=optimizer, model=model)
with strategy.scope():
  # Train step
  def train_step(inputs):
    images, labels = inputs

    with tf.GradientTape() as tape:
      predictions = model(images, training=True)
      loss = loss_object(labels, predictions)

    gradients = tape.gradient(loss, model.trainable_variables)
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))

    train_loss(loss)
    train_accuracy(labels, predictions)

  # Test step
  def test_step(inputs):
    images, labels = inputs

    predictions = model(images, training=False)
    t_loss = loss_object(labels, predictions)

    test_loss(t_loss)
    test_accuracy(labels, predictions)
with strategy.scope():
  # `experimental_run` replicates the provided computation and runs it 
  # with the distributed input.
  
  @tf.function
  def distributed_train():
    return strategy.experimental_run(train_step, train_iterator)
  
  @tf.function
  def distributed_test():
    return strategy.experimental_run(test_step, test_iterator)
    
  for epoch in range(EPOCHS):
    # Note: This code is expected to change in the near future.
    
    # TRAIN LOOP
    # Initialize the iterator
    train_iterator.initialize()
    for _ in range(train_steps_per_epoch):
      distributed_train()

    # TEST LOOP
    test_iterator.initialize()
    for _ in range(test_steps_per_epoch):
      distributed_test()
    
    if epoch % 2 == 0:
      checkpoint.save(checkpoint_prefix)

    template = ("Epoch {}, Loss: {}, Accuracy: {}, Test Loss: {}, "
                "Test Accuracy: {}")
    print (template.format(epoch+1, train_loss.result(), 
                           train_accuracy.result()*100, test_loss.result(), 
                           test_accuracy.result()*100))
    
    train_loss.reset_states()
    test_loss.reset_states()
    train_accuracy.reset_states()
    test_accuracy.reset_states()
Epoch 1, Loss: 0.5225825309753418, Accuracy: 80.9698486328125, Test Loss: 0.432892769575119, Test Accuracy: 84.58534240722656
Epoch 2, Loss: 0.34400758147239685, Accuracy: 87.69676971435547, Test Loss: 0.34699392318725586, Test Accuracy: 87.46995544433594
Epoch 3, Loss: 0.2954360246658325, Accuracy: 89.28929138183594, Test Loss: 0.2975158095359802, Test Accuracy: 89.20272827148438
Epoch 4, Loss: 0.26176968216896057, Accuracy: 90.3832015991211, Test Loss: 0.28567320108413696, Test Accuracy: 89.95392608642578
Epoch 5, Loss: 0.23702645301818848, Accuracy: 91.29869079589844, Test Loss: 0.2787027060985565, Test Accuracy: 89.69351196289062
Epoch 6, Loss: 0.21761010587215424, Accuracy: 92.06243133544922, Test Loss: 0.2878926694393158, Test Accuracy: 89.53324890136719
Epoch 7, Loss: 0.19936144351959229, Accuracy: 92.64107513427734, Test Loss: 0.2678224444389343, Test Accuracy: 90.64503479003906
Epoch 8, Loss: 0.184087872505188, Accuracy: 93.18470001220703, Test Loss: 0.28124910593032837, Test Accuracy: 90.25440979003906
Epoch 9, Loss: 0.1695927232503891, Accuracy: 93.6966323852539, Test Loss: 0.2541474401950836, Test Accuracy: 90.96554565429688
Epoch 10, Loss: 0.15550555288791656, Accuracy: 94.21858215332031, Test Loss: 0.2556819021701813, Test Accuracy: 90.79527282714844

 

最新のチェックポイントを復元してテストする

tf.distribute.Strategy でチェックポイントされたモデルはストラテジーとともに、またはストラテジーなしでリストアできます。

eval_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(
      name='eval_accuracy')

new_model = create_model()
new_optimizer = tf.keras.optimizers.Adam()

test_dataset = tf.data.Dataset.from_tensor_slices((test_images, test_labels)).batch(BATCH_SIZE)
@tf.function
def eval_step(images, labels):
  predictions = new_model(images, training=False)
  eval_accuracy(labels, predictions)
checkpoint = tf.train.Checkpoint(optimizer=new_optimizer, model=new_model)
checkpoint.restore(tf.train.latest_checkpoint(checkpoint_dir))

for images, labels in test_dataset:
  eval_step(images, labels)

print ('Accuracy after restoring the saved model without strategy: {}'.format(
    eval_accuracy.result()*100))
W0405 15:22:20.914693 140252361586432 tf_logging.py:161] Entity <method-wrapper '__call__' of weakref object at 0x7f8e145d07c8> could not be transformed and will be staged without change. Error details can be found in the logs when running with the env variable AUTOGRAPH_VERBOSITY >= 1. Please report this to the AutoGraph team. Cause: Object conversion is not yet supported. If you are trying to convert code that uses an existing object, try including the creation of that object in the conversion. For example, instead of converting the method of a class, try converting the entire class instead. See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/README.md#using-the-functional-api for more information.
W0405 15:22:20.920872 140252361586432 tf_logging.py:161] Entity <method-wrapper '__call__' of weakref object at 0x7f8e14520598> could not be transformed and will be staged without change. Error details can be found in the logs when running with the env variable AUTOGRAPH_VERBOSITY >= 1. Please report this to the AutoGraph team. Cause: Object conversion is not yet supported. If you are trying to convert code that uses an existing object, try including the creation of that object in the conversion. For example, instead of converting the method of a class, try converting the entire class instead. See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/README.md#using-the-functional-api for more information.
W0405 15:22:20.925516 140252361586432 tf_logging.py:161] Entity <method-wrapper '__call__' of weakref object at 0x7f8e145d02c8> could not be transformed and will be staged without change. Error details can be found in the logs when running with the env variable AUTOGRAPH_VERBOSITY >= 1. Please report this to the AutoGraph team. Cause: Object conversion is not yet supported. If you are trying to convert code that uses an existing object, try including the creation of that object in the conversion. For example, instead of converting the method of a class, try converting the entire class instead. See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/README.md#using-the-functional-api for more information.
W0405 15:22:20.930133 140252361586432 tf_logging.py:161] Entity <method-wrapper '__call__' of weakref object at 0x7f8e145d0318> could not be transformed and will be staged without change. Error details can be found in the logs when running with the env variable AUTOGRAPH_VERBOSITY >= 1. Please report this to the AutoGraph team. Cause: Object conversion is not yet supported. If you are trying to convert code that uses an existing object, try including the creation of that object in the conversion. For example, instead of converting the method of a class, try converting the entire class instead. See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/README.md#using-the-functional-api for more information.
W0405 15:22:20.934626 140252361586432 tf_logging.py:161] Entity <method-wrapper '__call__' of weakref object at 0x7f8e145d0368> could not be transformed and will be staged without change. Error details can be found in the logs when running with the env variable AUTOGRAPH_VERBOSITY >= 1. Please report this to the AutoGraph team. Cause: Object conversion is not yet supported. If you are trying to convert code that uses an existing object, try including the creation of that object in the conversion. For example, instead of converting the method of a class, try converting the entire class instead. See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/README.md#using-the-functional-api for more information.
W0405 15:22:20.938569 140252361586432 tf_logging.py:161] Entity <method-wrapper '__call__' of weakref object at 0x7f8e145d03b8> could not be transformed and will be staged without change. Error details can be found in the logs when running with the env variable AUTOGRAPH_VERBOSITY >= 1. Please report this to the AutoGraph team. Cause: Object conversion is not yet supported. If you are trying to convert code that uses an existing object, try including the creation of that object in the conversion. For example, instead of converting the method of a class, try converting the entire class instead. See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/README.md#using-the-functional-api for more information.
W0405 15:22:20.942585 140252361586432 tf_logging.py:161] Entity <method-wrapper '__call__' of weakref object at 0x7f8e145d0408> could not be transformed and will be staged without change. Error details can be found in the logs when running with the env variable AUTOGRAPH_VERBOSITY >= 1. Please report this to the AutoGraph team. Cause: Object conversion is not yet supported. If you are trying to convert code that uses an existing object, try including the creation of that object in the conversion. For example, instead of converting the method of a class, try converting the entire class instead. See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/README.md#using-the-functional-api for more information.
W0405 15:22:20.946619 140252361586432 tf_logging.py:161] Entity <method-wrapper '__call__' of weakref object at 0x7f8e145d06d8> could not be transformed and will be staged without change. Error details can be found in the logs when running with the env variable AUTOGRAPH_VERBOSITY >= 1. Please report this to the AutoGraph team. Cause: Object conversion is not yet supported. If you are trying to convert code that uses an existing object, try including the creation of that object in the conversion. For example, instead of converting the method of a class, try converting the entire class instead. See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/README.md#using-the-functional-api for more information.

WARNING: Entity <method-wrapper '__call__' of weakref object at 0x7f8e145d07c8> could not be transformed and will be staged without change. Error details can be found in the logs when running with the env variable AUTOGRAPH_VERBOSITY >= 1. Please report this to the AutoGraph team. Cause: Object conversion is not yet supported. If you are trying to convert code that uses an existing object, try including the creation of that object in the conversion. For example, instead of converting the method of a class, try converting the entire class instead. See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/README.md#using-the-functional-api for more information.
WARNING: Entity <method-wrapper '__call__' of weakref object at 0x7f8e14520598> could not be transformed and will be staged without change. Error details can be found in the logs when running with the env variable AUTOGRAPH_VERBOSITY >= 1. Please report this to the AutoGraph team. Cause: Object conversion is not yet supported. If you are trying to convert code that uses an existing object, try including the creation of that object in the conversion. For example, instead of converting the method of a class, try converting the entire class instead. See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/README.md#using-the-functional-api for more information.
WARNING: Entity <method-wrapper '__call__' of weakref object at 0x7f8e145d02c8> could not be transformed and will be staged without change. Error details can be found in the logs when running with the env variable AUTOGRAPH_VERBOSITY >= 1. Please report this to the AutoGraph team. Cause: Object conversion is not yet supported. If you are trying to convert code that uses an existing object, try including the creation of that object in the conversion. For example, instead of converting the method of a class, try converting the entire class instead. See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/README.md#using-the-functional-api for more information.
WARNING: Entity <method-wrapper '__call__' of weakref object at 0x7f8e145d0318> could not be transformed and will be staged without change. Error details can be found in the logs when running with the env variable AUTOGRAPH_VERBOSITY >= 1. Please report this to the AutoGraph team. Cause: Object conversion is not yet supported. If you are trying to convert code that uses an existing object, try including the creation of that object in the conversion. For example, instead of converting the method of a class, try converting the entire class instead. See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/README.md#using-the-functional-api for more information.
WARNING: Entity <method-wrapper '__call__' of weakref object at 0x7f8e145d0368> could not be transformed and will be staged without change. Error details can be found in the logs when running with the env variable AUTOGRAPH_VERBOSITY >= 1. Please report this to the AutoGraph team. Cause: Object conversion is not yet supported. If you are trying to convert code that uses an existing object, try including the creation of that object in the conversion. For example, instead of converting the method of a class, try converting the entire class instead. See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/README.md#using-the-functional-api for more information.
WARNING: Entity <method-wrapper '__call__' of weakref object at 0x7f8e145d03b8> could not be transformed and will be staged without change. Error details can be found in the logs when running with the env variable AUTOGRAPH_VERBOSITY >= 1. Please report this to the AutoGraph team. Cause: Object conversion is not yet supported. If you are trying to convert code that uses an existing object, try including the creation of that object in the conversion. For example, instead of converting the method of a class, try converting the entire class instead. See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/README.md#using-the-functional-api for more information.
WARNING: Entity <method-wrapper '__call__' of weakref object at 0x7f8e145d0408> could not be transformed and will be staged without change. Error details can be found in the logs when running with the env variable AUTOGRAPH_VERBOSITY >= 1. Please report this to the AutoGraph team. Cause: Object conversion is not yet supported. If you are trying to convert code that uses an existing object, try including the creation of that object in the conversion. For example, instead of converting the method of a class, try converting the entire class instead. See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/README.md#using-the-functional-api for more information.
WARNING: Entity <method-wrapper '__call__' of weakref object at 0x7f8e145d06d8> could not be transformed and will be staged without change. Error details can be found in the logs when running with the env variable AUTOGRAPH_VERBOSITY >= 1. Please report this to the AutoGraph team. Cause: Object conversion is not yet supported. If you are trying to convert code that uses an existing object, try including the creation of that object in the conversion. For example, instead of converting the method of a class, try converting the entire class instead. See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/README.md#using-the-functional-api for more information.
Accuracy after restoring the saved model without strategy: 90.97000122070312
 

以上






TensorFlow 2.0 Alpha : 上級 Tutorials : 分散訓練 :- TensorFlow の分散訓練

TensorFlow 2.0 Alpha : 上級 Tutorials : 分散訓練 :- TensorFlow の分散訓練 (翻訳/解説)

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

* 本ページは、TensorFlow の本家サイトの TF 2.0 Alpha – Advanced Tutorials – Distributed training の以下のページを翻訳した上で適宜、補足説明したものです:

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

 

分散訓練 :- TensorFlow の分散訓練

概要

tf.distribute.Strategy API は複数の処理ユニットに渡り貴方の訓練を分散するための抽象を提供します。目標はユーザに既存のモデルと訓練コードを (最小限の変更で) 使用して分散訓練を可能にすることです。

このチュートリアルは tf.distribute.MirroredStrategy を使用します、これは一つのマシン上の多くの GPU 上で同期訓練を伴う in-graph リプリケーションを行ないます。本質的には、それはモデルの変数の総てを各プロセッサにコピーします。それから、それは総てのプロセッサからの勾配を結合するために all-reduce を使用して結合された値をモデルの総てのコピーに適用します。

MirroredStategy は TensorFlow コアで利用可能な幾つかの分散ストラテジーの一つです。より多くのストラテジーについて 分散ストラテジー・ガイド で読むことができます。

 

Keras API

このサンプルはモデルと訓練ループを構築するために tf.kera API を使用します。カスタム訓練ループについては、このチュートリアル を見てください。

 

Import 依存性

from __future__ import absolute_import, division, print_function, unicode_literals
# Import TensorFlow
!pip install -q tensorflow==2.0.0-alpha0 
import tensorflow_datasets as tfds
import tensorflow as tf

import os

 

データセットをダウンロードする

MNIST データセットをダウンロードしてそれを TensorFlow Datasets からロードします。これは tf.data フォーマットの dataset を返します。

with_info を True に設定するとデータセット全体に対するメタデータを含みます、これはここでは ds_info にセーブされます。他のものの中で、このメタデータは訓練とテストサンプルの数を含みます。

datasets, ds_info = tfds.load(name='mnist', with_info=True, as_supervised=True)
mnist_train, mnist_test = datasets['train'], datasets['test']
Dl Completed...: 0 url [00:00, ? url/s]
Dl Size...: 0 MiB [00:00, ? MiB/s]

Dl Completed...:   0%|          | 0/1 [00:00<?, ? url/s]
Dl Size...: 0 MiB [00:00, ? MiB/s]

Dl Completed...:   0%|          | 0/2 [00:00<?, ? url/s]
Dl Size...: 0 MiB [00:00, ? MiB/s]

Dl Completed...:   0%|          | 0/3 [00:00<?, ? url/s]
Dl Size...: 0 MiB [00:00, ? MiB/s]

Dl Completed...:   0%|          | 0/4 [00:00<?, ? url/s]
Dl Size...: 0 MiB [00:00, ? MiB/s]

Dl Completed...:   0%|          | 0/4 [00:00<?, ? url/s]
Dl Size...: 0 MiB [00:00, ? MiB/s]

Extraction completed...: 0 file [00:00, ? file/s]
Downloading / extracting dataset mnist (11.06 MiB) to /root/tensorflow_datasets/mnist/1.0.0...

Dl Completed...:  25%|██▌       | 1/4 [00:00<00:00,  5.02 url/s]
Dl Size...: 0 MiB [00:00, ? MiB/s]

Dl Completed...:  25%|██▌       | 1/4 [00:00<00:00,  5.02 url/s]
Dl Size...:   0%|          | 0/1 [00:00<?, ? MiB/s]

Dl Completed...:  25%|██▌       | 1/4 [00:00<00:00,  5.02 url/s]
Dl Size...:   0%|          | 0/10 [00:00<?, ? MiB/s]

Dl Completed...:  25%|██▌       | 1/4 [00:00<00:00,  5.02 url/s]
Dl Size...:   0%|          | 0/10 [00:00<?, ? MiB/s]

Extraction completed...:   0%|          | 0/1 [00:00<?, ? file/s]

Dl Completed...:  25%|██▌       | 1/4 [00:00<00:00,  5.02 url/s]
Dl Size...:   0%|          | 0/10 [00:00<?, ? MiB/s]

Dl Completed...:  25%|██▌       | 1/4 [00:00<00:00,  5.02 url/s]
Dl Size...:   0%|          | 0/10 [00:00<?, ? MiB/s]

Dl Completed...:  50%|█████     | 2/4 [00:00<00:00,  5.29 url/s]
Dl Size...:   0%|          | 0/10 [00:00<?, ? MiB/s]

Dl Completed...:  50%|█████     | 2/4 [00:00<00:00,  5.29 url/s]
Dl Size...:   0%|          | 0/10 [00:00<?, ? MiB/s]

Extraction completed...:  50%|█████     | 1/2 [00:00<00:00,  4.26 file/s]

Dl Completed...:  50%|█████     | 2/4 [00:00<00:00,  5.29 url/s]
Dl Size...:   0%|          | 0/10 [00:00<?, ? MiB/s]

Extraction completed...: 100%|██████████| 2/2 [00:00<00:00,  4.76 file/s]
Dl Completed...:  50%|█████     | 2/4 [00:00<00:00,  5.29 url/s]
Dl Size...:  10%|█         | 1/10 [00:00<00:05,  1.59 MiB/s]

Dl Completed...:  50%|█████     | 2/4 [00:00<00:00,  5.29 url/s]
Dl Size...:  20%|██        | 2/10 [00:00<00:05,  1.59 MiB/s]

Dl Completed...:  75%|███████▌  | 3/4 [00:00<00:00,  4.29 url/s]
Dl Size...:  20%|██        | 2/10 [00:00<00:05,  1.59 MiB/s]

Dl Completed...:  75%|███████▌  | 3/4 [00:00<00:00,  4.29 url/s]
Dl Size...:  20%|██        | 2/10 [00:00<00:05,  1.59 MiB/s]

Extraction completed...:  67%|██████▋   | 2/3 [00:00<00:00,  4.76 file/s]
Dl Completed...:  75%|███████▌  | 3/4 [00:00<00:00,  4.29 url/s]
Dl Size...:  30%|███       | 3/10 [00:00<00:03,  2.16 MiB/s]

Extraction completed...:  67%|██████▋   | 2/3 [00:00<00:00,  4.76 file/s]

Dl Completed...:  75%|███████▌  | 3/4 [00:00<00:00,  4.29 url/s]
Dl Size...:  30%|███       | 3/10 [00:00<00:03,  2.16 MiB/s]

Extraction completed...: 100%|██████████| 3/3 [00:00<00:00,  3.61 file/s]
Dl Completed...:  75%|███████▌  | 3/4 [00:00<00:00,  4.29 url/s]
Dl Size...:  40%|████      | 4/10 [00:00<00:02,  2.75 MiB/s]

Dl Completed...:  75%|███████▌  | 3/4 [00:00<00:00,  4.29 url/s]
Dl Size...:  50%|█████     | 5/10 [00:00<00:01,  2.75 MiB/s]

Extraction completed...: 100%|██████████| 3/3 [00:00<00:00,  3.61 file/s]
Dl Completed...:  75%|███████▌  | 3/4 [00:01<00:00,  4.29 url/s]
Dl Size...:  60%|██████    | 6/10 [00:01<00:01,  3.50 MiB/s]

Dl Completed...:  75%|███████▌  | 3/4 [00:01<00:00,  4.29 url/s]
Dl Size...:  70%|███████   | 7/10 [00:01<00:00,  3.50 MiB/s]

Extraction completed...: 100%|██████████| 3/3 [00:01<00:00,  3.61 file/s]
Dl Completed...:  75%|███████▌  | 3/4 [00:01<00:00,  4.29 url/s]
Dl Size...:  80%|████████  | 8/10 [00:01<00:00,  4.47 MiB/s]

Extraction completed...: 100%|██████████| 3/3 [00:01<00:00,  3.61 file/s]
Dl Completed...:  75%|███████▌  | 3/4 [00:01<00:00,  4.29 url/s]
Dl Size...:  90%|█████████ | 9/10 [00:01<00:00,  5.31 MiB/s]

Dl Completed...:  75%|███████▌  | 3/4 [00:01<00:00,  4.29 url/s]
Dl Size...: 100%|██████████| 10/10 [00:01<00:00,  5.31 MiB/s]

Dl Completed...: 100%|██████████| 4/4 [00:01<00:00,  2.51 url/s]
Dl Size...: 100%|██████████| 10/10 [00:01<00:00,  5.31 MiB/s]

Dl Completed...: 100%|██████████| 4/4 [00:01<00:00,  2.51 url/s]
Dl Size...: 100%|██████████| 10/10 [00:01<00:00,  5.31 MiB/s]

Extraction completed...:  75%|███████▌  | 3/4 [00:01<00:00,  3.61 file/s]

Dl Completed...: 100%|██████████| 4/4 [00:01<00:00,  2.51 url/s]
Dl Size...: 100%|██████████| 10/10 [00:01<00:00,  5.31 MiB/s]

Extraction completed...: 100%|██████████| 4/4 [00:01<00:00,  1.94 file/s]
Dl Size...: 100%|██████████| 10/10 [00:01<00:00,  5.24 MiB/s]
1 examples [00:00,  6.16 examples/s]




60000 examples [00:13, 4349.69 examples/s]
Shuffling...:   0%|          | 0/10 [00:00<?, ? shard/s]WARNING: Logging before flag parsing goes to stderr.
W0405 15:23:16.461484 140384515561216 deprecation.py:323] From /usr/local/lib/python3.5/dist-packages/tensorflow_datasets/core/file_format_adapter.py:249: tf_record_iterator (from tensorflow.python.lib.io.tf_record) is deprecated and will be removed in a future version.
Instructions for updating:
Use eager execution and: 
`tf.data.TFRecordDataset(path)`

Reading...: 0 examples [00:00, ? examples/s]
Reading...: 6000 examples [00:00, 260273.29 examples/s]
Writing...:   0%|          | 0/6000 [00:00<?, ? examples/s]
Writing...: 100%|██████████| 6000/6000 [00:00<00:00, 156708.54 examples/s]
Reading...: 0 examples [00:00, ? examples/s]
Reading...: 6000 examples [00:00, 271998.27 examples/s]
Writing...:   0%|          | 0/6000 [00:00<?, ? examples/s]
Shuffling...:  20%|██        | 2/10 [00:00<00:00, 13.66 shard/s]
Reading...: 0 examples [00:00, ? examples/s]
Reading...: 6000 examples [00:00, 294326.80 examples/s]
Writing...:   0%|          | 0/6000 [00:00<?, ? examples/s]
Writing...: 100%|██████████| 6000/6000 [00:00<00:00, 144187.84 examples/s]
Reading...: 0 examples [00:00, ? examples/s]
Reading...: 6000 examples [00:00, 252869.48 examples/s]
Writing...:   0%|          | 0/6000 [00:00<?, ? examples/s]
Shuffling...:  40%|████      | 4/10 [00:00<00:00, 13.64 shard/s]
Reading...: 0 examples [00:00, ? examples/s]
Reading...: 6000 examples [00:00, 280211.82 examples/s]
Writing...:   0%|          | 0/6000 [00:00<?, ? examples/s]
Writing...: 100%|██████████| 6000/6000 [00:00<00:00, 150449.41 examples/s]
Reading...: 0 examples [00:00, ? examples/s]
Reading...: 6000 examples [00:00, 284910.10 examples/s]
Writing...:   0%|          | 0/6000 [00:00<?, ? examples/s]
Shuffling...:  60%|██████    | 6/10 [00:00<00:00, 13.86 shard/s]
Reading...: 0 examples [00:00, ? examples/s]
Reading...: 6000 examples [00:00, 238819.31 examples/s]
Writing...:   0%|          | 0/6000 [00:00<?, ? examples/s]
Writing...: 100%|██████████| 6000/6000 [00:00<00:00, 137965.23 examples/s]
Reading...: 0 examples [00:00, ? examples/s]
Reading...: 6000 examples [00:00, 244280.96 examples/s]
Writing...:   0%|          | 0/6000 [00:00<?, ? examples/s]
Shuffling...:  80%|████████  | 8/10 [00:00<00:00, 13.58 shard/s]
Reading...: 0 examples [00:00, ? examples/s]
Reading...: 6000 examples [00:00, 292693.93 examples/s]
Writing...:   0%|          | 0/6000 [00:00<?, ? examples/s]
Writing...: 100%|██████████| 6000/6000 [00:00<00:00, 148655.99 examples/s]
Reading...: 0 examples [00:00, ? examples/s]
Reading...: 6000 examples [00:00, 232564.68 examples/s]
Writing...:   0%|          | 0/6000 [00:00<?, ? examples/s]
Shuffling...: 100%|██████████| 10/10 [00:00<00:00, 13.61 shard/s]
10000 examples [00:02, 4444.35 examples/s]
Shuffling...:   0%|          | 0/1 [00:00<?, ? shard/s]
Reading...: 0 examples [00:00, ? examples/s]
Reading...: 10000 examples [00:00, 313138.63 examples/s]
Writing...:   0%|          | 0/10000 [00:00<?, ? examples/s]
Shuffling...: 100%|██████████| 1/1 [00:00<00:00,  9.25 shard/s]

 

分散ストラテジーを定義する

MirroredStrategy オブジェクトを作成します。これは分散を処理し、内側でモデルを構築するためのコンテキストマネージャ (tf.distribute.MirroredStrategy.scope) を提供します。

strategy = tf.distribute.MirroredStrategy()
W0405 15:23:20.099184 140384515561216 cross_device_ops.py:1111] Not all devices in `tf.distribute.Strategy` are visible to TensorFlow.
print ('Number of devices: {}'.format(strategy.num_replicas_in_sync))
Number of devices: 1

 

入力パイプラインをセットアップする

モデルがマルチ GPU 上で訓練されるのであれば、特別な計算パワーを効果的に利用するためにバッチサイズはそれに従って増やされるべきです。更に、学習率もそれに従って調整されるべきです。

# You can also do ds_info.splits.total_num_examples to get the total 
# number of examples in the dataset.

num_train_examples = ds_info.splits['train'].num_examples
num_test_examples = ds_info.splits['test'].num_examples

BUFFER_SIZE = 10000

BATCH_SIZE_PER_REPLICA = 64
BATCH_SIZE = BATCH_SIZE_PER_REPLICA * strategy.num_replicas_in_sync

0-255 のピクセル値は 0-1 範囲に正規化されなければなりません。このスケールを関数で定義します。

def scale(image, label):
  image = tf.cast(image, tf.float32)
  image /= 255
  
  return image, label

この関数を訓練とテストデータに適用し、訓練データをシャッフルし、そして 訓練のためにそれをバッチ化します

train_dataset = mnist_train.map(scale).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
eval_dataset = mnist_test.map(scale).batch(BATCH_SIZE)

 

モデルを作成する

strategy.scope のコンテキストで Keras モデルを作成してコンパイルします。

with strategy.scope():
  model = tf.keras.Sequential([
      tf.keras.layers.Conv2D(32, 3, activation='relu', input_shape=(28, 28, 1)),
      tf.keras.layers.MaxPooling2D(),
      tf.keras.layers.Flatten(),
      tf.keras.layers.Dense(64, activation='relu'),
      tf.keras.layers.Dense(10, activation='softmax')
  ])
  
  model.compile(loss='sparse_categorical_crossentropy',
                optimizer=tf.keras.optimizers.Adam(),
                metrics=['accuracy'])

 

コールバックを定義する

ここで使用されるコールバックは :

  • Tensorboard: このコールバックはグラフを可視化することを可能にする TensorBoard のためのログを書きます。
  • モデル・チェックポイント: このコールバックは総てのエポック後にモデルをセーブします。
  • 学習率スケジューラ: このコールバックを使用すると、総てのエポック/バッチ後に変更する学習率をスケジューリングできます。

説明目的で、このノートブックでは学習率を表示するための print コールバックを追加します。

# Define the checkpoint directory to store the checkpoints

checkpoint_dir = './training_checkpoints'
# Name of the checkpoint files
checkpoint_prefix = os.path.join(checkpoint_dir, "ckpt_{epoch}")
# Function for decaying the learning rate.
# You can define any decay function you need.
def decay(epoch):
  if epoch < 3:
    return 1e-3
  elif epoch >= 3 and epoch < 7:
    return 1e-4
  else:
    return 1e-5
# Callback for printing the LR at the end of each epoch.
class PrintLR(tf.keras.callbacks.Callback):
  def on_epoch_end(self, epoch, logs=None):
    print ('\nLearning rate for epoch {} is {}'.format(epoch + 1, 
                                                       model.optimizer.lr.numpy()))
callbacks = [
    tf.keras.callbacks.TensorBoard(log_dir='./logs'),
    tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_prefix, 
                                       save_weights_only=True),
    tf.keras.callbacks.LearningRateScheduler(decay),
    PrintLR()
]

 

訓練そして評価する

さて、通常の方法でモデルを訓練します、モデル上で fit を呼び出してチュートリアルの最初に作成されたデータセットを渡します。このステップは貴方が訓練を分散していてもそうでなくても同じです。

model.fit(train_dataset, epochs=10, callbacks=callbacks)
W0405 15:23:21.675539 140384515561216 distributed_training_utils.py:182] Your input callback is not one of the predefined Callbacks that supports DistributionStrategy. You might encounter an error if you access one of the model's attributes as part of the callback since these attributes are not set. You can access each of the individual distributed models using the `_grouped_model` attribute of your original model.
W0405 15:23:21.676841 140384515561216 distributed_training_utils.py:182] Your input callback is not one of the predefined Callbacks that supports DistributionStrategy. You might encounter an error if you access one of the model's attributes as part of the callback since these attributes are not set. You can access each of the individual distributed models using the `_grouped_model` attribute of your original model.
W0405 15:23:21.677886 140384515561216 distributed_training_utils.py:182] Your input callback is not one of the predefined Callbacks that supports DistributionStrategy. You might encounter an error if you access one of the model's attributes as part of the callback since these attributes are not set. You can access each of the individual distributed models using the `_grouped_model` attribute of your original model.
W0405 15:23:21.678794 140384515561216 distributed_training_utils.py:182] Your input callback is not one of the predefined Callbacks that supports DistributionStrategy. You might encounter an error if you access one of the model's attributes as part of the callback since these attributes are not set. You can access each of the individual distributed models using the `_grouped_model` attribute of your original model.

Epoch 1/10
    938/Unknown - 9s 9ms/step - loss: 0.1977 - accuracy: 0.9434
Learning rate for epoch 1 is 0.0010000000474974513
938/938 [==============================] - 9s 9ms/step - loss: 0.1977 - accuracy: 0.9434
Epoch 2/10
930/938 [============================>.] - ETA: 0s - loss: 0.0680 - accuracy: 0.9791
Learning rate for epoch 2 is 0.0010000000474974513
938/938 [==============================] - 7s 7ms/step - loss: 0.0678 - accuracy: 0.9791
Epoch 3/10
933/938 [============================>.] - ETA: 0s - loss: 0.0463 - accuracy: 0.9862
Learning rate for epoch 3 is 0.0010000000474974513
938/938 [==============================] - 7s 8ms/step - loss: 0.0464 - accuracy: 0.9861
Epoch 4/10
935/938 [============================>.] - ETA: 0s - loss: 0.0256 - accuracy: 0.9927
Learning rate for epoch 4 is 9.999999747378752e-05
938/938 [==============================] - 7s 8ms/step - loss: 0.0255 - accuracy: 0.9927
Epoch 5/10
934/938 [============================>.] - ETA: 0s - loss: 0.0221 - accuracy: 0.9941
Learning rate for epoch 5 is 9.999999747378752e-05
938/938 [==============================] - 7s 8ms/step - loss: 0.0220 - accuracy: 0.9941
Epoch 6/10
936/938 [============================>.] - ETA: 0s - loss: 0.0202 - accuracy: 0.9947
Learning rate for epoch 6 is 9.999999747378752e-05
938/938 [==============================] - 7s 7ms/step - loss: 0.0201 - accuracy: 0.9947
Epoch 7/10
932/938 [============================>.] - ETA: 0s - loss: 0.0187 - accuracy: 0.9952
Learning rate for epoch 7 is 9.999999747378752e-05
938/938 [==============================] - 7s 7ms/step - loss: 0.0186 - accuracy: 0.9952
Epoch 8/10
935/938 [============================>.] - ETA: 0s - loss: 0.0161 - accuracy: 0.9963
Learning rate for epoch 8 is 9.999999747378752e-06
938/938 [==============================] - 7s 8ms/step - loss: 0.0161 - accuracy: 0.9963
Epoch 9/10
932/938 [============================>.] - ETA: 0s - loss: 0.0158 - accuracy: 0.9964
Learning rate for epoch 9 is 9.999999747378752e-06
938/938 [==============================] - 7s 8ms/step - loss: 0.0158 - accuracy: 0.9964
Epoch 10/10
934/938 [============================>.] - ETA: 0s - loss: 0.0156 - accuracy: 0.9965
Learning rate for epoch 10 is 9.999999747378752e-06
938/938 [==============================] - 7s 7ms/step - loss: 0.0156 - accuracy: 0.9965


下で見れるように、チェックポイントはセーブされています。

# check the checkpoint directory
!ls {checkpoint_dir}
checkpoint           ckpt_5.data-00000-of-00001
ckpt_1.data-00000-of-00001   ckpt_5.index
ckpt_1.index             ckpt_6.data-00000-of-00001
ckpt_10.data-00000-of-00001  ckpt_6.index
ckpt_10.index            ckpt_7.data-00000-of-00001
ckpt_2.data-00000-of-00001   ckpt_7.index
ckpt_2.index             ckpt_8.data-00000-of-00001
ckpt_3.data-00000-of-00001   ckpt_8.index
ckpt_3.index             ckpt_9.data-00000-of-00001
ckpt_4.data-00000-of-00001   ckpt_9.index
ckpt_4.index

モデルがどのように遂行するかを見るために、最新のチェックポイントをロードしてテストデータ上で evaluate を呼び出します。

適切なデータセットを使用して前のように evaluate を呼び出します。

model.load_weights(tf.train.latest_checkpoint(checkpoint_dir))

eval_loss, eval_acc = model.evaluate(eval_dataset)
print ('Eval loss: {}, Eval Accuracy: {}'.format(eval_loss, eval_acc))
    157/Unknown - 2s 10ms/step - loss: 0.0388 - accuracy: 0.9872Eval loss: 0.03881146577201713, Eval Accuracy: 0.9872000217437744

出力を見るために、TensorBoard ログをダウンロードして端末で見ることができます。

$ tensorboard --logdir=path/to/log-directory
!ls -sh ./logs
total 12K
4.0K plugins  4.0K train  4.0K validation

 

SavedModel にエクスポートする

グラフと変数をエクスポートすることを望む場合、SavedModel はこれを行なうために最善の方法です。モデルはスコープとともに、あるいはスコープなしでロードし戻すことができます。更に、SavedModel はプラットフォーム不可知論者 (= agnostic) です。

path = 'saved_model/'
tf.keras.experimental.export_saved_model(model, path)
W0405 15:25:10.681121 140384515561216 deprecation.py:323] From /usr/local/lib/python3.5/dist-packages/tensorflow/python/saved_model/signature_def_utils_impl.py:253: build_tensor_info (from tensorflow.python.saved_model.utils_impl) is deprecated and will be removed in a future version.
Instructions for updating:
This function will only be available through the v1 compatibility library as tf.compat.v1.saved_model.utils.build_tensor_info or tf.compat.v1.saved_model.build_tensor_info.
W0405 15:25:10.683329 140384515561216 tf_logging.py:161] Export includes no default signature!
W0405 15:25:11.132856 140384515561216 tf_logging.py:161] Export includes no default signature!

strategy.scope なしでモデルをロードします。

unreplicated_model = tf.keras.experimental.load_from_saved_model(path)

unreplicated_model.compile(
    loss='sparse_categorical_crossentropy', 
    optimizer=tf.keras.optimizers.Adam(), 
    metrics=['accuracy'])

eval_loss, eval_acc = unreplicated_model.evaluate(eval_dataset)
print ('Eval loss: {}, Eval Accuracy: {}'.format(eval_loss, eval_acc))
    157/Unknown - 2s 10ms/step - loss: 0.0388 - accuracy: 0.9872Eval loss: 0.03881146577201713, Eval Accuracy: 0.9872000217437744

strategy.scope とともにロードします。

with strategy.scope():
  replicated_model = tf.keras.experimental.load_from_saved_model(path)
  replicated_model.compile(loss='sparse_categorical_crossentropy',
                           optimizer=tf.keras.optimizers.Adam(),
                           metrics=['accuracy'])

  eval_loss, eval_acc = replicated_model.evaluate(eval_dataset)
  print ('Eval loss: {}, Eval Accuracy: {}'.format(eval_loss, eval_acc))
    157/Unknown - 1s 9ms/step - loss: 0.0388 - accuracy: 0.9872Eval loss: 0.03881146577201713, Eval Accuracy: 0.9872000217437744
 

以上






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