알고리즘

TensorFlow 2.0 파라미터 저장 & 불러오기

WDmil 2024. 6. 21. 02:34
728x90

파라미터 저장

  • tf.train.Chackpoint 클래스의 인자값으로 저장하고자 하는 tf.kears.Model 인스턴스와 전역 반복횟수를 지정해서 선언한다.
ckpt = tf.train.Checkpoint(step=.tf.Variable(0), model=CNN_model)

 

  • tf.train.ChackpointManager에 인자값으로 선언한 tf.train.Chackpoint 인스턴스와 중간 파라미터를 저장할 경로를 설정한다.
ckpt_manager=tf.train.CheckpointManager(ckpt, directory=SAVER_DIR, max_to_keep=5)

 

  • 파라미터를 저장하고자 하는 시점에 해당 시점의 전역 반복횟수를 인자값으로 선언한
    tf.train.ChackpointManager의 save 메소드를 호출한다.
ckpt_manager.save(chackpoint_number=ckpt.step)

 

  • tf.train.Chackpoint의 전역 반복 횟수 값(ckpt.step)을 매 반복마다 1씩 증가시킨다.
ckpt.step.assign_add(1)

파라미터 불러오기

  • tf.train.latest_checkpoint의 인자값으로 파라미터가 저장된 폴더 경로를 지정해서 가장 최근의 체크 포인트 파일의 경로(full path)를 가져온다.
lates_ckpt=tf.train.latest_checkpoint(SAVER_DIR)

 

  • 선언한 tf.train_CheckpointManager의 restore함수의 인자값으로 불러올 체크포인트 파일의 경로를 지정해서 파라미터 값을 복원한다.
ckpt.restore(latest_ckpt)

코드예시

import tensorflow as tf

# MNIST 데이터를 다운로드 합니다.
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
# 이미지들을 float32 데이터 타입으로 변경합니다.
x_train, x_test = x_train.astype('float32'), x_test.astype('float32')
# 28*28 형태의 이미지를 784차원으로 flattening 합니다.
x_train, x_test = x_train.reshape([-1, 784]), x_test.reshape([-1, 784])
# [0, 255] 사이의 값을 [0, 1]사이의 값으로 Normalize합니다.
x_train, x_test = x_train / 255., x_test / 255.
# 레이블 데이터에 one-hot encoding을 적용합니다.
y_train, y_test = tf.one_hot(y_train, depth=10), tf.one_hot(y_test, depth=10)

# tf.data API를 이용해서 데이터를 섞고 batch 형태로 가져옵니다.
train_data = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_data = train_data.repeat().shuffle(60000).batch(50)
train_data_iter = iter(train_data)

# tf.keras.Model을 이용해서 CNN 모델을 정의합니다.
class CNN(tf.keras.Model):
  def __init__(self):
    super(CNN, self).__init__()
    # 첫번째 Convolution Layer
    # 5x5 Kernel Size를 가진 32개의 Filter를 적용합니다.
    self.conv_layer_1 = tf.keras.layers.Conv2D(filters=32, kernel_size=5, strides=1, padding='same', activation='relu')
    self.pool_layer_1 = tf.keras.layers.MaxPool2D(pool_size=(2, 2), strides=2)

    # 두번째 Convolutional Layer
    # 5x5 Kernel Size를 가진 64개의 Filter를 적용합니다.
    self.conv_layer_2 = tf.keras.layers.Conv2D(filters=64, kernel_size=5, strides=1, padding='same', activation='relu')
    self.pool_layer_2 = tf.keras.layers.MaxPool2D(pool_size=(2, 2), strides=2)

    # Fully Connected Layer
    # 7x7 크기를 가진 64개의 activation map을 1024개의 특징들로 변환합니다.
    self.flatten_layer = tf.keras.layers.Flatten()
    self.fc_layer_1 = tf.keras.layers.Dense(1024, activation='relu')

    # Output Layer
    # 1024개의 특징들(feature)을 10개의 클래스-one-hot encoding으로 표현된 숫자 0~9-로 변환합니다.
    self.output_layer = tf.keras.layers.Dense(10, activation=None)

  def call(self, x):
    # MNIST 데이터를 3차원 형태로 reshape합니다. MNIST 데이터는 grayscale 이미지기 때문에 3번째차원(컬러채널)의 값은 1입니다.
    x_image = tf.reshape(x, [-1, 28, 28, 1])
    # 28x28x1 -> 28x28x32
    h_conv1 = self.conv_layer_1(x_image)
    # 28x28x32 -> 14x14x32
    h_pool1 = self.pool_layer_1(h_conv1)
    # 14x14x32 -> 14x14x64
    h_conv2 = self.conv_layer_2(h_pool1)
    # 14x14x64 -> 7x7x64
    h_pool2 = self.pool_layer_2(h_conv2)
    # 7x7x64(3136) -> 1024
    h_pool2_flat = self.flatten_layer(h_pool2)
    h_fc1 = self.fc_layer_1(h_pool2_flat)
    # 1024 -> 10
    logits = self.output_layer(h_fc1)
    y_pred = tf.nn.softmax(logits)

    return y_pred, logits

# cross-entropy 손실 함수를 정의합니다.
@tf.function
def cross_entropy_loss(logits, y):
  return tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y))

# 최적화를 위한 Adam 옵티마이저를 정의합니다.
optimizer = tf.optimizers.Adam(1e-4)

# 최적화를 위한 function을 정의합니다.
@tf.function
def train_step(model, x, y):
  with tf.GradientTape() as tape:
    y_pred, logits = model(x)
    loss = cross_entropy_loss(logits, y)
  gradients = tape.gradient(loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))

# 모델의 정확도를 출력하는 함수를 정의합니다.
@tf.function
def compute_accuracy(y_pred, y):
  correct_prediction = tf.equal(tf.argmax(y_pred,1), tf.argmax(y,1))
  accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

  return accuracy

# Convolutional Neural Networks(CNN) 모델을 선언합니다.
CNN_model = CNN()

# tf.train.CheckpointManager를 이용해서 파라미터를 저장합니다.
SAVER_DIR = "./model"
ckpt = tf.train.Checkpoint(step=tf.Variable(0), model=CNN_model)
ckpt_manager = tf.train.CheckpointManager(
      ckpt, directory=SAVER_DIR, max_to_keep=5)
latest_ckpt = tf.train.latest_checkpoint(SAVER_DIR) # 불러오기 가장최근 알고리즘 학습값

# 만약 저장된 모델과 파라미터가 있으면 이를 불러오고 (Restore)
# Restored 모델을 이용해서 테스트 데이터에 대한 정확도를 출력하고 프로그램을 종료합니다.
if latest_ckpt:
  ckpt.restore(latest_ckpt)
  print("테스트 데이터 정확도 (Restored) : %f" % compute_accuracy(CNN_model(x_test)[0], y_test))
  exit()

# 10000 Step만큼 최적화를 수행합니다.
while int(ckpt.step) < (10000 + 1):
  # 50개씩 MNIST 데이터를 불러옵니다.
  batch_x, batch_y = next(train_data_iter)
  # 100 Step마다 training 데이터셋에 대한 정확도를 출력하고 tf.train.CheckpointManager를 이용해서 파라미터를 저장합니다.
  if ckpt.step % 100 == 0:
    ckpt_manager.save(checkpoint_number=ckpt.step)
    train_accuracy = compute_accuracy(CNN_model(batch_x)[0], batch_y)
    print("반복(Epoch): %d, 트레이닝 데이터 정확도: %f" % (ckpt.step, train_accuracy))
  # 옵티마이저를 실행해 파라미터를 한스텝 업데이트합니다.
  train_step(CNN_model, batch_x, batch_y)

  ckpt.step.assign_add(1)

# 학습이 끝나면 테스트 데이터에 대한 정확도를 출력합니다.
print("정확도(Accuracy): %f" % compute_accuracy(CNN_model(x_test)[0], y_test))

세이브 파일

 

세이브 파일을 생성하고 불러오는 부분만 리뷰한다.


세이브 파일 사전설정

# tf.train.CheckpointManager를 이용해서 파라미터를 저장합니다.
SAVER_DIR = "./model"
ckpt = tf.train.Checkpoint(step=tf.Variable(0), model=CNN_model)
ckpt_manager = tf.train.CheckpointManager(
      ckpt, directory=SAVER_DIR, max_to_keep=5)
latest_ckpt = tf.train.latest_checkpoint(SAVER_DIR) # 불러오기 가장최근 알고리즘 학습값

 

  • SAVER_DIR : 세이브 파일 경로설정
  • ckpt : Checkpoint의 핸들값 지정
    • step : 해당 번호위치부터. 0임으로 0번째부터 저장.
    • model : 저장하려는 모델 또는 불러오려는 모델
  • ckpet_manager : 저장하려는 디렉토리와 가장 최근에 얼마나 저장할것인지 지정
    • ckpt : 저장에 대한 핸들값
    • directory : 저장위치
    • max_to_keep : 가장 최근 저장값에서부터 몃번째까지 저장할 것 인지. 5임으로 5개의 모델데이터만 저장

스텝마다 저장

# 10000 Step만큼 최적화를 수행합니다.
while int(ckpt.step) < (10000 + 1):
  # 50개씩 MNIST 데이터를 불러옵니다.
  batch_x, batch_y = next(train_data_iter)
  # 100 Step마다 training 데이터셋에 대한 정확도를 출력하고 tf.train.CheckpointManager를 이용해서 파라미터를 저장합니다.
  if ckpt.step % 100 == 0:
    ckpt_manager.save(checkpoint_number=ckpt.step)
    train_accuracy = compute_accuracy(CNN_model(batch_x)[0], batch_y)
    print("반복(Epoch): %d, 트레이닝 데이터 정확도: %f" % (ckpt.step, train_accuracy))
  # 옵티마이저를 실행해 파라미터를 한스텝 업데이트합니다.
  train_step(CNN_model, batch_x, batch_y)

  ckpt.step.assign_add(1)

 

  • ckpt_manager.save() : 해당되는 checkpoint에 대한 이름과 경로로 학습데이터 저장

불러오기

# 만약 저장된 모델과 파라미터가 있으면 이를 불러오고 (Restore)
# Restored 모델을 이용해서 테스트 데이터에 대한 정확도를 출력하고 프로그램을 종료합니다.
if latest_ckpt:
  ckpt.restore(latest_ckpt)
  print("테스트 데이터 정확도 (Restored) : %f" % compute_accuracy(CNN_model(x_test)[0], y_test))
  exit()

 

  • latest_ckpt : 경로에 가장 최근의 저장알고리즘이 존재할 경우를 확인
  • ckpt.restore() : ckpt는 모델과 저장step의 핸들임으로, 여기에 저장된 알고리즘 핸들과 모델step을 덮어씌운다.
  • compute_accuracy(CNN_model(x_test[0], y_test)) : 지정된 학습 스텝으로 CNN을 돌린다.
728x90