ホーム » Keras » TensorFlow 2.0 Beta : Tutorials : ML 基本 :- モデルをセーブしてリストアする

TensorFlow 2.0 Beta : Tutorials : ML 基本 :- モデルをセーブしてリストアする

TensorFlow 2.0 Beta : Beginner Tutorials : ML 基本 :- モデルをセーブしてリストアする (翻訳/解説)

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

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

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

 

ML 基本 :- モデルをセーブしてリストアする

モデルの進捗は訓練の間に — そして後に — セーブすることが可能です。これは、モデルが (訓練を) 中止したところから再開できて長い訓練時間を回避できることを意味します。セービングはまた貴方がモデルを共有して他の人は貴方のワークを再作成できることもまた意味します。研究モデルとテクニックを公開するとき、多くの機械学習実践者は以下を共有します :

  • モデルを作成するためのコード、そして
  • モデルのために訓練された重み、またはパラメータ

このデータの共有は他の人たちがモデルがどのように動作するかを理解して新しいデータで彼ら自身がそれを試す手助けとなります。

Caution: 信頼できない (untrusted) コードに注意してください — TensorFlow モデルはコードです。詳細は Using TensorFlow Securely を見てください。

 

オプション

TensorFlow モデルをセーブする異なる方法があります — 貴方が使用している API に依拠します。このガイドは tf.keras, TensorFlow でモデルを構築して訓練するための高位 API を使用します。他のアプローチについては、TensorFlow Save and Restore ガイドや Saving in eager を見てください。

 

セットアップ

インストールとインポート

TensorFlow と依存関係をインストールしてインポートします :

!pip install -q h5py pyyaml

 

サンプル・データセットを取得する

重みのセーブを実演するために MNIST データセット を使用してモデルを訓練します。これらのデモの実行をスピードアップするために、最初の 1000 サンプルだけを使用します :

from __future__ import absolute_import, division, print_function, unicode_literals

import os

!pip install -q tensorflow==2.0.0-beta1
import tensorflow as tf
from tensorflow import keras

tf.__version__
'2.0.0-beta1'
(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()

train_labels = train_labels[:1000]
test_labels = test_labels[:1000]

train_images = train_images[:1000].reshape(-1, 28 * 28) / 255.0
test_images = test_images[:1000].reshape(-1, 28 * 28) / 255.0

 

モデルを定義する

重みのセーブとロードを実演するために使用する単純なモデルを構築しましょう。

# Returns a short sequential model
def create_model():
  model = tf.keras.models.Sequential([
    keras.layers.Dense(512, activation='relu', input_shape=(784,)),
    keras.layers.Dropout(0.2),
    keras.layers.Dense(10, activation='softmax')
  ])

  model.compile(optimizer='adam',
                loss='sparse_categorical_crossentropy',
                metrics=['accuracy'])

  return model


# Create a basic model instance
model = create_model()
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense (Dense)                (None, 512)               401920    
_________________________________________________________________
dropout (Dropout)            (None, 512)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 10)                5130      
=================================================================
Total params: 407,050
Trainable params: 407,050
Non-trainable params: 0
_________________________________________________________________

 

訓練の間にチェックポイントをセーブする

主なユースケースは訓練の間と最後にチェックポイントを自動的にセーブすることです。このように訓練されたモデルをそれを再訓練しなくても使用できたり、あるいは — 訓練プロセスが中断された場合には — 中止したところから訓練を選択することができます。

tf.keras.callbacks.ModelCheckpoint はこのタスクを遂行する callback です。この callback はチェックポインティングを構成するために 2, 3 の引数を取ります。

 

Checkpoint callback 使用方法

モデルを訓練してそれを ModelCheckpoint callback に渡します :

checkpoint_path = "training_1/cp.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)

# Create checkpoint callback
cp_callback = tf.keras.callbacks.ModelCheckpoint(checkpoint_path,
                                                 save_weights_only=True,
                                                 verbose=1)

model = create_model()

model.fit(train_images, train_labels,  epochs = 10,
          validation_data = (test_images,test_labels),
          callbacks = [cp_callback])  # pass callback to training

# This may generate warnings related to saving the state of the optimizer.
# These warnings (and similar warnings throughout this notebook)
# are in place to discourage outdated usage, and can be ignored.
WARNING: Logging before flag parsing goes to stderr.
W0614 17:44:59.997754 139650494461696 deprecation.py:323] From /tmpfs/src/tf_docs_env/lib/python3.5/site-packages/tensorflow/python/ops/math_grad.py:1250: add_dispatch_support..wrapper (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Use tf.where in 2.0, which has the same broadcast rule as np.where

Train on 1000 samples, validate on 1000 samples
Epoch 1/10
 992/1000 [============================>.] - ETA: 0s - loss: 1.1820 - accuracy: 0.6512
Epoch 00001: saving model to training_1/cp.ckpt
1000/1000 [==============================] - 1s 502us/sample - loss: 1.1799 - accuracy: 0.6520 - val_loss: 0.7200 - val_accuracy: 0.7890
Epoch 2/10
 544/1000 [===============>..............] - ETA: 0s - loss: 0.4237 - accuracy: 0.8787
Epoch 00002: saving model to training_1/cp.ckpt
1000/1000 [==============================] - 0s 170us/sample - loss: 0.4251 - accuracy: 0.8800 - val_loss: 0.5577 - val_accuracy: 0.8340
Epoch 3/10
 544/1000 [===============>..............] - ETA: 0s - loss: 0.3251 - accuracy: 0.9118
Epoch 00003: saving model to training_1/cp.ckpt
1000/1000 [==============================] - 0s 171us/sample - loss: 0.3021 - accuracy: 0.9210 - val_loss: 0.5011 - val_accuracy: 0.8350
Epoch 4/10
 544/1000 [===============>..............] - ETA: 0s - loss: 0.2239 - accuracy: 0.9485
Epoch 00004: saving model to training_1/cp.ckpt
1000/1000 [==============================] - 0s 170us/sample - loss: 0.2135 - accuracy: 0.9520 - val_loss: 0.4270 - val_accuracy: 0.8640
Epoch 5/10
 544/1000 [===============>..............] - ETA: 0s - loss: 0.1613 - accuracy: 0.9669
Epoch 00005: saving model to training_1/cp.ckpt
1000/1000 [==============================] - 0s 167us/sample - loss: 0.1620 - accuracy: 0.9630 - val_loss: 0.4244 - val_accuracy: 0.8590
Epoch 6/10
 576/1000 [================>.............] - ETA: 0s - loss: 0.1253 - accuracy: 0.9774
Epoch 00006: saving model to training_1/cp.ckpt
1000/1000 [==============================] - 0s 161us/sample - loss: 0.1215 - accuracy: 0.9780 - val_loss: 0.4317 - val_accuracy: 0.8520
Epoch 7/10
 576/1000 [================>.............] - ETA: 0s - loss: 0.0925 - accuracy: 0.9844
Epoch 00007: saving model to training_1/cp.ckpt
1000/1000 [==============================] - 0s 163us/sample - loss: 0.0903 - accuracy: 0.9860 - val_loss: 0.4201 - val_accuracy: 0.8600
Epoch 8/10
 576/1000 [================>.............] - ETA: 0s - loss: 0.0642 - accuracy: 0.9931
Epoch 00008: saving model to training_1/cp.ckpt
1000/1000 [==============================] - 0s 158us/sample - loss: 0.0640 - accuracy: 0.9930 - val_loss: 0.4130 - val_accuracy: 0.8600
Epoch 9/10
 576/1000 [================>.............] - ETA: 0s - loss: 0.0511 - accuracy: 0.9965
Epoch 00009: saving model to training_1/cp.ckpt
1000/1000 [==============================] - 0s 159us/sample - loss: 0.0497 - accuracy: 0.9980 - val_loss: 0.4306 - val_accuracy: 0.8650
Epoch 10/10
 576/1000 [================>.............] - ETA: 0s - loss: 0.0386 - accuracy: 1.0000
Epoch 00010: saving model to training_1/cp.ckpt
1000/1000 [==============================] - 0s 165us/sample - loss: 0.0423 - accuracy: 0.9990 - val_loss: 0.4258 - val_accuracy: 0.8640

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

これは、各エポックの最後に更新される TensorFlow チェックポイント・ファイルの単一のコレクションを作成します :

!ls {checkpoint_dir}
checkpoint  cp.ckpt.data-00000-of-00001  cp.ckpt.index

新しい、未訓練のモデルを作成します。重みだけからモデルをリストアするときは、元のモデルと同じアーキテクチャを持つモデルを持たなければなりません。それは同じモデル・アーキテクチャですから、それがモデルの異なるインスタンスであるにもかかわらず重みを共有することができます。

さて未使用の、未訓練のモデルを再構築して、それをテストセット上で評価しましょう。未訓練モデルは偶然レベル (~10% 精度) で遂行します :

model = create_model()

loss, acc = model.evaluate(test_images, test_labels)
print("Untrained model, accuracy: {:5.2f}%".format(100*acc))
1000/1000 [==============================] - 0s 104us/sample - loss: 2.3691 - accuracy: 0.0700
Untrained model, accuracy:  7.00%

それからチェックポイントから重みをロードして、再評価します :

model.load_weights(checkpoint_path)
loss,acc = model.evaluate(test_images, test_labels)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))
1000/1000 [==============================] - 0s 46us/sample - loss: 0.4258 - accuracy: 0.8640
Restored model, accuracy: 86.40%

 

Checkpoint callback オプション

callback は結果としてのチェックポイントに一意な名前を与えて、チェックポイントする頻度を調整するために幾つかのオプションを提供します。

新しいモデルを訓練して、一意に名前付けられたチェックポイントを 5 エポック毎に一度セーブします :

# include the epoch in the file name. (uses `str.format`)
checkpoint_path = "training_2/cp-{epoch:04d}.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)

cp_callback = tf.keras.callbacks.ModelCheckpoint(
    checkpoint_path, verbose=1, save_weights_only=True,
    # Save weights, every 5-epochs.
    period=5)

model = create_model()
model.save_weights(checkpoint_path.format(epoch=0))
model.fit(train_images, train_labels,
          epochs = 50, callbacks = [cp_callback],
          validation_data = (test_images,test_labels),
          verbose=0)
W0614 17:45:03.020097 139650494461696 callbacks.py:859] `period` argument is deprecated. Please use `save_freq` to specify the frequency in number of samples seen.


Epoch 00005: saving model to training_2/cp-0005.ckpt

Epoch 00010: saving model to training_2/cp-0010.ckpt

Epoch 00015: saving model to training_2/cp-0015.ckpt

Epoch 00020: saving model to training_2/cp-0020.ckpt

Epoch 00025: saving model to training_2/cp-0025.ckpt

Epoch 00030: saving model to training_2/cp-0030.ckpt

Epoch 00035: saving model to training_2/cp-0035.ckpt

Epoch 00040: saving model to training_2/cp-0040.ckpt

Epoch 00045: saving model to training_2/cp-0045.ckpt

Epoch 00050: saving model to training_2/cp-0050.ckpt

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

さて、結果としてのチェックポイントを見て最新のものを選択します :

! ls {checkpoint_dir}
checkpoint            cp-0025.ckpt.index
cp-0000.ckpt.data-00000-of-00001  cp-0030.ckpt.data-00000-of-00001
cp-0000.ckpt.index        cp-0030.ckpt.index
cp-0005.ckpt.data-00000-of-00001  cp-0035.ckpt.data-00000-of-00001
cp-0005.ckpt.index        cp-0035.ckpt.index
cp-0010.ckpt.data-00000-of-00001  cp-0040.ckpt.data-00000-of-00001
cp-0010.ckpt.index        cp-0040.ckpt.index
cp-0015.ckpt.data-00000-of-00001  cp-0045.ckpt.data-00000-of-00001
cp-0015.ckpt.index        cp-0045.ckpt.index
cp-0020.ckpt.data-00000-of-00001  cp-0050.ckpt.data-00000-of-00001
cp-0020.ckpt.index        cp-0050.ckpt.index
cp-0025.ckpt.data-00000-of-00001
latest = tf.train.latest_checkpoint(checkpoint_dir)
latest
'training_2/cp-0050.ckpt'

Note: デフォルトの tensorflow フォーマットは 5 つの直近のチェックポイントだけをセーブします。

テストするためには、モデルをリセットして最新のチェックポイントをロードします :

model = create_model()
model.load_weights(latest)
loss, acc = model.evaluate(test_images, test_labels)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))
1000/1000 [==============================] - 0s 100us/sample - loss: 0.4908 - accuracy: 0.8760
Restored model, accuracy: 87.60%

 

これらのファイルは何でしょう?

上のコードは重みを (訓練された重みだけをバイナリ形式で含む) チェックポイント 形式ファイルのコレクションにストアします。チェックポイントは次を含みます : * モデルの重みを含む一つまたはそれ以上のシャード。* どの重みがどのシャードにストアされているかを指し示すインデックスファイル。

単一のマシン上でモデルを訓練しているだけであれば、サフィックス: .data-00000-of-00001 を持つ一つのシャードを持つでしょう。

 

重みを手動でセーブする

上で重みをどのようにモデルにロードするかを見ました。

手動で重みをセーブするのは同様に単純で、Model.save_weights メソッドを使用します。

# Save the weights
model.save_weights('./checkpoints/my_checkpoint')

# Restore the weights
model = create_model()
model.load_weights('./checkpoints/my_checkpoint')

loss,acc = model.evaluate(test_images, test_labels)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))
1000/1000 [==============================] - 0s 100us/sample - loss: 0.4908 - accuracy: 0.8760
Restored model, accuracy: 87.60%

 

モデル全体をセーブする

モデルと optimizer はそれらの状態 (重みと変数) とモデル構成 (= configuration) の両者を含むファイルにセーブできます。これはモデルをエクスポートしてそれは元の python コードへのアクセスなしに使用できます。optimizer-状態がリカバーされますので正確に貴方がやめたところから訓練を再開することさえできます。

完全に機能するモデルのセーブは非常に有用です — それらを TensorFlow.js にロード (HDF5, Saved Model) してから web ブラウザでそれらを訓練して実行することができます、あるいは TensorFlow Lite を使用して (HDF5, Saved Model) モバイルデバイス上で実行するためそれらを変換できます。

 

HDF5 ファイルとして

Keras は HDF5 標準を使用した基本的なセーブ・フォーマットを提供します。私達の目的のためには、セーブされたモデルは単一のバイナリ・ブロブとして扱うことができます。

model = create_model()

model.fit(train_images, train_labels, epochs=5)

# Save entire model to a HDF5 file
model.save('my_model.h5')
W0614 17:45:12.451796 139650494461696 util.py:244] Unresolved object in checkpoint: (root).optimizer.iter
W0614 17:45:12.453363 139650494461696 util.py:244] Unresolved object in checkpoint: (root).optimizer.beta_1
W0614 17:45:12.454297 139650494461696 util.py:244] Unresolved object in checkpoint: (root).optimizer.beta_2
W0614 17:45:12.455039 139650494461696 util.py:244] Unresolved object in checkpoint: (root).optimizer.decay
W0614 17:45:12.455814 139650494461696 util.py:244] Unresolved object in checkpoint: (root).optimizer.learning_rate
W0614 17:45:12.456508 139650494461696 util.py:252] A checkpoint was restored (e.g. tf.train.Checkpoint.restore or tf.keras.Model.load_weights) but not all checkpointed values were used. See above for specific issues. Use expect_partial() on the load status object, e.g. tf.train.Checkpoint.restore(...).expect_partial(), to silence these warnings, or use assert_consumed() to make the check explicit. See https://www.tensorflow.org/alpha/guide/checkpoints#loading_mechanics for details.
W0614 17:45:12.459612 139650494461696 util.py:244] Unresolved object in checkpoint: (root).optimizer.iter
W0614 17:45:12.460473 139650494461696 util.py:244] Unresolved object in checkpoint: (root).optimizer.beta_1
W0614 17:45:12.461083 139650494461696 util.py:244] Unresolved object in checkpoint: (root).optimizer.beta_2
W0614 17:45:12.461607 139650494461696 util.py:244] Unresolved object in checkpoint: (root).optimizer.decay
W0614 17:45:12.462147 139650494461696 util.py:244] Unresolved object in checkpoint: (root).optimizer.learning_rate
W0614 17:45:12.463938 139650494461696 util.py:252] A checkpoint was restored (e.g. tf.train.Checkpoint.restore or tf.keras.Model.load_weights) but not all checkpointed values were used. See above for specific issues. Use expect_partial() on the load status object, e.g. tf.train.Checkpoint.restore(...).expect_partial(), to silence these warnings, or use assert_consumed() to make the check explicit. See https://www.tensorflow.org/alpha/guide/checkpoints#loading_mechanics for details.

Train on 1000 samples
Epoch 1/5
1000/1000 [==============================] - 0s 259us/sample - loss: 1.1410 - accuracy: 0.6710
Epoch 2/5
1000/1000 [==============================] - 0s 103us/sample - loss: 0.4294 - accuracy: 0.8760
Epoch 3/5
1000/1000 [==============================] - 0s 102us/sample - loss: 0.2867 - accuracy: 0.9170
Epoch 4/5
1000/1000 [==============================] - 0s 100us/sample - loss: 0.2247 - accuracy: 0.9420
Epoch 5/5
1000/1000 [==============================] - 0s 96us/sample - loss: 0.1540 - accuracy: 0.9670

さてそのファイルからモデルを再作成します :

# Recreate the exact same model, including weights and optimizer.
new_model = keras.models.load_model('my_model.h5')
new_model.summary()
Model: "sequential_6"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_12 (Dense)             (None, 512)               401920    
_________________________________________________________________
dropout_6 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_13 (Dense)             (None, 10)                5130      
=================================================================
Total params: 407,050
Trainable params: 407,050
Non-trainable params: 0
_________________________________________________________________

その精度を確認します :

loss, acc = new_model.evaluate(test_images, test_labels)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))
1000/1000 [==============================] - 0s 106us/sample - loss: 0.4157 - accuracy: 0.8630
Restored model, accuracy: 86.30%

このテクニックは総てをセーブします :

  • 重み値。
  • モデルの構成 (= configuration) (アーキテクチャ)
  • optimizer 構成

Keras はアーキテクチャを調べてモデルをセーブします。現在、TensorFlow optimizer (from tf.train) をセーブすることはできません。それらを使用するときはモデルをロードした後で再コンパイルする必要があり、そして optimizer の状態を失うでしょう。

 

saved_model として

Caution: tf.keras モデルをセーブするこのメソッドは実験的で将来的なバージョンでは変更されるかもしれません。

新しいモデルを構築します :

model = create_model()

model.fit(train_images, train_labels, epochs=5)
Train on 1000 samples
Epoch 1/5
1000/1000 [==============================] - 0s 252us/sample - loss: 1.1906 - accuracy: 0.6560
Epoch 2/5
1000/1000 [==============================] - 0s 98us/sample - loss: 0.4405 - accuracy: 0.8700
Epoch 3/5
1000/1000 [==============================] - 0s 98us/sample - loss: 0.3088 - accuracy: 0.9220
Epoch 4/5
1000/1000 [==============================] - 0s 96us/sample - loss: 0.2122 - accuracy: 0.9480
Epoch 5/5
1000/1000 [==============================] - 0s 91us/sample - loss: 0.1579 - accuracy: 0.9650

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

saved_model を作成して、それをタイムスタンプされたディレクトリに置きます :

import time
saved_model_path = "./saved_models/{}".format(int(time.time()))

tf.keras.experimental.export_saved_model(model, saved_model_path)
saved_model_path
W0614 17:45:15.955815 139650494461696 deprecation.py:323] From /tmpfs/src/tf_docs_env/lib/python3.5/site-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.
W0614 17:45:15.957547 139650494461696 export_utils.py:182] Export includes no default signature!
W0614 17:45:16.200236 139650494461696 export_utils.py:182] Export includes no default signature!

'./saved_models/1560534315'

貴方の saved model をリスティングします :

!ls saved_models/
1560534315

saved model から新鮮な (= fresh) keras モデルを再ロードします。

new_model = tf.keras.experimental.load_from_saved_model(saved_model_path)
new_model.summary()
Model: "sequential_7"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_14 (Dense)             (None, 512)               401920    
_________________________________________________________________
dropout_7 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_15 (Dense)             (None, 10)                5130      
=================================================================
Total params: 407,050
Trainable params: 407,050
Non-trainable params: 0
_________________________________________________________________

復元されたモデルを実行します。

model.predict(test_images).shape
(1000, 10)
# The model has to be compiled before evaluating.
# This step is not required if the saved model is only being deployed.

new_model.compile(optimizer=model.optimizer,  # keep the optimizer that was loaded
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

# Evaluate the restored model.
loss, acc = new_model.evaluate(test_images, test_labels)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))
1000/1000 [==============================] - 0s 99us/sample - loss: 0.4428 - accuracy: 0.8500
Restored model, accuracy: 85.00%

 

What’s Next

tf.keras によるセーブとロードへの簡単なガイドでした。

  • tf.keras ガイド は tf.keras によるモデルのセーブとロードについて更に示します。
  • eager execution の間のセーブについては Saving in eager を見てください。
  • Save and Restore ガイドは TensorFlow セービングについての下位詳細を持ちます。
 

以上



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