케라스 버전 확인
import keras
keras.__version__
IMDB 데이터셋
영화 리뷰 텍스트를 기반으로 해당 리뷰를 긍정과 부정으로 분류하는 방법, 즉 이진 분류 방법에 대해 알아본다.
- IMDB 데이터셋은 훈련데이터, 테스트데이터 각각 25,000개로 구성 (긍정리뷰 50%, 부정리뷰 50%)
- 같은 데이터를 가지고 모델을 훈련하고 테스트해서는 안되기 때문에 훈련 데이터와 테스트 데이터를 나누게 됨
- 훈련 데이터에서의 작동이 새로운 데이터에서의 작동을 보장해주지는 않음 (훈련 데이터의 레이블은 이미 알고 있기 때문에 이를 예측하는 모델은 필요없음)
데이터셋을 로드한다.
from keras.datasets import imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words = 10000)
- num_words = 10000 자주 나타나는 단어 10,000개를 사용하겠다는 의미
- train_data, test_data 리뷰 목록 (각 리뷰는 단어 인덱스의 리스트, 단어 시퀀스 인코딩)
- train_labels, test_labels 부정 0, 긍정 1 을 나타내는 리스트
리뷰 하나를 열어보자.
train_data[0]
긍정적인 리뷰로 분류되어 있다.
train_labels[0]
num_words = 10000 으로 제한했기 때문에 단어 인덱스는 10,000개를 넘지 않는다.
max([max(sequence) for sequence in train_data])
해당 리뷰를 원래의 영어 단어로 바꿔보자
word_index = imdb.get_word_index()
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
decoded_review = ' '.join([reverse_word_index.get(i - 3, '?') for i in train_data[0]])
decoded_review
데이터 준비
신경망에 숫자 리스트를 넣을 수는 없다. 따라서 아래와 같이 해당 리스트를 텐서로 바꾸어야 한다.
리스트를 텐서로 바꾸는 방법
1) 같은 길이가 되도록 리스트에 패딩 추가 → (samples, sequence_length) 크기의 정수 텐서로 변환 → 정수 텐서를 다룰 수 있는 층을 신경망의 첫 번째 층으로 사용 (Embedding 층)
가장 긴 리뷰는 2,494개의 단어로 이루어져 있다. 이 경우 훈련 데이터를 변환한 텐서의 크기는 (25000, 2494)이다.
max([len(sequence) for sequence in train_data])
2) 리스트를 one-hot encoding 하여 0과 1의 벡터로 변환
예를 들어, 시퀀스 [3, 5]를 인덱스 3과 5의 위치는 1이고 그 외는 모두 0인 10,000 차원의 벡터로 각각 변환
그 다음으로 부동 소수 벡터 데이터를 다룰 수 있는 Dense 층을 신경망의 첫 번째 층으로 사용한다.
리스트가 하나의 벡터로 변환되므로 훈련 데이터를 변환한 텐서의 크기는 (25000, 10000)이 된다.
여기서는 2)의 방법을 이용하기로 한다. 정수 시퀀스를 이진 행렬로 디코딩해보자.
크기가 (len(sequences), dimension))이고 모든 원소가 0인 행렬을 만들고, results[i, sequence] = 1. # results[i]에서 특정 인덱스의 위치를 1로 만든 다음, 훈련 데이터와 테스트 데이터를 벡터로 변환하면 된다.
import numpy as np
def vectorize_sequences(sequences, dimension=10000):
results = np.zeros((len(sequences), dimension))
for i, sequence in enumerate(sequences):
results[i, sequence] = 1
return results
x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)
샘플은 다음과 같이 나타나게 된다.
x_train[0]
레이블을 다음과 같이 벡터로 바꾼다.
y_train = np.asarray(train_labels).astype('float32')
y_test = np.asarray(train_labels).astype('float32')
신경망 모델 만들기 Building our network
입력데이터는 벡터, 레이블은 스칼라(1 또는 0)
- 16개의 은닉 유닛을 가진 두 개의 은닉층
- 현재 리뷰의 감정을 스칼라 값의 예측으로 출력하는 세 번째 층
중간에 있는 은닉층은 활성화 함수로 relu를 사용하고, 마지막 층은 확률을 출력하기 위해 시그모이드 활성화 함수 사용한다. relu는 음수를 0으로 만드는 함수이고, 시그모이드는 임의의 값을 [0, 1] 사이로 압축하므로 출력 값을 확률처럼 해석할 수 있다. 즉, 이 신경망의 다음과 같은 구조를 가진다.
source : https://s3.amazonaws.com/book.keras.io/img/ch3/3_layer_network.png
위의 신경망을 케라스로 구현하면 다음과 같다.
from keras import models
from keras import layers
model = models.Sequential()
model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(16, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
이제 손실함수와 옵티마이저를 선택한다. rmsprop 옵티마이저와 binary_crossentropy 손실 함수 모델로 설정하고, 훈련하는 동안 정확도를 사용하여 모니터링한다.
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy'])
훈련검증 Validating our approach
원본 훈련데이터에서 10,000개의 샘플을 가져와 검증 셋트를 만든다.
x_val = x_train[:10000]
partial_x_train = x_train[10000:]
y_val = y_train[:10000]
partial_y_train = y_train[10000:]
512개씩 미니샘플을 만들어 20번의 에포크 동안 훈련시킨다. x_train 과 y_train 텐서에 있는 모든 샘플에 대해 20번 반복한다. 동시에 다로 떼어놓은 10,000개의 샘플에서 손실과 정확도를 측정한다. validation_data 매개변수에 검증 데이터를 전달한다.
history = model.fit(partial_x_train,
partial_y_train,
epochs=20,
batch_size=512,
validation_data=(x_val, y_val))
훈련하는 동안 발생한 정보를 담고 있는 딕셔너리인 history 의 속성을 살펴보자. 4개의 항목을 담고 있다. 맷플롯립을 사용하여 훈련과 검증 데이터에 대한 손실과 정확도를 그려보자.
history_dict = history.history
history_dict.keys()
먼저 훈련과 검증손실 그래프이다.
import matplotlib.pyplot as plt
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(acc) + 1)
plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
다음으로 그래프를 초기화하고, 훈련과 검증 정확도를 그려보자.
plt.clf()
acc = history_dict['acc']
val_acc = history_dict['val_acc']
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.show()
그래프에서 보듯이 손실은 에포크마다 감소하고 정확도는 에포크마다 증가하고 있다.
다시 새로운 신경망을 4번의 에포크 동안만 훈련하고 테스트 테이터에서 평가해보자.
model = models.Sequential()
model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(16, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy'])
model.fit(x_train, y_train, epochs=4, batch_size=512)
results = model.evaluate(x_test, y_test)
최종결과는 다음과 같다.
results
위와 같이 훈련을 시킨 후 predict 메소드를 사용하여 어떤 리뷰가 긍정일 확률을 예측할 수 있다.
model.predict(x_test)
예측 결과 긍정적인 리뷰로 분류되는 x_test[1]의 내용을 보자.
word_index = imdb.get_word_index()
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
decoded_review = ' '.join([reverse_word_index.get(i - 3, '?') for i in test_data[1]])
decoded_review
deep-learning-with-python-notebooks 3.5 imdb
https://www.kaggle.com/juanjotwo/deep-learning-with-python-notebooks-3-5-imdb
'프로그래밍 Programming' 카테고리의 다른 글
Deep Learning Tutorial for Beginners - 2. Logistic Regression (0) | 2018.12.20 |
---|---|
Deep Learning Tutorial for Beginners - 1. Overview the Data Set (0) | 2018.12.18 |
아나콘다 matplotlib 설치 (0) | 2018.12.15 |
딥러닝 툴 설치하기 Anaconda, Jupyter Notebook, TensorFlow and Keras for Deep Learning (0) | 2018.12.15 |
Computer Vision (4) scikit-image 이미지 처리 기본 (0) | 2018.12.09 |