Recurrent Neural Networks (RNNs)
20 May 2023 #nlp
Sequence data를 분석하기 위한 딥러닝 모델 구조로, Rumelhart et al., 1986에 근간을 둔다. Deep neural networks (DNNs)와는 달리 hidden state node 간 연결을 통해 이전 시점의 정보를 현재 시점에서 사용할 수 있게 디자인되었다.
현재 시점 node인 $s_t$에 전 시점의 $s_{t-1}$ node에서 정보가 들어온다. 이 정보를 현재 시점의 입력인 $x_t$와 함께 받아 다음 node $s_{t+1}$로 전송될 값을 계산한다. 이 작업을 회귀적으로(recurrently) 진행한다.
Weight sharing
Weight $U$, $W$, $V$는 모든 시점에서 동일하다. 이것으로
- 학습에 필요한 weight 수를 줄일 수 있다.
- 데이터의 sequence 길이에 유연하다: 하나의 모델을 다른 길이의 sequence에 적용할 수 있다.
- 다른 길이의 sequence에 같은 weight값을 계속 사용함으로써 next token generation이 가능하다
RNN 계산
위 그림을 보면 hidden state $s_t$와 output $o_t$의 계산은 다음과 같다.
\[\begin{align*} s_t&=\tau(Ws^{t-1})+Ux^t \\ o_t&=softmax(Vs^t) \\ \end{align*}\]여기서 node 수가 $D$, $J$, $K$인 경우 각 변수의 차원은 아래와 같다.
\[x\in\mathbb{R}^D, s\in\mathbb{R}^J, o\in\mathbb{R}^K, U\in\mathbb{R}^{J\times D}, W\in\mathbb{R}^{J\times J}, U\in\mathbb{R}^{K\times J}\]Long-term dependency problem
hidden state 연산은 다음과 같이 표현할 수 있다.
\[s^t=\tau(Ux^t+W\tau(Ux^{t-1}+Ws^{t-2}))\]$s$가 tanh activation function 내에서 중첩되는 것을 볼 수 있다. 이렇게 되면
- feed forward 시 앞 단에서 입력된 정보가 점점 소실된다: tanh의 output은 $\tau(\cdot)\in(-1,1)$인데, 즉 tanh 연산의 중첩은 1보다 작은 값을 계속해서 곱하는 것과 같다. 이렇게 되면 앞에서 곱해진 값은 점점 작아진다.
- back-propagation 시 기울기 소실(gradient vanishing) 혹은 폭발(explosion)의 문제가 생길 수 있다: tanh 함수에 의해 기울기가 0에 가깝게 되거나 너무 커지는 경우가 생긴다. 작은 gradient는 더 작아지고, 큰 gradient는 더 커진다.
*Gradient vanishing: back-propagation 시 반영되는 gradient 값이 layer를 지날 수록 소실되는 문제
*Gradient explosion: gradient가 실제 값보다 증폭되어 loss 계산 시 정답과의 차이가 너무 커져, 업데이트에 과도하게 반영되는 문제
다양한 RNN 구조
입출력 형태에 따라 다양하게 RNN을 구성할 수 있다.
- One-to-One: hidden state가 1개인 모형, 기본적인 Neural network 구조
- One-to-Many: 하나의 입력값을 받아 순차적으로 여러 개의 값(한 sequence)을 생성
- Many-to-One: 한 sequence를 입력 받아 마지막에 하나의 값을 생성
- e.g. sentence classification
- Many-to-Many: 한 sequence를 입력 받아 latent represenation을 구한 후 이것을 통해 sequence를 출력
- e.g. machine translation
-
Many-to-Many: 한 sequence의 매 token을 입력 받는대로 대응하는 token을 출력하여 한 seqeunce를 생성