모두의 딥러닝 - 17장(순환 신경망, RNN, 마지막장)
RNN은 여러 개의 데이터가 순서대로 입력됐을 때 앞에서 입력된 데이터를 기억해 놓고,
그 중요도를 판단해 가중치를 주는 순환 신경망 모델이다.
문장을 분석할 때 쓰일 수 있다.
RNN을 보완하기 위해 LSTM을 같이 사용하는데,
이런 식으로 앞선 입력의 결과에서 기억된 정보를 넘길지 말지를 관리한다.
즉, 기억값의 가중치를 관리한다.
LSTM 모델을 이용해서 뉴스 카테고리 분류 모델을 설계해볼 것이다.
데이터는 keras에서 가져온다.
이렇게 가져오는데, X_train에 저장된 값들을 보면 숫자로 나와 있다.
이 숫자가 의미하는 것은 단어의 빈도 순위인데, 2는 2번째로 많이 등장한 단어라는 뜻이다.
빈도가 너무 적은 단어는 제외하기 위해서 num_words=1000으로 설정해 1000 이상의 숫자는 제거한다.
from typing import Sequence
from keras.preprocessing import sequence
from keras.utils import to_categorical
from keras.models import Sequential
from keras.layers import Dense, LSTM, Embedding
from matplotlib import pyplot as plt
word_to_index = reuters.get_word_index()
x_train = sequence.pad_sequences(X_train, maxlen=100)
x_test = sequence.pad_sequences(X_test, maxlen=100)
y_train = to_categorical(Y_train, category)
y_test = to_categorical(Y_test, category)
model = Sequential()
model.add(Embedding(1000, 100))
model.add(LSTM(100, activation='tanh'))
model.add(Dense(46, activation='softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
history = model.fit(x_train, y_train, batch_size=100, epochs=20, validation_data=(x_test, y_test))
print('\n 테스트 정확도: %.4f' % (model.evaluate(x_test, y_test)[1]))
y_vloss = history.history['val_loss']
y_loss = history.history['loss']
x_len = numpy.arange(len(y_loss))
plt.plot(x_len, y_vloss, marker='.', c="red", label='Testset_loss')
plt.plot(x_len, y_loss, marker='.', c="blue", label='Trainset_loss')
plt.legend(loc='upper right')
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()
모델 코드이다.
우선 x_train, x_test를 길이 100으로 동일하게 맞춰주고, y_train, y_test는 어떤 카테고리인지를 예측해야 하기 때문에 원핫인코딩을 해준다.
그리고 모델에서 Embedding은 입력된 값을 다음 층이 알아들을 수 있는 형태로 변환해준다.
LSTM은 RNN의 기억 값의 가중치에 대한 층이고, tanh를 활성화 함수로 사용했다.
실행 결과이다.
또 다른 실습으로 영화 리뷰 분류하기가 있다.
이번 모델에는 Conv1D와 MaxPooling1D 를 사용한다.
Conv1D는 CNN에서 했던 컨볼루션 레이어와 같은 개념인데 1차원으로 만든 것이다.
MaxPooling1D도 마찬가지로 1차원 배열로 정해진 구역 안에서 가장 큰 값을 다음 층으로 넘긴다.
from keras.preprocessing import sequence
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from keras.layers import Embedding, LSTM, Conv1D, MaxPooling1D
from keras.datasets import imdb
import numpy
import tensorflow as tf
import matplotlib.pyplot as plt
seed = 0
numpy.random.seed(seed)
tf.random.set_seed(seed)
(x_train,y_train), (x_test, y_test) = imdb.load_data(num_words=5000)
x_train = sequence.pad_sequences(x_train, maxlen=100)
x_test = sequence.pad_sequences(x_test, maxlen=100)
model = Sequential()
model.add(Embedding(5000, 100))
model.add(Dropout(0.5))
model.add(Conv1D(64, 5, padding='valid', activation='relu', strides=1))
model.add(MaxPooling1D(pool_size=4))
model.add(LSTM(55))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.summary()
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
history = model.fit(x_train, y_train, batch_size=100, epochs=5, validation_data=(x_test, y_test))
print('\n 테스트 정확도: %.4f' % (model.evaluate(x_test, y_test)[1]))
y_vloss = history.history['val_loss']
y_loss = history.history['loss']
x_len = numpy.arange(len(y_loss))
plt.plot(x_len, y_vloss, marker='.', c="red", label='Testset_loss')
plt.plot(x_len, y_loss, marker='.', c="blue", label='Trainset_loss')
plt.legend(loc='upper right')
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()