데이터 분석가
article thumbnail
  • 이번 글에서는 영화에 대한 긍정과 부정 리뷰 5만개로 이루어진 IMDB데이터셋을 활용하여 이진 분류모델을 구현해보겠습니다.

교재 홍보

 

케라스 창시자에게 배우는 딥러닝 개정 2판 - 예스24

단어 하나, 코드 한 줄 버릴 것이 없다!단 한 권의 딥러닝 책을 선택한다면 바로 이 책이다!케라스 창시자이자 구글 딥러닝 연구원인 저자는 ‘인공 지능의 민주화’를 강조한다. 이 책 역시 많

www.yes24.com

1. 데이터 생성

  • IMDB데이터를 가져와 훈련데이터와 테스트데이터로 나눕니다.
from tensorflow.keras.datasets import imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words = 10000)
    # 가장 자주 등장하는 단어 1만개로 제한
    # train_data와 test_data는 리뷰를 담은 리스트로 단어가 숫자로 인코딩되어 있음
    # labels는 부정을 나타내는 0과 긍정을 나타내는 0을 담은 리스트

2. 데이터 전처리

  • 훈련데이터는 모두 길이가 다르지만 신경망은 동일한 크기의 배치를 원하므로 아래 두 가지 방법 중 하나로 리스트를 텐서(벡터)로 바꿔줘야 한다. 여기서는 방법2로 진행한다.
    • 방법 1 : 같은 길이가 되도록 리스트에 패딩 0을 추가하여 (samples, max_length) 크기의 정수 텐서로 변환하고, 정수 텐서를 다루는 층으로 신경망을 시작
    • 방법 2 : 리스트를 멀티-핫 인코딩하여 0과 1의 벡터로 변환하고, 부동 소수점 벡터 데이터를 다룰 수 있는 층으로 신경망을 시작
import numpy as np

def vectorize_sequences(sequences, dimension=10000):
  results = np.zeros((len(sequences), dimension))
  for i, sequence in enumerate(sequences):
    for j in sequence:
      results[i, j] = 1.
  return results

x_train = vectorize_sequences(train_data) # 훈련 데이터를 벡터로 변환한다.
x_test = vectorize_sequences(test_data)
  • 레이블 또한 벡터로 변환해줘야 하는데, 아래 두 가지 방법 중 하나를 선택해 진행해야 한다. 여기서는 방법 1로 진행한다.
    • 방법 1 : 레이블의 리스트를 정수 텐서로 변환한다.
    • 방법 2 : 레이블의 리스트를 원-핫 인코딩하여 0과 1의 벡터로 변환한다.
y_train = np.asarray(train_labels).astype('float32')
y_test = np.asarray(test_labels).astype('float32')

3. 모델 정의 및 컴파일

  • 16개의 유닛을 가진 2개의 은닉층과 현재 리뷰의 감정을 스칼라 값으로 출력하는 출력 층으로 된 모델을 정의합니다.
from tensorflow import keras
from tensorflow.keras import layers

model = keras.Sequential([
    layers.Dense(16, activation='relu'),
    layers.Dense(16, activation='relu'),
    layers.Dense(1, activation='sigmoid') # 확률표현을 위해 sigmoid 사용
])
  • 모델이 훈련을 마칠 수 있도록 손실 함수와 옵티마이저를 선택해 컴파일 해줍니다.
model.compile(
    optimizer='rmsprop', # SGD 확률적 경사하강법
    loss = 'binary_crossentropy', # 이진 분류(binary), 확률을 출력하기 때문에(crossentropy) 설정
    metrics = ['accuracy']
)

4. 검증 데이터 준비

  • 훈련 과정 중 모델의 정확도를 모니터링하기 위해 원본 훈련 데이터에서 훈련 데이터와 검증 데이터로 분리해 줍니다.
x_val = x_train[:10000] # 검증 데이터
partial_x_train = x_train[10000:] # 훈련 데이터
y_val = y_train[:10000]
partial_y_train = y_train[10000:]

5. 모델 훈련

  • 훈련 데이터에서 512개의 배치사이즈로 샘플을 만들고, 20번의 에포크 동안 모든 샘플에 대해 모델을 훈련시킵니다.
  • model.fit()메서드는 History객체를 반환하므로 이를 history에 할당해준다.
history = model.fit(partial_x_train,
                    partial_y_train,
                    epochs = 20,
                    batch_size = 512,
                    validation_data=(x_val, y_val)) # 위에서 만들어둔 검증데이터로 에포크가 끝날 때마다 손실과 정확도를 계산해줍니다.
  • history의 history속성으로 모델을 훈련하는 동안 발생한 모든 정보를 딕셔너리 형태로 가져올 수 있고, 이 딕셔너리의 키값을 확인하면 다음과 같다.
history_dict = history.history # history의 history속성으로 딕셔너리 정보를 가져온다.
history_dict.keys()

6. 손실과 정확도 그래프

  • history 객체로부터 딕셔너리 정보를 가져와 훈련과 검증 데이터에 대한 손실과 정확도 그래프를 그려주는 함수를 정의하고 이를 실행해준다.
import matplotlib.pyplot as plt

def vis(history):
  history_dict = history.history
  loss_values = history_dict["loss"]
  val_loss_values = history_dict["val_loss"]
  acc = history_dict["accuracy"]
  val_acc = history_dict["val_accuracy"]
  epochs = range(1, len(loss_values) + 1)

  figure, ax = plt.subplots(nrows = 1, ncols = 2, figsize = (15, 8))

  ax[0].plot(epochs, loss_values, "bo", label="Training loss")
  ax[0].plot(epochs, val_loss_values, "b", label="Validation loss")
  ax[0].set_title("Training and validation loss")
  ax[0].set_xlabel("Epochs")
  ax[0].set_ylabel("Loss")
  ax[0].legend()

  ax[1].plot(epochs, acc, "bo", label="Training acc")
  ax[1].plot(epochs, val_acc, "b", label="Validation acc")
  ax[1].set_title("Training and validation accuracy")
  ax[1].set_xlabel("Epochs")
  ax[1].set_ylabel("Accuracy")
  ax[1].legend()

  plt.show()

vis(history)
  • 결과를 살펴보면 네 번째 에포크 이후부터 검증 데이터에 비해 훈련 데이터의 정확도가 치솟는 것을 볼 수 있는데, 이는 훈련 데이터에 대해 모델이 과도하게 최적화되어 훈련 세트 이외의 데이터에 적용이 어려운 현상입니다. 이를 과적합이라고 합니다.

'DeepLearning' 카테고리의 다른 글

CNN_강아지 vs 고양이  (0) 2023.08.30
CNN_MNIST  (0) 2023.08.29
다중 분류 모델_Reuter  (0) 2023.08.29
tensorflow를 통한 선형 분류기 구현  (0) 2023.08.25
MNIST데이터를 활용한 딥러닝  (0) 2023.08.24
profile

데이터 분석가

@이꾹꾹

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!