무슨 생각을 해 그냥 하는거지

[학습정리] 2021-09-07 본문

Naver AI Tech 2기/Today I Learned

[학습정리] 2021-09-07

빛나는콩 2021. 9. 8. 02:55

※ 정보전달이 목적인 포스트가 아니라 개인 학습 기록 및 정리가 목적인 포스트입니다 ※

해당 포스트는 네이버 커넥트 재단의 부스트캠프 마스터님이신 주재걸 교수님의 강의를 바탕으로 작성되었습니다.

 

 

1. 강의 복습 내용

[RNN]

좌: rolled RNN, 우: unrolled RNN

  • RNN의 특징은 매 timestep마다 같은 weight를 사용한다는 것.
  • 이때 output vector y_t는 problem setting이 어떤 것이냐에 따라 매 timestep마다 계산해야 할 수도 있고, 마지막에만 계산해야 할 수도 있다.
  • y_t는 binary classification인 경우, output dimension이 1. multi-class classification인 경우 class 개수만큼의 dimension을 갖는다. (vector로 봐서 dimension이라고 표현한 듯 하다.)

h_t가 계산되는 과정

 

Problem Settings

  • one-to-one: standard neural network
  • one-to-many: 입력은 하나의 timestep, 출력은 여러 timestep인 경우. 이때 출력 timestep 길이에 맞게 0으로 이루어진(원래 입력값과 같은 dimension의) 입력이 각 timstep에 들어간다. e.g.) Image Captioning.
  • many-to-one: 입력으로는 sequence of text, 출력은 하나의 결과가 나오는 것. e.g.) Sentiment Classification

  • many-to-many(좌): 입력으로 주어진 문장을 다 읽고 나서 출력을 만드는 경우. (그래서 delay 발생) e.g.) Machine Translation
  • many-to-many(우): delay 없이 바로 출력을 생성하는 경우 e.g.) PoS tagging

 

RNN의 단점: backpropagation 동안 각 timestep에서 같은 행렬을 곱해주기 때문에 gradient vanishing / exploding이 발생할 확률이 높고 이는 학습이 제대로 이뤄지지 않게 함.

이런 단점을 개선하기 위해 LSTM, GRU가 등장!

 

 

[LSTM]

  • 어떤 transformation도 거치지 않고 cell state 정보를 그대로 통과시키자! 가 핵심 아이디어.
  • cell state 중에서 필요한 정보를 쏙쏙 뽑아서 현재 timestep의 hidden state로 업데이트해준다.
  • LSTM의 관점으로는 RNN의 hidden state vector를 단기 기억을 담당하는 소자로 볼 수 있음.
  • {C_t, h_t} = LSTM( x_t, C_(t-1), h_(t-1) )

Long Short-Term Memory

네 개의 gate를 갖고 있다.

  • i: input gate, h_(t-1)과 x_t를 cell에 반영(write)할 것인지 정하는 게이트
  • g: gate gate (update gate), C tilde. input gate와 곱해지면서 얼마나 cell에 반영할지 정하는 게이트
  • f: forget gate, cell을 지울지(잊어버릴지) 정하는 게이트
  • o: output gate, cell을 얼마나 드러낼지(reveal) 정하는 게이트

x_t, h_(t-1)

 

Forget gate (f)

: 이전 timestep의 cell state c_(t-1)과 element-wise로 곱해져서 이전 timestep에서 넘어온 정보를 얼마나 유지할지 결정한다. (f vector 값이 0.7이면 30 퍼센트만 유지한다는 뜻 → sigmoid가 0에서 1 사이 값으로 만들어주기 때문)

 

 

 

Input gate (i) & Gate gate (g, C tilde)

: gate gate는 4개의 게이트 중 유일하게 tanh를 거쳐 -1에서 1 사이 값을 갖는다. (regulate 기능을 한다는 데 sigmoid와 무슨 차일까?)

 

 

Output gate (o)

: o_t는 sigmoid를 거치기 때문에 0에서 1사이의 값을 갖는다. 이게 C_t가 tanh를 거친 값과 곱해지기 때문에 방대한 C_t에서 지금 당장 필요한 내용을 필터링해 현재 timestep의 hidden state를 만든다.

 

 

[GRU]

GRU 특징

  1. LSTM의 cell state와 hidden state을 hidden state 하나로 일원화.
  2. 두 개의 독립된 게이트를 하나의 게이트로 연산 → 계산량과 메모리 용량을 줄임. 경량화 모델

c.f 는 LSTM에서 gate를 쓰는 방식, 나머지 위의 내용들은 GRU 관련 내용이다.

LSTM은 forget gate를 사용했는데, GRU는 input gate(GRU에서는 z_t)만 사용하고, 1에서 input gate를 뺀 만큼(1-z_t)을 forget gate처럼 사용했다. input gate z_t가 커지면 forget gate 역할인 (1-z_t)가 작아지고, z_t가 sigmoid를 거친 형태기 때문에 0과 1 사이의 값을 가져 가중 평균 형태로 계산된다.

 

 

Backpropagation in LSTM & GRU

LSTM과 GRU 모두 RNN과 다르게 덧셈에 기반한 연산(additive interactions)이기 때문에 gradient vanishing/exploding 문제가 발생하지 않는다.

 

 

 


2. 과제 수행 과정 / 결과물 정리

[RNN 실습]

nn.RNN()

inputs: input, h_0

input: batch_first=False 인 경우 (L(sequence length), N(batch size), H_in(input size)) 형태의 tensor

        batch_first=True 인 경우 (N, L, H_in) 형태의 tensor를 입력으로 받는다.

h_0: (D(bidirectional=True이면 2, 아니면 1)*num_layers, N, H_out(hidden size)) 형태의 tensor. default로 zeros

 

outputs: output, h_n

output: batch_first=False 인 경우 (L, N, D*H_out) 형태의 tensor

        batch_first=True 인 경우 (N, L, D*H_out) 형태의 tensor

h_n: (D*num_layers, N, H_out)

 

output은 hidden_states(각 time step에 해당하는 hidden state들의 묶음)를, h_n은 모든 sequence를 거치고 나온 마지막 hidden state를 의미한다. 

여기서 얻은 마지막 hidden state를 nn.Linear의 인풋으로 넣어 classification에 활용할 수 있다.

혹은 hidden_states를 이용하여 token-level의 task도 수행할 수 있다. (마찬가지로 nn.Linear 활용)

 

PackedSequence

길이가 다른 sequence들을 학습 데이터로 사용할 때 가장 긴 sequence 길이에 맞추어 0으로 padding을 하는데, 원래 길이 기준으로 정렬하면 불필요한 pad 계산을 하지 않아도 된다.

 

 

[LSTM, GRU 실습]

nn.LSTM

cell state가 추가되어 RNN 사용법에서 cell state를 추가해주면 된다.

 

nn.GRU

cell state가 없기 때문에 RNN 사용법과 동일하다.

 

 

[필수과제2. RNN-based Language Model]

input → encoding (by encoder) → (dropout) → model(RNN) → (dropout) → decoding → F.log_softmax()

nn.RNN의 아웃풋으로 output, hidden이 나오는데, language model이니까 decoder의 인풋으로는 output(모든 hidden states)이 들어가야 한다.

 

 


3. 피어세션 정리

  • pack_padded_sequence를 사용할 때 embedding한 데이터를 왜 transpose(0, 1)하는가?

→ rnn을 처음 만들어줄 때 batch_first 옵션을 True로 한다면 하지 않아도 된다. (어차피 batch size가 앞이니까.) default가 False기 때문에 실습 코드에서는 transpose(0, 1)를 해줘야 차원이 맞다.

  • Truncated BPTT는 many-to-many일 때만 가능한가?

→ 팀원분들의 설명이 맞는 것 같은데 좀 더 확실하게 알아보고 싶다.

  • 피어세션 시간을 추가적으로 써서 TMI 시간을 가졌다. 오늘의 tmi는 인상깊었던 여행지 소개하기~!

 

 


4. 학습 회고

  • 오늘은 솔직히 집중을 많이 못했다. 왜 이렇게 눈에 안들어오는지😂 낮에 집중을 못하니 밤에 고생한다 허허..
  • 1일 1커밋 3일차! 내일도 파이팅해서 작심삼일만 하지 말자😈

 

'Naver AI Tech 2기 > Today I Learned' 카테고리의 다른 글

[학습정리] 2021-09-09  (0) 2021.09.11
[학습정리] 2021-09-08  (0) 2021.09.09
[학습정리] 2021-09-06  (4) 2021.09.07
[학습정리] 2021-08-27  (0) 2021.08.27
[학습정리] 2021-08-25  (0) 2021.08.27