=================================
학습내용
(7강) Transformer
Add-on 처럼 사용되던 attention 만 사용해서 만들 수 있다. 라는걸 보여주는게 transformer

일단 RNN 부터 보자.
RNN은 왼쪽에서 오른쪽으로 가거나 반대로 해서 오른쪽에서 왼쪽으로 감. bi-direction RNNs 은 두개 다 하는데 이러면 I go home 단어를 넣는다고 했을 때 go 단어는 정방향에서 I 정보를 역방향에선 home 정보를 hidden state에서 가지게 된다. 그래서 이 두 벡터를 concat 해서 두개 다 가지게 함.
Further Reading
http://jalammar.github.io/illustrated-transformer/
The Illustrated Transformer
Discussions: Hacker News (65 points, 4 comments), Reddit r/MachineLearning (29 points, 3 comments) Translations: Chinese (Simplified), French, Japanese, Korean, Russian, Spanish, Vietnamese Watch: MIT’s Deep Learning State of the Art lecture referencing
jalammar.github.io
https://nlpinkorean.github.io/illustrated-transformer/
The Illustrated Transformer
저번 글에서 다뤘던 attention seq2seq 모델에 이어, attention 을 활용한 또 다른 모델인 Transformer 모델에 대해 얘기해보려 합니다. 2017 NIPS에서 Google이 소개했던 Transformer는 NLP 학계에서 정말 큰 주목을
nlpinkorean.github.io
https://pytorch.org/tutorials/beginner/transformer_tutorial.html
Language Modeling with nn.Transformer and TorchText — PyTorch Tutorials 1.10.1+cu102 documentation
Note Click here to download the full example code Language Modeling with nn.Transformer and TorchText This is a tutorial on training a sequence-to-sequence model that uses the nn.Transformer module. The PyTorch 1.2 release includes a standard transformer m
pytorch.org
가중치결정 query. query 벡터와 곱해지는 재료 벡터 keys, 어느것을 가져올지. 또다른 재료역할 values 벡터

각 단어들에 대해 계산할 때 각 단어에 대한 keys 와 values 벡터는 같으나 q가 달라진다. 그래서 이 달라진 q를 가지고 k 와 곱하고 여기서 새로나온 가중치에 대한 값을 values 벡터와 선형결합해서 최종적인 Attention output vector를 얻어내는 것. 이게 결국 h2가 된다.

Queries 와 keys 벡터 차원은 같아야 하지만, values는 상관없다. 왜냐하면 어차피 모두 더해서 scalar 값을 만들기 때문.

A(q,K,V)는 values 벡터에 대한 가중평균. quary를 attention model 을 통해 encoding 한 벡터는 최종적으로 dv 차원 만큼이 나옴.
key 와의 내적에 기반한 유사도


그럼 왜 softmax 전에 root(dk) 로 나누는가?

평균과 분산이 있으니까 두개를 더하게 되면 평균은 그대로 0이지만 분산은 늘어난다. 근데 이게 단순히 개수가 늘어나면 늘어나는 거기 때문에 k차원이 늘어나면 늘어날수록 더하는게 많아지고 그러면 분산도 더 커진다. 그래서 단순히 k차원이 늘어난다고 분산이 커지고, 분산이 커지면 굉장히 큰 값이 나오고 큰 값과 작은값의 차이가 softmax 에 상당한 영향을 주기 때문에 표준편차로 나눠서 정규화 하는 것. 즉 softmax 하기 전에 한번 정규화를 시켜줘서 k차원이 얼마나 크든 작던간에 상관없이 만들어 주는 거다.

그렇게 만든 self attention인 z를 여러개 만듬. 여기선 8개 만들어 concat 해준 뒤 나중에 입력값 vector와 그대로 더해야 하기 때문에 linear로 입력값 vector 차원만큼 줄여서 최종 값을 내놓는다.

n 은 입력 sequence의 길이, d는 query의 d 차원길이.

우리가 한 Self-Attention의 경우 입력길이, k차원 길이가 행렬곱셈 정의에 의해 O(n^2*d) 가 된다. 하지만 이것은 병렬처리가 가능하기 때문에 병렬처리의 시간복잡도 Sequential Operations는 1이 됨. 단어와의 길이도 매번마다 query vector 와 key vector를 각 단어마다 계산해서 O(1)인듯.


RNN의 경우 hidden state인 h의 차원이 d이고 d*d 크기의 weight와 곱셈을 하고, 이것이 입력 길이 n번만큼 수행되기 때문에 O(n*d^2). 그러나 이렇게 순차적으로 계산하는 것이기 때문에 병렬처리가 불가능해서 그냥 시간복잡도는 O(n)이 된다. 단어길이도 n번 거쳐가 도착하니까 O(n).



한 block을 구성하는 Multi-Head Attention, residual connection, Layer Normalization. Feed Forward는 fully connected layer. Transformer에서 제안한 self-attention인 Multi-Head Attention을 포함한 한 블럭.
지금까지는 multi-head attention 을 본거고, transformer에서는 이 multi-head attention을 덧붙혀서 추가적인 후처리. residual connection. gradient의 vanishing 문제를 해결하여 layer를 여러개 쌓아 올려 성능을 올리겠다. 그럼 add와 Norm을 왜 하는가? 밑에 설명할거다.

그냥 neural network의 경우(linear regression 같은걸 말하는 듯) hidden 결과가 나왔을 때 hidden state 의 평균과 분산 정보가 어쨋든 버리고 입력값에 대해 빼주고 표준편차로 나눠 정규화 시켜줬다. 그래야 원래 식 y=2x+3 에서 분산이 4이고 평균이 3이라는 원래 식 정보를 반영하기 때문인 것 같다. 그래서 특정 노드에 발견되어야 하는 값에 가장 최적화된 평균과 분산을 원하는 만큼 가지도록 동작하게 된다. 그래서 layer norm 도 batch norm과 유사하게 첫번째 단계에서는 주어진 sample에 대한 평균 분산을 0과 1로 만들고 다음엔 우리가 원하는 평균 분산을 주입하는 두 단계로 이루어져 있다.

보면 thinking과 machines 단어를 넣었을 때 나온 hidden state를 정규화 해주고 내가 원하는 평균과 분산 값을 Affine transformation을 통해 주입하는 걸 볼 수 있다. 이게 layer normalization. batch normalization은 조금 다르다고 하지만 대강 비슷하다고 함.
문제가 하나 있는데 순서에 대한 변인요소가 없어서 단어가 바뀌어도 어순을 파악못한다. 이는 values 벡터와 곱할때 교환법칙이 성립하기 때문.





그리고 "I go home"을 "나는 집에 간다" 로 번역할 때 마지막에 linear를 거치는데 여기서 모든 한글 단어에 대해 linear을 펼쳐서 본다. 만약 한글 사전에 단어가 10만개 있으면 10만개 output을 내놓도록 linear에서 펼쳐놓고 softmax해서 가장 가능성이 높은 걸 출력한다.



실습
(실습 7강) Multi-head Attention 구현


##7. Multi-head Attention 1. Multi-head attention 및 self-attention 구현. 2. 각 과정에서 일어나는 연산과 input/output 형태 이해.
필요 패키지 import
데이터 전처리
[[62, 13, 47, 39, 78, 33, 56, 13, 39, 29, 44, 86, 71, 36, 18, 75, 0, 0, 0, 0],
[60, 96, 51, 32, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[35, 45, 48, 65, 91, 99, 92, 10, 3, 21, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[75, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[66, 88, 98, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[21, 39, 10, 64, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[77,
65,
51,
77,
19,
15,
35,
19,
23,
97,
50,
46,
53,
42,
45,
91,
66,
3,
43,
10],
[70, 64, 98, 25, 99, 53, 4, 13, 69, 62, 66, 76, 15, 75, 45, 34, 0, 0, 0, 0],
[20, 64, 81, 35, 76, 85, 1, 62, 8, 45, 99, 77, 19, 43, 0, 0, 0, 0, 0, 0]]
Hyperparameter 세팅 및 embedding
Linear transformation & 여러 head로 나누기
Multi-head attention 내에서 쓰이는 linear transformation matrix들을 정의합니다.
Q, k, v를 num_head개의 차원 분할된 여러 vector로 만듭니다.
Scaled dot-product self-attention 구현
각 head에서 실행되는 self-attetion 과정입니다.
각 head의 결과물 병합
각 head의 결과물을 concat하고 동일 차원으로 linear transformation합니다.
전체 코드
위의 과정을 모두 합쳐 하나의 Multi-head attention 모듈을 구현하겠습니다.
(실습 8강) Masked Multi-head Attention 구현


##8. Masked Multi-head Attention 1. Masked Multi-head Attention 구현. 2. Encoder-Decoder Attention 구현.
필요 패키지 import
데이터 전처리
데이터의 값과 형태를 좀 더 명확하게 보기 위해 sample을 줄이겠습니다.
[[62, 13, 47, 39, 78, 33, 56, 13, 0, 0],
[60, 96, 51, 32, 90, 0, 0, 0, 0, 0],
[35, 45, 48, 65, 91, 99, 92, 10, 3, 21],
[66, 88, 98, 47, 0, 0, 0, 0, 0, 0],
[77, 65, 51, 77, 19, 15, 35, 19, 23, 0]]
Hyperparameter 세팅 및 embedding
Mask 구축
True는 attention이 적용될 부분, False는 masking될 자리입니다.
Linear transformation & 여러 head로 나누기
Masking이 적용된 self-attention 구현
-1* inf로 masking된 부분은 softmax 후 0이 됩니다.
전체 코드
Encoder-Decoder attention
Query, key, value만 달라질 뿐 구현은 동일합니다.
Decoder에 들어갈 batch만 별도 구현하겠습니다.
src_emb를 encoder에서 나온 결과, 그리고 trg_emb를 masked multi-head attention 후 결과로 가정합니다.
Masked multi-head attention 후 나온 결과와 동일한 shape를 가지며 이후 layer에서 전체 연산도 동일하게 진행됩니다.
==================================
과제 / 퀴즈
Natural Language Processing
Assignment 4: Byte Pair Encoding
1. Introduction
- 일반적으로 하나의 단어에 대해 하나의 embedding을 생성할 경우 out-of-vocabulary(OOV)라는 치명적인 문제를 갖게 됩니다. 학습 데이터에서 등장하지 않은 단어가 나오는 경우 Unknown token으로 처리해주어 모델의 입력으로 넣게 되면서 전체적으로 모델의 성능이 저하될 수 있습니다. 반면 모든 단어의 embedding을 만들기에는 필요한 embedding parameter의 수가 지나치게 많습니다. 이러한 문제를 해결하기 위해 컴퓨터가 이해하는 단어를 표현하는 데에 데이터 압축 알고리즘 중 하나인 byte pair encoding 기법을 적용한 sub-word tokenizaiton이라는 개념이 나타났습니다.
- 본 과제에서는 byte pair encoding을 이용한 간단한 sub-word tokenizer를 구현해봅니다. 과제 노트북의 지시사항과 각 함수의 docstring과 논문의 3페이지 algorithm 1 참고하여 build_bpe 함수를 완성하고 모든 test case를 통과해주세요.
2-1.build_bpe 함수를 완성해주세요.
2-2. build_bpe 함수 평가
==================================
피어세션
복습 및 DACON 데이터 분석 및 전처리 해봄.
===================================
후기
피곤해