순환 신경망 (RNN, Recurrent Neural Network)에 대한 정리
RNN (Recurrent Neural Network)
RNN 개요
- 순환 신경망이라고하며, 음성이나 문자처럼 순차적으로 나타나는 시계열 데이터(Sequence data)에 적합한 모델
- 인접한 다음 노드로만 계산되는 것이 아니라 자기자신에게 혹은 그 전 노드로 계산되는 구조
RNN 구조
- RNN의 기본 구조로써, 시계열 데이터 ()가 RNN 계층에 입력되고, ()가 출력되는 것을 표현함
- 그림을 보면 출력층이 두개로 분기 되어 하나는 그대로 출력, 하나는 자기 자신에 입력됨(순환)
- 시계열 데이터를 시간에 따라 펼쳐서 보면 위와 같은 그림으로 나타낼 수 있다(같은 아키텍처임)
- 시계열 데이터의 길이에 관계없이 입력과 출력을 받아들일 수 있기에, 유연하게 구조를 만들 수 있는 장점이 있음
RNN 연산
기본 RNN (Vanilla RNN) 연산
- RNN 은 라는 상태를 가지고 있으며, 아래 수식과 같은 형태로 상태가 갱신되는 구조
-
직전 )에 대한 가중치 , 입력값()에 대한 가중치 가 사용됨
-
다음 시점으로 넘겨줄 정보를 hidden state()라고 하고, 다음 시점의 정보는 전 시점의 정보만이 아니라 이전까지의 정보들을 모두 가지고 있을 것임
-
전 시점의 과 현 시점의 에 함수 를 취하여 현 시점의 를 구하고, 현 시점의 로 현 시점의 출력값 를 구함
-
RNN에서 activation function으로는 일반적으로
tanh
가 사용됨 -
초기 hidden state는 랜던값을 활용
RNN: Many to One
- 시계열 데이터에 대한 하나의 출력
- 최종 hidden state에서만 결과 값이 나오며, 감정분석 등의 분야에 사용됨
RNN: One to Many
- 하나의 입력에 대한 여러 출력
- Image captioning 과 같은 하나의 이미지에 대한 여러 단어를 출력하는 모델 등
- Input 이미지는 주로 CNN 등으로 만들어낸 Feature가 됨
RNN: Many to Many
- 여러 입력에 대한 여러 출력
- many to one과 one to many를 조합해서 사용할 수도 있다(Seq2Seq Model)
Sequence to Sequence
- 주로 기계번역(machine translation)에서 사용
- Mony to one 과 ono to many의 조합
- Encoder + Decoder
- 예를 들어, Encoder는 영어문장과 같은 가변입력을 받아들여 final hidden state에 전체 sentence를 요약합니다.
- 여기서 Decoder는 이 sentence를 받아 다른 언어로 번역된 문장을 출력할 수 있다.
- END 와 같은 임의에 토큰을 지정하여 출력 길이를 조절할 수 있으며, 입력과 같은 경우 0을 집어넣는 경우가 많다.
RNN 예제 : Character-level Language Model
- 어떤 일련의 글자가 입력되었을 때, 다음에 나오는 글자를 예측하는 모델
- ‘hell’ 을 넣으면, ‘o’를 반환하게 하여 결과적으로 ‘hello’를 출력하기 위함
- 우학습데이터의 글자는 ‘h’, ‘e’, ‘l’, ‘o’ 네 개를 one-hot-vector로 바꾸면 각각 [1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]이 됩니다.
RNN 역전파 (Backpropagation)
순전파 그래프
역전파 그래프
BPTT(Backpropagation Through Time)
- 매 time step마다 입력이 주어진다.
- 이전 time step에서 오는 hidden state와 현재 time step에서 온 입력을 가지고 현재 time step에서 출력할 hidden state를 구한다.
- 구한 hidden state를 가지고 현재 time step의 output을 계산한다.
- 예측한 output과 ground truth 간의 loss를 구하고, 모든 time step에 관해 이 loss를 줄이는 방향으로 학습한다.
- 순전파를 따라 최종 출력되는 결과는
- 최종 Loss에 대한 의 그래디언트()가 역전파 연산에서 가장 먼저 등장하고, 이를 편의상 라고 표기함
- 는 덧셈 그래프를 타고 양방향에 모두 그대로 분배됨
- 는 흘러들어온 그래디언트 에 로컬 그래디언트 를 곱해 구함
- 는 흘러들어온 그래디언트 에 를 곱한 값
- 는 흘러들어온 그래디언트 에 로컬 그래디언트인 를 곱해 구함
- 나머지도 동일한 방식으로 구할 수 있다
- 위 그림에 주의할 필요가 있는데, RNN은 히든 노드가 순환 구조를 띄는 신경망이므로, 를 만들 때 이 반영됨
- 위 그림은 은 시점의 Loss에서 흘러들어온 그래디언트인 뿐 아니라 별표에 해당하는 그래디언트 또한 더해져 동시에 반영된다는 뜻
Truncated Backpropagation Through Time
- 일반적으로 RNN은 모든 출력을 구하면서 학습을 진행하면 너무 느립니다(한정된 자원의 문제). 이러한 문제를 해결하기 위해서 배치별로 나누어서 학습을 진행하는 방법을 사용함.
- 배치 크기만큼에 loss를 보고 학습을 진행하는 방식
- 아래 그림은 총 길이가 6이고 Truncated batch의 크기가 3인 경우
RNN 한계점
- RNN은 출력과 먼 위치에 있는 정보를 기억할 수 없다
- 즉 RNN은 최근의 정보일수록 더 예측에 반영할 수 있게 설계되어 있다 (RNN은 Long-Term Dependencies가 없다)
- 이를 해결한 것이 LSTM(Long Short-Term Memory)
- 곱셈이 많이 이루어 지면서 값이 1보다 크거나 1보다 작은 경우 각각 Exploding과 Vanishing gradients 문제를 가짐
- Exploding gradients 문제는 gradient clipping 기법을 써서 해결 가능
- Vanishing gradients 문제는 RNN 아키텍처를 바꿔서 해결할 수 있음