CS231n 10강 요약

RNN에 대해서 한 번 알아보자!

0. Today’s Goal

  • RNN이란?
  • Image Captioning
  • LSTM

1. 강의 및 강의 자료

강의를 들어볼 수 있는 링크와 강의 자료를 pdf형식으로 준비했다.

한글 자막이 필요하신 분은 다음의 링크를 확인해주세요. :)

  • 한글 자막을 첨부하고 싶으면 여기를 눌러주세요.

2. RNN이란?

RNN이란 Recurrent Neural Network의 줄임말로
지금까지 우리가 배운 CNN 구조와는 살짝 다른 모델 구조를 갖는다.

지금까지 우리가 배운 구조를 “Vanilla” Neural Network라고 하자.

입력이 하나 들어가고, 출력이 하나 나오는 형태로 hidden layer를 거쳐서 하나의 output 형태로 나오는 것을 주로 배웠다.

하지만, 만약 입 / 출력의 갯수가 변하면 어떻게 될까?

이처럼 다양한 입 / 출력을 다룰 수 있도록 만든 모델이 RNN이다.

예를 들어, ‘one to many’의 같은 경우는 Image Captioning이 될 수 있고,
‘many to one’의 경우는 Sentiment Classification이 될 수 있고,
‘many to many’인 경우는 Machine Translation이나 Video classification on frame level의 경우가 될 수 있다.

입 / 출력이 단일이더라도, 찾는 과정을 가변과정으로 찾게 되면 RNN을 사용할 수 있다.

그렇다면 RNN의 흐름은 어떻게 될까?

  1. 입력을 받는다.
  2. 모든 step마다 Hidden state를 update 한다.
  3. 출력 값을 내보낸다.

일반적인 CNN의 흐름과 비슷한 것(?) 같다.

그림을 통해 다시 한 번 알아보자.

매 step마다 $x_t$가 들어오고 기존에 있던 $h_{t-1}$를 가지고, $h_t$를 update한다.

이 모델에서 알아야 할 것은 같은 set의 parameter들을 가지고 매 step마다 update를 진행한다는 것이다.

방금 설명한 부분을 식으로 나타내면,

여기서 비선형성을 위해 $tanh$ 함수를 사용한다.


RNN의 Computational Graph를 한 번 알아보자.

처음의 $h_0$는 대부분 0으로 초기화 한다.
출력인 $h_1$가 다음에는 입력으로 들어가는 모습을 볼 수 있다.

또 다른 $x_2$를 받아 다시 출력으로 $h_2$를 만들어 낸다.

이 과정을 무한반복한다.

아까 언급했다시피 똑같은 set의 parameter를 가지고 update를 진행하는 것을 볼 수 있다.

만약 출력이 다수라면 ‘many to many’ 분류할 수 있고,
그에 대한 Loss function도 많다는 것을 알 수 있다.

또 다른 예로 입력이 하나이고, 출력이 다수라면 Computational graph는 다음과 같이 나타낼 수 있다.

이제 Character-level language Model를 통해 RNN을 좀 더 이해해보자.

쉽게 말해 문자열 시퀀스를 입력으로 받아서 다음 문자를 예측하는 모델을 말한다.

예를 들어 [h,e,l,o]라는 문자열 시퀀스가 있고,
내가 “hello”라는 문자열을 만들고 싶다고 하자.

먼저 Input 문자를 4d 벡터로 만든 다음
$h_t = tanh(W_{hh}h_{t-1} + W_{xh}x_t)$ 윗 식을 이용하여 hidden layer의 값을 구해준다.

여기서도 $W_{hh}$와 $W_{xh}$는 모두 같은 값을 사용한다.

그 다음 target chars를 고를 때는 확률 분포에서 샘플링을 진행한 후,
다음 Input chars로 넣어줄 문자를 골라준다.

이렇게 하는 이유는 Softmax에서 가장 높은 값이 나온 문자가 우리가 원하는 문자가 아닐 수 있기 때문이다!

이러한 모델을 train을 하려면 어떻게 될까?

하나의 출력값을 알기 위해서 처음부터 모든 Loss 값들을 알아야 한다..
이렇게 되면 계산량이 어마어마해진다.

따라서 실제로 사용하는 방법은 다음과 같다.

train 할 때 한 스텝을 일정 단위로 나눈 후, 서브시퀀스의 Loss들만 계산한다.


RNN은 여러 분야에서 활용될 수 있다.

여기서 발견한 신기한 점은 다음 문자가 어떤 것이 나올지 예측하는 모델을 만들었는데, 이 모델은 전체적인 문장 구조를 파악해서 알아서 그 구조를 학습한다는 점이다.

RNN을 이용하여 Latex source를 학습한 모습


RNN을 이용하여 C code를 학습한 모습


물론 증명이 안되는 수식들과 컴파일도 안되는 엉망인 코드를 적어놓았지만 그래도 이런 틀을 학습했다는 것이 매우 놀랍다..!

3. Image Captioning

Image Captioning이란 하나의 사진을 보고 이 사진이 무엇인지 설명하는 문장을 만들어 내는 딥러닝 모델을 말한다.

사진을 보고 CNN 구조를 통과한 결과가
RNN의 입력으로 들어가는 모습을 볼 수 있다.

실제로 test Image가 들어가게 되면
Softmax를 통과하기 바로 전 Fully Connected Layer를 이용한다.

새로운 가중치 행렬을 추가하여 이미지 정보를 추가해준다.

그리고 RNN 구조를 이용하여 문자열 결과를 출력해준다.

Image Captioning의 여러 예들을 살펴보면

물론 이런 결과는 모두 Supervised Learning이다.


조금 더 진보된 모델인 Image Captioning with Attention를 살펴보자.

Input Image를 통해 공간 정보를 담고 있는 Grid of Vector 값을 얻어낸다.
내가 이해하기론 Feature Map과 비슷한 개념이라 생각한다.

그 다음 Output을 살펴보면 총 2가지의 출력이 있다는 것을 알 수 있다.

  • 이미지에서 어느 부분을 집중적으로 보았는지? (이미지 분포)
  • 단어의 분포는 어떻게 되는지? (단어의 분포)

그림에서 a1, a2 등이 이미지의 분포를 나타낸 출력값,
d1, d2 등이 단어의 분포를 나타낸 출력값이다.

z는 다음과 같은 수식을 통해 만들어진다.

$z = \sum^L_{i=1} p_iv_i$

a1의 결과와 Feature의 결과를 곱해서 z를 표현하게 됩니다.

Image Captioning with Attention과정을 시각화하면

모델의 caption을 생성하기 위해 이미지의 attention을 이동하는 모습을 볼 수 있다.

즉, 의미가 있다고 생각하는 부분에 스스로 attention을 집중하는 모습을 보인다.


이와 비슷한 Task로 VQA(Visual Question Answering)이라는 일이 있다.

이미지와 질문을 동시에 던졌을 때, 답을 맞추는 과정을 말한다.

이러한 Task 역시 RNN을 통해서 학습을 할 수 있다.

모델이 깊어질 수록 다양한 문제들에 대해서 성능이 더 좋아지는 것을 확인할 수 있다.

Train을 하기 위해서 Gradient값을 구해야 하는데,

먼저 Vanilla RNN Gradient Flow를 살펴보면

RNN 하나의 cell을 통과할 때 마다 가중치 행렬의 일부를 곱하게 되는 모습을 볼 수 있다.

하나의 cell이 아닌 전체적인 cell로 gradient를 구하는 모습을 살펴보면

많은 W 행렬들이 개입하게 되어 계산량이 늘어나는 것을 확인할 수 있다.

그리고 또 하나의 문제점이 생기는데

Weight 행렬에서 특이값의 최대값에 따라 Gradient값이 폭발적으로 증가할 수도, 너무 작게 감소할 수도 있는 문제점이 발생한다.

이러한 문제점을 해결하기 위해 나온 새로운 RNN 구조가 있는데,

그것이 바로 LSTM이다.

4. LSTM

LSTM이란 Long Short Term Memory에 약자로 RNN의 새로운 구조 중 하나이다.

기본적인 RNN 구조와 비교를 해보면,
LSTM은 두개의 hidden state가 존재하고 $c_t$라는 내부에만 존재하는 변수가 존재한다.

위 그림에서 보이는 $\sigma$ 함수는 Sigmoid를 뜻한다.

좀 더 자세히 LSTM을 살펴보자.
총 4가지의 gate가 있다고 생각할 수 있다.

  • i - Input gate : cell에 대한 입력 ($x_t$에 대한 가중치)
  • f - Forget gate : 이전 cell에 대한 정보를 얼마나 지울 것인가?
  • o - Output gate : $c_t$를 얼마나 밖으로 드러낼 것인가?
  • g - Gate gate(?) : Cell을 얼마나 포함 시킬 것인지?

LSTM에 대한 Flow chart는 다음과 같다.

여기서 Gradient Flow 과정을 살펴보면

하나의 cell에서 Weight행렬을 거치지 않고도 cell 단위에서 gradient 계산을 할 수 있다.

여러 cell을 거치더라도 계산량이 크게 증가하지 않는다는 것을 알 수 있다.

즉, forget gate와 곱해지는 연산이 행렬 단위의 곱셈 연산이 아니라 element-wise (원소별 연산)이기 때문에 계산량이 크게 증가하지 않는다.

마치 CNN의 ResNet 구조와 비슷하게 생겼다..

여러 RNN 구조 중에서 GRU라는 구조가 있는데,
이건 그냥 이런게 있구나 하고 넘어가자…ㅎ

신기하긴 하지만 RNN이라는 개념 자체가 좀 어려운 것 같다…

이렇게 RNN에 대한 요약을 마무리해본다.

댓글남기기