[NLP] Recurrent Neural Network (RNN)
🧚🏻♀️참고
이 포스트는 Boostcourse의 ‘자연어처리의 모든 것’을 듣고 정리한 포스트입니다.
| Recurrent Neural Network (RNN)
Recurrent Neural Network (RNN)
Recurrent Neural Network(RNN)은 시퀀스 데이터를 활용하는 신경망이다. 매 time step마다 동일한 모듈(그림에서의 A)을 사용하며 이번 모듈의 출력이 다음 모듈의 입력이 되는 재귀적인 형태를 띈다.
입력으로는 현재 입력 \({x_t}\)와 이전 state에서 계산된 hidden state vector \({h_{t-1}}\)을 받으며, hidden state vector \({h_t}\)를 출력한다. \({h_t}\)의 계산 과정을 수식으로 표현하면 아래와 같다. 이때 \(f_W\)는 RNN 함수이고 RNN에 필요한 선형 변환 행렬을 결정하는 파라미터 \(W\)를 가진다. 그리고 파라미터와 함수 모두 매 time step에 대해 같다는 특징을 지닌다.
\[\begin{align} h_t & = f_W(h_{t-1}, x_t)\\ & = tanh(W_{hh}h_{t-1} + W_{xh}x_t) \\ y_t & = W_{hy}h_t \end{align}\]\({h_t}\)는 다음 state에 입력으로 전달되기도 하지만 예측 결과(output) \(y_t\)을 연산하는 데에도 사용된다. 예측 결과를 계산하는 시점은 태스크에 따라 달라진다. 예를 들어, 품사 태깅(POS tagging)에서는 매 time step마다 연산하고, 감정 분석(sentiment analysis)에서는 마지막에만 연산을 수행한다.
RNN types
입출력이 하나의 시점으로 이루어졌는지 또는 여러 시점에 걸쳐있는지에 따라 RNN을 분류하였다.
Type | Input | Output | Additional Explanation | Example of Tasks |
---|---|---|---|---|
one-to-one | 1 time step | 1 time step | - | - |
one-to-many | 1 time step | sequence (multi time steps) |
입력이 없는 시점에 대해서는 입력과 같은 크기지만 모두 0으로 채워진 벡터가 주어진다. |
image captioning |
many-to-one | sequence (multi time steps) |
1 time step | 마지막 step에서만 결과를 계산 및 출력한다. | sentiment analysis |
many-to-many (1) | sequence (multi time steps) |
sequence (multi time steps) |
입력으로 주어진 문장을 먼저 다 읽은 후 결과를 출력한다. | machine translation |
many-to-many (2) | sequence (multi time steps) |
sequence (multi time steps) |
입력이 주어질 때마다 결과를 출력한다. | POS tagging |
RNN을 활용한 언어 모델 예시
주어진 언어 모델은 글자(character) 단위의 언어 모델이고, ‘hello’를 학습한다고 가정해보자.
가장 먼저 Vocabulary를 구축하고, 각 글자를 one-hot vector로 표현한다.
- Vocabulary : [‘h’, ‘e’, ‘l’, ‘o’]
- one-hot vectors : ‘h’ [1,0,0,0], ‘e’ [0,1,0,0], ‘l’ [0,0,1,0], ‘o’ [0,0,0,1]
🐨잠깐
학습 과정에 들어가기 앞서, 총 세가지의 파라미터가 등장하는데 모두 \(W_{ab} \leftarrow\) 이런 형태로 표현이 된다.
여기에서 \(W_{ab}\)는 \(a\)를 \(b\)로 변환해주는 파라미터로 생각하면 된다.
‘h’가 현재 시점 \(t\)의 입력이라고 하자. 그렇다면 \(x_t\)는 ‘h’의 one-hot vector, [1,0,0,0]이다. \(h_t\)를 계산하기 위하여 \(x_t\)와 \({h_{t-1}}\)를 각각 \({W_{xh}, W_{hh}}\)와 곱한다. 계산된 두 값을 더하고, \(tanh\) 함수를 통과시키면, \(h_t\)가 생성된다. 우리는 입력되는 글자마다 다음 글자를 예측해야한다. 그러므로 모든 시점에서 output \(y_t\)을 계산하고, softmax 함수도 적용한다. 현재 입력이 ‘h’이기 때문에, 다음 글자로는 ‘e’가 예측되어야 한다. 즉 계산을 마친 벡터가 [0,1,0,0]에 가장 가까워질 수 있도록 하는 게 이 과정의 목표이다. 그 다음으로는 ‘e’를 입력으로 하고, ‘l’이 예측될 수 있도록 학습을 진행한다. 모든 글자에 대해 이 과정을 반복하면 학습이 끝난다.
🐨참고
테스트를 진행할 때에는 학습을 할 때와 달리 첫번째 글자만 입력하고 예측된 글자들을 다음 입력으로 하여 그 과정을 반복한다.
Backpropagation through time (BPTT)
다른 모델들과 마찬가지로 RNN에서도 backpropagation을 통해 파라미터 \(W_{hh}, W_{xh}, W_{hy}\)가 학습된다. 하지만 모든 시퀀스에 대한 loss를 계산한 후 backpropagation을 진행한다면 긴 시퀀스에 대해선 memory 문제가 발생할 수 있다. 이를 방지하기 위해 RNN은 시퀀스를 잘라 전체가 아닌 일부 시퀀스에 대해 backpropagation을 수행한다.
RNN의 한계
- gradient vanishing/exploding
RNN에서는 매 time step마다 같은 파라미터가 곱해진다. 이로 인해 역전파를 수행할 때 gradient가 너무 작아 없어지거나 반대로 너무 커져서 업데이트가 이루어지지 않는 문제가 발생할 수 있다. (이해가 안된다면 고등학교 때 배운 등비수열을 생각해보도록 하자.) - long-term dependency
gradient가 0이 되어(=gradient vanishing) 더 이상 업데이트가 되지 않는다면 왜 문제냐. 앞쪽의 정보가 멀리 뒷쪽까지 전달되지 못할 수 있다. 그리고 그게 바로 long-term dependency 문제이다.
댓글남기기