본문 바로가기
AI/딥러닝

[NLP] Transformer

by 채채씨 2021. 9. 19.
728x90
반응형

※ 이 글은 KAIST 주재걸 교수님의 강의 내용 및 자료를 바탕으로 작성합니다.



오늘은 Recurrent 모델을 사용하지 않고, Attention으로만 encoder와 decoder를 설계한 Transformer에 대해 다룰 것이다. 먼저 RNN모델에 대해 살펴보자.


기존의 RNN모델은 input에 대한 hidden vector를 순차적으로 구하였으며, 오른쪽 그림처럼 이전 time step의 input은 다음 time step의 hidden vector생성에 영향을 미친다.

왼쪽의 단어만 오른쪽의 단어에 영향을 미치면, 가령 I go home에서 I에 대한 hidden vector를 생성할 때는 go나 home에 대한 정보를 담을 수 없는 문제가 발생한다. 이때 양방향의 정보를 포함시키기 위해 Bi-Directional RNN을 사용할 수 있다.


왼쪽에서 오른쪽으로 흐르는 Forward RNN과 오른쪽에서 왼쪽으로 흐르는 Backward RNN의 hidden vector을 concatenate를 하여 각 time step에서의 hidden vector를 생성할 수 있다.

LSTM을 도입하여도 Long-Term dependency문제가 남아있으며, 병렬적인 연산이 불가하기 때문에 Sequence길이에 따라 느려지는 속도 문제를 해결할 수 없다. 이러한 문제를 개선한 것이 바로 Transformer이다.


 

Transformer와 Attention


Transformer도 RNN모델과 마찬가지로 I go home이라는 문장이 입력되었을 때, 주변 단어와의 관계를 고려하여 각 단어에 대한 hidden vector h1, h2, h3을 생성한다. 즉, RNN모델과 Transformer는 주변 단어를 활용한다는 공통점이 있다.


아래 그림에서 Transformer의 구조를 대략적으로 보면, I go home에서 각 단어는 자기 자신+자신을 제외한 나머지 단어와의 유사도를 계산한 후, softmax를 취하여 가중치를 얻고 가중합을 통해 최종 hidden vector를 정의한다.

Attention 구조


이 경우, 자기 자신과의 유사도가 가장 크기 떄문에 자기 자신에 대한 정보만을 주로 표현하는 vector가 될 수 있다. 이 문제를 개선하기 위해 역할을 구분한다. 역할을 구분한다는 것을 이해하기 위해 input로 들어가는 각 단어의 역할에 대해 생각해보자.


I go home이라는 문장에서 각 단어에 대한 encoding vector를 만드는 상황에서,

1) I는 다른 단어와의 유사도를 계산하기 위한 기준이 되기도 하고 ▶ Query vector
2) go나 home의 유사도를 계산하기 위한 재료가 되기도 하고 ▶ Key vector
3) 유사도에 softmax를 취하여 가중 평균을 구하기 위한 재료가 되기도 한다 ▶ Value vector


세 단어 모두 Attention을 통해 encoding하는 과정에서 위의 Query, Key, Value 역할을 모두 수행한다. 아래 그림과 같이 역할별로 구분된 Query, Key, Value는 input vector에 서로 다른 weight인 WQ, WK, WV를 연산하여 생성된다.

Query, Key, Value 생성



이렇게 나누어서 어떻게 한다는 것인지 의문이 들 것이다. 이제 Query, Key, Value를 사용하여 어떻게 hidden vector를 만들어내는 지 살펴보자.


먼저 encoding하고자 하는 단어인 Query 1개와 Query와의 유사도가 계산되는 Key 3개와 유사도 결과인 가중치와 계산되는 Value 3개를 만든다.

I go home에서 I를 Query로 하는 경우에 대해 살펴보자. Query와 Key로 유사도를 계산하면 [3.8, -2.0, 5.9]가 나오고, 이 점수에 softmax를 취하면 [0.2, 0.1, 0.7]이 나온다. 최종적으로 이 점수와 Value로 가중합을 계산하면, I에 대한 encoding vector인 h1이 완성된다.

Attention 구조


하나의 단어에 대한 encoding vector를 만들 때, 다른 단어와의 거리와 관계없이 문장 내의 모든 단어 정보가 유사도에 따라 적절하게 포함되는 것을 알 수 있다. 즉, 기존의 Long-Term Dependency 문제를 완전히 극복한 것이다.


정리하면, Attention의 input은 WQ, WK, WV와 연산된 Query와 Key-Value 쌍이 되고, 최종 output은 Value에 대한 가중합이 되며, 각 Value의 weight는 Query와 Key의 inner product로 계산된다. Qeury와 Key는 내적을 위해 두 차원이 dk로 같아야 하며, Value의 차원은 달라도 상관없다. encoding vector의 차원은 Value의 차원과 같게 될 것이다.



Transformer의 Encoding 과정을 단계별로 정리하면 다음과 같다.

1) input vector에 WQ, WK, WV를 곱하여 Query, Key, Value를 구한다.
2) Query와 Key를 내적하여 유사도 score를 구한다.

3) 그 score를 루트dk로 나누어 scaling한다. (이유는 아래에서 자세히 설명할 예정)
4) scaling한 값에 softmax를 취하여 가중치를 얻는다.
5) 각 가중치와 Value를 곱한다.
6) 가중치가 곱해진 Value들을 더한다.  

 

Attention 과정



위의 과정을 계산식으로 살펴보자.

Attention 그림식



위 그림식을 수식으로 표현하면 다음과 같다.

 

단어 하나에 대한 encoding 수식 (소문자 q = 벡터)

 

모든 단어 하나에 대한 encoding수식 (대문자 Q = 행렬)

 

모든 단어 하나에 대한 encoding수식 그림

 


 

  Query·Key내적 후 Scaling하는 이유  


Query [a, b]와 Key [x, y]의 평균이 0이고 분산이 1이라고 가정했을 때, Query·Key내적인 ax+by의 평균은 0이고 분산은 2가 된다(증명 생략). 이때 분산은 각 항의 분산을 모두 더한 값과 동일하므로 Query와 Key의 차원수, 즉 dk사이즈가 클 수록 내적의 분산도 커지게 된다.

만약, 분산이 2라면 내적의 결과가 가령 [1.1, -0.8, -1.7]과 같을 것이고, 분산이 100이라면 [8, -11, 7]과 같을 것이다.



위 그림의 분산 100과 같이 내적의 분산이 크면 softmax를 취했을 때 분포가 logit값이 큰 쪽으로 확률이 쏠리는 현상이 발생하고, 이는 backpropagation시 gradient vanishing문제를 발생시킬 수 있다. 이 문제를 해결하기 위해 dk에 루트 씌운 값으로 나누어 scaling을 하여 모든 Key에 확률이 고르게 부여되도록 한다.

scaling하는 이유

 


 

  Multi-Head Attention  


동일한 Query, Key, Value에 대해서(=하나의 단어에 대해서) 여러개의 Attention을 동시에 병렬적으로 수행하는 것을 Multi-Head Attention이라 한다. 여러개의 WQ, WK, WV행렬이 존재하며, 동일한 단어에 대해 여러 버전의 encoding vector가 나오고, 그 encoding vector들을 concatenate한 것을 최종 encoding vector로 가지게 된다.


여러 버전의 Attention을 수행하기 위한 다수의 선형 변환 행렬(WQ, WK, WV)을 Multi-Head라 부르며, 이 Multi-Head에 대해 Attention수행하는 것을 Multi-Head Attention이라 부른다.

※ Multi-Head Attention이 필요한 이유?


하나의 단어가 여러가지 feature을 가질 수 있으므로 다수의 represention을 포함하기 위함이다. 예를 들어, 아래 그림의 making의 경우 more difficult처럼 '어떻게'에 대한 정보와, 2009처럼 '언제'에 대한 정보와 연결될 수 있다. 이 경우, 다양한 representation을 반영하기 위해 Multi-Head Attention을 수행할 수 있다.



그럼 Multi-Head Attention의 경우 어떤 과정을 거치게 되는지 살펴보자.



Query, Key, Value에 여러개의 서로 다른 WQ, WK, WV가 곱해져서 Attentio과정을 거치면, 그 결과로 여러개의 encoding vector가 생성된다. 아래 그림과 같이 다수의 encoding vector를 단어별로 concatenate한 후, input과 동일한 차원을 만들기 위해 선형 변환 행렬을 곱하면 최종 encoding vector가 도출된다.


encoding vector의 차원을 input의 차원과 동일하게 만들어주는 이유는 Multi-Head Attention Layer를 지나 Add & Norm Layer에서 residual connection을 수행하기 위해서이다. residual connection은 아래에서 설명할 예정이다.


 

  시간 복잡도  


Self-Attention, Recurrent, Convolutional 세 종류의 모델에 대해 Complexity, Sequential Operation, Path Length를 구하면 다음과 같다.


Self-Attention을 보면, Complexity per Layer는 Query와 Key내적 시, d차원의 Query와 n개의 Key 내적을 n번 수행하므로 n^2*d의 시간복잡도를 가진다. Sequential Operations는 time step이라는 개념이 없어 병렬화가 가능하므로 Sequence길이가 아무리 길더라도 동시에 연산을 수행할 수 있기 때문에 O(1)의 시간복잡도를 가진다. Maximum Path Length는 Long-Term dependency와 관련이 있는데, 단어 사이의 거리가 멀더라도 Query와 Key를 설정하여 계산하므로 O(1)를 갖는다.


 

  Encoder Block  


이제 Transformer의 Encoder를 구성하는 Block에 대해 알아보자.

 


각 블록은 크게 Multi-Head Attention과 Feed-Forward Neural Network를 가지며, Add&Norm이라는 Residual connection과 layer normalization을 수행한다.


Residual connection이란 input vector와 Multi-Head Attention을 거친 encoding vector를 sum하여 input의 정보를 그대로 output에 전달하는 것이다. 이를 통해 gradient vanishing문제를 해결하고 학습을 안정화시킨다(이유?). input vector와 encoding vector를 sum하기 위해서 두 vector의 차원을 맞추었던 것이다. Residual connection이후 Layer Normaization을 적용한다.


Normalization은 데이터들의 평균과 분산을 각각 0, 1로 바꾸어준 후, Affine layer를 통해 원하는 평균과 분산으로 변환하기 위한 작업이다. 참고로 이때 정해지는 평균과 분산은 최적화에 의해 학습되는 parameter가 된다.


Layer Normalization에서도 마찬가지로 두 가지 단계를 적용한다.


아래 Layer Normalization의 예시를 보자. thinking과 machines라는 두 단어의 encoding vector를 평균 0, 분산 1로 정규화한 다음 row별로 Affine transformation을 적용한다.

 


 

  Positional Encoding  


Self-Attention은 단어의 순서와 상관없이 Query와 Key의 유사도를 통해 encoding을 하므로, 문장 내의 단어 순서를 뒤섞어서 Self-Attention을 적용해도 모든 단어의 encoding vector는 동일할 것이다. 따라서 Transformer에서 Sequence를 고려하기 위해 Positional encoding을 더한다.


Positional encoding에서는 각 단어의 순서를 특정지을 수 있는 unique한 상수 vector들을 순서에 맞게 단어들에 더해준다. 이 상수 vector는 sin과 cos함수를 사용하여 서로 다른 주기를 써서 함수를 만든다. 단어 인덱스를 나타내는 x에 대한 함숫값을 모아서 위치값으로 사용한다.


오른쪽 그림을 보면, Position=0인 128차원의 input vector에 대해 각 요소에 어떤 값들이 더해져야 하는지 알 수 있다.


Q1. 왜 주기함수를 사용할까?
A1.
Q2. 포지션마다(=단어마다) Vector요소에 서로 다른 상수값을 더해주는데, 그럼 왼쪽의 주기함수가 vector size만큼 존재해야 하는 것인가?
A2.


 

  Decoder Block  


Decoder Block을 대략적으로 보면 Encoder Block과 비교하여 Masked Multi-Head Attention + Add&Norm이 한 층 더 생겼다. 그리고 Multi-Head Attention의 input으로 Encoder의 output이 들어가는 것을 볼 수 있다. 각 Sub layer에서 어떤 일을 수행하는지 자세히 살펴보자.


I go home의 문장을 예로 들면, Decoder의 input으로 '<sos> 나는 집에'가 들어간다. <sos>는 sentence의 시작을 알리는 토큰이며, home은 마지막 단어이므로 예측할 단어가 없기 때문에 input에 포함되지 않는다. '<sos> 나는 집에' 각각에 대한 input vector가 들어가면, Masked Multi-Head Attention은 이 단어 간의 유사도를 측정하여 encoding vector를 뽑는데, 이 때 주안점은 "Masked"이다.


■ Masked Multi-Head Attention
Transformer의 Decoder는 단어가 주어졌을 때 그 다음에 올 단어를 예측하며 번역해야하기 때문에 다음에 어떤 단어가 와야하는지에 대한 정보를 담을 수 있도록 encoding해야 한다. 이를 위해 다음에 오는 단어를 Mask처리하여 encoding한다. 이것이 무슨 의미인지 자세하게 알아보자.


input vector를 기존의 Multi-Head Attention과 마찬가지로 Query, Key, Value를 만들고 Query·Key를 내적하여 유사도 score를 구한다. 여기까지는 똑같다. 그 다음 기존 Multi-Head Attention의 경우, softmax를 취하여 Weighted Value Sum을 하여 최종 Encoding vector를 구했는데, Masked Multi-Head Attention은 softmax를 적용한 후, encoding 대상 단어 다음에 오는 단어들은 0으로 처리하여 Weighted Value Sum을 한다. 즉, 다음에 오는 단어의 정보는 encoding시 직접적으로 포함하지 않고 가중치 계산에만 사용하는 것이다.


위의 방법 이외에 일반적으로 Masking하는 방법으로, softmax적용하기 전에 다음에 올 단어들을 -inf로 변환하여 softmax를 취하는 방법이 있다. 두 방법의 결과는 서로 다른 결과를 도출하는데 후자의 경우 exponential function으로 인해 softmax output의 차이가 크고, 전자의 경우 softmax output distirbution을 더 고르게 만들어주는 특징이 있다.


위 과정을 통해 Masked Multi-Head Attention이 끝나면 마찬가지로 Add&Norm Layer를 거쳐 '<sos> 나는 집에'의 각 단어에 대한 encoding vector가 나온다. 이 encoding vector를 앞으로 decoder vector라 부를 것이다.


이렇게 다음에 올 단어를 예측하도록 encoding을 하였으면, 이제 번역을 할 수 있도록 encoding하는 작업을 해야한다.


■ Multi-Head Attention
번역을 위한 encoding은 바로 다음 Layer인 Multi-Head Attention에서 수행한다. Multi-Head Attention의 input으로는 decoder vector와 encoder ouput vector가 들어가고, decoder vector에서 Query를 만들고, encoder vector에서 Key와 Value를 만든다.


예를 들어, <sos>가 Query이면, I go home 세 단어의 Key와 내적하여 유사도 score를 구하게 된다. score에 scaling한 후 softmax를 취하여 가중치를 구한 후, Weighted Value의 Sum으로 <sos>에 대한 decoder output vector를 얻는다.
<sos>의 경우 I go home 중 I와 유사도가 가장 높을 것이고, 따라서 <sos>가 주어지면 I가 나올 것이다. 그 다음 <나는>이 주어지면 go와 제일 유사도가 높을테니 go가 나올 것이다.

※ Multi-Head Attention에서 자기 자신과의 유사도를 구하지 않는 이유는 초점이 다음에 올 단어를 예측하는 것이기 때문이다.

 


 

Transformer의 Machine Translation 성능

 

 



[reference]
• Illustrated transformer http://jalammar.github.io/illustrated-transformer/
• The Annotated Transformer http://nlp.seas.harvard.edu/2018/04/03/attention.html
• CS224n –Deep Learning for Natural Language Processing http://web.stanford.edu/class/cs224n/
• Convolution Sequence to Sequence https://arxiv.org/abs/1705.03122
• Fully-parallel text generation for neural machine translation https://blog.einstein.ai/fully-parallel-text-generation-for-neural-machine-translation/

「Attention Is All You Need, NeurIPS’17」

728x90
반응형

'AI > 딥러닝' 카테고리의 다른 글

[NLP] GPT-2 , GPT-3 , ALBERT , ELECTRA  (0) 2021.09.21
[NLP] GPT-1 , BERT  (0) 2021.09.19
[NLP] Beam search decoding , BLEU score  (1) 2021.09.12
[NLP] Seq2seq with Attention  (0) 2021.09.10
[NLP] NLP Tasks , Bag of Words , Word Embedding , GloVe  (0) 2021.09.09

댓글