본문 바로가기
Deep Learning

RNN(Recurrent Neural Network) 순환 신경망

by xangmin 2022. 8. 19.
반응형

RNN(Recurrent Neural Network)은 입력과 출력을 시퀀스 단위로 처리하는 반복적인 데이터, 순차적인 데이터를 학습하는데 특화된 시퀀스(Sequence) 모델입니다. 번역기를 생각해보면 입력은 번역하고자 하는 단어의 시퀀스인 문장이다. 출력에 해당되는 번역된 문장 또한 단어의 시퀀스이다. 이와 같이 시퀀스들을 처리하기 위해 고안된 모델들을 시퀀스 모델이라고 한다. 그 중 RNN은 가장 기본적인 인공 신경망 시퀀스 모델이다.

 

RNN 구조

기존의 인공 신경망은 이와 같이 각 층의 뉴런이 연결되어 있는 구조이다.

 

이에 추가적으로 RNN은 아래와 같은 방식을 사용한다.

 

이렇게 과거 자신의 정보(가중치)를 기억하고 이를 학습에 반영한다. 위의 layer를 한개의 box로 취급하여 단순화 시키면 다음 그림과 같다.

 

 

이런 RNN의 이전 작업을 현재 작업과 연결할 수 있다는 것이 큰 의미를 갖는다.

 

RNN 학습 방법

인공 신경망과 다르게 RNN은 순환 구조이므로 hidden layer의 데이터를 저장하고 있어서 좀더 직관적으로 아래와 같이 layer가 펼쳐져있다고 생각할 수 도 있다.

 

 

일반적인 인공신경망과 비슷하게 Gradient Descent backpropagation을 이용해 학습을 하는데 시간의 흐름에 따른 작업이기 때문에 backpropagation을 확장한 BPTT(Back-Propagation Through Time)을 사용해서 학습을 한다.

 

시간을 거슬러 올라가면서 backpropagation이 적용되는 구조이고 이것으로 인해 문제가 발생한다. 바로 기울기 소실(Gradient Vanishing) 문제이다.

 

RNN이 시간을 거슬러 올라가면서 학습을 하는데 과거로 올라가면 올라갈수록 gradient 값이 계산이 잘 되지 않는다. 그 이유는 gradient 계산 곱셈 연산으로 이루어져 있기 때문이다. 1보다 큰 값들을 계속해서 곱하면 발산하겠지만 이것은 최대 값을 지정해주면 해결된다. 1보다 작은 값들을 계속해서 곱하면 0으로 수렴해 사라져 버린다. gradient가 사라져 버리는 것 의미있는 값을 전달할 수 없다는 것이므로 문제가 된다.

 

RNN 사용 예시

Keras에서 RNN을 사용한 예시이다. 다음에 나올 숫자를 예측하고자 한다. 

예를들어, [1, 2, 3]이 입력되었을 때 다음 나올 값은 4이다. [4, 5, 6]이 입력되었을 때 다음 나올 값은 7이다.

import numpy as np
import keras
import tensorflow as tf
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense, SimpleRNN

# 1. 데이터
x = np.array([[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]])
y = np.array([4, 5, 6, 7])

print(f'x shape : {x.shape}')
print(f'y shape : {y.shape}')

#  x  y
# 123 4
# 234 5
# 345 6
# 456 7


print(x)
print('-------x reshape-----------')
x = x.reshape((x.shape[0], x.shape[1], 1))
print(f'x shape : {x.shape}')
print(x)
#  x        y
# [1][2][3] 4
# .....


# 2. 모델 구성
model = Sequential()
model.add(SimpleRNN(units=10, activation = "relu", input_shape=(3,1)))
model.add(Dense(5))
model.add(Dense(1))

model.summary()

model.compile(optimizer='adam', loss='mse')
model.fit(x, y, epochs=100, batch_size=1)

x_input = np.array([6, 7, 8])
x_input = x_input.reshape(1, 3, 1)

yhat = model.predict(x_input)
print(yhat)

 

프로그램을 실행하게 되면 모델의 구조는 다음과 같다.

 

정답은 9이고 최종 예측 값은 9.55가 나오는 것을 확인할 수 있다.

 

반응형

댓글