In [ ]:
#@title Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
In [ ]:
#@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.
Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도 불구하고 공식 영문 문서의 내용과 일치하지 않을 수 있습니다. 이 번역에 개선할 부분이 있다면 tensorflow/docs 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다. 문서 번역이나 리뷰에 참여하려면 docs-ko@tensorflow.org로 메일을 보내주시기 바랍니다.
훈련하는 도중이나 훈련이 끝난 후에 모델을 저장할 수 있습니다. 모델을 중지된 지점부터 다시 훈련할 수 있어 한 번에 오랫동안 훈련하지 않아도 됩니다. 또 모델을 저장하면 다른 사람에게 공유할 수 있고 작업을 재현할 수 있습니다. 연구한 모델과 기법을 공개할 때 많은 머신 러닝 기술자들이 다음과 같은 것들을 제공합니다:
이런 데이터를 공유하면 다른 사람들이 모델의 작동 방식을 이해하고 새로운 데이터로 모델을 실험하는데 도움이 됩니다.
주의: 신뢰할 수 없는 코드는 조심하세요. 텐서플로 모델은 프로그램 코드입니다. 자세한 내용은 텐서플로를 안전하게 사용하기 문서를 참고하세요.
사용하는 API에 따라서 여러가지 방법으로 텐서플로 모델을 저장할 수 있습니다. 이 문서는 텐서플로 모델을 만들고 훈련하기 위한 고수준 API인 tf.keras를 사용합니다. 다른 방법들에 대해서는 텐서플로의 저장과 복원 문서와 즉시 실행(eager execution) 문서의 저장하기 섹션을 참고하세요.
필요한 라이브러리를 설치하고 텐서플로를 임포트(import)합니다:
In [ ]:
!pip install h5py pyyaml
MNIST 데이터셋으로 모델을 훈련하여 가중치를 저장하는 예제를 만들어 보겠습니다. 모델 실행 속도를 빠르게 하기 위해 샘플에서 처음 1,000개만 사용겠습니다:
In [ ]:
import os
import tensorflow.compat.v1 as tf
from tensorflow import keras
tf.__version__
In [ ]:
(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
가중치를 저장하고 불러오는 예제를 위해 간단한 모델을 만들어 보죠.
In [ ]:
# 간단한 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()
In [ ]:
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]) # 훈련 단계에 콜백을 전달합니다
# 옵티마이저의 상태를 저장하는 것과 관련되어 경고가 발생할 수 있습니다.
# 이 경고는 (그리고 이 노트북의 다른 비슷한 경고는) 이전 사용 방식을 권장하지 않기 위함이며 무시해도 좋습니다.
이 코드는 텐서플로 체크포인트 파일을 만들고 에포크가 종료될 때마다 업데이트합니다:
In [ ]:
!ls {checkpoint_dir}
훈련하지 않은 새로운 모델을 만들어 보겠습니다. 가중치만 복원할 땐 원본 모델과 동일한 구조로 모델을 만들어야 합니다. 여기서는 동일한 구조로 모델을 만들었으므로 다른 객체이지만 가중치를 공유할 수 있습니다.
훈련하지 않은 새 모델을 만들고 테스트 세트에서 평가해 보죠. 훈련되지 않은 모델의 성능은 무작위로 선택하는 정도의 수준입니다(~10% 정확도):
In [ ]:
model = create_model()
loss, acc = model.evaluate(test_images, test_labels, verbose=2)
print("훈련되지 않은 모델의 정확도: {:5.2f}%".format(100*acc))
체크포인트에서 가중치를 로드하고 다시 평가해 보죠:
In [ ]:
model.load_weights(checkpoint_path)
loss,acc = model.evaluate(test_images, test_labels, verbose=2)
print("복원된 모델의 정확도: {:5.2f}%".format(100*acc))
In [ ]:
# 파일 이름에 에포크 번호를 포함시킵니다(`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)
만들어진 체크포인트를 확인해 보고 마지막 체크포인트를 선택해 보겠습니다:
In [ ]:
! ls {checkpoint_dir}
In [ ]:
latest = tf.train.latest_checkpoint(checkpoint_dir)
latest
노트: 텐서플로는 기본적으로 최근 5개의 체크포인트만 저장합니다.
모델을 초기화하고 최근 체크포인트를 로드하여 테스트해 보겠습니다:
In [ ]:
model = create_model()
model.load_weights(latest)
loss, acc = model.evaluate(test_images, test_labels, verbose=2)
print("복원된 모델의 정확도: {:5.2f}%".format(100*acc))
위 코드는 가중치를 일련의 체크포인트 포맷의 파일에 저장합니다. 이 파일에 포함되는 것은 훈련된 이진 포맷의 가중치입니다. 체크포인트가 담고 있는 것은 다음과 같습니다:
단일 머신에서 모델을 훈련한다면 .data-00000-of-00001
확장자를 가진 샤드 하나만 만들어 집니다.
In [ ]:
# 가중치를 저장합니다
model.save_weights('./checkpoints/my_checkpoint')
# 가중치를 복원합니다
model = create_model()
model.load_weights('./checkpoints/my_checkpoint')
loss,acc = model.evaluate(test_images, test_labels, verbose=2)
print("복원된 모델의 정확도: {:5.2f}%".format(100*acc))
전체 모델을 파일 하나에 저장할 수 있습니다. 여기에는 가중치, 모델 구성 심지어 옵티마이저에 지정한 설정까지 포함됩니다. 모델의 체크포인트를 저장하므로 원본 코드를 사용하지 않고 나중에 정확히 동일한 상태에서 훈련을 다시 시작할 수 있습니다.
전체 모델을 저장하는 기능은 매우 유용합니다. TensorFlow.js로 모델을 로드한 다음 웹 브라우저에서 모델을 훈련하고 실행할 수 있습니다(HDF5, Saved Model). 또는 모바일 장치에 맞도록 변환한 다음 TensorFlow Lite를 사용하여 실행할 수 있습니다(HDF5, Saved Model).
케라스는 HDF5 표준을 따르는 기본 저장 포맷을 제공합니다. 저장된 모델을 하나의 이진 파일(binary blob)처럼 다룰 수 있습니다.
In [ ]:
model = create_model()
model.fit(train_images, train_labels, epochs=5)
# 전체 모델을 HDF5 파일로 저장합니다
model.save('my_model.h5')
이제 이 파일로부터 모델을 다시 만들어 보죠:
In [ ]:
# 가중치와 옵티마이저를 포함하여 정확히 동일한 모델을 다시 생성합니다
new_model = keras.models.load_model('my_model.h5')
new_model.summary()
정확도를 확인해 보겠습니다:
In [ ]:
loss, acc = new_model.evaluate(test_images, test_labels, verbose=2)
print("복원된 모델의 정확도: {:5.2f}%".format(100*acc))
이 기법은 모든 것을 저장합니다:
케라스는 모델 구조를 확인하고 저장합니다. 현재는 텐서플로 옵티마이저(tf.train
)를 저장할 수 없습니다. 이런 경우에는 모델을 로드한 후에 다시 컴파일해야 합니다. 옵티마이저의 상태는 유지되지 않습니다.
주의: tf.keras
모델을 저장하는 이 메서드는 실험적이므로 향후 버전에서 변경될 수 있습니다.
새로운 모델을 만들어 보겠습니다:
In [ ]:
model = create_model()
model.fit(train_images, train_labels, epochs=5)
saved_model
을 만듭니다:
In [ ]:
saved_model_path = tf.contrib.saved_model.save_keras_model(model, "./saved_models")
타임스탬프를 이름으로 가진 디렉토리에 모델이 저장되어 있습니다:
In [ ]:
!ls saved_models/
저장된 모델로부터 새로운 케라스 모델을 로드합니다.
In [ ]:
new_model = tf.contrib.saved_model.load_keras_model(saved_model_path)
new_model.summary()
복원된 모델을 실행합니다.
In [ ]:
# 이 모델을 평가하려면 그전에 컴파일해야 합니다.
# 단지 저장된 모델의 배포라면 이 단계가 필요하지 않습니다.
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, verbose=2)
print("복원된 모델의 정확도: {:5.2f}%".format(100*acc))
이 문서에서는 tf.keras
를 사용하여 모델을 저장하고 로드하는 방법을 간단하게 안내했습니다.
tf.keras 가이드에서 tf.keras
로 모델을 저장하고 로드하는 정보를 더 볼 수 있습니다.
즉시 실행 모드에서 모델을 저장하려면 즉시 실행에서 저장하기 문서를 참고하세요.
저장과 복원 문서는 저수준의 텐서플로 저장 기능에 대해 설명합니다.