티스토리 뷰

 

 

 

 

RNN in TensorFlow

 

1단계

 
 
 

rnn을 구현 할 때에는 2가지를 고려해야 한다.
이번 출력이 다음번 cell로 연결되기 때문에 어떤 형태의 cell을 만들 것인가 고민해야 한다.
대표적인 것들로 rnn, lstm, gru 같은 것들이 있다. 그리고 cell을 만들때 가장 중요한 점은 cell에서 나가는 아웃풋(출력,ht)의 크기가 얼마일지 결정해 주는 것이다.
두번째로는 셀을 만든 것을 실제로 구동시켜서 입력을 주고 출력값을 뽑아내야 하는데 드라이버 or 또는 다른 형태의 함수(레퍼)라고 볼수도 있는데 보통 tf.nn.dynamic_rnn을 사용한다. 우리가 만든 셀과 입력 데이터를 넣어주면 output 출력과 states 출력 값을 준다.
이렇게 나눈 이유는 셀을 생성하는 부분과 구동시켜주는 부분을 나눠줌으로써 우리가 원하는 형태의 셀을 마음대로 바꾸도록 하기 위함이다. 예를들어 처음에 BasicRNNCell을 만들었는데 성능이 안나와 BasicLSTMCell으로 바꾸고자 할 때, 구동하는 부분은 그대로 두고 셀을 생성하는 부분에서만 바꿔주면 된다.

 

그러면 실제 x 데이터를 넣어보고 어떤 값이 나오는지 관찰해보자.

 
 
 

인풋 디멘션은 4라는 것에 초점을 맞춰보자. 그러면 아웃풋 디멘션은 어떻게 될까? cell을 만들때 hidden_size를 정한다고 했다. 이 히든 사이즈를 무엇으로 정했느냐에 따라 아웃풋 디멘션이 정해진다. 예를들어 히든 사이즈가 1라고 하면 아웃풋 디멘션은 3가 된다.

 

실제 코드에서 입력을 줬을때 출력이 어떻게 나오는지 관찰해보자.

 
[In]
# One cell RNN input_dim (4) -> output_dim (2)
hidden_size = 2
cell = tf.contrib.rnn.BasicLSTMCell(num_units=hidden_size)

x_data = np.array([[[1, 0, 0, 0]]], dtype=np.float32)
outputs, _states = tf.nn.dynamic_rnn(cell, x_data, dtype=tf.float32)

sess.run(tf.global_variables_initializer())
pp.pprint(outpus.eval())
 
[Out] 
array([[[-0.42409304, 0.64651132]]])
 

2단계

 

sequence_length는 입력데이터의 모양에 따라 결정된다.

 
 
 

실제 코드에서 입력을 줬을때 출력이 어떻게 나오는지 관찰해보자.

 
[In]
# One cell RNN input_dim (4) -> output_dim (2). sequence:5
hidden_size = 2
cell = tf.contrib.rnn.BasicLSTMCell(num_units=hidden_size)
x_data = np.array([[h, e, l, l, o]], dtype=np.float32)
print(x_data.shape)
pp.pprint(x_data)
outputs, states = tf.nn.dynamic_rnn(cell, x_data, dtype=tf.float32)
sess.run(tf.global_variables_initializer())
pp.pprint(outputs.eval())

# One hot encoding
h = [1, 0, 0, 0]
e = [0, 1, 0, 0]
l = [0, 0, 1, 0]
l = [0, 0, 0, 1]
 
[Out]
X_data=array
  ([[[1., 0., 0., 0.],
     [0., 1., 0., 0.],
     [0., 0., 1., 0.],
     [0., 0., 0., 1.]]], dtype=float32)
Outputs = array
  ([[[0.19709368, 0.24918222],
     [-0.11721198, 0.1784237],
     [-0.35297349, -0.66278851],
     [-0.70915914, -0.58334434],
     [-0.38886023, 0.47304463]]], dtype=float32)
 

3단계

 

배치 사이즈를 정해서 데이터를 여러개 줄 수 있다. 시퀀스 길이와 마찬가지로 배치 사이즈의 크기는 입력과 출력이 같다.

 
 
 

실제 코드에서 입력을 줬을때 출력이 어떻게 나오는지 관찰해보자.`

 
[In]
# One cell RNN input_dim (4) -> output_dim (2). sequence: 5, batch: 3
# 3 batches 'hello', 'eolll', 'lleel'
x_data = np.array([[h, e, l, l, o],
                   [e, o, l, l, l],
                   [l, l, e, e, l]], dtype=np.float32)
pp.pprint(x_data)

cell = rnn.BasicLSTMCell(num_units=2, state_is_tuple=True)
outputs, _states = tf.nn.dynamic_rnn(cell, x_data, dtype=tf.float32)
sess.run(tf.global_variables_initializer())
pp.pprint(outputs.eval())


array([[[1., 0., 0., 0.],
        [0., 1., 0., 0.],
        [0., 0., 1., 0.],
        [0., 0., 1., 0.],
        [0., 0., 0., 1.]],

       [[0., 1., 0., 0.],
        [0., 0., 0., 1.],
        [0., 0., 1., 0.],
        [0., 0., 1., 0.],
        [0., 0., 1., 0.]],

       [[0., 0., 1., 0.],
        [0., 0., 1., 0.],
        [0., 1., 0., 0.],
        [0., 1., 0., 0.],
        [0., 0., 1., 0.]]], dtype=float32)
 
[Out]
array([[[ 0.05147979, -0.12499733],
    [-0.03096316,  0.0606184 ],
    [ 0.07608285, -0.03678102],
    [ 0.13522112, -0.0920362 ],
    [ 0.0235186 ,  0.02936662]],

   [[-0.08701393,  0.11020429],
    [-0.10396396,  0.17681563],
    [ 0.04137699,  0.01251686],
    [ 0.11497379, -0.06123064],
    [ 0.15778907, -0.10736831]],

   [[ 0.09156778, -0.06834684],
    [ 0.14449464, -0.11151826],
    [ 0.0351325 ,  0.04766054],
    [-0.06127799,  0.13465708],
    [ 0.06125095,  0.00202556]]], dtype=float32)

'beginner > 파이썬 딥러닝 기초' 카테고리의 다른 글

Long Sequence RNN  (0) 2019.05.16
RNN-Hi Hello  (0) 2019.05.15
NN의 꽃 RNN 이야기  (0) 2019.05.13
Class, tf.layers, Ensemble (MNIST 99.5%)  (0) 2019.05.13
TensorFlow로 MNIST 99% 구현하기  (0) 2019.05.13
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
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
글 보관함