Lecture 10 | Recurrent Neural Networks

2022. 3. 5. 16:37

Lecture 10 | Recurrent Neural Networks

RNN(Recurrent Nueral Network)

RNN의 형태

  • RNN은 input, output의 형태에 따라 쓰임이 다르다.

종류

  • one to one: Vanilla Neural Network, 입력하나가 hidden layer를 거쳐 하나의 출력을 내보냄
  • one to many: Image captioning, 입력은 이미지와 같은 단일입력, 출력은 caption과 같은 가변출력
  • many to one: Sentiment Classification, 입력은 텍스트와 같은 가변입력, 출력은 하나의 감정과같은 단일 출력
  • many to many: Machine Translation, 가변입력과 가변출력
  • many to many: Video classification on frame level, 가변입력과 가변출력

Non-Sequence Data에서의 RNN

  • 입출력이 고정된 길이이지만 가변과정인 경우 RNN은 상당히 유용하다.
  1. 이미지 전체를 보는것이 아니라 이미지의 여러부분을 조금씩 살펴보며 숫자가 몇인지 최종적으로 판단

  1. Train time에서 본 이미지를 바탕으로 새로운 이미지를 만들어냄 (순차적으로 전체 출력의 일부분씩 생성)

DRAW: A Recurrent Nueral Network For Image Generataion

기본적인 RNN 구조

 

동작 순서

  1. 입력 x가 RNN에 들어온다.
  2. Hidden state를 업데이트한다.
  3. 출력값을 내보낸다.

특징

  • 일반적으로 RNN은 작은 Recurrent Core Cell을 가지고 있다.
  • RNN Block은 재귀적인 관계를 연산 할 수 있도록 설계되었다.
  • RNN에서 출력값 y를 얻을려면 FC layer를 추가해야한다. 이때 FC layer는 매번 업데이트 되는 hidden state를 기반으로 출력값을 결정한다.
  • 함수 $f_w$는 이전 상태의 Hidden state와 현재 상태의 입력인 $X_t$를 입력으로 받아 $H_t$를 출력한다.
  • 또한 함수 f와 파라미터 w는 매 스텝 동일하다.

Vanilla RNN 수식화

  • 아래는 Vanilla RNN을 수식화한것이다.

  • 함수 $f_w$를 활성화 함수 tanh와 가중치 W를 나눠 다시 쓰면 위와 같다.
  • 각각의 가중치 W는 이전 Hidden state와 입력 x의 곱한후 이 둘을 더해 tanh의 들어가 새로운 Hidden state인 $h_t$를 생성한다.
  • 또한 각각의 $h_t$의 또 다른 가중치 W를 곱해 출력값 $y_t$를 생성한다.

RNN의 Computation graph

  • 보통 $h_0$는 0으로 초기화한다.
  • backward pass시 $\frac{dloss}{dw}$를 계산하기 위해 w의 gradient를 모두 더해주었다.
  • 따라서 backprop을 위란 w의 gradient를 구하려면 각 스텝에서 w에 대한 gradient를 전부 계산한 뒤에 이 값들을 모두 더해주면 된다.
  • $h_t$는 또 다른 네트워크레 들어가 $y_t$를 만들어낸다. 이때 $y_t$는 매 step의 calss score가 될 수 있다.
  • RNN의 최종 loss는 각 개별 loss들의 합이고 loss flowing은 각 step에서 이루어 진다.
  • 따라서 각 step에서 가중치 w에 대한 local gradient를 계산할 수 있고 또한 개별로 구해진 local gradient,를 최종 gradient에 더한다.
  • 용어정리Ground truth → 우리의 모델이 우리가 원하는 답으로 예측해주길 바라는 답
  • 참고사이트 : https://mac-user-guide.tistory.com/14?category=775535
  • Label → 명확하게 정해져있는 답

Seq2seq 모델의 구성

ex) Muchine translation

  • Many to one: 이 부분은 encoder로 가변입력을 받아 하나의 단일 출력을 만든다. encoder의 final hidden state를 통해 전체 sentence를 용약한다.
  • One to many: 이 부분은 decoder로 encoder로부터 단일 입력을 받아 가변출력을 만든다.
  • output sentence의 각 loss를 합해서 backprop을 계산한다.

RNN Example: Character-level Language Model

Train time

과정

  • 각각의 char를 원-핫 인코딩하여 input으로 넣는다.
  • input은 hidden state에 들어가 연산과정을 거친후 score로 변하고 매 step마다 output을 만든다. 이때 hidden state의 $h_t$는 다음 step의 연산에 참여한다.
  • 각 step에서 만들어진 output은 $x_t$다음에 어떤것이 올지 예측한는 척도로 사용된다.

Test time

  • output에 대해 softmax함수를 사용하여 각각의 char의 확률분포를 만든다.
  • 만들어진 확률분포에 근거하여 sampling을 하여 다은 step의 input으로 사용한다.
  • 이 과정을 반복한다.

Q. 가장 높은 score를 선택하면 그만인데 왜 굳이 확률붙포에서 sampling하는지?

→ 실제로는 두 경우 모두 사용할 수 있다. 어떤경우에는 argmax probablity만을 사용할 수 있다. 또한 이러한 방법은 안정적인 방법이다. 하지만 sampling하는 방법을 사용하면 일반적인 모델에서 다양성을 얻을 수 있다.

→ 항상 같은 접두사(예제에서는 ‘h’)라던지, 이미지라면 같은 사진이라던지를 모델 입력으로 주면 argmax를 하지않고 sampling을 하게되면 그럴듯한 다양한 문장을 출력할 수 있게 된다. 즉 첫 step에서 어떤 값이 sampling되는지에 따라서 출력이 다양해 질 수 있는 것이다.

Q. test-time에서 softmax vector를 one-hot vector대신 넣을 수 있는지?

→ train-time에서의 입력과 달라져서 모델이 재성능을 발휘하지 못하게된다.

→ one-hot vector는 실제로 sparse vector operation으로 처리하기 때문에 연산량이 엄청날 것이다.

RNN backpropagation 문제점

  • forward pass에서는 전체 시퀀스가 끝날때까지 출력값을 생선한다. 따라서 backward pass에서도 전체 시퀀스를 가지고 loss를 구해야 한다.
  • 하지만 전체 시퀀스가 너무 길경우에는 loss의 업데이트가 너무 느리게 된다.

Truncated backpropagation

  • 해결책: Truncated backprop을 통해 근사시키는 방법

방법

  • Train time의 한 step을 일정 단위로 자른다.
  • 이 서브 시퀀스만 forward pass하고 loss를 계산하고 gradient step을 진행한다.
  • SGD와 같은 개념

→ 이러한 과정을 반복한다. 다만 이전 batch에서 계산한 hidden state는 계속 유지한다. 다음 batch에 forward pass를 진행할 때는 이전 hidden state를 이용한다. 그리고 gradient step은 현재 batch에서만 진행한다.

RNN 활용 예시

  • William Shakespeare

  • Latex source

  • linux source code

 

Searching for interpretable cells

hidden vector 하나를 뽑아서 어떤값이 있는지 살펴보기

  • 대부분의 hidden state는 아무의미 없는 패턴으로 예의 주시하고 있다. (RNN의 대부분 cell은 해석하기 어렵다.)

의미있는 cell

  • quote dectection cell(따옴표를 찾는 벡터)

 

→ 처음에는 파란색이지만 따옴표를 만나면 값이 커진다(빨간색으로 변함). 그리고 따옴표가 닫히기 전까지 유지된다.

  • line length tracking cell

→ 줄바꿈을 위한 현재 줄의 단어 개수를 세는듯해 보이는 cell

  • if statement cell

→ if문을 구별하는 cell

  • quote/comment cell

  • code depth cell

Image Captioning

image captioning은 입력은 이미지(단일 입

력)이고 출력은 자연어로된 caption(가변출력)이다.

 

  • CNN은 요약된 이미지정보가 들어있는 vector를 출력하고 이 vector는 RNN의 초기 step의 입력으로 들어간다.
  • RNN은 caption에 사용할 문자들을 하나씩 만들어 낸다.

Image captioning 과정

  • 이미지가 input으로 CNN에 들어가 Conv layer를 거쳐 하나의 vector로 변환된다.
  • 이때 기존 CNN과 다른점은 Classification을 위한 FC-layer와 softmax함수를 제거 했다는 점이다.
  • 이렇게 만들어진 vector는 RNN의 hidden state의 이미지 정보가 담긴 하나의 변수로 사용된다.

  • RNN의 hidden state에서는 똑같이 출력값을 만들고 sampling과정을 수행한다.

  • 네트워크가 학습되는 동안에 시퀀스의 끝에 토큰을 넣어줘야한다는 것을 알려줘야 하기 때문에 train time에는 모든 caption의 종료지점에 토큰을 삽입한다.
  • 토큰이 sampling되면 종료한다.
  • 이 모델은 supervised learning으롷 학습한다. 따라서 natural language caption이 있는 이미지를 가지고 있어야한다.
  • 이 모델을 학습시킬때 natural language model과 CNN을 동시에 backprop시킬수 있다.???

Base Image captioning Example

  • 성공

  • 실패

Image captioning with Attention

기본적인 image captioning방식을 업그레이드 시킨 방법

  • 이 모델은 Caption을 생성할 때 이미지의 다양한 부분을 집중해서 볼 수 있다.

Image captioning with Attention 과정

  • CNN에서 벡터하나를 만들어 내는 것이 아니라 각 벡터가 공간정보를 가지고 있는 grid of vector를 만들어 낸다.
  • hidden state에서는 이 grid of vector를 가지고 이미지 위치에 대한 분포를 계산하여 a를 만들어 낸다.
  • a는 기존 grid of vector와 연산하여 이미지 attention인 z를 생성한다.

→ forward pass시 매 step vocabulary에서 sampling 할 때 모델이 이미지에서 보고싶은 위치에 대한 분포 또한 만들어 낸다.

→ 이미지의 각 위치에 대한 분포는 train time에 모델이 어느 위치를 봐야하는지에 대한 attention이라고 할 수 있다.

  • 요약된 벡터 z는 다은 step의 입력으로 사용된다.
  • hidden state에서는 단어들에 분포와 이미지 위치에 대한 분포 두 개를 만든다.
  • 이 과정을 반복한다.

Attention vector

Soft attention: 모든 feature와 모든 image location간의 weighted combination을 취하는 경우

Hard attention: 모델이 각 time step마다 단 한 곳만 보도록 강제한 경우 (이미지 위치를 딱 한 곳만 정해야 하지만 사실상 정하기 까다롭다. 따라서 Hard attention을 학습시키려면 기본 backprop보다는 조금 다른 방법을 사용해야 한다.)

Image captioning with Attention Example

  • 이미지의 중요한 곳에 attention을 하게 된다.

Visual Question Answering

RNN + Attention 방식

  • 두 개의 input(이미지, 이미지에 대한 질문)을 갖는다.

Multi layer RNN

  • 지금까지는 단일층에 대한 RNN이었다면 위에 그림은 여러층의 hidden state층이 쌓인 multi layer RNN이다.
  • 입력이 첫 번째 RNN으로 들어가서 첫 번째 hidden layer를 만든다. RNN를 돌리면 hidden states 시퀀스가 생기게 된다.
  • 이렇게 만들어진 hidden state는 시퀀스를 다른 RNN의 입력으로 넣어 줄 수 있다.
  • 모델이 깊어질 수록 성능일 좋아지지만 너무많이 쌓지 않고 보통 2~4정도가 적당하다.

Vanilla RNN의 gradient flow

  • backward pass시 $h_t$에 대한 loss를 얻고 그 다음 그 loss에 대한 $h_{t-1}$를 얻는다.
  • gradient는 tanh gate를 타고 흘러가고 드 다음 mat mul gate를 통과한다.
  • 이때 mat mul gate의 backprop은 transpose(가중치 행렬)을 곱하게 된다. (이것은 매번 Vanilla RNN cell을 하나 통과할 때마다 가중치 행렬의 일부를 곱하게 된다는것을 의미한다.)

  • RNN의 hidden state의 파라미터인 W는 매 step마다 똑같은 값을 가지기 때문에 W값이 1보다 클 경우 Exploding gradients를 발생시키고 1보다 작을 경우 Vanishing gradients를 발생시킨다.

Exploding / Vanishing gradient 해결방법

  • Exploding gradient: Gradient clipping (gradient를 계산하고 gradient L2 norm이 threshold보다 큰 경우 gradient가 최대 threshold를 넘ㅁ지 못하게 조정해준다.)
  • Vanishing gradient: Change RNN architecture, 딱히 좋은 방법이 없음

Long short Term Memory(LSTM)

  • LSTM은 Vanilla RNN의 fancier한 버전이며 exploding/vanishing gradient문제를 완화시키기 위해 디자인 되었다.
  • LSTM도 두 개의 input($h_{t-1}$, $x_t$)를 받고 i, f, o, g 4개의 gate를 계산한다. 이 gate들은 $c_t$를 업데이트 하는데 이용되며 $c_t$는 다음 hidden state를 업데이트한다.
  • LSTM은 한 cell당 두 개의 hidden state가 존재한다. 하나는 $h_t$이고 이는 vanilla RNN에 있얶던 hidden state와 유사하다. 다른 하나는 $c_t$(cell state)이며 이는 LSTM내부에만 존재하며 밖에 노출되지 않는다.

LSTM 구성

  • Vanilla RNN은 $h_{t-1}$과 $x_t$를 concat하고 행렬곱 연산으로 hidden state를 직접 구했지만 LSTM은 다르다.
  • LSTM은 $h_{t-1}$과 $x_t$를 stack으로 쌓고 가중치행렬 W를 곱한 뒤 4개의 gate(i, f, o, g)를 거친다.
  • 이때 각각의 gate들은 다른 활성화함수를 사용한다.

Gate

  • i: cell에서의 입력 x에 대한 가중치
  • f: 이전 step의 cell의 정보를 얼마나 망각할지에 대한 가중치, $c_t$의 onoff를 결정
  • o: cell state, $c_t$를 얼마나 밖에 드러내 보일지에 대한 가중치
  • g: input cell을 얼마나 포함시킬지 결정하는 가중치

LSTM 과정

전체적인 과정

  • $h_{t-1}$과 $x_t$를 stack으로 쌓아 가중치 행렬 W와 mat mul 연산을 한다.
  • 연산된 경과값을 각각의 gate로 보내 연산을 수행한다.
    • f gate는 $c_{t-1}$과 element wise mul을 수행한다. (이전 $c_{t-1}$을 기억할지 말지 결정)
    • i gate와 g gate는 서로 element wise mul을 수행한다. (cell에서 사용하고 싶은 후보를 결정)
  • 위에 두 gate의 연산과정의 결과값들을 더해 $c_t$를 생성한다. ($c_t$의 각 요소는 scaler interger counter처럼 값이 늘었다 줄었다 하는것으로 볼 수 있다.)
  • $c_t$는 tanh를 통과후 o gate와 element wise mul을 하여 최종적인 $h_t$를 생성한다.

2가지 장점

  • 매 step 같은 W값이 곱해지는 Vanilla RNN과 달리 step마다 다른 f값이 곱해진다.
  • backprop시 mat mul연산 대신에 element wise mul을 수행한다.

  • 이러한 LSTM의 backward flow는 마치 highway와 같이 쉽고 빠르게 수행된다.

Other RNN variants

Summary


Syllabus

Youtube

BELATED ARTICLES

more