모델 저장과 복원

TensorFlow.org에서 보기 구글 코랩(Colab)에서 실행하기 깃허브(GitHub) 소스 보기

훈련하는 도중이나 훈련이 끝난 후에 모델을 저장할 수 있습니다. 모델을 중지된 지점부터 다시 훈련할 수 있어 한 번에 오랫동안 훈련하지 않아도 됩니다. 또 모델을 저장하면 다른 사람에게 공유할 수 있고 작업을 재현할 수 있습니다. 연구한 모델과 기법을 공개할 때 많은 머신 러닝 기술자들이 다음과 같은 것들을 제공합니다:

  • 모델을 만드는 코드
  • 모델의 훈련된 가중치 또는 파라미터

이런 데이터를 공유하면 다른 사람들이 모델의 작동 방식을 이해하고 새로운 데이터로 모델을 실험하는데 도움이 됩니다.

주의: 신뢰할 수 없는 코드는 조심하세요. 텐서플로 모델은 프로그램 코드입니다. 자세한 내용은 텐서플로를 안전하게 사용하기 문서를 참고하세요.

저장 방식

사용하는 API에 따라서 여러가지 방법으로 텐서플로 모델을 저장할 수 있습니다. 이 문서는 텐서플로 모델을 만들고 훈련하기 위한 고수준 API인 tf.keras를 사용합니다. 다른 방법들에 대해서는 텐서플로의 저장과 복원 문서와 즉시 실행(eager execution) 문서의 저장하기 섹션을 참고하세요.

설정

설치와 임포트

필요한 라이브러리를 설치하고 텐서플로를 임포트(import)합니다:

!pip install -q h5py pyyaml

예제 데이터셋 받기

MNIST 데이터셋으로 모델을 훈련하여 가중치를 저장하는 예제를 만들어 보겠습니다. 모델 실행 속도를 빠르게 하기 위해 샘플에서 처음 1,000개만 사용겠습니다:

from __future__ import absolute_import, division, print_function, unicode_literals, unicode_literals

import os

import tensorflow as tf
from tensorflow import keras

tf.__version__
'1.12.0'
(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
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11493376/11490434 [==============================] - 0s 0us/step

모델 정의

가중치를 저장하고 불러오는 예제를 위해 간단한 모델을 만들어 보죠.

# 간단한 Sequential 모델을 반환합니다
def create_model():
  model = tf.keras.models.Sequential([
    keras.layers.Dense(512, activation=tf.keras.activations.relu, input_shape=(784,)),
    keras.layers.Dropout(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()
_________________________________________________________________
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)를 자동으로 저장하도록 하는 것이 많이 사용하는 방법입니다. 다시 훈련하지 않고 모델을 재사용하거나 훈련 과정이 중지된 경우 이어서 훈련을 진행할 수 있습니다.

tf.keras.callbacks.ModelCheckpoint은 이런 작업을 수행하는 콜백(callback)입니다. 이 콜백은 체크포인트 작업을 조정할 수 있도록 여러가지 매개변수를 제공합니다.

체크포인트 콜백 사용하기

ModelCheckpoint 콜백을 전달하여 모델을 훈련해 보죠:

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])  # 훈련 단계에 콜백을 전달합니다

# 옵티마이저의 상태를 저장하는 것과 관련되어 경고가 발생할 수 있습니다.
# 이 경고는 (그리고 이 노트북의 다른 비슷한 경고는) 이전 사용 방식을 권장하지 않기 위함이며 무시해도 좋습니다.
Train on 1000 samples, validate on 1000 samples
Epoch 1/10
 960/1000 [===========================>..] - ETA: 0s - loss: 1.2234 - acc: 0.6458
Epoch 00001: saving model to training_1/cp.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb6ed34d0b8>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.
1000/1000 [==============================] - 1s 667us/step - loss: 1.1989 - acc: 0.6530 - val_loss: 0.7384 - val_acc: 0.7920
Epoch 2/10
 928/1000 [==========================>...] - ETA: 0s - loss: 0.4298 - acc: 0.8869
Epoch 00002: saving model to training_1/cp.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb6ed34d0b8>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.
1000/1000 [==============================] - 0s 257us/step - loss: 0.4358 - acc: 0.8850 - val_loss: 0.5345 - val_acc: 0.8350
Epoch 3/10
 896/1000 [=========================>....] - ETA: 0s - loss: 0.2922 - acc: 0.9263
Epoch 00003: saving model to training_1/cp.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb6ed34d0b8>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.
1000/1000 [==============================] - 0s 265us/step - loss: 0.2914 - acc: 0.9270 - val_loss: 0.4568 - val_acc: 0.8570
Epoch 4/10
 864/1000 [========================>.....] - ETA: 0s - loss: 0.2003 - acc: 0.9525
Epoch 00004: saving model to training_1/cp.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb6ed34d0b8>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.
1000/1000 [==============================] - 0s 269us/step - loss: 0.2042 - acc: 0.9510 - val_loss: 0.4542 - val_acc: 0.8560
Epoch 5/10
 896/1000 [=========================>....] - ETA: 0s - loss: 0.1574 - acc: 0.9676
Epoch 00005: saving model to training_1/cp.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb6ed34d0b8>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.
1000/1000 [==============================] - 0s 272us/step - loss: 0.1552 - acc: 0.9680 - val_loss: 0.4319 - val_acc: 0.8660
Epoch 6/10
 896/1000 [=========================>....] - ETA: 0s - loss: 0.1118 - acc: 0.9788
Epoch 00006: saving model to training_1/cp.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb6ed34d0b8>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.
1000/1000 [==============================] - 0s 266us/step - loss: 0.1125 - acc: 0.9790 - val_loss: 0.4242 - val_acc: 0.8660
Epoch 7/10
 896/1000 [=========================>....] - ETA: 0s - loss: 0.0897 - acc: 0.9877
Epoch 00007: saving model to training_1/cp.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb6ed34d0b8>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.
1000/1000 [==============================] - 0s 267us/step - loss: 0.0870 - acc: 0.9890 - val_loss: 0.4227 - val_acc: 0.8630
Epoch 8/10
 864/1000 [========================>.....] - ETA: 0s - loss: 0.0692 - acc: 0.9896
Epoch 00008: saving model to training_1/cp.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb6ed34d0b8>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.
1000/1000 [==============================] - 0s 269us/step - loss: 0.0647 - acc: 0.9910 - val_loss: 0.4466 - val_acc: 0.8630
Epoch 9/10
 896/1000 [=========================>....] - ETA: 0s - loss: 0.0556 - acc: 0.9944
Epoch 00009: saving model to training_1/cp.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb6ed34d0b8>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.
1000/1000 [==============================] - 0s 268us/step - loss: 0.0558 - acc: 0.9950 - val_loss: 0.4093 - val_acc: 0.8640
Epoch 10/10
 896/1000 [=========================>....] - ETA: 0s - loss: 0.0372 - acc: 0.9978
Epoch 00010: saving model to training_1/cp.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb6ed34d0b8>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.
1000/1000 [==============================] - 0s 269us/step - loss: 0.0380 - acc: 0.9980 - val_loss: 0.4121 - val_acc: 0.8680

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

이 코드는 텐서플로 체크포인트 파일을 만들고 에포크가 종료될 때마다 업데이트합니다:

!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("훈련되지 않은 모델의 정확도: {:5.2f}%".format(100*acc))
1000/1000 [==============================] - 0s 200us/step
훈련되지 않은 모델의 정확도: 10.30%

체크포인트에서 가중치를 로드하고 다시 평가해 보죠:

model.load_weights(checkpoint_path)
loss,acc = model.evaluate(test_images, test_labels)
print("복원된 모델의 정확도: {:5.2f}%".format(100*acc))
1000/1000 [==============================] - 0s 60us/step
복원된 모델의 정확도: 86.80%

체크포인트 콜백 매개변수

이 콜백 함수는 몇 가지 매개변수를 제공합니다. 체크포인트 이름을 고유하게 만들거나 체크포인트 주기를 조정할 수 있습니다.

새로운 모델을 훈련하고 다섯 번의 에포크마다 고유한 이름으로 체크포인트를 저장해 보겠습니다:

# 파일 이름에 에포크 번호를 포함시킵니다(`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,
    # 다섯 번째 에포크마다 가중치를 저장합니다
    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)
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb7fbcc4c50>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.

Epoch 00005: saving model to training_2/cp-0005.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb7fbcc4c50>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.

Epoch 00010: saving model to training_2/cp-0010.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb7fbcc4c50>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.

Epoch 00015: saving model to training_2/cp-0015.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb7fbcc4c50>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.

Epoch 00020: saving model to training_2/cp-0020.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb7fbcc4c50>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.

Epoch 00025: saving model to training_2/cp-0025.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb7fbcc4c50>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.

Epoch 00030: saving model to training_2/cp-0030.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb7fbcc4c50>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.

Epoch 00035: saving model to training_2/cp-0035.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb7fbcc4c50>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.

Epoch 00040: saving model to training_2/cp-0040.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb7fbcc4c50>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.

Epoch 00045: saving model to training_2/cp-0045.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb7fbcc4c50>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.

Epoch 00050: saving model to training_2/cp-0050.ckpt
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb7fbcc4c50>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.

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

만들어진 체크포인트를 확인해 보고 마지막 체크포인트를 선택해 보겠습니다:

! 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'

노트: 텐서플로는 기본적으로 최근 5개의 체크포인트만 저장합니다.

모델을 초기화하고 최근 체크포인트를 로드하여 테스트해 보겠습니다:

model = create_model()
model.load_weights(latest)
loss, acc = model.evaluate(test_images, test_labels)
print("복원된 모델의 정확도: {:5.2f}%".format(100*acc))
1000/1000 [==============================] - 0s 160us/step
복원된 모델의 정확도: 87.60%

체크포인트 파일

위 코드는 가중치를 일련의 체크포인트 포맷의 파일에 저장합니다. 이 파일에 포함되는 것은 훈련된 이진 포맷의 가중치입니다. 체크포인트가 담고 있는 것은 다음과 같습니다:

  • 모델의 가중치를 포함하는 하나 이상의 샤드(shard)
  • 가중치가 어느 샤드에 저장되어 있는지를 나타내는 인덱스 파일

단일 머신에서 모델을 훈련한다면 .data-00000-of-00001 확장자를 가진 샤드 하나만 만들어 집니다.

수동으로 가중치 저장하기

앞에서 가중치를 모델에 로드하는 방법을 보았습니다.

수동으로 가중치를 저장하는 것도 쉽습니다. Model.save_weights 메서드를 사용합니다.

# 가중치를 저장합니다
model.save_weights('./checkpoints/my_checkpoint')

# 가중치를 복원합니다
model = create_model()
model.load_weights('./checkpoints/my_checkpoint')

loss,acc = model.evaluate(test_images, test_labels)
print("복원된 모델의 정확도: {:5.2f}%".format(100*acc))
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb7faeef908>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.
1000/1000 [==============================] - 0s 138us/step
복원된 모델의 정확도: 87.60%

모델 전체를 저장하기

전체 모델을 파일 하나에 저장할 수 있습니다. 여기에는 가중치, 모델 구성 심지어 옵티마이저에 지정한 설정까지 포함됩니다. 모델의 체크포인트를 저장하므로 원본 코드를 사용하지 않고 나중에 정확히 동일한 상태에서 훈련을 다시 시작할 수 있습니다.

전체 모델을 저장하는 기능은 매우 유용합니다. TensorFlow.js로 모델을 로드한 다음 웹 브라우저에서 모델을 훈련하고 실행할 수 있습니다(HDF5, Saved Model). 또는 모바일 장치에 맞도록 변환한 다음 TensorFlow Lite를 사용하여 실행할 수 있습니다(HDF5, Saved Model).

HDF5 파일로 저장하기

케라스는 HDF5 표준을 따르는 기본 저장 포맷을 제공합니다. 저장된 모델을 하나의 이진 파일(binary blob)처럼 다룰 수 있습니다.

model = create_model()

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

# 전체 모델을 HDF5 파일로 저장합니다
model.save('my_model.h5')
Epoch 1/5
1000/1000 [==============================] - 1s 503us/step - loss: 1.2223 - acc: 0.6260
Epoch 2/5
1000/1000 [==============================] - 0s 180us/step - loss: 0.4388 - acc: 0.8730
Epoch 3/5
1000/1000 [==============================] - 0s 184us/step - loss: 0.3011 - acc: 0.9100
Epoch 4/5
1000/1000 [==============================] - 0s 196us/step - loss: 0.2148 - acc: 0.9490
Epoch 5/5
1000/1000 [==============================] - 0s 230us/step - loss: 0.1616 - acc: 0.9580

이제 이 파일로부터 모델을 다시 만들어 보죠:

# 가중치와 옵티마이저를 포함하여 정확히 동일한 모델을 다시 생성합니다
new_model = keras.models.load_model('my_model.h5')
new_model.summary()
_________________________________________________________________
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("복원된 모델의 정확도: {:5.2f}%".format(100*acc))
1000/1000 [==============================] - 0s 169us/step
복원된 모델의 정확도: 86.70%

이 기법은 모든 것을 저장합니다:

  • 가중치 값
  • 모델 설정(구조)
  • 옵티마이저 설정

케라스는 모델 구조를 확인하고 저장합니다. 현재는 텐서플로 옵티마이저(tf.train)를 저장할 수 없습니다. 이런 경우에는 모델을 로드한 후에 다시 컴파일해야 합니다. 옵티마이저의 상태는 유지되지 않습니다.

saved_model을 사용하기

주의: tf.keras 모델을 저장하는 이 메서드는 실험적이므로 향후 버전에서 변경될 수 있습니다.

새로운 모델을 만들어 보겠습니다:

model = create_model()

model.fit(train_images, train_labels, epochs=5)
Epoch 1/5
1000/1000 [==============================] - 1s 581us/step - loss: 1.1622 - acc: 0.6750
Epoch 2/5
1000/1000 [==============================] - 0s 189us/step - loss: 0.4244 - acc: 0.8790
Epoch 3/5
1000/1000 [==============================] - 0s 187us/step - loss: 0.2906 - acc: 0.9200
Epoch 4/5
1000/1000 [==============================] - 0s 192us/step - loss: 0.2237 - acc: 0.9420
Epoch 5/5
1000/1000 [==============================] - 0s 202us/step - loss: 0.1540 - acc: 0.9620

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

saved_model을 만듭니다:

saved_model_path = tf.contrib.saved_model.save_keras_model(model, "./saved_models")
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.Adam object at 0x7fb7fb3b1ba8>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved.

Consider using a TensorFlow optimizer from `tf.train`.
WARNING:tensorflow:Model was compiled with an optimizer, but the optimizer is not from `tf.train` (e.g. `tf.train.AdagradOptimizer`). Only the serving graph was exported. The train and evaluate graphs were not added to the SavedModel.
INFO:tensorflow:Signatures INCLUDED in export for Eval: None
INFO:tensorflow:Signatures INCLUDED in export for Predict: ['serving_default']
INFO:tensorflow:Signatures INCLUDED in export for Classify: None
INFO:tensorflow:Signatures INCLUDED in export for Train: None
INFO:tensorflow:Signatures INCLUDED in export for Regress: None
INFO:tensorflow:No assets to save.
INFO:tensorflow:No assets to write.
INFO:tensorflow:SavedModel written to: ./saved_models/temp-b'1556906846'/saved_model.pb

타임스탬프를 이름으로 가진 디렉토리에 모델이 저장되어 있습니다:

!ls saved_models/
1556906846

저장된 모델로부터 새로운 케라스 모델을 로드합니다.

new_model = tf.contrib.saved_model.load_keras_model(saved_model_path)
new_model.summary()
_________________________________________________________________
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
_________________________________________________________________

복원된 모델을 실행합니다.

# 이 모델을 평가하려면 그전에 컴파일해야 합니다.
# 단지 저장된 모델의 배포라면 이 단계가 필요하지 않습니다.

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

# 복원된 모델을 평가합니다
loss, acc = new_model.evaluate(test_images, test_labels)
print("복원된 모델의 정확도: {:5.2f}%".format(100*acc))
1000/1000 [==============================] - 0s 372us/step
복원된 모델의 정확도: 86.50%

그 다음엔

이 문서에서는 tf.keras를 사용하여 모델을 저장하고 로드하는 방법을 간단하게 안내했습니다.

#@title MIT License
#
# Copyright (c) 2017 François Chollet
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.