코딩걸음마

[딥러닝] TensorFlow 모델 save / Load (+Keras Callback ) 본문

딥러닝_TensorFlow

[딥러닝] TensorFlow 모델 save / Load (+Keras Callback )

코딩걸음마 2022. 7. 1. 04:56
728x90

 

Titanic 데이터를 활용하여 TensorFlow 의 모델 save와 load 방법을 알아봅시다.

save와 load 방법을 알아보기 위해 기본적인 딥러닝 모델 플로우를 작성하겠습니다.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn import model_selection, preprocessing
import seaborn as sns

데이터 불러오기

titanic_df = pd.read_csv("titanic_modified.csv")

titanic_target = titanic_df[['Survived']].copy()
titanic_data = titanic_df.copy()

del titanic_data['Survived']

train, test set 분리

train_data, test_data, train_label, test_label = model_selection.train_test_split(titanic_data, titanic_target,
                                                                                 test_size=0.3,
                                                                                 random_state=0)

One-Hot-Encoding

enc = preprocessing.OneHotEncoder(categories='auto') 

train_label = enc.fit_transform(train_label).toarray()
test_label = enc.fit_transform(test_label).toarray()

 

모델 생성

import tensorflow as tf
from tensorflow.keras import datasets, utils
from tensorflow.keras import models, layers, activations, initializers, losses, optimizers, metrics
model = models.Sequential() 

model.add(layers.Dense(input_dim=8, units=256, activation=None, kernel_initializer=initializers.he_uniform())) 
model.add(layers.Activation('elu')) # elu or relu

model.add(layers.Dense(units=512, activation=None, kernel_initializer=initializers.he_uniform())) 
model.add(layers.Activation('elu')) 

model.add(layers.Dense(units=512, activation=None, kernel_initializer=initializers.he_uniform())) 
model.add(layers.Activation('elu'))

model.add(layers.Dense(units=256, activation=None, kernel_initializer=initializers.he_uniform())) 
model.add(layers.Activation('elu')) 
model.add(layers.Dropout(rate=0.5))

model.add(layers.Dense(units=2, activation='softmax')) # One-hot vector for 0 & 1
model.compile(optimizer=optimizers.Adam(), 
              loss=losses.categorical_crossentropy, 
              metrics=[metrics.categorical_accuracy])
history = model.fit(train_data, train_label, batch_size=100, epochs=20, validation_split=0.3, verbose=0)

모델평가

result = model.evaluate(test_data, test_label)

print('loss (cross-entropy) :', result[0])
print('test accuracy :', result[1])
9/9 [==============================] - 0s 2ms/step - loss: 0.4263 - categorical_accuracy: 0.8134
loss (cross-entropy) : 0.42633432149887085
test accuracy : 0.8134328126907349

모델 저장하기

model.save('trained_model.h5') # "Save" the model

모델 전체 저장하기(architecture, optimizer, 파라미터 값)
model.save('trained_model.h5')

모델 전체 불러오기
model = models.load_model('trained_model.h5')

weights(파라미터 값)만 따로 저장하기
model.save_weights('trained_model.h5')

weights(파라미터 값)만 따로 불러오기
model.load_weights('trained_model.h5') 

 

모델 불러와서 사용하기

model = models.load_model('trained_model.h5') # "Load" the "model"

result = model.evaluate(test_data, test_label)

print('loss (cross-entropy) :', result[0])
print('test accuracy :', result[1])

 

 

모델 중간 저장(Keras Callbacks)

위 방법은 모델을 훈련이 완료된 후, 저장하는 방법이었다. 하지만 데이터가 많은 모델의 경우 한번의 실행으로 모델을 만들기는 어려운 경우가 많이 있다. 그래서 몇일에 걸쳐서 모델을 생성해야하는데 아래의 방법은 모델을 생성하면서 중간저장을 하는 방법이다.

 

filepath = "경로/경로/ f'xxx_project_{epoch:02d}-{val_loss:.5f}.h5'"
tf.keras.callbacks.ModelCheckpoint( 
    filepath, # 모델 저장 경로, f'{epoch:02d}-{val_loss:.5f}.h5'
    monitor = 'val_loss', # 'loss', 'val_loss', 'accuracy', etc.
    verbose = 0,
    save_best_only = True, # True : monitor 중인 지표 기준 가장 좋은 모델 저장 or False : 하단 save_freq 기준 주기적 저장
    save_weights_only = False, # True == model.save_weights(filepath) or False == model.save(filepath) 
    mode = 'auto', # 자동으로 'auto', 작을수록 좋은거'min', 클수록 좋은거'max'
    #save_freq = 'epoch', # 'epoch' or integer(== # of batches)   save_best_only= False일때 사용가능
#     save_freq = 5 * num_of_batch # == saves the model's weights every 5 epochs (variable 'batch_size' should be set already)
)

그럼 다른 모델을 한번 실행해보자

model = models.Sequential() 
model.add(layers.Dense(input_dim=8, units=256, activation=None, kernel_initializer=initializers.he_uniform())) 
model.add(layers.Activation('elu')) # elu or relu
model.add(layers.Dense(units=512, activation=None, kernel_initializer=initializers.he_uniform())) 
model.add(layers.Activation('elu')) 
model.add(layers.Dense(units=512, activation=None, kernel_initializer=initializers.he_uniform())) 
model.add(layers.Activation('elu'))
model.add(layers.Dense(units=256, activation=None, kernel_initializer=initializers.he_uniform())) 
model.add(layers.Activation('elu')) 
model.add(layers.Dropout(rate=0.5))
model.add(layers.Dense(units=2, activation='softmax')) # One-hot vector for 0 & 1

model.compile(optimizer=optimizers.Adam(), 
              loss=losses.categorical_crossentropy, 
              metrics=[metrics.categorical_accuracy])
model.summary()
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_5 (Dense)              (None, 256)               2304      
_________________________________________________________________
activation_4 (Activation)    (None, 256)               0         
_________________________________________________________________
dense_6 (Dense)              (None, 512)               131584    
_________________________________________________________________
activation_5 (Activation)    (None, 512)               0         
_________________________________________________________________
dense_7 (Dense)              (None, 512)               262656    
_________________________________________________________________
activation_6 (Activation)    (None, 512)               0         
_________________________________________________________________
dense_8 (Dense)              (None, 256)               131328    
_________________________________________________________________
activation_7 (Activation)    (None, 256)               0         
_________________________________________________________________
dropout_1 (Dropout)          (None, 256)               0         
_________________________________________________________________
dense_9 (Dense)              (None, 2)                 514       
=================================================================
Total params: 528,386
Trainable params: 528,386
Non-trainable params: 0
_________________________________________________________________

 

# 모델 체크포인트 파일(중간 저장 모델)을 저장할 경로 설정 
checkpoint_path = 'saved_models/파일명.h5' # 필히 saved_models 폴더를 먼저 만들어줘야 합니다

# "ModelCheckpoint" 콜백함수 객체 생성
callback_checkpoint = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_path, 
                                                         monitor='val_loss', # default
                                                         save_best_only=True, # "Save" the "best" model "only"
                                                         verbose=0)
# 콜백함수를 호출하며 모델 학습 진행 
history = model.fit(train_data, train_label, 
                    batch_size=100, epochs=100, validation_split=0.3, verbose=0,
                    callbacks=[callback_checkpoint]) # 콜백 함수 추가

최종 학습 완료 시점을 기준으로 한 모델 성능 불러오기

result = model.evaluate(test_data, test_label)
print('loss (cross-entropy) :', result[0])
print('test accuracy :', result[1])
9/9 [==============================] - 0s 2ms/step - loss: 0.5146 - categorical_accuracy: 0.8209
loss (cross-entropy) : 0.5146127343177795
test accuracy : 0.8208954930305481

 

 Validation loss결과가 가장 좋은 기준으로 저장한  모델 성능

model = models.load_model('saved_models/titanic_4-layer_elu.h5') # "Load" the "model"

result = model.evaluate(test_data, test_label)
print('loss (cross-entropy) :', result[0])
print('test accuracy :', result[1])
9/9 [==============================] - 0s 2ms/step - loss: 0.4417 - categorical_accuracy: 0.8246
loss (cross-entropy) : 0.4417162537574768
test accuracy : 0.8246268630027771
728x90
Comments