네이버 부스트캠프/LEVEL-2

[부스트캠프][WK06 / Day26] RNN, LSTM, and GRU 1

1. 강의 내용

Recurrent Neural Network and Language Modeling (주재걸 교수님)

1) Basics of Recurrent Neural Networks (RNNs)


RNN은 위와 같은 구조를 가지고 있으며 시퀀스데이터가 입력 또는 출력으로 주어진 상황에서 각 time step에서 들어오는 입력벡터 $X_t$와 이전 time step의 RNN 모델에서 계산한 hidden state vector $h_{t-1}$을 입력으로 받아 $h_t$를 출력으로 내보냅니다. 여기서 중요한 사실은 동일한 파라미터를 가지고 있는 모델을 매 time step에서 동일하게 사용한다는 사실입니다.

 

해당 수식은 아래와 같이 표현됩니다.


점화식(recurrence formula)은 이웃하는 두개의 항 사이에 성립하는 관계를 나타낸 식으로 위의 식을 보면 $h_t$에 대한 점화식이라고 할 수 있습니다.


위의 수식 중 $W_{hh}h_{t-1}+W_{xh}x_t$를 아래와 같이 계산할 수 있습니다.


위에서 나온 결과 $W_{hh}h_{t-1}+W_{xh}x_t$를 비선형변화인 $tanh$를 통과시켜줌으로써 현재 time step의 hidden state인 $h_t$를 구합니다. 해당 time step t에서 예측값이 필요한 경우, $h_t$를 입력으로 하여 추가적인 output layer를 만들고 output layer에 선형변환 matrix인 $W_{hy}$를 곱합으로써 최종 output $y_t$를 만들어 줍니다.

 

Binary classification을 할 때, output vector는 1차원이 되고, 이 때 sigmoid를 활용해서 확률값을 예측값으로 계산할 수 있습니다. Multi classification의 경우 $y_t$가 클래스 개수만큼의 차원을 가진 벡터가 되어 softmax를 통과시켜 클래스와 동일한 개수의 확률분포를 얻을 수 있습니다.

2) Types of RNNs

[자료 출처: http://cs231n.stanford.edu/slides/2017/cs231n_2017_lecture10.pdf]

1. one to one

입력과 출력 데이터의 time step이 1개인 것으로 시퀀스 데이터가 아닌 일반적인 경우의 모델구조 입니다. 예시로는 키, 몸무게, 나이와 같은 3차원 입력이 들어가면 hidden state vector로 변환하고 저혈압인지, 고혈압인지, 정상인지를 고르는 일반적인 형태의 Neural Net이 있습니다.

2. one to many

입력은 1개, 출력은 여러 개인 방법으로 대표적인 예로 이미지 캡셔닝이 있습니다. 입력으로 이미지 하나를 첫번째 time step에만 주게 되고 해당 이미지에 대한 설명을 예측 혹은 생성하기 위해 그에 필요한 단어를 time step별로 순차적으로 생성하게 됩니다. 여기서 비어있는 input자리에는 사이즈가 동일한 0 벡터로 입력을 넣어 줍니다.

3. many to one

시퀀스를 입력으로 받은 후에 최종 값이 마지막 time step에서 출력으로 나오는 task입니다. 예시로 감정 분류(setiment Classification)가 있습니다.

4. many to many

many to many는 두 가지로 나눠지는 데, 대표적으로 기계번역(Machine Translation)이 있습니다. 기계번역은 문장이 주어지면 해당 문장을 끝까지 읽은 후 마지막 time step부터 순차적으로 번역된 언어를 내보내게 됩니다. 다른 예시로 입력이 주어질 때마다 예측값이 나오는 task가 존재하는데, 각 단어별로 문장 성분이나 품사를 예측하는 PoS tagging이나 비디오가 시간순의 이미지 프레임으로 주어질 때, 각 프레임이 어떤 장면에 해당하는지 분류하는 task가 있습니다.

3) Character-level Language Model

위의 예시는 "hello"를 Character 단위로 나누어 vocabulary를 만들어준 후 ['h','e','l','l']을 넣어 ['e','l','l','o']가 나오도록 하는 task입니다. 먼저 input layer에서는 각 단어들이 원 핫 벡터로 표현되어 입력으로 주어집니다. hidden layer에서는 입력벡터와 전 time step에서 주어지는 $h_{t-1}$을 선형결합하고 비선형변환인 tanh를 통과하여 $h_t$를 만들어줍니다. 이때, $h_0$는 디폴트값으로 모두 0인 벡터로 주어집니다. output layer에서는 이전 layer에서 받은 $h_t$를 선형변환 파라미터 $W_{hy}$에 곱해준 후 bias term인 b도 고려하여 output vector를 구해줍니다. 이후 나온 output vector(logit)를 분류하기위해 softmax를 통과시켜 각 글자에 대한 확률값이 나오게 됩니다. 이렇게 나온 확률값이 ground truth에 가까워지도록 loss를 적용하여 학습하게 됩니다.

 

이렇게 나온 모델로 inference할 때에는 첫 time step의 입력만 주고 나온 결과를 다음 입력으로 주는 방식으로 진행됩니다.

Backpropagation through time (BPTT)

[자료 출처: http://cs231n.stanford.edu/slides/2017/cs231n_2017_lecture10.pdf]
길이가 긴 시퀀스가 입력으로 주어지면 학습하고 계산하는 과정에서 한꺼번에 계산하기 힘들어집니다. 이 경우 truncation으로 잘라 제한된 길이의 시퀀스만으로 학습을 진행합니다. 이렇게 잘린 시퀀스 안에서 forward와 backward 계산이 진행됩니다.

RNN이 어떻게 학습했으며 해당 정보는 hidden state vector에 저장되어 있는데, hidden state vector의 어느 차원에 필요한 정보가 저장되었는지 한 차원을 고정시키고 그 값이 time step이 진행됨에 따라 어떻게 변하는지 분석하며 RNN의 특성을 확인할 수 있습니다.

 

original RNN에서는 $h_t$에 동일한 matrix($W_{hh}$)를 매 time step마다 곱해주기 때문에 backpropagation 과정에서도 같은 숫자가 계속해서 곱해져 gradient vanishing이나 exploding 현상이 발생합니다.


2. 과제 수행 과정 / 결과물 정리

필수과제 2에서 corpus를 만들 때 train, dev, test 데이터를 모두 dictionary 에 포함 시켰을 때의 문제와 그 해결방안을 작성하였습니다. 또한 RNNModel의 forward 부분을 완성하였으며 train과정의 빈칸도 채우며 마무리하였습니다.

 

필수과제 3의 subword 단위로 토크나이징하는 코드를 완성하였으나 학습코드에서 cuDNN error: CUDNN_STATUS_EXECUTION_FAILED 에러가 발생하여 해결중입니다.
-> 해결완료.


3. 피어세션 정리

https://www.notion.so/9-7-9fd0636d46334f27b7b1defe7527a2ef


4. 학습 회고

강의내용을 정리하는데 시간을 좀 많이 사용했습니다. 조금 더 간략하게 해야할지 고민이 됩니다. 과제에서도 에러가 계속 발생해 해결하는데 애를 먹었습니다. 코드를 꼼꼼히 살피지 못해 발생한 에러였던만큼 앞으로 더 꼼꽇미 체크해야겠습니다.