티스토리 뷰

728x90

이번 포스팅은 cs231n 강의의 Lecture 10 Recurrent Neural NetworksEECS 498.008 / 598.008 강의의 Lecture 16 Recurrent Neural Network을 참고하여 정리하였습니다. 이번 강의는 cs231n의 자료가 더 좋습니다.

 

이번 강의에서 다루는 내용은

  • RNN, LSTM, GRU
  • Language modeling
  • Sequence-to-sequence
  • Image captioning

입니다.

 

RNN의 Process Sequence를 보면 이렇습니다.
 

1) One to one
Image classification: Image  Label
2)One to many
Image Captioning: Image  Sequence of words
3) Many to one
Video classification: Sequence of images  label (비디오는 비디오 프레임의 시퀀스로 이뤄집니다.)
4) Many to many
Machine Translation: Sequence of words  Sequence of words
5) Many to many
Per-frame video classification: Sequence of images  Sequence of labels

 

Why existing convnets are insufficient?

왜 CNN이 시퀀스 데이터를 다루기 적합하지 않을까요? 일단 시퀀스는 입력과 출력 길이가 가변적입니다.

 

예를 들어, Video captioning을 작업할 때 입력값으로 비디오는 다양한 프레임 수를 가집니다. 출력으로는 captions이 다양한 길이를 가질 수 있습니다.

 

변수 입력을 받아 모든 단계에서 출력을 생성하는 작업부터 시작하겠습니다.

 

 

 

Recurrent Neural Networks

RNN은 sequence를 진행하며 업데이트 해 줄 'internal state'를 갖고 있다는 것이 핵심 아이디어입니다.

 

 

모든 스텝마다 vector $x$의 sequence마다 recurrence formula를 적용하여 진행할 수 있습니다.

 

$h_t = f_W(h_{t-1}, x_t)$

 

 

그리고 같은 함수와 같은 파라미터 세트를 모든 스텝에서 사용합니다.

 

(Vanilla) Recurrent Neural Networks

 

state는 "hidden" vector $h$로 구성되어 있습니다.

 

 

첫 번째 hidden state는 모두 0에서 세팅되어 있고 학습을 시작합니다.

 

 

모든 time-step에서 같은 가중치 행렬이 재사용됩니다.

 

Many to Many

 

 

Many to One

 

 

One to Many

 

 

Sequence to Sequence (seq2seq): (Many to one) + (One to many)

 

 

 

Example: Language Modeling

characters 1,2, …, t-1이 순서대로 주어질 때, 모델은 character t를 예측해야 합니다.

 

 

학습 시퀀스로 "hello"가 주어질 때, Vocabulary는 [h, e, l, o]입니다. 만약 "hell"이 주어지면, "o"를 예측합니다.

 

test-time에선, 새로운 텍스트를 생성합니다. 

 

지금까진 one-hot-vector로 입력을 인코딩했습니다.

 

one-hot vector의 행렬 곱은 가중치 행렬에서부터 column을 추출합니다. 종종 이것을 별도의 임베딩 레이어로 추출합니다.

 

 

 

 

 

Backpropagation Trough Time

loss를 계산하기 위해 전체 sequence를 forward하고, gradient를 계산하기 위해 전체 sequence를 backward합니다.

 

이 방법의 문제는 긴 sequences는 너무 많은 메모리를 사용하게 된다는 점인데요. 그것 때문에 나온 방법이 Truncated Backpropagation Through Time입니다.

 

 

Truncated Backpropagation Trough Time

 

전체 sequence를 대신하여 sequence의 chunk를 통해 forward/backward합니다.

 

 

hidden states를 계속해서 forward해서 가져오지만, backpropagation의 경우엔 한 덩어리만큼 실행합니다. 

 

마지막에 loss가 계산됩니다.

 

RNN tradeoffs

 

RNN의 장점:
- length input을 처리 가능합니다.
- 단계 t에 대한 계산은 (이론적으로) 여러 단계 뒤로의 정보를 사용할 수 있습니다.
- 더 긴 입력에 대해 모델 크기가 증가하지 않습니다.
- 모든 타임스텝에 동일한 가중치가 적용되므로 입력 처리 방식이 대칭입니다.


RNN의 단점:
- 반복 계산이 느립니다.
- 실제로는 여러 단계에서 정보에 접근하기 어렵습니다.

 

그 다음은 이미지 캡셔닝 개념입니다.

 

 

Example: Image Captioning

CNN과 RNN이 같이 사용됩니다.

 

ImageNet으로 CNN을 훈련 시키고 마지막 레이어를 삭제합니다.

 

Sample word와 copy를 input에 넣습니다. 이 과정을 <END> 토큰이 나올 때까지 진행합니다.

 

 

Image Captioning: Example Results

좋은 결과의 예시입니다.

 

Image Captioning: Failure Cases

안 좋은 결과의 예시입니다.

 

이제 Gradient가 계산되는 flow를 살펴봅니다.

 

Vanilla RNN Gradient Flow

 

$h_t = tanh(W_{hh}h_{t-1} + W_{xxt}X_t + b_n$)

$=tanh( (w_{hh} \ w_{hh})$ $h_{t-1} \choose x_t$ $ + b_n)$

$= tanh (w$ $h_{t-1} \choose x_t$ $ + b_n)$

 

 

$h_t$에서 $h_{t-1}$의 $W$(실제로 $W_{hh}^T$)의 곱들로부터 Backpropagation합니다.

 

 

 

$h_0$의 gradient 연산에는 $W$의 많은 factor(및 반복되는 tanh)를 포함합니다. (repeated tanh)

 

비선형성이 없다고 가정하면 어떻게 될까요?

 

 

1. Largest singular value > 1 : Exploding gradients
2. Largest singular value < 1 : Vanishing gradients

 

1의 경우 Gradient clipping을 통해 해결할 수 있습니다. 각 norm들이 너무 큰 경우에 gradient를 scale합니다. 코드는 아래와 같습니다.

 

grad_norm = np.sum(grad * grad)
if grad_norm > threshold :
	grad *= (threshold / grad_norm)

 

2의 경우 RNN architecture를 좀 손보면서 해결할 수 있습니다.

 

 

Long Short Term Memory (LSTM)

 

위에서 살펴보았던 Vanilla RNN은 아래와 같습니다.

 

 

LSTM의 경우 각 timestep마다 두 vector가 있습니다.

 

  • Cell state: $c_t \in R^H$
  • Hidden state: $h_t \in R^H$

 

각 timestep마다 네 gates를 연산합니다.

 

  • Input gate: $i_t \in R^H$
  • Forget gate: $f_t \in R^H$
  • Output gate: $o_t \in R^H$
  • “Gate?” gate: $g_t \in R^H$

 

  • i: Input gate, whether to write to cell
  • f: Forget gate, Whether to erase cell
  • o: Output gate, How much to reveal cell
  • g: Gate gate(?), How much to write to cell

 

 

$i_t$, $f_t$, $o_t$는 시그모이드에 곱해지고, 마지막 $g_t$는 tanh에 곱해집니다.

 

gate 별로 빨간색 박스로 보여줍니다.

 

 

Long Short Term Memory (LSTM)

 

Long Short Term Memory (LSTM): Gradient Flow

$c_t$에서 $c_{t-1}$로의 역전파 $f$에 의한 요소별 곱셈, W에 의한 행렬 곱셈 없음

 

LSTM은 기울기 소실 문제를 해결하나요? LSTM 아키텍처를 사용하면 RNN이 여러 시간 단계에 걸쳐 정보를 더 쉽게 보존할 수 있습니다. 예를 들어 $f = 1$이고 $i = 0$이면 해당 셀의 정보가 무한정 보존됩니다.

대조적으로, Vanilla RNN은 hidden state에서 정보를 보존하는 recurrent weight matrix $W_h$를 학습하기가 더 어렵습니다. LSTM은 vanishing/exploding gradient이 없음을 보장하지 않지만 모델이 long-distance dependencies을 학습하는 더 쉬운 방법을 제공합니다.

 

 

 

 

layer가 하나일 때

 

 

layer가 여러 개일 때

 

 

 

첫 번째 레이어에서 나온 hidden state를 다음 RNN의 input으로 전달합니다.

 

 

세 개 이상의 레이어가 있는 경우에서도 동일합니다.

 

 

Other RNN variants (GRU)

 

다른 RNN의 변형으로 GRU가 있습니다.

 

이는 statistical machine translation을 위한 RNN의 encoder-decoder를 사용한 구문 표현 학습입니다.

 

 

 

RNN Architectures: Neural Architecture Search

LSTM의 구조를 살펴볼 수 있습니다.

 

 

 

 

Summary

요약하면 아래와 같습니다.

 

  • RNN은 architecture 디자인에 따라 많이 유동적입니다.
  • Vanilla RNN은 단순하지만 효과적으로 잘 작동하는 것은 아닙니다. 
  • 보통 LSTM이나 GRU를 사용합니다. 이는 서로 상호작용을 추가해 gradient 흐름을 유지시킵니다.
  • RNN에서 gradient의 역전파 흐름은 explode 되거나 vanish됩니다.
    • Exploding은 gradient clipping으로 다룰 수 있습니다.
    • Vanishing은 상호작용을 더해 다룰 수 있습니다. (→LSTM)
  • 더 낫고 단순한 아키텍처는 현재 연구에서 주요 관심 분야입니다.
  • 이론과 실증 모두 더 나은 이해가 필요합니다.

 

728x90
댓글