When will you grow up?

Long Short Term Memory(using IMDB dataset) 본문

02. Study/Keras

Long Short Term Memory(using IMDB dataset)

미카이 2017. 11. 12. 19:50

저번시간에는 word embedding /1D conv, maxpool 을 이용하여 IMDB dataset을 학습 시켰다면,

이번시간에는 RNN중에서도 가장 많이사용되는, LSTM으로 IMDB dataset을 학습시켜 볼 예정입니다.


기본적으로 RNN(Recurrent Neural Network)은 시간에 따라 x가 변화하는 데이터를 학습시키기에 좋은 Neural Network 입니다

(ex. 동영상, 음성, text 등등)





[1.기본적인 RNN 구조]


RNN은 기존에 NN와 비슷한 모양처럼 생겼지만, 중간에 Recurrent의 구조가 반복되는 구조가 다른점 입니다.

이 구조를 펼쳐보면 오른쪽과 1번 이미지의 오른쪽의 구조처럼 각 중간중간의 Hidden Layer들이 연결되어 있는 구조 입니다.

보통 Neural Network 구조중에서 가장 Deep한 구조라고 보통 사람이 말을 하며, 

이유는 재귀되는 부분이 엄청 길수도 있으며, x->hidden->h1 인 경우가 더 깊한 구조일 수 있기 때문입니다.


RNN의 구조중에 대표적인 문제가, Vanishing Gradient Problem인데,

  ->이렇게 전달되는 부분에서 같은 값을 가질텐데, 만약 저 값이 0.7이라고 가정하면 time serial이 깊어지면(0.7*0.7 ....0.7) 늘어나게 되므로써, 0이 되어버려 Back Propagation할때 뒤로 갈수록 업데이트가 안되는 현상이 발생하게 됩니다.


이 Vanishing Gradient Problem을 해결하기 위한 나온 방법을 생각을 하다가, 나온 방법이 각 Time마다 어떤 조건을 두어서 그 조건에 의하여 값이 너무 커지지도 않고 작아지지도 않게 만들어서 전달되는 값을 상수로 넘기지 말고 Control Unit Gate을 만들어서 넘겨주자 하는 방법이 LSTM(Long Short Term Memory)입니다.


[2. LSTM 구조]


직관적으로, 그림2.에서 A부분에서 Activation만 사용하는것이 아니라 안에 조그마한 Network가 담겨져 있어서, 옛날 정보를 다음에 넘겨줄지, 없앨지 Control 하는 Unit이 추가되었다고 생각한다.


Keras에서는 LSTM을 간단하게 Layer 쌓듯이 사용을 할 수가 있다.



그럼 이제 LSTM모델을 이용하여 IMDB dataset을 학습데이터이용하여 학습해보자



먼저 epoch를 2번 200번 했을때를 비교하여 확인해보자.

모델 구성은 다음과 같다.

Input -> Embedding ->LSTM ->Dense(fully connected) -> output


output은 0과 1 로 나타내며 즉 true, false 라벨이다.




[epoch 2]                                                        [epoch 200]

[val acc : 83.16%]                                                 [val acc : 81.44%]

위 그래프와 같은 성능을 나타나고 있습니다

즉 epoch가 많다고 성능이 좋은것도 아니고 깊다고 좋은것도 아니고 적절히 잘 조절하면서 

학습결과도 확인를 해야되는것을 확인할 수 있었습니다.


GTX1060 6G 기준으로 [3분 / 293분] 정도 걸렸으며, 





전체 코드는 아래와 같습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#RNN-LSTM
from keras.preprocessing import sequence
from keras.models import Sequential
from keras.layers import Dense, Embedding
from keras.layers import LSTM
from keras.datasets import imdb
import time
from matplotlib import pyplot as plt
 
#Setting the start variable for time measurement
start_time = time.time()
 
#Variable
max_features = 5000
maxlen = 80  # 단어중에 가장 많이 쓰이는 단어중 가장 일반적인 단어 80개로 자르고 나머지는 0으로 ..
batch_size = 32
 
print('Loading the data...')
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features)
print(len(x_train), 'train data sequences')
print(len(x_test), 'test data sequences')
 
 
print('Pad sequences (samples x time)')
x_train = sequence.pad_sequences(x_train, maxlen=maxlen)
x_test = sequence.pad_sequences(x_test, maxlen=maxlen)
print('x_train shape:', x_train.shape)
print('x_test shape:', x_test.shape)
 
print('Build model...')
model = Sequential()
model.add(Embedding(max_features, 128))
model.add(LSTM(128, dropout=0.2, recurrent_dropout=0.2))
model.add(Dense(1, activation='sigmoid'))
 
# try using different optimizers and different optimizer configs
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
 
print('Train...')
hist = model.fit(x_train, y_train, validation_data=(x_test, y_test), nb_epoch=2, batch_size=batch_size, verbose=1)
score, acc = model.evaluate(x_test, y_test, batch_size=batch_size, verbose=0)
print('Test score:', score)
print('Test accuracy:', acc)
 
#model visualize
fig, loss_ax = plt.subplots()
acc_ax = loss_ax.twinx()
loss_ax.plot(hist.history['loss'], 'y', label='train loss')
loss_ax.plot(hist.history['val_loss'], 'r', label='val loss')
acc_ax.plot(hist.history['acc'], 'b', label='train acc')
acc_ax.plot(hist.history['val_acc'], 'g', label='val acc')
loss_ax.set_xlabel('epoch')
loss_ax.set_ylabel('loss')
acc_ax. set_ylabel('accuracy')
loss_ax.legend(loc='upper left')
acc_ax.legend(loc='lower left')
plt.show()
 
 
#using svg visual model
from IPython.display import SVG
from keras.utils.vis_utils import model_to_dot
SVG(model_to_dot(model, show_shapes=True).create(prog='dot'format='svg'))
 
#spent to time
print("--- %s seconds ---" %(time.time() - start_time))
 
cs




reference

http://colah.github.io/posts/2015-08-Understanding-LSTMs/

keras.io

https://www.youtube.com/watch?v=SoNtAjxA3Jo


Comments