AI/Deep Learning
[DL] LSTM 모델을 사용한 IMDb 데이터 추론
운호(Noah)
2022. 3. 24. 16:36
들어가기 앞서,
- 해당 포스트에서는, LSTM 모델을 사용한 Batch 단위의 IMDb 데이터 추론 성능 측정 코드를 다루고 있으며,
- 실행 시간을 측정하기 위한 디버깅 코드가 포함되어있습니다.
- IMDb 데이터는 영화 리뷰에 대한 감정 분류 데이터셋입니다. (1:긍정, 0:부정)
예제 코드
# Model: LSTM
# Dataset: imdb
import tensorflow as tf
import numpy as np
import time
import pandas as pd
# Check GPU Availability
device_name = tf.test.gpu_device_name()
if not device_name:
print('Cannot found GPU. Training with CPU')
else:
print('Found GPU at :{}'.format(device_name))
# 전역 변수 설정
model = None
load_model_time = None
X_test = None
result_df = pd.DataFrame(columns=['batch_size', 'accuracy', 'load_model_time', 'load_dataset_time','total_inference_time', 'avg_inference_time','ips', 'ips_inf'])
# 모델 훈련 및 저장
def train_and_save_model(saved_model_dir):
global model
num_words = 20000
maxlen = 80
(X_train, y_train), (X_test, y_test) = tf.keras.datasets.imdb.load_data(num_words=num_words)
X_train = tf.keras.preprocessing.sequence.pad_sequences(X_train,
value = 0,
padding = 'pre',
maxlen = maxlen)
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Embedding(num_words, 128, input_length = len(X_train[0])))
model.add(tf.keras.layers.LSTM(128, dropout=0.2, recurrent_dropout=0.2))
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer="rmsprop",
metrics=['accuracy'])
history = model.fit(X_train,
y_train,
validation_split=0.2,
epochs = 5,
batch_size = 128,
verbose = 1)
model.save(saved_model_dir, include_optimizer=False, save_format='tf')
# 모델 로드
def load_model(saved_model_dir):
global load_model_time
global model
load_model_time = time.time()
model = tf.keras.models.load_model(saved_model_dir)
load_model_time = time.time() - load_model_time
# 테스트 데이터를 배치 단위로 제공
def load_test_batch(batch_size):
global X_test
num_words = 20000
maxlen = 80
(X_train, y_train), (X_test, y_test) = tf.keras.datasets.imdb.load_data(num_words=num_words)
X_test = tf.keras.preprocessing.sequence.pad_sequences(X_test,
value= 0,
padding = 'pre',
maxlen = maxlen )
test_batch = tf.data.Dataset.from_tensor_slices((X_test, y_test)).batch(batch_size)
return test_batch
def inference(batch_size):
# 전체 데이터에 대한 예측라벨 및 실제라벨 저장
pred_labels = []
real_labels = []
# 배치 단위에 따른 추론 시간 저장
# iter_times = []
# 배치 단위의 테스트 데이터 로드
load_dataset_time = time.time()
test_batch = load_test_batch(batch_size)
load_dataset_time = time.time() - load_dataset_time
# 디버깅용 변수
success = 0
# 전체 데이터에 대한 추론 시작
inference_time = time.time()
# 전체 데이터를 배치 단위로 묶어서 사용 (반복문 한번당 배치 단위 추론 한번)
for i, (X_test_batch, y_test_batch) in enumerate(test_batch):
# 배치별 데이터 추론 시간
# inference_time_per_batch = time.time()
# 배치 단위별 데이터셋 분류
y_pred_batch = model(X_test_batch)
# 배치별 데이터 추론 시간 저장
# iter_times.append(time.time() - inference_time_per_batch)
# 배치 사이즈 만큼의 실제 라벨 저장
real_labels.extend(y_test_batch.numpy())
# 배치 사이즈 만큼의 예측 라벨 저장
y_pred_batch = np.where(y_pred_batch > 0.5, 1, 0)
y_pred_batch = y_pred_batch.reshape(-1)
pred_labels.extend(y_pred_batch)
# 디버깅
success += batch_size
if (success % 500 == 0):
print("{}/{}".format(success,len(test_batch)*batch_size))
inference_time = time.time() - inference_time
# 모든 데이터에 대한 배치별 추론 시간을 배열화
# iter_times = np.array(iter_times)
# 모든 데이터에 대한 실제라벨과 예측라벨을 비교한 뒤, 정확도 계산
accuracy = np.sum(np.array(real_labels) == np.array(pred_labels))/len(real_labels)
# Metric 결과 저장
global result_df
result_df = result_df.append({'batch_size' : batch_size ,
'accuracy' : accuracy,
'load_model_time' : round(load_model_time, 4),
'load_dataset_time' : round(load_dataset_time, 4),
'total_inference_time' : round(inference_time, 4),
'avg_inference_time' : round(inference_time / len(X_test), 4),
'ips' : round(len(X_test) / (load_model_time + load_dataset_time + inference_time), 4),
'ips_inf' : round(len(X_test) / inference_time, 4)}, ignore_index=True)
# 배치 단위 추론 결과 데이터 저장
result_df.to_csv(result_csv, index=False)
# 모델이 저장되어있는/저장할 경로
model_name = 'lstm_imdb'
saved_model_dir=f'./model/{model_name}_model'
# 배치 단위 추론 결과 데이터를 저장할 경로
result_csv=f'./csv/{model_name}_result.csv'
# 저장되어있는 모델이 없다면, 모델을 새롭게 학습한 뒤 저장
# train_and_save_model(saved_model_dir)
# 저장되어있는 모델이 있다면, 로드
load_model(saved_model_dir)
# 배치 단위로 추론
for batch_size in [1, 2, 4, 8, 16, 32, 64, 128]:
inference(batch_size)