GD(Gradient Descent)**는 시작 지점에서 기울기의 반대 방향으로 하강하면서 **손실 함수(loss function)를 최소화하는 지점을 찾기 위한 가장 직관적인 방법입니다. 이처럼 전체 데이터 셋을 가지고 학습하게 되면 안정적이긴 하지만, 계산량과 학습 비용이 많아지게 됩니다.
이때 전체 데이터 셋이 아닌, 무작위로 뽑은 데이터들에 대한 Gradient Descent를 진행하고, 이를 반복하며 정확도를 찾아 나가는 것을 SGD(Stochastic Gradient Descent)라고 합니다.
이번 실습에서는 동일한 모델 생성 및 학습을 통하여 두 최적화 기법을 비교해보도록 하겠습니다.
데이터셋은 IMDB 영화 리뷰 데이터 셋을 사용합니다. 해당 데이터셋은 훈련용 데이터 25,000개와 테스트용 데이터 25,000개로 이루어져 있으며, 레이블은 긍정/부정으로 두 가지입니다. 이때 긍정은 1, 부정은 0으로 표시되어 있습니다. 우리의 목표는 전처리된 영화 리뷰 데이터를 가지고 그 리뷰가 긍정적인지 혹은 부정적인지를 예측하는 것입니다.
모델 구조 확인과 학습을 위한 함수/라이브러리
- model.summary()
: 생성한 모델의 구조를 확인합니다.
- history = model.fit(train_data, train_labels, epochs = 20, batch_size = 500, validation_data = (test_data, test_labels), verbose = 0)
: 모델을 학습시킬 때 검증용 데이터를 설정하는 방법입니다. 이전 장의 실습과는 다르게, 이번에는 모델을 학습시킬 때 검증용 데이터(validation_data)를 설정합니다.
import numpy as np
import tensorflow as tf
from visual import *
import logging, os
logging.disable(logging.WARNING)
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
# 데이터를 전처리하는 함수
def sequences_shaping(sequences, dimension):
results = np.zeros((len(sequences), dimension))
for i, word_indices in enumerate(sequences):
results[i, word_indices] = 1.0
return results
'''
1. GD를 적용할 모델을 자유롭게 생성합니다.
'''
def GD_model(word_num):
model = tf.keras.Sequential([tf.keras.layers.Dense(32, input_shape = (word_num,), activation = 'relu'), tf.keras.layers.Dense(32, activation = 'relu'), tf.keras.layers.Dense(1, activation = 'sigmoid')])
return model
'''
2. SGD를 적용할 모델을 GD를 적용할 모델과 똑같이 생성합니다.
'''
def SGD_model(word_num):
model = tf.keras.Sequential([tf.keras.layers.Dense(32, input_shape = (word_num,), activation = 'relu'), tf.keras.layers.Dense(32, activation = 'relu'), tf.keras.layers.Dense(1, activation = 'sigmoid')])
return model
'''
3. 두 모델을 불러온 후 학습시키고 테스트 데이터에 대해 평가합니다.
Step01. GD 함수와 SGD 함수를 이용해
두 모델을 불러옵니다.
Step02. 두 모델의 손실 함수, 최적화 알고리즘,
평가 방법을 설정합니다.
Step03. 두 모델의 구조를 확인하는 코드를 작성합니다.
Step04. 두 모델을 각각 학습시킵니다.
검증용 데이터도 설정해주세요.
'epochs'는 20으로 설정합니다.
GD를 적용할 경우 학습 시
전체 데이터 셋(full-batch)을
사용하므로 'batch_size'를
전체 데이터 개수로 설정합니다.
SGD를 적용할 경우 학습 시
미니 배치(mini-batch)를 사용하므로
'batch_size'를 전체 데이터 개수보다
작은 수로 설정합니다.
여기선 500으로 설정하겠습니다.
Step05. 학습된 두 모델을 테스트하고
binary crossentropy 값을 출력합니다.
둘 중 어느 모델의 성능이 더 좋은지 확인해보세요.
'''
def main():
word_num = 100
data_num = 25000
# Keras에 내장되어 있는 imdb 데이터 세트를 불러오고 전처리합니다.
(train_data, train_labels), (test_data, test_labels) = tf.keras.datasets.imdb.load_data(num_words = word_num)
train_data = sequences_shaping(train_data, dimension = word_num)
test_data = sequences_shaping(test_data, dimension = word_num)
gd_model = GD_model(word_num)
sgd_model = SGD_model(word_num) # SGD를 사용할 모델입니다.
gd_model.compile(loss = 'binary_crossentropy', optimizer='sgd', metrics= ['accuracy', 'binary_crossentropy'])
sgd_model.compile(loss = 'binary_crossentropy', optimizer='sgd', metrics= ['accuracy', 'binary_crossentropy'])
gd_model.summary()
sgd_model.summary()
gd_history = gd_model.fit(train_data, train_labels, epochs = 20, batch_size = data_num, validation_data = (test_data, test_labels), verbose = 0)
print('\n')
sgd_history = sgd_model.fit(train_data, train_labels, epochs = 20, batch_size = 500, validation_data = (test_data, test_labels), verbose = 0)
print('\n')
scores_gd = gd_history.history['val_binary_crossentropy'][-1]
scores_sgd = sgd_history.history['val_binary_crossentropy'][-1]
print('\nscores_gd: ', scores_gd)
print('scores_sgd: ', scores_sgd)
Visulaize([('GD', gd_history),('SGD', sgd_history)])
return gd_history, sgd_history
if __name__ == "__main__":
main()
출처: 앨리스 교육
반응형