본문 바로가기
데이터 과학 관련 스터디/cs231n

cs231n 10강 Recurrent Neural Networks 요약

by inhovation97 2020. 12. 12.

10장은 시계열 데이터에서 많이 쓰이는 RNN에 대해서 공부합니다.

 

이제껏 배운 보통의 뉴럴넷은 입력값 1개 -> 출력값 1개 였습니다.

 

입력값이 많거나 출력값이 많을 수도 있죠.

RNN은 이럴때 쓰입니다.

 

one to many는 지난 강의에서 언급한 적이 있는 이미지 캡셔닝에서 많이 쓰입니다.

 

many to one은 감정 분류에 많이 쓰인다고 합니다.

뉴스 카테고리 분석에서도 많이 쓰이죠

아마 입력 데이터가 sequential한 문장들일 겁니다.

 

중간에 hidden state가 많은 many to many는 Machine Translation 번역 머신에 많이 쓰인다고 합니다.

언어 -> 언어로 번역해주는 역할

 

마지막 many to many는 매 프레임 마다 값이 입력되고, 출력이 돼야하는 비디오에 쓰인다고합니다.

 

위에서 말한 데이터들은 전부 가변길이를 지닌 데이터들입니다.

문장이나 단어들은 전부 길이가 다르고, 비디오 데이터는 sequential해서 데이터 point 하나 하나 독립적으로 보면 안되고, 매 프레임마다 출력이 돼야하죠.

RNN은 이렇게 가변길이를 지닌 데이터에 강점이 있습니다.

 

하지만 고정길이의 데이터에도 유용하다고합니다.

위 데이터는 전부 크기가 같은 데이터입니다.

RNN은 데이터를 sequential하게 접근하는데, 아마 위 숫자를 인식하는 데에 그 부분이 잘먹힌 것 같습니다.

 

이제 RNN을 자세히 살펴봅시다.

RNN은 입력값이 입력되면, hidden state로 들어갑니다.

이 hidden state는 입력값 마다 매번 update됩니다.

hidden state를 담당하는 가중치가 따로 있는 것입니다.

 

수식을 봅시다.

입력값에 이전의 hidden state값이 함께 함수에 들어가는게 보이시죠??

그렇게 function을 거치면 새로운 new state값이 되는 것입니다.

sequential하게 접근한다는 것이 이해가 됩니다.

 

기본적인 RNN의 구조를 봅시다.

이전의 state값과 입력값이 new state를 만들고 출력값 y를 뱉어낸다고 했습니다.

그 과정에서 가중치가 3개나 쓰입니다.

x 입력값에 대한 Wxh, old state에 대한 Whh, new state에 대한 Why

 

계속해서 이전의 state가 반영되어 새로운 state를 만드니 sequential 데이터에 강점이 있지만, 주의할 점이 있습니다.

3개의 가중치는 절대 변하지 않습니다.

모두 고정된 가중치 벡터를 이용한다고합니다.

매 step에서 파라미터나 function이 달라지진 않고, 과거 데이터의 변동만으로 따라가는 것이지요.

 

순서도로 이해해봅시다.

입력값이 계속해서 들어가고, state가 만들어지는 상황이 만들어집니다.

아 h0은 initial state로 보통 0으로 시작한다고 합니다.

 

이것을 보면, 계속해서 똑같은 가중치 W 값이 function에 관여합니다.

그리고 각 출력값마다 나오는 loss값들의 총합이 최종 loss값이 됩니다.

 

개별 loss, hidden state가 있어 일반적인 모델과 다르니 back prop 과정을 생각해봅시다.

학습시 dl/dw를 구해야합니다.

step마다의 loss를 가중치 w에 대해서 local gradient를 계산한 뒤, 이 local gradient를 전부 더해줍니다.

 

Many to Many를 예로 Computational Graph를 이해한겁니다.

 

Many to one, one to many입니다.

입력값은 많고, y는 1개만 나옵니다.

딱히 특별히 다룰게 없습니다.

 

이번에는 many to one과 one to many를 더한 구조입니다,

seqeunce to sequence라고 설명합니다.

2개의 state가 합쳐진 구조인데, Encoder는 가변 입력을 받고 요약하면, 이를 다시 입력값으로 넣어 decoder가 가변 출력을 뱉습니다.

가령, 영어 문장 -> 문장이 요약된 single vector -> 다른 언어로 번역되어 최종 출력

 

hello를 예롤 봅시다.

일단 원-핫 인코딩을 해준 것을 볼 수 있습니다.

입력값은 h, e, l, l 순으로 들어갑니다.

출력값은 e, l, l, o가 나오면 베스트겠죠?

다음에 올 문자를 예측하는 겁니다.

 

그런데 여기서 결과를 보면 o 일 확률이 4.1로 가장 높게 나왔다. 즉, 잘못 예측하고 있는 것이다. 마찬가지로 다음 문자들에 대해 진행을 해보면 이전 internal state 를 이용해 새로운 internal state 를 만들게 된다.현재의 상태에서는 잘못 예측하는 값들이 많은데, 이러할 경우 loss 가 클 것이고, 적절하게 학습 과정이 진행된다면 나중에는 잘 예측하는 모델이 완성될 것이다.
이 모델의 test time 은 어떨까? 입력값이 들어가면 train 때 모델이 봤을 법한 문자를 만들어 내게 된다. 첫 입력인 h 가 있다면, 모든 character (h,e,l,o) 에 대해 score 가 output layer 로 나오게 된다. test time 에서는 이 score 를 다음 글자 선택에 사용하게 된다.
이 score 의 확률분포를 표현하기 위해 softmax 로 변환하는 과정을 거치는데, h 다음의 문자를 예측하기 위해서 이 확률분포를 사용하게 된다. 가장 큰 score 는 o 였으나, 확률적으로 운이 좋아 e 가 선택된 경우가 바로 위의 이미지이다.
그러한 과정을 거쳐서 test time 때 입력에 대한 출력의 예측값을 표현하게 된다.
score 를 쓰지 않고 확률분포를 쓰는 것에 대해 의아해할 수 있으나, score 만 보았다면 위의 hello 예제에서 올바른 답을 낼 수 없었을 것이다. 실제로 확률분포와 score 를 모두 사용할 수 있다고 하나 확률분포를 사용하는 이유는 모델에서 다양성을 얻을 수 있기 때문이다.

https://leechamin.tistory.com/108

첫 번째 출력값에서 o가 확률이 제일 높은데 e로 예측한 이유를 확률 분포를 썼기 때문이라고 설명하고 있습니다. 저도 softmax에 대해서 좀 더 자세히 살펴보고 와야할 것 같습니다.

 

y값마다 나오는 loss의 값들을 통해서 최종 loss를 얻습니다.

입력값이 전부 입력되고 위의 과정이 전부 끝나야 최종 loss를 얻고 그제서야 back prop을 할 수 있습니다.

이게 문제가 됩니다.

 

입력 sequence가 너무 길면, 그 입력값을 전부 넣고 위 과정이 전부 끝나야 back prop을 할 수 있는 겁니다.

너무나도 비효율적입니다.

 

그래서 보통 Truncated Back prop을 씁니다.

train time에서 한 step을 일정 단위로 자릅니다.

mini batch의 개념이랑 같은데, n개로 자르면 n개를 forwad 하고, loss를 계산하고 gradient를 통해 update해나갑니다.

 

지난 강의에서 언급했었던 이미지 캡셔닝은 CNN과 RNN을 합친 구조입니다.

한 번 살펴봅시다.

 

test time 과정입니다.

CNN의 구조에서 최종 출력 layer를 제거하여, FC layer에서 이미지의 vector값만을 가져옵니다.

이는 이미지에 대한 정보들이 요약되어 있습니다.

 

이 값들을 이제 RNN에 넣습니다.

이 벡터들에 대해서 Wih라는 가중치가 생깁니다.

 

이런 식으로 sample값으로 단어가 나오고, 그것이 입력값으로 들어가면서 최종 end token이 나옵니다.

end 토큰은 train 과정에서 해당 caption에 대해서 끝이 났음을 알려줘야하므로 미리 삽입해 놓는다고 합니다.

 

이미지 캡셔닝이 이렇게 학습이 잘 됐습니다.

이미지 캡셔닝은 Supervised learning으로 natural language caption이 있는 이미지를 이용해서 학습해야 하죠. 

 

1번째 사진을 보면, 여성을 고양이라고 설명하고 있습니다.

이렇게 학습이 잘 안되는 경우도 물론 있습니다.

 

이번에는 좀 더 상위 버전인 Image captioning with Attention 알고리즘을 봅시다.

이미지의 다양한 부분에 attention해서 해석해줍니다,

 

먼저 CNN에서 LxD의 필터(?) 비슷한 것을 만들어냅니다.

공간 정보를 가지고 있는 grid of sector입니다.

 

forward과정에서 매 step(hidden state)에서 이미지 위치에 대한 다양한 분포를 계산합니다. attention하고 싶은 위치를 계산하는 거죠.

이 값이 a1이고 이게 grid of sector와 연산하여 attention(z1)을 만들어냅니다.

 

이제 이 z1 값이 word와 함께 입력값으로 들어가고 a2, d1이 나옵니다 이게 반복되죠.

 

a값이 hidden state마다 달라니지attention 부분이 계속해서 달라지는 것이 보입니다.

soft 부분은 모든 특징과 weight를 보고, hard는 attention의 위치에 좀 더 집중한다고 합니다.

 

attention을 이용한 이미지 캡셔닝은 이미지 내에 중요한 객체에 집중한 것이 눈에 띕니다.

 

이건 Visual Question Answering으로 입력이 image와 image에 관련된 질문이라고 합니다.

이미지에 맞춰서 답을 찾는 모델인거죠.

이 알고리즘도 CNN과 RNN을 합친 모델입니다.

many to one이죠.

 

보통은 RNN은 잘 쓰지않고, LSTM을 많이 쓴다고 합니다.

RNN은 오른쪽 그래프처럼 multi layer로 쌓아야 성능이 웬만큼 나옵니다.

하지만 그렇게하면 문제가 생기기 때문이죠.

 

RNN은 이전 state와 입력값을 stack해줍니다.

그렇게하면 backward시에 tanh함수를 지나쳐 mul게이트에서 가중치 행렬을 다시 곱해주게 됩니다.

cell을 지날때마다 가중치를 계속 곱해줍니다.

 

가중치가 1보다 크면 값이 계속 커져서 기울기가 explode하게됩니다.

그나마 explode는 clipping이라는 것으로 제한해줄 수 있지만,

1보다 작아서 vanishing 한다면, 답이 없습니다.

슬라이드에서는 아예 RNN 아키텍쳐를 바꾸라고 나오죠.

 

그래서 LSTM(Long Short Term Memory)을 씁니다.

RNN에서 기울기의 문제를 완화하기 위해 나온 알고리즘입니다.

 

하나의 셀에 2개의 hidden state가 존재합니다. ct, ht

ct값은 lstm 내부에만 있고, 노출되지 않습니다.

 

hidden state를 스택하고 4개의 gate로 가중치 행렬을 곱해줍니다. (ifog)

i 는 input gate 인데 cell 에서의 입력 x_t 에 대한 가중치입니다.

f 는 forget gate 이다. 이전 스텝의 cell 을 얼마나 잊을지 정합니다.

o 는 output gate 이다. cell state 를 얼마나 밖으로 출력할 것이냐를 정합니다.

g 는 따로 부르는게 없어서 강의자는 gate gate 라 부른다. input cell 을 얼마나 포함시킬지를 정합니다.

 

 

sigmoid gate를 나온 값들 보다는 tanh gate를 나온 값이 main인 것 같은데 아직 제대로 이해는 안갑니다...

그래도 아까 가중치가 굉장히 많아서 back prop하기가 지저분했던 RNN보다는 활성화 함수를 4개 이용한 LSTM에서의 Back prop이 훨씬 나아 보입니다.

 

ifog 게이트가 ResNet처럼 gradient flow에 매우 도움이 됐다고합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

댓글