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

[학습정리] 2021-09-13 ~ 본문

Naver AI Tech 2기/Today I Learned

[학습정리] 2021-09-13 ~

빛나는콩 2021. 9. 23. 01:47

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

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

 

1. 강의 복습 내용

[Transformer]

Bi-Directional RNNs

단방향 RNN은 문장의 마지막 단어로부터 멀리 있는 단어에 대한 정보 유실/변질이 발생한다. (Long-Term Dependency)

이를 해결하기 위해 순방향과 역방향을 모두 고려한 Bi-directional RNN이 소개되었다.

위 그림의 파란색 hidden state는 bi-direction RNN의 hidden state로, 순방향의 hidden state와 역방향의 hidden state를 concat하여 단방향 hidden state*2가 된다.

 

Transformer

transformer는 attention을 사용하면서 Long-term dependency를 해결하였다.Seq2Seq with attention에서 사용했던 방식과 유사한데, transformer에서는 self-attention을 사용하면서 약간의 차이가 있다.

transformer의 attention module

  • 각 단어의 input vector(예를 들어 위의 단어 I에 대한 벡터)가 Seq2Seq에서의 decoder의 특정 timestep의 hidden state vector 같은 역할을 한다.
  • 단어들의 input vector들(위 그림에서의 x_1, x_2, x_3)은 Seq2Seq에서의 encoder의 hidden state vectors와 같다.

1) I는 I(자기 자신), go, home과 각각 내적 → 각 단어에 대한 유사도를 구한다.2) 각 내적값을 softmax를 취하고 더한 후, 입력 벡터에 대한 선형 결합(가중 평균)을 통해 encoding vector(h_1)를 생성한다.두 번째 단어인 go를 위와 같은 방식으로 수행 (I, go(자기 자신), home과 각각 내적 ... ) → h_2마지막 단어까지 수행 → h_3

 

그런데 단순 입력 벡터에 대한 내적을 수행하면, 항상 자기 자신에 대한 내적값이 가장 높게 나올 것이다.

그래서 각 단어(같은 단어)가 상황에 맞게 다른 역할을 수행할 수 있도록 선형 변환을 해 세 가지의 벡터를 만든다.

 

  • Query: 기준이 되는 벡터. decoder의 hidden state 역할
  • Key: query와 내적되는 재료 벡터
  • Value: 가중치가 실제로 적용되는 벡터

https://jalammar.github.io/illustrated-transformer/

  • key와 value는 1:1로 매칭된다.
  • 기준이 되는 거니까 query는 하나의 벡터고, key와 value는 행렬(각 벡터들이 합쳐져 있는)이다.
  • query vector와 key vector는 내적해야 하니까 dimension이 같아야 하고,
  • 두 벡터의 내적의 합으로 생긴 가중치를 곱하는 거니까 value는 dimension이 같을 필요는 없다. (편의를 위해 코드상에서는 같게 하긴 함)
  • 최종 아웃풋의 dimension은 value의 dimension이다.

 

사실 query도 하나의 벡터만 있는 건 아니기 때문에 (단어가 여러 개니까) query도 행렬로 표현하면 아래와 같다.

여기서 또 문제는... 위의 식대로 하면 gradient vanishing 문제가 발생할 수 있다는 것이다.

 

a, b, x, y이 모두 각각 평균 0 분산 1인 랜덤변수라고 하자.

각 랜덤 변수들이 통계적으로 독립인 경우에 ax의 평균은 0, 분산은 1이 된다. (by도 마찬가지)

그럼 ax+by의 분산은 2가 된다.

지금은 2차원이라 작지만, key의 차원이 커지면 그만큼 분산도 커지게 된다. (100차원이면 분산은 100)

분산이 너무 큰 경우, softmax를 취했을 때 그만큼 하나의 노드에 너무 많이 몰리게 된다.

이렇게 query, key의 dimension이 softmax의 확률 분포에 영향을 끼치기 때문에, 이 영향을 줄이기 위해 분산이 key의 차원에 관계없이 1을 유지하도록 scaling factor sqrt(d_k)로 나눠주는 것이다.

attention 모듈의 최종 아웃풋

 

Transformer: Multi-Head Attention

동일한 sequence가 주어져도 다른 측면에서 정보를 뽑아야 할 수 있음. (주체의 행동의 정보, 장소의 정보, ... )

여러 개의 attention이 각각 다른 관점을 갖게 하자.

h는 attention 모듈의 개수
각 attention은 다른 W_Q, W_K, W_V를 갖고 있음

각각의 attention에서 output을 얻는다. (0번째 attention에서 Z_0, 1번째 attention에서 Z_1, ... )

 

각각의 attention에서 얻은 아웃풋들을 concat하고, concat하면 크기가 커지니까 원하는 dimension으로 만들어주기 위해 선형 변환을 한다.

 

Transformer: Block-based model

transformer의 block

각각의 block들은 두 개의 sub-layer(Multi-head attention, Two-layer feed-forward NN with ReLU)로 이루어져 있다.

근데 그 두 개의 sub-layer도 각각 residual connection과 layer normalization 있음.

 

Add & Norm 부분을 수식으로 표현하면,

Add

: Residual connection → gradient vanishing 문제 해결, 학습 안정화 효과

 입력 벡터와 attention 아웃풋의 차원이 같아야 함. (그래서 multi-head attention에서 concat한 아웃풋을 선형변환을 통해 원하는 크기로 바꿔준 것)

 

Norm

: Layer normalization

Batch normalization이랑 비슷하다고 생각할 수 있는데, batch norm은 mini-batch 단위로 normalization하고,

layer norm은 batch 와 무관하게 channel map C에 대해 normalization한다. 위 그림을 보고 좀 헷갈렸는데 아래 그림을 추가로 보고 이해가 됐다.

출처: https://yonghyuc.wordpress.com/2020/03/04/batch-norm-vs-layer-norm/ 에서 가져왔는데, 원본은 다른 사이트인 것 같다. (근데 원래 글에 안들어가지고 다른 사이트로 우회된다ㅠ)

위 그림의 batch를 살펴보면, [1, 2, 0, 4, 5, 1]이 하나의 sample이다. 이 sample의 1은 첫 번째 feature, 2는 두 번째 feature, 0은 세 번째 feature를 의미한다.

다음 sample인 [3, 2, 1, 6, 2, 0]도 마찬가지로 3은 첫 번째 feature, 2는 두 번째 feature, 1은 세 번째 feature.

다음 세 번째 sample인 [6, 2, 5, 1, 3, 1]도 위의 방식대로 6개의 feature를 갖는다.

위의 그림대로면 batch size가 3(하나의 batch에 sample 3개)이면서, 하나의 sample 당 6개의 feature를 갖는 것이다.

batch norm은 한 batch(모든 sample들)를 feature 마다 평균과 분산을 구해 정규화하고,

layer norm은 각 sample에 대해 모든 feature의 평균과 분산을 구해 정규화한다. (따라서 layer norm은 batch size에 영향을 받지 않는다.)

 

 

Transformer: Positional Encoding

문장은 특정 단어가 어디 있냐에 따라 의미가 완전히 달라진다. 그래서 단어의 위치를 표현하는 것이 굉장히 중요한데, 만약 transformer에서 positional encoding이 없다면 문장을 순서가 중요한 sequence로 여기는 게 아니라 집합으로 여기는 것과 같다.

dimension마다 다른 frequency를 갖는 sinusodial function을 사용

Q) 왜 토큰 순서대로 1, 2, 3 ... 과 같은 정수는 사용하지 않는가?

→ positional encoding 값이 커지면서 모델에 끼치는 영향이 지나치게 커질 수 있다.

🐣 sin / cos 함수는 1에서 -1 사이 값을 갖는다 !

→ 일정 길이의 토큰 정보만을 활용하면, 일정 길이 이상인 경우의 test dataset에서는 결과가 좋지 않다.

🐣 sin / cos 함수는 주기 함수라서 괜찮다 !

 

 

Transformer: Decoder

encoder와 다르게 Masked multi-haed attention, encoder-decoder attention이 있다.

빨간 박스 부분이 decoder

 

Transformer: Masked Self-Attention

batch processing을 위해 입력을 동시에 주긴 하지만, 아직 만들어지지 않은 단어에 모델이 접근할 수 없도록 제외(masking)해주어야 한다.

위 그림 오른쪽에서, 특정 timestep 뒤의 단어를 masking해주는 것 뿐만 아니라 masking하지 않은 다른 단어에 대해서 새로 softmax를 해줘야 한다. e.g. 0.91 → 1.0

 

 

 

 


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

[Masked multi-head attention 실습]

torch.tril(input, diagonal=0)

pytorch documentation torch.tril

diagonal=0 (default)일 때 대각 윗부분을 모두 0으로 변환해줌.

 

torch.Tensor.masked_fill_(mask, value)

mask(BoolTensor)가 True인 부분의 값을 value(float)로 채우는 함수.

 

<mask 생성>

(True인 곳은 attention이 적용됨, False인 곳이 masking될 자리)

실습 코드에서 padding_mask는 padding 부분을 False, padding 하지 않은 유효한 토큰을 True로 만들어준 것.

nopeak_mask는 대각 위로는 False, 대각 아래로는 True로 만들어준 것이다.

최종 마스크는 padding_mask와 nopeak_mask를 비트 연산 &를 수행해서 완성된다.

python & 비트연산 예시

mask.shape가 torch.Size([5])이고, test_tensor.shape가 torch.Size([2, 5])인데 자동으로 결과가 [2, 5]로 나오는 것을 확인할 수 있다.

실습 코드에서도 padding_mask가 [B, 1, L]의 사이즈를 갖고, nopeak_mask가 [1, L, L]의 사이즈를 가지는데,

둘의 비트 연산 결과는 [B, L, L]의 사이즈를 갖는다.

padding_mask의 빨간색 박스(문장 하나)와 nopeak_mask의 초록색 박스를 비트 연산 AND을 수행하면 result의 빨간색 박스로 된다. result는 해당 timestep 전까지의 입력이면서 padding 되지 않은 유효한 단어인 경우만 True를 갖게 된다.

 

 


3. 피어세션 정리

https://lilianweng.github.io/lil-log/2018/06/24/attention-attention.html

  • 논문리뷰 시작! 다른 캠퍼님들께서 TACOTRON, Including Signed Languages in Natural Laguage Processing를 리뷰해주셨다. 오랜만에(?) tacotron을 봐서 반가웠고, 수어를 nlp task로 볼 수 있다는 것이 흥미로웠다.
  • 함께 읽은 논문에 대해서 정리하는 게 아니라, 모두 다른 논문을 읽고 발표하는 것이기 때문에 핵심을 잘 짚을 수 있도록 리뷰하자는 의견이 나왔다.

 

 


4. 학습 회고

  • 사실 여기에 쓰면 안되지만... 다른 글 업로드가 조금 늦어질 것 같아서 여기에 쓴다. 이번주는 첫 nlp 강의 발표 요약+처음 접하는 분야(summarization)의 논문 리뷰 발표여서 엄청 스트레스를 받았다. 그래서 강의/실습/과제에 좀 집중을 못했다. (안했다는 게 아니라 전처럼 파보고 이해하는 과정을 못 겪고 놓친 것 같다.)
  • 학습정리를 꼼꼼히(이걸 꼼꼼히라고 해도 될지..ㅎ) 작성하면서 그래도 이해는 확실히 한 것 같다. 주재걸 교수님 강의가 정말 명강의여서 흐름을 이해하고 세부적인 사항을 추가로 찾아보는 게 가능했다. 이번에 작성한 학습정리는 나중에 transformer를 또 살펴볼 일이 있을 때 꺼내볼 것 같다. 마찬가지로 9, 10강 self-supervised pre-training models 강의도 꼼꼼하게 작성해서 업로드해야지... 임시저장 상태를 못 벗어나고 있다^^..
  • 이번주에 피어세션에서 진행했던 논문 리뷰가 정말 좋았다. 이미 배운 내용과 관련된 논문은 더 추가적인 것들(코드 등)을 알 수 있어서 유익했고, 새로운 논문은 시야를 넓히는 데 도움이 됐다. P stage가 시작되면 논문리뷰는 더 할 수 없겠지만 유튜브로 논문 리뷰 찾아보게 될 것 같다. (도움이 많이 될 것 같다!)

해야 할 일

self-supervised pre-training models (bert, gpt ... ) 포스팅하기

huggingface/transformers/bert 이해

huggingface tutorial

wikidocs 딥러닝을 이용한 자연어처리 입문

 

언제 하지....🤦‍♀️

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

[학습정리] 2021-10-13  (0) 2021.10.13
[학습정리] 2021-09-23/24 특강  (1) 2021.10.07
[학습정리] 2021-09-10  (0) 2021.09.12
[학습정리] 2021-09-09  (0) 2021.09.11
[학습정리] 2021-09-08  (0) 2021.09.09