Deep Learning study

Recurrent Neural Network(RNN)을 사용해보자 ! 본문

AI/Tensorflow

Recurrent Neural Network(RNN)을 사용해보자 !

HwaniL.choi 2018. 1. 9. 17:46
반응형

https://www.youtube.com/watch?v=39_P23TqUnw&index=43&list=PLlMkM4tgfjnLSOjrEJN31gZATbcj_MpUm


RNN은 NN의 꽃 이라고 하신다. 이유는 현재 가장 많은 분야에서 쓰이고 가장 활발한 연구가 이루어지고 있는 분야이기 때문이 아닐까 

또 그럴수 밖에 없는 이유가, 우리가 가장 많이 쓰고 있고 가장많이 활용하는 것 이라고 하면 '언어'이기 때문에 그에대한 연구를 한다면 많은 발전을 이룰 수 있어서가 아닐까... 생각해 본다 ㅎㅎ


여튼 이론적인 부분은 나중에 다시 쓰도록하고, Tensorflow 예제코드를 보며 복습해보자


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
import tensorflow as tf
import numpy as np
 
hidden_size = 5
sequence_length = 6
batch_size = 1
input_dim = 5
 
 
idx2char = ['h''i''e''l''o']
x_data = [[0,1,0,2,3,3]]
x_one_hot = [[[1,0,0,0,0],
              [0,1,0,0,0],
              [1,0,0,0,0],
              [0,0,1,0,0],
              [0,0,0,1,0],
              [0,0,0,1,0]]]
 
y_data = [[1,0,2,3,3,4]]
= tf.placeholder(tf.float32, [None, sequence_length, input_dim])#X one-hot
= tf.placeholder(tf.int32, [None, sequence_length])#Y Label
 
cell = tf.contrib.rnn.BasicLSTMCell(num_units=hidden_size, state_is_tuple=True)
initial_state = cell.zero_state(batch_size, tf.float32)
outputs, _states = tf.nn.dynamic_rnn(cell, X, initial_state = initial_state, dtype = tf.float32)
 
weights = tf.ones([batch_size, sequence_length])
 
sequence_loss = tf.contrib.seq2seq.sequence_loss(logits = outputs, targets = Y, weights= weights)
loss = tf.reduce_mean(sequence_loss)
train = tf.train.AdamOptimizer(learning_rate=0.1).minimize(loss)
 
prediction = tf.argmax(outputs, axis=2)
 
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for i in range(2000):
        l, _ = sess.run([loss, train], feed_dict={X: x_one_hot, Y: y_data})
        result = sess.run(prediction, feed_dict={X: x_one_hot})
        print(i, "loss:", l , "prediction: ", result, "true Y: ", y_data)
 
        result_str = [idx2char[c] for c in np.squeeze(result)]
        print("\tPrediction str: "''.join(result_str))
 
cs


코드의 전반적인 내용을 보면 학습시키고자 하는 문자열은 'hihello' 이다. 

그중에 먼저 unique한 알파벳 만을 추려낸다. 그것이 idx2char이다. idx2char은 각 알파벳에 인덱스를 부여하는데, 그인덱스를 주면 그에 해당하는 알파벳을 반환해 주도록 만든 것 이다. 그런 의미로 xdata를 해석해보면 'hihell'이 된다. 


x_one_hot은 x_data 를 one hot encoding한 것인데 역시 차례대로 h,i,h,e,l,l을 의미하고 있다.

y_data는 예측하려는 문자열로 'ihello'를 나타낸다.


X 에는 x_data가 들어갈 placeholder이고 차례대로 [batch_size, sequence_length, input_dim] 이다.

Y 에는 y_data가 들어갈 placeholder이고 차례대로 [batch_size, sequence_length] 이다.

여기서는 batch_size가 1 이지만 None로 준 것은 사실 batch를 몇개를 받아와도 상관없어서 그렇게 했다고 하신다.

sequence_length는 one hot의 개수로 6이 되고 input_dim은 x 벡터의 차원으로 5가 된다.


그 다음엔 cell을 만들어준다. cell에는 output크기에 맞는 값을 적어주는데 hidden_size가 그것을 의미하니 설정해 준다. cell을 dynamic rnn을 적용시킨다. 그뒤로는 비슷한데 , weights를 주고 손실함수를 설정한다. 

RNN에서는 손실함수를 다른것을 쓰게 되는데 이전에 쓰던 함수(corss entropy 등..)를 쓰게되면 복잡해지는 문제가 있어서 라고 하셨다. 이유는 정확히 모르겠다. 

sequence_loss 함수는 예측값(prediction)과 y_data(Label)을 비교해 손실값을 계산해 낸다. 여기서 예측값은 dynamic_rnn에서 나온 output값이 된다. (사실 이 output을 바로 logit으로 사용하면 좋지 않지만 그건 다음에 할 내용이라고 하신다)


뒤로는 똑같이  Session을 열고 학습을 시켜주고 그결과를 보기위해 출력을 해주도록 했다


2000번 돌렸는데 이미 100번도 안됐는데 정확한 값이 나오기 시작했다. 


여튼 점점 loss가 줄어들면서 예측하려고하는 ihello가 나왔다.!

반응형
Comments