Ordinary day

RNN Tensorflow Example 본문

Study/ML 실습 - Tensorflow

RNN Tensorflow Example

minung14 2017. 1. 8. 20:21

모두를 위한 머신러닝 lab12: TensorFlow에서 RNN 구현

실습 강의를 토대로 정리한 것입니다.


1. 필요한 라이브러리 임포트

#-*- coding: utf-8 -*-
import tensorflow as tf
from tensorflow.models.rnn import rnn, rnn_cell
import numpy as np

2. 직접 dictionary 정의

나는 여기서 ‘anaconda’ 라는 단어로 테스트를 했다.
anaconda 는 a, n, c, o, d 총 다섯개의 단어로 이루어져 있으며,
각 단어의 벡터를 직접 정의했다. (one hot vector)

char_rdic = ['a', 'n', 'c', 'o', 'd']
char_dic = {w: i for i, w in enumerate(char_rdic)}
x_data = np.array([[1,0,0,0,0], [0,1,0,0,0], [0,0,1,0,0], [0,0,0,1,0], [0,0,0,0,1]], dtype='f')
sample = [char_dic[c] for c in "anaconda"]

3. Configuration

vocab_size는 dictionary 크기와 동일하므로 5
time_step_size 도 vocab_size와 동일해야 한것 같다..
임의의 수로 해봤는데 에러나....

char_vocab_size = len(char_dic)
rnn_size = char_vocab_size
time_step_size = 5
batch_size = 1

4. RNN Model

rnn_cell은 원하는 것을 사용하면 되고, 들어가는 파라미터만 정의해주면 됨 -> output size

ex) BasicRNNCell, BasicLSTMCell, GRUCell 등..

초기 state값은 0 (0으로 패딩)
갖고있는 데이터(x_data)를 time_step 크기로 분할 => X_split

아….이래서 위에서 time_step_size를 x_data 배열 크기만큼 준거였다…

rnn_cell이 몇 개가 필요한가는 rnn이 실행될 때 결정나는 부분!
그렇다면 rnn은 어떻게 실행시키는가?

rnn.rnn(rnn_cell, X_split, state) 으로 rnn_cell 실행
이 부분에서 X_split이 들어가는데 입력 array 벡터가 몇 개 들어가는지 결정됨

마지막에 출력되는 state 값을 training할 때 사용하기 위해 state값도 input으로 넣어

rnn_cell = rnn_cell.BasicRNNCell(rnn_size)
state = tf.zeros([batch_size, rnn_cell.state_size])
X_split = tf.split(0, time_step_size, x_data)
outputs, state = rnn.rnn(rnn_cell, X_split, state)

5. Cost

logits: 예측값, targets: 실제값, weigths: default 1
loss를 계산하는 sequence_loss_by_example 함수를 사용하기 위해서는 각 파라미터를 맞춰서 넘겨야한다.

logits는 2D shape [batch_size * num_decoder]
targets는 1D int32
weights는 1D float
그래서 reshape 함수를 사용하여 각각을 변환

세개의 dimension 도 동일하게 맞춰줘야함
처음에는 아무것도 모르고 예제 코드 그대로
targets = tf.reshape(sample[1:], [-1]) 로 썼다가 dimension이 서로 안맞다고 계속 에러..
그래서 확인을 해봤더니 targets는 7차원, 나머지 둘은 5차원이었다

dictionary에는 a, n, c, o, d 다섯 개의 단어
time_step_size도 위에서 5로 정의했고, batch 크기는 1로 정의했으니 결국 5차원으로 맞춰야 하는데
targets = tf.reshape(sample[1:], [-1]) 로 해버리면 ‘anaconda’에서 ‘a’를 제외한 ‘naconda’가 되어버리므로 7차원이 되는 것
따라서 targets = tf.reshape(sample[3:], [-1]) 으로 주고 ‘conda’ 가 output으로 나오도록 수정함

강의에서 targets에서 [-1]은 예제는 하나밖에 없어서 필요없으니까 [-1]로 주라는데...모르겠다...
weight는 그냥 1로 줘…

logits = tf.reshape(tf.concat(1, outputs), [-1, rnn_size])
targets = tf.reshape(sample[3:], [-1])
weights = tf.ones([time_step_size*batch_size])

print (logits)
print (targets)
print (weights)
Tensor("Reshape:0", shape=(5, 5), dtype=float32)
Tensor("Reshape_1:0", shape=(5,), dtype=int32)
Tensor("ones:0", shape=(5,), dtype=float32)

위에서 정의한 것들을 다 넣고 loss를 구한 후,
loss를 모두 더해서 batch 크기로 나눈 값을 cost로 정의.
Optimization을 할 때 Optimizer는 원하는 것 사용하기

여기서 RMSPropOptimizer의 첫번째 파라미터는 learning rate, 두번째 파라미터는 decay

loss = tf.nn.seq2seq.sequence_loss_by_example([logits], [targets], [weights])
cost = tf.reduce_sum(loss)/batch_size
train_op = tf.train.RMSPropOptimizer(0.01, 0.9).minimize(cost)

6. Train & Prediction

이제 트레이닝을 하면서 나오는 값을 찍어보자!
먼저 세션을 생성하고 initialize를 한다.
100번 반복하면서 train_op를 실행하는데, 이때 결과값을 출력
어차피 예측값(logits) 하나만 보면 되니까 제일 큰 값 하나만 출력 => arg_max(logits,1)

with tf.Session() as sess:
    tf.initialize_all_variables().run()
    for i in range(100):
        sess.run(train_op)
        result = sess.run(tf.arg_max(logits,1))
        print(result, [char_rdic[t] for t in result])
(array([4, 0, 1, 4, 0]), ['d', 'a', 'n', 'd', 'a'])
(array([4, 0, 1, 4, 0]), ['d', 'a', 'n', 'd', 'a'])
(array([4, 0, 1, 4, 0]), ['d', 'a', 'n', 'd', 'a'])
(array([4, 0, 1, 4, 0]), ['d', 'a', 'n', 'd', 'a'])
(array([4, 0, 1, 4, 0]), ['d', 'a', 'n', 'd', 'a'])
(array([4, 0, 1, 4, 0]), ['d', 'a', 'n', 'd', 'a'])
(array([2, 0, 1, 4, 0]), ['c', 'a', 'n', 'd', 'a'])
(array([2, 0, 1, 4, 0]), ['c', 'a', 'n', 'd', 'a'])
(array([2, 0, 1, 4, 0]), ['c', 'a', 'n', 'd', 'a'])
(array([2, 0, 1, 4, 0]), ['c', 'a', 'n', 'd', 'a'])
(array([2, 0, 1, 4, 0]), ['c', 'a', 'n', 'd', 'a'])
(array([2, 0, 1, 4, 0]), ['c', 'a', 'n', 'd', 'a'])
(array([2, 0, 1, 4, 0]), ['c', 'a', 'n', 'd', 'a'])
(array([2, 0, 1, 4, 0]), ['c', 'a', 'n', 'd', 'a'])
(array([2, 0, 1, 4, 0]), ['c', 'a', 'n', 'd', 'a'])
(array([2, 0, 1, 4, 0]), ['c', 'a', 'n', 'd', 'a'])
(array([2, 0, 1, 4, 0]), ['c', 'a', 'n', 'd', 'a'])
(array([2, 0, 1, 4, 0]), ['c', 'a', 'n', 'd', 'a'])
(array([2, 0, 1, 4, 0]), ['c', 'a', 'n', 'd', 'a'])
(array([2, 0, 1, 4, 0]), ['c', 'a', 'n', 'd', 'a'])
(array([2, 0, 1, 4, 0]), ['c', 'a', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])
(array([2, 3, 1, 4, 0]), ['c', 'o', 'n', 'd', 'a'])

여기서는 그냥 간단하게 rnn cell 하나로 돌렸는데
여러 층을 쌓고 싶다면(deep하게..)

one_cell = rnn_cell.BasicRNNCell(rnn_size)
rnn_cell = rnn_cell.MultiRNNCell([one_cell] * depth)

이런 식으로 하나의 셀을 만든 후에 이 셀을 depth 크기만큼 MultiRNNCell 함수를 이용해서 여러 단 쌓으면 된다!

'Study > ML 실습 - Tensorflow' 카테고리의 다른 글

CNN Tensorflow Example  (0) 2017.01.03
Comments