本シリーズでは,ディープラーニングを実装する際に強力な手助けをしてくれる「TensorFlow」についてです。公式チュートリアルを,初心者に向けてかみ砕きながら翻訳していこうと思います。(公式ページはこちらより)
今回はNo.6で,「モデルの保存と復元」編です。その他の記事は,こちらの「TensorFlowの公式チュートリアルを初心者向けに読み解く」をご覧ください。
基本的な流れ
TensolFlowでディープラーニングを実装する流れは,以下のようになります。
●データセットの読み込み
●ネットワークの定義
●最適化アルゴリズムの定義
●学習の実行
●評価の実行
●予測の実行
必要なモジュール等の準備
import os
import tensorflow as tf
from tensorflow import keras
tensorflowとkerasをインポートしましょう。今回は,ファイルを作成するためosもインポートします。
データセットの読み込み
(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
今回は,データセットとしてmnistを利用します。ただし,データセットの内容には興味はなく,どのようにしてモデルを保存して読み込むのかという点に注目しながら話を進めていきましょう。reshapeに-1という引数を指定することで,28*28以外の大きさのしわ寄せを-1に含めることができます。
ネットワークの定義
def create_model():
model = tf.keras.models.Sequential([
keras.layers.Dense(512, activation=tf.nn.relu, input_shape=(784,)),
keras.layers.Dropout(rate=0.2),
keras.layers.Dense(10, activation=tf.keras.activations.softmax)
])
model.compile(optimizer=tf.keras.optimizers.Adam(),
loss=tf.keras.losses.sparse_categorical_crossentropy,
metrics=['accuracy'])
return model
今まで通りの流れです。前回お伝えしたドロップアウトを適用しています。実際にできたモデルを見てみましょう。
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
_________________________________________________________________
最適化アルゴリズムの定義
ネットワークの定義の中で定めてしまいました。
学習の実行
checkpoint_path = "training_1/cp.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)
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])
チェックポイントを格納するディレクトリのパスを指定して作成します。モデル訓練時にcallbacks引数にModelCheckPointのインスタンスを渡すことで,チェックポイントを記憶させておくことが可能になります。
実際に確認してみましょう。
!ls {checkpoint_dir}
checkpoint cp.ckpt.data-00001-of-00002
cp.ckpt.data-00000-of-00002 cp.ckpt.index
評価の実行
model = create_model()
loss, acc = model.evaluate(test_images, test_labels)
print("Untrained model, accuracy: {:5.2f}%".format(100*acc))
Untrained model, accuracy: 5.30%
訓練していないネットワークを利用して評価を行ってみましょう。もちろん,精度は非常に悪く,5.3%でした。続いて,保存した重みを利用して評価を行ってみましょう。
model.load_weights(checkpoint_path)
loss,acc = model.evaluate(test_images, test_labels)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))
Restored model, accuracy: 87.10%
先ほどとは異なり,精度は87%出ました。また,重みの保存の際には名前を決めたり保存するエポック数を決めたりできます。
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,
period=5)
model = create_model()
model.fit(train_images, train_labels,
epochs = 50, callbacks = [cp_callback],
validation_data = (test_images,test_labels),
verbose=0)
確認してみます。
! ls {checkpoint_dir}
checkpoint cp-0030.ckpt.data-00000-of-00002
cp-0005.ckpt.data-00000-of-00002 cp-0030.ckpt.data-00001-of-00002
cp-0005.ckpt.data-00001-of-00002 cp-0030.ckpt.index
cp-0005.ckpt.index cp-0035.ckpt.data-00000-of-00002
cp-0010.ckpt.data-00000-of-00002 cp-0035.ckpt.data-00001-of-00002
cp-0010.ckpt.data-00001-of-00002 cp-0035.ckpt.index
cp-0010.ckpt.index cp-0040.ckpt.data-00000-of-00002
cp-0015.ckpt.data-00000-of-00002 cp-0040.ckpt.data-00001-of-00002
cp-0015.ckpt.data-00001-of-00002 cp-0040.ckpt.index
cp-0015.ckpt.index cp-0045.ckpt.data-00000-of-00002
cp-0020.ckpt.data-00000-of-00002 cp-0045.ckpt.data-00001-of-00002
cp-0020.ckpt.data-00001-of-00002 cp-0045.ckpt.index
cp-0020.ckpt.index cp-0050.ckpt.data-00000-of-00002
cp-0025.ckpt.data-00000-of-00002 cp-0050.ckpt.data-00001-of-00002
cp-0025.ckpt.data-00001-of-00002 cp-0050.ckpt.index
cp-0025.ckpt.index
最後のチェックポイントを使ってネットワークを構成してみましょう。
latest = tf.train.latest_checkpoint(checkpoint_dir)
latest
'training_2/cp-0050.ckpt'
実際にモデルを構成します。
model = create_model()
model.load_weights(latest)
loss, acc = model.evaluate(test_images, test_labels)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))
Restored model, accuracy: 87.30%
重みは,手動でも保存することができます。
model.save_weights('./checkpoints/my_checkpoint')
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))
Restored model, accuracy: 87.30%
モデル全体も保存することができます。HDF5ファイルという形式を利用します。
model = create_model()
model.fit(train_images, train_labels, epochs=5)
model.save('my_model.h5')
このモデルは,以下のようにして読み込むことができます。
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))
Restored model, accuracy: 86.80%
予測の実行
今回は行っていません。