본문 바로가기

Deep Learning for Computer Vision

EECS 498-007 / 598-005 Lecture 12 : Recurrent Neural Networks

 

지금까지 강의에서 다룬 신경망 모델들은 단순히 하나의 입력을 받아 하나의 출력을 만들어내는 Feedforward Neural Network에 관해서 배웠다. 지금부터는 sequence, 즉 순서가 있는 시계열 데이터를 다루며 입력과 출력의 크기가 자유로운 Recurrent Neural Network (이하 RNN)에 관해서 배워볼 것이다. 먼저 RNN 모델은 세부적으로 Image Captioning으로 대표되는 'one to many'와 Video Classification으로 대표되는 'many to one', Machine Translation으로 대표되며 입력과 출력의 크기가 다른 'many to many', 마지막으로 Per-frame Video Classification으로 대표되며 입력과 출력의 크기가 동일한 'many to many'로 나눌 수 있다.

 

 

앞서 서술했다시피 RNN 모델은 시계열 데이터를 처리하기 위해 개발되었고 사용되지만, 놀랍게도 몇몇 논문에 따르면 이미지를 연속적으로 일부를 관찰해서 RNN 모델로 이미지 분류 작업을 수행하는 등 비시계열 데이터를 시계열 데이터처럼 처리해보았고 나름 괜찮은 결과를 얻었다고 한다. 그런데 뭐 이건 솔직히 보여주기라서 그냥 이런 것도 할 수도 있구나 하고 넘어가면 될 것 같다.

 

 

어쨌든 RNN 모델의 핵심은 앞서 언급했다시피 시계열 데이터를 처리하기 위한 것이다. 그래서 RNN 모델에서는 입력과 출력 말고도 순서 정보를 처리하기 위해 순서에 따라 업데이트되는 일종의 벡터인 internal state 혹은 hidden state를 가지고 있다. 그리고 RNN 모델에서는 데이터 상의 매 순서 혹은 시간마다 hidden state와 그 시간의 입력을 입력으로 받아 연산을 수행하는 recurrence formula를 통해서 새로운 순서 정보를 생성해낸다.

 

 

RNN 모델은 recurrence formula에 따라 세부적으로 다양한 종류의 모델들로 나뉘는데 그 중 가장 기본적인 모델은 Vanilla RNN 혹은 Elman RNN이라고 불리는 모델이다. Vanilla RNN의 recurrence formula는 단순히 Linear Layer에 이어 tanh activation이 연결된 형태로 구성되어 있다.

 

 

 그리고 입력과 출력의 길이에 따른 RNN 모델들의 Computational Graph를 그려보면 위와 같다. 그런데 위에서 볼 수 있듯이 recurrence formula 연산에 필요한 hidden state는 이전 time step에서의 연산으로부터 얻어지지만, 첫 번째 time step에서의 hidden state는 다른 것들과 달리 임의로 만들어 주어야 한다. 그래서 일반적으로는 일반적으로 hidden state vector의 값을 모두 0으로 만들거나 학습 가능한 vector로 구현하는 등의 방법으로 만들어 준다. 그리고 recurrence formula에서 사용되는 weight은 모든 시간대의 recurrence formula에서 공유된다는 것을 확인할 수 있는데 그렇기에 backpropagation 시에는 모든 시간대의 recurrence formula에서의 weight의 gradient는 합해준 후에 gradient descent를 진행해야 한다. 어쨌든 RNN 모델에서는 time step과 무관하게 weight은 항상 동일하므로 입력으로 주어지는 데이터의 시간대의 길이와 무관하게 데이터를 처리할 수 있는 것이다.

 

 

위의 유형들의 모델들말고도 기계 번역 등에서 매우 널리 사용되는 Sqeuence to Sequence 모델이 있다. 이 모델은 서로 다른 길이의 vector들을 각각 입력과 출력으로 가진다는 특징이 있다. Sequence to Sequence RNN 모델은 입력 데이터를 many to one 형태의 encoder로 인코딩하고 one to many 형태의 decoder로 출력을 생성해낸다.

 

 

Sequence to Sequence 모델에 관해서는 입력 알파벳으로 단어를 완성하는 Language Modeling을 통해 자세히 알아볼 것이다. 여기서는 'hell'이 주어졌을 때, 'hello'를 완성하는 것을 보여줄 것이데 먼저 'hello'는 one-hot encoding 방식을 통해 인코딩 되어 입력으로 주어진다. 그리고 그에 대응한 outut이 각각의 time step마다 생성되는데 이때 output은 각 알파벳의 다음 알파벳으로 기대되는 값들이 생성되도록 한다. 여기서는 입력 'h', 'e', 'l', 'l'에 대응해서 출력은 'e', 'l', 'l', 'o'로 생성하는 것이 목표이다.

 

 

모델의 학습이 끝나고 모델이 평가모드로 전환되면 각각의 time step들의 출력 값들이 다음 time step의 입력으로 주어지는 식으로 해서 처음 받은 알파벳으로 단어를 완성하게 된다. 그리고 예시 모델에서는 입력을 one-hot encoding을 통해서 가공했늗데 이렇게 하면 위에서 볼 수 있듯이 행렬곱이 너무 단순해진다. 따라서 보통은 one-hot encoding 된 입력을 embedding 해서 사용한다.

 

 

그리고 앞서 살펴보았던 RNN 모델의 computational graph에서는 각 time step의 모든 loss를 합한 후에 backpropagation을 수행하는 구조였었다. 하지만 이런 식으로 구현되었을 경우에는 입력 데이터의 길이가 길면 그것에 비례해서 GPU 메모리가 요구된다는 문제가 있다.

 

 

그래서 입력 데이터를 몇 부분으로 쪼개서 각각의 부분마다는 단지 hidden state만을 공유하고 부분별로 forward propagation이나 backward propagation은 모두 별도로 진행하는 방법이 사용되기도 한다.

 

 

그리고 2016년에는 RNN 모델이 어떻게 시계열 데이터를 학습하는 것인지에 대한 연구가 이루어졌는데, RNN 모델의 각 hidden state의 -1과 1사이에 위치한 값을 그 값에 따라 색을 칠하는 방식으로 이를 시각화하였다. 예를 들어 위의 우측의 시각화에서는 큰 따옴표 사이의 텍스트를 파란색, 그 외의 텍스트는 빨간색으로 칠해진 것을 볼 수 있는데, 이를 통해 RNN 모델이 문장의 유형에 따라 서로 다르게 값을 처리하는 것을 알 수 있다.

 

 

지금부터는 CNN과 RNN 모델의 융합 모델이 어떻게 Image Captioning을 수행하는 것인지 살펴볼 것이다. 

 

 

먼저 CNN 모델을 통해 이미지에 대한 feature vector를 생성하고, 그 feature vector를 weight과의 행렬곱 연산을 통해 생성한 값을 매 time step의 recurrence formula에게 전달한다. 이 값은 위 이미지에서 $W_{ih}*v$에 해당한다. 그리고 RNN 모델의 첫 번째 입력값은 문장의 시작을 알리는 special token인 '<START>'로 하며 첫 번째 출력 값을 생성하며 이후 출력 값으로 문장의 끝을 알리는 speical toekn '<END>'가 나올 때까지 각 time step의 출력 값들을 다음 입력값으로 계속해서 전해주어 최종적인 이미지의 설명을 생성해낸다.

 

 

이어서 Vanilla RNN 모델의 gradient flow에 관해서 알아볼 것이다. Vanilla RNN 모델의 gradient는 위와 같은 흐름으로 전달되는데, Vanilla RNN 모델에서는 activation으로 매번 많은 연산량을 요구하는 tanh activation을 사용하고, backpropagation 시에 weight을 transpose 해주어야 한다는 문제점들을 관찰할 수 있다.

 

 

그리고 RNN Cell을 100개, 200개 등 매우 많이 사용하는 모델에서는 매번 동일한 weight을 반복해서 곱해주는 데, 이때 weight이 1보다 크다면 weight을 반복해서 곱하는 것 때문에 gradient가 폭발적으로 증가하는 exploding gradients 문제가 발생할 수 있으며, 1보다 작다면 gradient가 값이 너무 작아져 아예 사라져 버리는 vanishing gradients 문제가 발생할 수 있는 것을 알 수 있다. 그래서 이 문제에 대처하기 위해 먼저 exploding gradient의 경우에는 gradient의 최댓값을 제한하는 gradient clipping 기법을 사용하며, vanishing gradient의 경우에는 RNN 모델의 아키텍처를 변경하는 식으로 대처한다. 

 

 

그중 한 가지 모델이 바로 Long Short Term Memory(LSTM) 모델로 이 모델에서는 Vanilla RNN 모델과 달리 두 개의 hidden state, cell state와 hidden state를 사용하며 이것들을 계산하기 위해서 각 time step마다 4개의 gate를 새로 계산해서 이용한다. 

 

 

LSTM 모델의 hidden state들과 gate들의 계산을 이미지로 나타내면 위와 같다. LSTM 모델에서 Forget Gate는 이전의 cell state $c_{t-1}$의 값들을 0으로 초기화할 것인지 아니면 계속 전달할 것인지를 나타내며, Input Gate는 현재의 cell state $c_t$에 값을 얼마나 빼주거나 더해줄지, Gate Gate는 Input Gate가 전달한 값의 방향을 정해주는 역할을 한다. 마지막으로 output state는 LSTM Cell의 출력 값과 연관되는 $h_t$에 $c_t$의 값이 얼마나 반영될 것인지를 정한다.

 

 LSTM 모델은 매 $t$마다의 $c_t$는 이전 $c_{t-1}$과 element wise 연산을 통해서 결정되므로 복잡한 nonlinearity나 행렬곱 연산이 필요 없이 ResNet에서의 residual connection과 유사하게 정보를 계속해서 전달할 수 있기에 Vanilla RNN에 비해 학습이 용이하다. 

 

 

그리고 RNN 모델에서도 레이어를 적층 하는 Multilayer RNN 혹은 Deep RNN이라고 부르는 모델이 있는데 CNN 모델과는 달리 널리 사용되지는 않는다.

 

 

LSTM 말고도 RNN 모델의 여러 변형 모델들이 존재하는데 그중 대표적인 모델이 Gated Recurrent Unit(GRU)로 이 모델은 LSTM을 조금 더 간결하게 변형한 모델로 gradient flow를 개선했다는 의미는 동일하다. 그리고 그것 말고도 RNN의 update formula를 변경해보는 연구가 있었는데 모두 별 의미는 없었다. 

 

 

또한 CNN 모델에서와 유사하게도 RNN 모델의 아키텍쳐를 학습시켜 개발하려는 시도가 있었고 결국에는 LSTM보다 소폭 나은 성능을 보여주는 모델이 발견되었다. 하지만 굳이 이럴 필요 없이 그냥 LSTM이나 GRU를 쓰면 최적은 아니지만 제법 괜찮은 결과가 나온다. 

요약

 

728x90