[Deep Learning] Recurrent Neural Network(RNN)
CS/Deep Learning

[Deep Learning] Recurrent Neural Network(RNN)

[Deep Learning] Recurrent Neural Network(RNN)

 

Recurrent Neural Network(순환 신경망, RNN)

기존의 Neural Network 알고리즘은 이미지처럼 고정된 크기의 입력을 다루는 데는 좋지만, 가변적인 크기의 데이터를 모델링하기에는 적합하지 않다. 이에 등장한 Neural Network가 RNN이다. RNN은 sequence data를 모델링 하기에 적합하다. 여기서 sequence data란 데이터 집합 내의 객체들이 어떤 순서를 가진 데이터를 의미한다. 예시로는 음성신호, 자연어 문장 등이 있다. RNN은 이러한 sequence data를 처리하기 위해 이전 출력값이 현재 결과에 영향을 미치는 구조로 설계한다. 즉, 이전 데이터에서 새로운 입력이 들어올 때마다 그 데이터들을 조금씩 수정한다. 입력을 모두 처리한 후 남은 수정된 데이터가 sequence data 전체를 요약하는 정보라고 할수 있다. 이는 사람이 sequence를 처리하는 방식과 비슷하다. 이 글을 읽을 때도 이전까지의 단어에 대한 기억을 바탕으로 새로운 단어를 이해하기 때문이다. 이러한 방식은 단어마다 계속 반복되기 때문에 순환적, 즉 recurrent라고 불린다. RNN은 이러한 반복을 통해 아무리 긴 sequence라도 처리할 수 있다.

 


RNN으로 할수 있는것

 RNN의 입력과 출력에 따라서 RNN으로 할수 있는 것이 달라진다. 예시를 살펴보자

  1. 고정크기 입력 & 고정크기 출력. 순환적인 부분이 없기 때문에 RNN이 아니다.
  2. 고정크기 입력 & sequence 출력. (예) 이미지를 입력해서 이미지에 대한 설명을 문장으로 출력하는 이미지 캡션 설정
  3. sequence 입력 & 고정크기 출력 (예) 문장을 입력해서 긍부정 정도를 출력하는 감성 분석기
  4. sequence 입력 & sequence 출력 (예) 영어를 한국으로 번역하는 자동 번역기
  5. 동기화된 sequence 입력 & sequence 출력 (예) 문장에서 다음에 나올 단어를 예측하는 언어 모델

 


RNN 구조

RNN 기본 구조

  • cell : 각각의 상태(state)에서의 RNN 모델을 의미. 위의 그림에서 A라고 적혀진 부분을 말한다.
  • Ht : t시간 스텝에서의 output vector
  • Xt : t시간 스텝에서의 input vector
  • state : cell에서 다음 cell로 가는 화살표를 통해 이전 출력값이 다음 statre에 영향을 미친다.
# hidden_size: output size
cell = tf.contrib.rnn.BasicRNNCell(num_units=hidden_size)

# output = Ht, _ in _states means will not use
# state = takes information to next cell
# x_data = input
output, _states = tf.nn.dynamic_rnn(cell, x_data, dtype=tf.float32)
  • hidden_size = output dimension, 즉 각 RNN cell 을 거치고 나온 output을 표현하는 벡터의 차원을 의미함 (hyperparameter)
import tensorflow as tf
import numpy as np
import pprint

pp = pprint.PrettyPrinter(indent=4)
sess = tf.InteractiveSession()

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(outputs.eval())

'''
result
array([[[-9.0053304, -0.03459153]]], dtype=float32)
'''
# Input : hello, output: ello
# 문자열 자체가 RNN의 input으로 들어가지 않음. 숫자로 바꿔서 들어감
import tensorflow as tf
import numpy as np
import pprint

pp = pprint.PrettyPrinter(indent=4)
sess = tf.InteractiveSession()

# One hot encoding for each char in 'hello'
h = [1, 0, 0, 0]
e = [0, 1, 0, 0]
l = [0, 0, 1, 0]
o = [0, 0, 0, 1]

hidden_size = 2
cell = tf.keras.layers.SimpleRNNCell(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())

'''
(1, 5, 4)
array([[[1., 0., 0., 0.],
        [0., 1., 0., 0.],
        [0., 0., 1., 0.],
        [0., 0., 1., 0.],
        [0., 0., 0., 1.]]], dtype=float32)
array([[[-0.28871554,  0.7363053 ],
        [ 0.67190826,  0.2598518 ],
        [-0.89049965, -0.81862164],
        [-0.54996073,  0.5126091 ],
        [ 0.45227858,  0.16163607]]], dtype=float32)
'''

 

  • shape = (3, 5, 4) = (batch size, sequence length, vector size)

 

 

Reference

 

https://dreamgonfly.github.io/rnn/2017/09/04/understanding-rnn.html

 

 

 

 

728x90
반응형