brunch

You can make anything
by writing

C.S.Lewis

by 유윤식 May 08. 2019

Python: m.l with Keras #13

시간의 흐름속에서, RNN(WITH LSTM, GRU)

시계열 데이터에 대해서는 많이 접할 수 있는 기회가 있다.


우리 삶이 시간의 흐름속에서 일련의 과정처럼 일어난다.

말하는 순간 순간, 무언가를 생각하는 순간 순간.


모두 시간의 연속이자 한 순간의 시점에서 발생하고

서로 연관성이 어느 정도는 있기 마련이다.


예)

I said: I like to do something for my...


라고 말한다면,


우리는 뒤에(...) 어떤 말이 올지 감으로 알 수 있다.


경험도 있지만, 패턴도 있지만, 영어 실력도 있지만

I, like, to, do, something, for, my, WHAT?!


이렇게 보면(1-gram) 대충 뭔가 올 것 같다는 느낌은 있다.


더 정확하게 답을 찾기 위해서는 Context 가 필요하다.

'Context의 시대'. 라는 책이 있다. :)


여자친구에 대한 고민을 하고 있다면 당연히 'girl-friend' 가 나오는게 맞다.

가족에 대해 고민을 하고 있다면 'family'가 맞다.


예가 좀 길었는데,

중요한건 시간의 흐름과 그 순간의 시점, 그리고 문맥(분위기) 이다.


사실 이번 RNN 관련 스터디를 통해 얻은 것이 이게 전부다.


이걸 영화평론리뷰 데이터셋을 통해서 구현하는 예제가 있다.



from keras.models import Sequential

from keras.layers import Embedding, SimpleRNN, LSTM, Dense, GRU

from keras.datasets import imdb

from keras.preprocessing import sequence

import matplotlib.pyplot as plt


필요한 라이브러리를 모두 불러오고,



max_features = 10000

maxlen = 1000

batch_size = 32


(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features)


x_train = sequence.pad_sequences(x_train, maxlen=maxlen)

x_test = sequence.pad_sequences(x_test, maxlen=maxlen)


이게 중요한데,

데이터를 가지고 와서 가공하는 부분이다.


10000 개의 단어 안에서(빈번히 사용된) 리뷰의 [ 0 : 1000 ] 의 길이 만큼만 사용하는

데이터셋을 만드는 과정이다.



model = Sequential()

model.add(Embedding(max_features, 32))

model.add(LSTM(32))

model.add(Dense(1, activation='sigmoid'))


model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])

history = model.fit(input_train, y_train, epochs=10, batch_size=128, validation_split=0.3)


어렵다고 생각하지 마시고,

이전 포스트에 남겨둔 링크에서 코드에 대한 자세한 설명을 참고하시오.


그냥 당연하다는 듯이 넘길 수 있는 코드이다.


혹시나,

'sigmoid' 는 이진분류(0 or 1) 에서 자주 사용되고,

'softmax' 는 다중분류(0 일 확률 몇?!, 1 일 확률 몇?!!, 등등) 에서 자주 사용된다.


결과,


이번에는 다른 모델(GRU 사용)


model = Sequential()

model.add(Embedding(max_features, 32))

model.add(GRU(32, dropout=0.2, recurrent_dropout=0.2))

model.add(Dense(1, activation='sigmoid'))


model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])

history = model.fit(input_train, y_train, epochs=10, batch_size=128, validation_split=0.3)



결과,


이번엔 GRU 모델을 한 층 더 쌓아올린 모델,


model = Sequential()

model.add(Embedding(max_features, 32))

model.add(GRU(32, dropout=0.2, recurrent_dropout=0.2, return_sequences=True))

model.add(GRU(64, dropout=0.2, recurrent_dropout=0.2))

model.add(Dense(1, activation='sigmoid'))


model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])

history = model.fit(input_train, y_train, epochs=10, batch_size=128, validation_split=0.3)



결과,


한 스템이 더 남았다.

바로 튜닝을 통한 과소적합을 완화시키는 일이다.


다음 글에서 계속하자.


끝.

작가의 이전글 Suricata: 수리카타 설치(2)
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari