본문 바로가기
Ai/Notion

Transformer

by yooom 2023. 10. 12.

Transformer를 이해해보자

개인적으로 transformer를 공부하면서 이해했다싶으면 또 갸우뚱하는 지점이 생기고, 다른 블로그나 유튜브 영상을 보면 예시가 내가 이해한 거랑 좀 다른 것 같았다. 지식을 공유하는 목적이기보단, 나의 공부 기록이자 앞으로 더 좋은 해석 혹은 오류가 있다면 계속 갱신할 자료이므로 잘못된 해석이 있다면 조언 댓글로 부탁드리며 포스팅을 시작한다.

 

전체 구조는 다음과 같다. 왼쪽은 Encoder, 오른쪽은 Decoder다.

- Encoder는 두 개 층으로 이루어져있고, 각 층은 다시 2개 층으로 구성된다.

- Decoder는 세 개의 묶음으로 이루어져 있고 Encoder와 차이점은, 시작 부분에 Masked Multi-Head Attention 층이 추가된 것과, Multi-Head Attention 층이 Encoder에서와 약간 다르게 동작한다.

 

번역기를 예로 들 때, 영어를 입력하면 이탈리아어로 번역하는 과정을 수행하려면 Encoder input의 언어가 영어, Decoder input의 언어가 이탈리아어로 train하면 된다.

 

구조는 Encoder 6개, Decoder 6개로 이루어져있다고 하는데, 사실 어떤 방식으로 연결돼있는지는 잘 모르겠다.

다만, Encoder와 Decoder에서 어떤 방식으로 정보가 처리되는지 살펴보는 것을 목표로하자.

이제 순서대로 하나씩 뜯어먹어보자.
<Encoder>
1. Embedding
2. Self Attention
3. Multi-Head Attention ( in Encoder )
4. Add & Norm
<Decoder>
5. Masked Multi-Head Attention
6. Multi-Head Attention ( in Decoder )
<Output>
7. Linear
8. Softmax + Cross Entropy Loss
9. Result & Summary

 

 

 

--- Encoder ---

인코더는 이 부분이다. 인코더는

Embedding → ( Multi-Head Attention → Add-Norm ) → ( Feed Forward → Add&Norm )으로 진행된다.

우선 Multi-Head Attention를 이해하기에 앞서, Embedding 과 Self Attention을 묶어서 알아보자.

 

1. Embedding

input Embedding의 위치와 원리

각 단어는 고유한 ID가 있는데, 이는 인덱스(위치)를 의미한다. 위의 이미지를 예시로 보자면 훈련 데이터셋에 단어가 10,000개가 있다면,CAT은 10,000개의 index중 6587가 index 번호이자, ID인 위치가 된다.

Embedding은 각 단어에 고유한 ID에 해당하는 n차원 벡터를 지정해주는 과정이다. 각 단어의 벡터는 고유하므로 위 그림처럼 CAT의 ID와 Embedding은 고유한 값을 가지는 것을 알 수 있다.

현재 이 예시와 논문에서는 512차원 벡터를 사용하고있다.

 

positional Embedding의 위치와 원리

positional Embedding은 동일한 단어, 동일한 Embedding을 가진 것 요소에 위치정보를 부여하는 과정이다. 이 과정을 통해 다른 위치에 있는 단어는 다른 의미를 띠는 것을 포착할 수 있는 여지를 남긴다.

1. Although I did not get 98 in last TOEFL, I could get in the Ph.D program
2. Although I did get 98 in last TOEFL, I could not get in the Ph.D program

한편 Encoder input은 Embedding과 positional Embedding의 합이므로 두 벡터의 차원은 같아야한다.

즉, 현 예시에서는 둘 다 512차원의 벡터로 상정한다.

 

positional Embedding의 공식

\(d_{model}\)은 Embedding 과 positional Embedding의 벡터 차원을 뜻한다.

Embedding과 positional Embedding이 더해지는 과정을 보이는 위 차트를 보면, positional Embedding은 복잡한 소수를 띠고 있다. 복잡한 소수를 만들어내는 위 공식이 어떤 의미를 가지고 있는지, 어떤 과정을 통해 만들어졌는지는 논문에 자세히 밝혀져있지 않다. 하지만 나름의 해석을 포스팅 해놓은 것이 있으니, 공식을 이해하고싶다면 참고하면 좋을 것 같다.

 

https://yooom.tistory.com/130

 

Transformer 에서 cos, sin 함수를 사용한 이유(position encoding)

Transformer를 공부하면서 무시무시한 수식이 나오는데, 이 함수가 왜 사용되는지, 어떻게 유도되었는지, 무슨 의미인지 살펴보도록 하자. 오늘 포스팅은 순차적으로 진행되는 것이 아니라 내용이

yooom.tistory.com

 

 

2. Self Attention

 

Multi-Head Attention이나 Self Attention이나 그게 그거지만 어쨋든 Self Attention 부터 살펴보자. 

우리가 사용하는 예시 문장은  "YOUR CAT IS A LOVELY CAT"이다. 단어가 6개, Embedding이 512차원이므로 Encoder input은 6x512 행렬이 된다. 

 

동일한 input으로부터 다른 weight를 가진 행렬과 행렬곱 계산을 하여 Q,K,V를 생성한다.

딕셔너리 용어처럼, Q - 문의, K - 검색값, V - 고유값 이 된다. 굳이 이렇게 이름이 붙여진 이유는 (6)Decoder에서 Multi-Head Attention을 다룰 때 이해할 수 있을 것이다. 일단 계산이 어떻게 이루어지는지만 보고 가자.

 

Key를 transpose하여 Query와 행렬곱을 한 뒤 6x6 행렬 각각의 값을 \(d_{model}\)의 제곱근으로 나누고 softmax 한다. 알다시피, softmax는 지수항이 포함되어 있으므로 숫자 크기를 줄여주는 것이 연산에 안전하기 때문이다.

그 뒤, 6x6 행렬을 Value와 행렬곱하여 6x512인 원래 Encoder input과 같은 형상으로 돌아오게 만든다.

 

 

좀 더 뜯어보자.

 Query와 transpose한 key를 행렬곱하여 \(\sqrt{512}\)를 나눈 뒤 softmax한 6x6행렬을 보자.

행 단위로 softmax가 되었기 때문에 각 행의 합은 softmax 전체 확률인 1이 된다.

 

각 단어는 Embedding 과정을 거치면서 벡터로 치환된다. 즉, 단어간의 유사성, 관계성을 벡터 내적을 통해 유추할 수 있게끔 만들었다. 즉, 벡터 내적이 클 수록 단어간의 유사성, 관계성이 큰 것이다.

 

6x6 행렬의 주대각성분은 같은 단어와 내적하여 softmax를 거친 값이다. 그래서 각 행에서 가장 큰 값을 가지고 있고, 자신과 같은 성분은 가장 유사하다는 것을 알 수 있다.

또한 그 다음으로 내적 값이 높은 단어들을 분포를 파악하여 단어간의 관계성을 알아내는 것이다.

 

한 줄 정리 : 6x6 행렬에서 내적값이 크다 = 관련있는 단어 쌍이다.

아아..! 이해했다..!

어떤 글에서는 softmax를 거친 행렬을 대칭행렬로 표현했었는데, 동일한 input에서 시작했으나 각각 다른 weight가 곱해졌으므로 대칭행렬이 무조건 나오는 것은 아니다.

 

 

그 후 ( 단어 별 관계의 강함 정도를 나타내는 값인 ) 6x6행렬과 ( 원래의 행렬에서 조금 변형된 ) Value를 행렬곱하여 원래 input과 같은 형상인 Attention 행렬이 생성된다.

 

지금까지 과정에 파이썬의 딕셔너리처럼 의미를 부여해보자면, 우선 Key는 Value와 한 쌍이다.

Query(요청)과 Key(키)의 유사도를 먼저 조사한 다음, Query와 큰 유사도를 가진 Key를 강조해주고, 강조된 Key값을 바탕으로 Value에 반영하여 최종적으로 Query가 요청을 보낸 값에 대한 가장 큰 유사도를 가진 Value를 탐색하는 과정이다.

 

솔직히 무슨 의미인지 잘 이해가 안 간다!

 

Query와 Key를 내적해서 값이 큰 것은 단어 사이의 연관성이 강하다는 뜻은 이해했다. 그런데 Value 설명이 후루룩 지나가버린 기분 !

( 여기 부터는 Value의 개인적인 해석이니 조심하여 이해하자. )

 

예시 속의 예시! 로 이해해보자. 예시 문장에서 "YOUR CAT"만 가져오자.
두 문장이므로 2x512 Encoding input이 입력된다. Q,K,V도 2x512가 생성된다.
Q,K의 행렬곱인 [2,512][512,2] = [2,2]이 된다. 2x2 행렬은 단어 간의 유사도라고 말했다.

이때, value weight를 통과한 Value vector가 아래와 같이 생성되었다고 치자.

경우 1) 두 단어 간의 유사도가 크다. (2x2 행렬의 대각 행렬 )
경우 2) 두 단어 간의 유사도가 작다.
단어 "YOUR", "CAT"은 512차원으로 이루어진 Embedding 벡터를 가진다.
무작위 값인 Value vector가 유사도를 띠는 softmax값을 반영하여 Attention vector를 생성한다.
Value vector는 비교적 Encoder input의 원형을 잘 유지하고 있는 벡터다 ( ←확신 없는 부분)
Q,K의 softmax이후 Value vector의 값들은 행렬곱을 통해 Attention vector로 변하게 되는데,
단어 간의 관계가 깊을 수록 Attention vector는 유사해진다. ( → 내적 값이 커지도록 변형 )
단어 간의 관계가 적을 수록 Attention vector는 본인 형태를 유지한다. 

 

 

3. Multi-Head Attention ( in Encoder )

Self Attention은 대충 이해했고, Multi-Head Attention을 살펴보자.

예시 문장 "The animal didn't cross the street because it was too tired" 에서 it과 관련이 깊은 단어를 찾는 task를 수행할 것이다.

Self Attention에서 softmax를 통해 단어 간의 관계를 찾는 과정을 수행했다. 문장 속에서 it과 가장 유사한 단어를 벡터 내적을 통해 알아볼 것이다. 하지만 그게 진짜 가장 유사도가 큰 단어라고 확신할 수 있을까? 혹은 유사도가 큰 단어가 하나뿐일까?

이걸 Multi-Head로 해결한다.

self Attention, h=1인 Multi-Head Attention,  h=8인 Multi-Head Attention

단순하게 Multi-Head Attention을 표현하자면 위 그림 그대로 유사도를 여러 방면으로 점검해보는 것이다.

1번 째 그림은, it과 관련 깊은 단어를 The, animal로 판단했다.

2번 째 그림은, it과 관련 깊은 단어를 1번 head는 The, animal로, 2번 head는 tire, d로 판단했다. 맥락상 둘 다 정답이다. Multi-Head를 두면서 여러 시선에서 유사도를 점검할 수 있게 된다.

3번 째 그림은, it과 관련 깊은 단어를 8개의 head에서 점검한다. 분홍색 head는 cross를 it과 관련있다고 판단했고, 회색 head는 because를 it과 관련있다고 판단했다. 결과적으로 보면 몇몇 개는 맥락을 유추하는데 실패한 듯 하지만 다양한 가능성을 고려했다는 점에서 의미가 깊다.

 

Multi-Head Attention의 의미는 이렇고, 진짜 계산을 보자.

 

Multi-Head Attention은 Self Attention에서 한 발자국만 더 나가면 된다. 이전 예시에서는 Query, Key, Value의 형상이 6x512였다. 그리고 최종적으로 만들어진 6x512의 attention 결과는 문장 단어 간의 유사도를 반영한 결과가 된다.

 

이걸 여러 번 하자는 거다. 어떻게? 쪼개서!

\(d_{model}\)은 전체 벡터 차원을 뜻한다. 지금 예시에서는 512차원, 이걸 쪼갤 거다.

이 예시는 h=4인 경우다. 그럼 \(d_{v}\)는 512/4=128이 된다. 즉, Q1,K1,V1의 형상은 6x128이다.

 

그러면 head가 4개 만들어진다. 그 뒤 concat(=단순 붙이기)한다. H행렬이 만들어진다.

H행렬은 Encoder input과 동일한 형상을 가진다. 여기에 512x512의 weight를 곱해주면 Multi-Head Attention이 생성된다.

 

4. Add & Norm

Multi-Head Attention을 거쳐 올라오는 값과, 원본 그대로 올라오는 값이 동일하게 Add & Norm된다. 이 기법은 Resnet에서 좋은 결과를 낸 것을 차용했다.

 

특히나 Attention에서는 Batch Normalization이 아닌, Layer Normalization을 사용했다.

Layer Normalization을 사용하면 여러 층의 batch에 분포한 동일한 단어에 표준화를 해주는 것이다.

Batch Normalization이 적합하지 않은 이유는 다양한 문장길이에서 분모에 들어갈 정규화 상수(보통 문장의 총 길이)가 변동성이 생기기 때문에 훈련과정에서 불안정해질 수 있다고 한다.

 

또한 \(\beta\)와 \(\gamma\)를 추가하는데, 정류화를 통해 모든 값이 0~1 사이에 배치되면 너무 제한적인 상황이 만들어지기 때문에 학습 가능한 두 개의 파라미터를 두어 덧셈, 곱셈 연산을 조금 가해준다고 한다.

왜 필요한지 잘 모르겠다 !

 

 

 

--- Decoder ---

Decoder 부분에서는 Encoder의 Attention과 계산법은 동일하나, 의미에서 차이가 꽤 크기 때문에 넓은 시야에서 살펴볼 필요가 있을 것 같다.

영어를 이탈리아어로 번역하는 과정이라면, Decoder input은 이탈리아어여야한다. 하지만 앞의 예시를 재활용하기위해 그냥 영어로 쓰는 점을 알고가자. 

 

 

5. Masked Multi-Head Attention

말 그대로 Multi-Head Attention을 수행할 건데, Masked하여 수행할 거다.

문장 "your cat is a lovely cat" 에서는 학습을 할 때, 뒷 단어들을 가리고 학습을 하기위해

Q,K 내적 연산 후, softmax 연산 전에 뒷 단어들의 내적 값을  - 으로 변경하여 lower triangular matrix를 만들어준다.

그러면 앞에 제시된 단어들 사이에서만 서로의 관계를 파악하게 된다.

즉, Decoding할 새로운 언어의 문법적 관계에 집중할 수 있게 된다.

마찬가지로 Multi-Head를 생성하여 수행한다.

 

6. Multi-Head Attention ( in Decoder )

이제 Attention의 정수! 번역기의 input 언어와 output 언어가 기가막히게 관계를 찾아가는 단계이다.

우린 Query, Key, Value를 만들었었다.

지금까지는 Self 여서 동일한 input에서 만들었지만, 이번에는

Encoder에서 Key, Value를,

Decoder에서 Query를 가져온다.

Self Attention을 다시 상기해보자. ( 예시 문장은 "I love you very much" → "Ti amo molto", embedding값은 재활용 )

이탈리아어의 단어와 영어 단어의 관계를 찾아내는 내적과 softmax 연산을 거친다.

그 다음, 영어로 된 Value 벡터에 행렬곱 연산이 되며 영어로 된 Attention이 생성된다.

여기서 눈여겨 볼 점은 Query 개수가 Key와 달라도 된다. !
self attention에서는 동일한 matrix에서 Key, Query, Value가 나왔기 때문에 모두 형상이 같았지만,
지금은 Key, Value의 형상은 같지만 Query의 형상은 달라도 되는 것이다.

형상을 점검해보자.
Key = (5, 512), Value = (5, 512), Query = (3, 512)인 경우
\((Q \cdot K^{T}) = (3, 5) \)
\(Softmax(Q \cdot K^{T}) \cdot V = (3, 512)\) 가 된다.

최종적으로 Query의 형상으로 돌아오기 때문에 Query의 단어 뜻 그대로, "요청"으로 봐도 될 것 같다. !
하지만 형상만 Query와 같을 뿐, 출력은 Value에 의한 것이므로 아직은 영어 data라고 봐야한다.

 

Decoder에서 왜 영어로 된 Attention이 만들어져버리는지 갸우뚱 할 수도 있다. 사실 다음 과정까지 봐야 답답함이 해소된다!

 

--- Output ---

7. Linear

이전 Multi-Head Attention에서 ( Feed Forward 설명 생략 ) 영어로 된 Attention을 만들어냈다.

이 Attention은 ( 문장 단어 개수 x 512 ) 의 형상을 가진 Embedding이라고 볼 수 있다. 이것을 직접 이탈리아어 단어 set로 연결시켜주는 과정이다.

 

만일 위의 예시처럼 "I LOVE YOU VERY MUCH"를 "TI AMO MOLTO" 로 번역하며,

Embedding \(d_{model}\) 은 512,

이탈리아어 단어 set의 수는 10,000개라고 하자.

 

Multi-Head Attention을 거친 Embedding데이터의 형상은 5 x 512

Linear 계층의 weight는 512x10000을 거쳐

최종적으로 5x10000 의 형상을 output 한다.

즉, 5개의 영어 단어를 10,000개의 이탈리아 단어와 maching 시키는 과정이다 !!!

 

와 !

이제 왜 Query, Key, Value라 불렸는지 조금 알 수 있다. !! Decoder 이후의 Linear 단계까지 따라왔다면 슬슬 견적 나온다 !

 

8. Softmax + Cross Entropy Loss

최종적으로 Linear를 거쳐 영어를 이탈리아 어로 matching 시켰다. 이제 Softmax를 거쳐 각 단어에 대한 확률 값을 구해낸 뒤, 실제 정답 "Ti amo molto"를 기준으로 Backpropagation을 계산한다.

 

이게 위대한 연산인 이유는, RNN, LSTM을 설명할 땐, 이전의 결과가 뒤의 연산에 영향을 주는 등, 여러 과정에 거쳐 연산이 진행됐다. 그런데 Transformer는 문장 덩어리를 던져주면 한 번의 연산으로 끝나버린다.

매우 긴 문장을 엄청 빠르고 쉽게 훈련할 수 있게 된 것이다 !

 

이로써 이론은 끝났다. 이제 전체적인 이미지를 보며 요약하자.

 

 

9. Result & Summary

 

I love you very much를 Ti amo molto로 번역하는 과정은 4번의 절차가 있다.

(sos = start of sentence, eos = end of sentence)

 

<Time step 1>에서는 Encoder에서 영어를 입력받은 뒤 Decoder에서 번역 개시 신호인 <SOS>를 입력받는다.

훈련이 잘 된 신경망이라면 Decoder에서 첫 번째 단어인 Ti를 출력한다.

 

<Time step 2>에서는 더이상 Encoder는 연산하지 않고 최종 결과만 이용된다.

변하는 것은 Decoder input 뿐이다. 두 단어인 <SOS> Ti 를 입력받고, 다음 단어를 예측한다.

 

<Time step 3>와 <Time step 4> 는 동일하다. 다만, <EOS>가 출력되면 번역 종료 신호이므로 번역을 종결한다.

 

 

 

 

 

https://youtu.be/bCz4OMemCcA?si=VgRkHfC4DehTFlio 

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

 

 

728x90

'Ai > Notion' 카테고리의 다른 글

Transformer 에서 cos, sin 함수를 사용한 이유(position encoding)  (0) 2023.10.17
VIT (Vision Transformer)  (0) 2023.10.12
VggNet  (0) 2023.10.12
AlexNet architecture  (1) 2023.10.10
LeNet-5 - A Classic CNN Architecture  (1) 2023.10.05

댓글