본문 바로가기
CS231

Lecture 10 : Recurrent Neural Networks

by Keep It Simple, Stupid! 2020. 5. 9.

Recurrent Neural Networks


 

  •  

 

"Vanilla" Neural Network


 지금까지 어떤 모델에 하나의 input을 넣어서 하나의 output이 나오는 것을 살펴봤었다. 이번에는 n개의 input과 n개의 output이 나오는 모델(n : 1 이상)을 살펴보려고 한다. 

 

Recurrent Neural Networks : Process Sequences


경우에 따라서 아래와 같이 분류하면 다음과 같다.

  • one to many (e.g. : Image Captioning : image → sequence of words)
  • many to one (e.g. : Sentiment Classification : sequence of words → sentiment)
  • many to many (e.g. : Machine Traslation : seq of words → seq of words)
  • many to many (e.g : Video classification on frame level)

 RNN은 시퀀스 길이에 관계없이 input과 output을 받아들일 수 있는 네트워크 구조며, 필요에 따라 다양하고 유연하게 구조를 만들 수 있음

 

Recurrent Neural Networks : Processing of Non-Sequences Data


  •  Classify images by taking a series of “glimpses” (glimpses : 언뜻 보다, 주어진 이미지의 주변부를 보고 판단)

 non-sequence data는 fixed size input과 fixed size output을 가지는 몇 문제점이 있지만, RNN은 그래도 유용하다고 합니다.

 

Recurrent Neural Network


 RNN의 구조 및 목적 : RNN은 내부에 hidden state(녹색 부분에 해당하는 layer)를 출력하기 때문에, RNN의 목적인 time steps에 따른 다음 vector(정답)를 예측하는게 가능하다.  

 RNN을 구성하는 요소

  1. $x_t$ : input vector at some time step
  2. $h_{t-1}$ : old state
  3. $f_W$ : some function with parameters W
  4. $h_t$ : new state

 Recurrence formula

$$h_{t} = f_{W}(h_{t-1}, x_{t})$$

  •  중요 : 각 input이 새롭게 들어온 경우, hidden layer의 weight와 function은 모든 time step에서 동일

 

"Vanilla" Neural Network


 state는 하나의 "hidden" vector $h$로 구성되어 있다. (single 의미 : 공식에 의해 $y$를 예측 및 다음 time-step에서의 "hidden layer"에 들어감) 

가중치는 아래와 같이 3개로 구분되어 사용된다. 

  • $W_{hh}$ : $W_{hh}$는 time-step $t-1$에서 미리 얻어진 $h_{t-1}$을 곱하여 function의 input에 들어감
  • $W_{hy}$ : $W_{hy}$는 time-step $t$에서 hidden layer 를 통해 $y_{t}$(output)을 도출하는데 사용
  • $W_{xh}$ : $W_{xh}$는 time-step $t$에서 들어온 $x_{t}$(input)을 hidden layer에 function의 input에 사용

 계산 그래프

  • Seq2Seq Model
  • Machine Translation
  • Many to one과 one to Many의 조합
  • Encoder + Decoder

추가적으로 2개의 stage(many-to-one(encode input sequence in a single vector)과 one-to-many(produce output sequence from single input vector)를 결합)로 구분된 seq2seq라는 모델도 있다. 이는 번역기에서 활용된다고 한다. 

Example: Character-level Language Model


 Train 과정 

자연어(언어) 모델을 학습하는 과정을 살펴보자. "hello"라는 단어를 학습하는 과정이다. "hello"라는 단어는 "h", "e", "l", "o"로 4개의 문자만 있으면 표현할 수 있게 된다. 따라서, input layer에 들어가는 벡터의 size는 4이며, "h"를 {1, 0, 0, 1}로 vector로 만들어 계산가능한 상태로 바뀌게 된다. 그리고, ouput layer에 보이는 vector의 size도 4이다. 

 output layer에서 얻어진 vector에 대해 softmax를 취하면 vector의 요소들의 범위가 "0 ~ 1" 인 확률분포로 변하게 되고, 이중에서 가장 큰 값에 해당하는 index를 찾아 해당되는 ouput를 추론하게 된다. (위 그림은 학습하는 과정이기 때문에 숫자가 다소 다름, 잘 예측을 못하는 부분)  loss가 커지며, 이 과정을 반복하면 잘 학습될 것이다. 

추가 설명 : score를 사용하여도 값이 큰 기준으로 ouput을 예측할 수 있지만, softmax를 사용하면 확률 분포가 만들어지기 때문에, 이는 다양성을 줌으로써 학습이 잘 되도록 도와준다고 한다.  

 Test 과정 

 모든 Time-step에서 다음에 올 단어를 예측하고 오차를 Cross Entropy로 구함

 

Backpropagation through time


 예를 들어 many-to-many를 학습하는 과정에서 발생하는 Loss에 대해 각각의 가중치를 업데이트하려면 위와 같이 한번에 전체적으로 gradient를 계산하여 backpropagation을 진행해야 할 것이다. sequence가 매우 긴 경우에는 계산하는데 엄청난 시간을 필요로 할 것이다. 정말 느린 학습이 예상된다. 

RNN은 매우 느리고 converge되지 않습니다. 많은 memory를 사용하는 것이 RNN의 단점

 

Truncated Backpropagation through time


 위에서 발생한 학습 속도의 문제점 개선을 위해 전체 Sequence를 일정 간격(batch와 비슷)으로 잘라서 Loss를 구한 뒤 그에 대한 Gradient를 구하는 방법을 고안했다. 

 

Image Captioning


 Image Captioning은 어떤 image를 input으로 넣었을 때, CNN과 RNN을 통해나온 output이 어떤 image인지 언어로 셜명하는 작업.  (CNN에서 나온 결과를 RNN의 hidden layer의 초기값으로 들어가게 된다.) 

 Image captioning 예제를 확인해보자. 아래는 forward 과정이다. 

 기존 CNN에서 class를 분류를 위해 FC layer와 Softmax가 존재하였지만, Image Captioning에서는 이를 필요로하지 않는다. 

 FC-4096 Layer의 출력을 V라고 하자. 이는 vector 형태를 가질 것이다. V 와 $W_ih$를 곱하여 RNN 구조의 time-step <START>에서 function에 "이미지에 대한 정보"가 추가적으로 대입이 된다.

CNN에서 나온 것을 hidden layer의 초기값으로 설정

  • $W_{hh}$ : $W_{hh}$는 time-step $t-1$에서 미리 얻어진 $h_{t-1}$을 곱하여 function의 input에 들어감
  • $W_{xh}$ : $W_{xh}$는 time-step $t$에서 들어온 $x_{t}$(input)을 hidden layer에 function의 input에 사용
  • $W_{ih}$ : $W_{ih}$는 time-step <start>과정에서 어떤 Image에 대한 CNN output(정보) vector와 곱하여 function의 input으로 사용  
  • $W_{hy}$ : $W_{hy}$는 time-step $t$에서 hidden layer 를 통해 $y_{t}$(output)을 도출하는데 사용

 RNN 구조에 input이 모두 준비딘다면 설정된 sequence에 의해 output이 나오게 된다. 

 test image를 input으로 넣어 CNN을 걸쳐 그 정보가 RNN의 초기 v값으로 들어가고 계산을 통해 "straw" → "hat"이 라는 ouput이 나오게 됨으로써 test image에 대한 묘사를 할 수 있게 된다. 

  위는 결과가 어느정도 잘 맞는 image이다.

 위는 결과가 이상하게 나온 image 예제이다.

Image Captioning with Attention


 이미지의 특정 부분에 기반해 단어를 유추했다고 보여줌

 Attention, RNN, LSTM에 대한 내용은 CS231에선 많이 다루고 있지 않습니다. [CS224를 참고]

 

 

 

Multilayer RNNs


 RNN의 depth를 늘려서 Multillayer RNNs을 만들수 있다. 하지만, 이는 성능이 좋지 않기 때문에 기본 RNN구조의 단점을 해결해주는 LSTM 존재한다. 우선, RNN의 문제점을 확인해보자. 

 $h_{t}$에서 $h_{t-1}$의 Backpropagation은 빨간 부분인데, 이는 tanh의 gate를 타고, $W$곱셈 gate를 지나온다. 앞장에서 보았듯이 곱에대한 gradient의 gate는 결국 $W_{hh}^{T}$(가중치 행렬)을 곱하게 된다. 

 RNN에서 sequence가 위와 같이 4로 설정한다면, 역전파로 전해지는 $h_0$의 gradient는 총 4번의 "tanh gate", "+", "$W$(MatMul gate, 행렬곱)" 연산을 통과되는것을 확인할 수 있다.  "chain rule"을 이용하면 헤당 gradient를 구할 수 있습니다. 

여기서 잠깐 역전파에 대한 계산 그래프를 확인하도록 하겠습니다. 

  • "+"의 역전파 : 그대로 하류로 흐르기 때문에, 기울기는 변화가 없다.
  • "tanh"의 역전파 : 기울기 소실 발생 (이하 설명)
  • "$MatMul$"의 역전파 : 기울기 폭발 및 소실 발생 (이하 설명)

우선, "tanh(x)"에 대한 미분 값을 살펴보자.

$$\frac{dtanh(x)}{dx} = 1 - tanh(x)^2$$

 위 그래프를 보면 주황색으로 표시된 점선이 $y = tanh(x)$의 미분이다. 보다시피 1.0 이하이며, $x$가 0으로부터 멀어질수록 작아지게 되는데, 즉, 역전파에서는 기울기가 $tanh$를 지날 때마다 값은 계속 작아진다는 뜻이다. 그래서 $tanh$ 함수를 $T$번 통과하면 기울기도 $T$번 반복해서 작아지게 된다.

 참고 : RNN 계층의 활성화 함수로는 tanh 함수를 사용하는데, 이를 ReLU로 바꾸면 기울기 소실을 줄일 수 있다.

"$MatMul(행렬 곱)$"노드의 역전파에 대한 그림을 살펴보자. (단, $tanh(x)$ node 무시)

 같은 계산을 시계열 데이터의 시간 크기(sequence) 만큼 반복하고 있다. 여기서 주목할 점은 이 행렬 곱셈에서는 매번 똑같은 가중치인 $W_h$가 사용된다는 것이다. 그러면 역전파 시 기울기는 MatMul(행렬 곱)을 지날 때마다 어떻게 변하게 되는지 아래 그림을 보고 확인해 보자. 

 [Figure 6-8]을 보면 기울기의 크기는 시간에 비례해 지수적으로 증가함을 알 수 있었다. 이것이 기울기 폭발이다. 이러한 기울기 폭발이 일어나면 결국 오버플로를 일으켜 NaN같은 값을 발생시킨다. 따라서 신경망 학습을 제대로 수해할 수 없게 된다. 

 [Figure 6-9]를 보면, 이번에는 기울기가 지수적으로 감소함을 확인할 수 있다. 이것이 기울기 소실(vanishing gradient)이다. 기울기 소실이 일어나면 기울기가 매우 빠르게 작아진다. 그리고 기울기가 일정 수준 이하로 작아지면 가중치 매개변수가 더 이상 갱신되지 않으므로, 장기 의존 관계를 학습할 수 없게 된다.

 지금까지의 실험에서 기울기의 크기는 지수적으로 증가하거나 감소했었다. 왜 이런 지수적 변화가 일어날까?
물론 행렬 Wh T번 반복해서 "곱"했기 때문이다. 만약 Wh가 스칼라면 이야기는 단순해지는데, Wh가 1보다 크면 지수적으로 증가하고, 1보다 작으면 지수적으로 감소한다.

 그럼 Wh가 스칼라가 아니라 Matrix(행렬)이라면 어떨까?

 행렬의 "Sigular Value(특잇값)"이 척도가 된다. 행렬의 특잇값이란? 단단히 말해서 데이터가 얼마나 펴져 있는 정보를 나타낸다. 이 특잇값의 값(더 정확하게는 여러 특잇값 중 최댓값)이 1보다 큰지 여부를 보면 기울기가 어떻게 변할지 예측할 수 있다.

 Vanilla RNN의 형태는 Exploding gradients/Vanishing gradients 문제를 위에서 살펴보았다. 이에 대한 해결책을 살펴보자. 

  Exploding gradients : singular value가 1보다 큰 경우 "Gradient clipping" 을 이용하여 norm이 커지고 있다면 grad를 scale하여 값을 줄여줘 이를 gradient가 Exploding 하는것을 방지할 수 있다.

 Vanishing gradients : singular value가 1보다 작은 경우 해결 방법이 없기 때문에, RNN 학습에서는 기울기 소실도 큰 문제이다. 그리고 이 문제를 해결하려면 RNN 계층의 구조를 근본부터 뜯어고쳐야 한다. 여기서 등장하는 것이, 이번 장의 핵심 주제인 '게이트'가 추가된 RNN인 LSTM입니다. (etc. GRU)

Long Short Term Memory (LSTM)


 LSTM은 기존 RNN과 달리 gate가 4개 존재한다. 각각의 gate가 의미하는 것은 아래와 같다.

  • $i$ : Input gate : 새 정보를 무비판적으로 수용하는게 아니라, 적절히 취사선택하는 것, input gate에 의해 가중된 정보가 새로 추가되는 셈
  • $f$ : Forget gate : 기억 셀에 "무엇을 잊을까"를 명확하게 지시하는 gate
  • $o$ : Output gate : 다음 은닉 상태 $h_{t}$의 출력을 담당하는 gate, 즉, ouptut 게이트의 열림 상태는 (다음 몇 %만 흘려보낼까?)는 입력 
  • $g$ : Gate gate : 앞에서 forget 게이트를 거치면서 이전 시각의 기억 셀로부터 잊어야 할 기억이 삭제되었다. 그런데 이 상태로는 기억 셀이 잊는 것밖에 하지 못한다. 그래서 새로 기억해야할 정보를 기억 셀에 추가해야 한다.

 

소실이 일어나지 않는 이유

  1. "+" Node : 상류에서 전해지는 기울기를 그대로 흘릴 뿐, 따라서 기울기 변화(감소)는 일어나지 않음
  2. " X(element wise)" Node : 여기서 사용한 Node는 MatMul(행렬곱)이 아닌, "원소별 곱"을 계산

 

GRU


 

 

'CS231' 카테고리의 다른 글

Lecture 11 : Detection and Segmentation  (0) 2020.05.17
Lecture 9 : CNN Architectures  (0) 2020.05.02
Lecture 8 : Deep Learning Software  (0) 2020.05.02
Lecture 7 : Training Neural Networks II  (2) 2020.04.16
Lecture 6 : Training Neural Networks I  (2) 2020.04.12

댓글