Transformer
( 참고 : “딥러닝을 이용한 자연어 처리 입문” (https://wikidocs.net/book/2155) )
목차
- 1.Introduction
- 2.Transformer의 hyperparameter
- 3.Attention & Transformer의 구조
- 4.Positional Encoding
- 5.Encoder의 구조
- 6.[Attention 1] Encoder의 Self-attention
- 7.Encoder/Decoder의 Position-wide FFNN
- 8.Masking
- 9.Decoder의 구조
- 10.[Attention 2] Decoder의 Masked Self-attention
- 11.[Attention 3] Decoder의 Encoder-Decoder attention
1. Introduction
- Transformer은 기존의 seq2seq과 다르게 , cell 안에 RNN,LSTM,GRU 등의 방식을 사용하지 않는다
( Attention을 RNN의 보정 용도가 아니라, 아예 Attention만으로 Encoder & Decoder 생성 ) - Encoder & Decoder의 구조는 유지한다
- Encoder & Decoder라는 단위가 1개가 아닌 N개를 사용할 수 있다
( 논문에서는 Encoder와 Decoder을 각각 6개 사용함 ) - 순차적 (X), 모든 것을 한번에 병렬적(O)으로 처리!
.
.
이 그림을 보면, Encoder로부터 정보를 받아 Decoder가 출력 결과를 만드는 구조는 동일하다.
다만 RNN은 사용하지 않음을 확인할 수 있다
2. Transformer의 hyperparameter
transformer에 대해 구체적으로 설명하기 이전에, 어떠한 hyperparameter들이 있는지 살펴보자
hyperparameters
- 1 ) d_model : Encoder & Decoder에서의 정해진 입력 & 출력의 크기 (즉, Embedding Vector의 크기 또한 d_model )
- 2 ) num_layers : Encoder & Decoder의 구성 층 수
- 3 ) num_heads : Transformer에서는 병렬로 Attention을 수행하는데, 이때의 병렬 개수
- 4 ) d_ff : Transformer 내부에 존재하는 Feed Forward 신경망의 은닉층 크기
3. Attention & Transformer의 구조
.
사용 되는 세 종류의 Attention :
- 1) (Encoder의) self-attention
- 2) (Decoder의) Masked self-attention
- 3) (Decoder의) encoder-decoder attention
4. Positional Encoding
RNN이 자연어 처리에서 많이 사용된 이유는, 단어를 “순차적으로 입력”받아 처리하는 RNN의 특징 때문이다! 이것이 각 단어의 위치 정보를 알려줬기 때문이다. 하지만, Transformer은 RNN을 사용하지 않는다. 대신에, Positional Encoding이라는 방법을 통해 단어의 위치(순서)를 파악한다. 단어의 위치 정보를 얻기 위해, 각 단어를 임베딩 한 이후, 이에 위치 정보를 더한 다음 모델에 입력한다.
임베딩 벡터가 Encoder의 입력으로 사용되기 전에, 다음과 같이 Positional Encoding값이 더해진다
위 그림처럼 “벡터” 단위로 더해지는게 아니라, 사실은 Embedding Vector가 모여서 만들어진 “문장 벡터 행렬”에
“Positional Encoding 행렬”이 이루어진다
Positional Encoding의 값은 다음과 같다
5. Encoder의 구조
Encoder의 구조는 다음과 같이 생겼다
.
Encoder의 구조
-
n개의 encoder를 가진다 ( = num_layers )
-
Encoder를 하나의 ‘층’으로 생각해보자.
하나의 Encoder는 총 2개의 sub layer로 구성된다
- **1 ) Self Attention **
- 2 ) Position wise Feed Forward Neural Network
6. [Attention 1] Encoder의 Self Attention
a) Self Attention
기존의 seq2seq에서 Attention의 Q,K,V
- 1 ) Q : t 시점의 Decoder cell에서의 Hidden state
- 2 ) K : 모든 시점의 Encoder cell에서의 Hidden states
- 3 ) V : 모든 시점의 Encoder cell에서의 Hidden states
t 시점의 Decoder state가 아니라, 전체 시점으로 일반화하면
- 1 ) Q : 모든 시점의 Decoder cell에서의 Hidden state
- 2 ) K : 모든 시점의 Encoder cell에서의 Hidden states
- 3 ) V : 모든 시점의 Encoder cell에서의 Hidden states
BUT, Transformer의 Self-Attention의 Q,K,V는 모두 같다!
- Q,K,V : 입력 문장의 모든 단어 벡터들
Self Attention을 사용하면 좋은 이유? ( 아래 Example 참고 )
- 아래 그림을 보면, 의미 상 it은 animal에 해당한다.
- 기계는 이를 ‘입력 문장 내의 단어들끼리의 유사도’를 통해 찾아낸다!
- (it은 animal, street 중 animal과 더 높은 유사도를 보인다)
Example
기존의 seq2seq의 attention은, 서로 다른 Encoder & Decoder 문장 사이의 연관성을 찾아냈기 때문에, 위 예시와 같은 정보는 찾아낼 수 없었다.
b) Q,K,V vector
입력받은 단어 vector로 바로 Self-Attention? NO!
각 단어 vector로부터 Q,K,V벡터를 먼저 얻어낸다 ( 차원 축소가 이루어짐 )
- input 되는 단어 vector : d_model 차원 ( 논문에서 d_model = 512 )
- Q,K,V vector : d_model / num_heads 차원 ( 논문에서 num_heads = 8, 즉 64차원 )
c) scaled-dot product attention
기존과(attention mechanism 참고) 유사하다.
구해낸 Q,K,V벡터를 사용하여 다음과 같은 순서로 context vector를 구해낸다
( Attention Score -> Attention Distribution -> Attention Value(Context Vector) )
차이점 : 단순 내적이 아니라, “특정 값으로 나눠준 attention 함수”를 사용한다
아래 그림을 통해 쉽게 이해할 수 있다.
위 그림에서는 ‘I’라는 단어의 Q 벡터에 대해 연산이 이루어졌다. 하지만, 행렬 연산으로 일괄적으로 처리하면, 이렇게 모든 Q벡터마다 일일히 따로 계산할 필요가 없다.
d) 행렬 연산으로 일괄 처리
[ STEP 1 ] Q, K, V행렬 구하기
실제로는 벡터 간의 연산이 아니라, 행렬로 한번에 연산이 이루어지기 때문에 Q,K,V 행렬을 우선 구해야 한다.
[ STEP 2 ] 행렬 연산을 통해 Attention Score 구하기
Q 행렬을 K 행렬의 전치행렬과 곱해준다
[ STEP 3 ] Attention Value 구하기
Attention Score에 Softmax함수를 사용하고, 이에 V 행렬을 곱한다
위 연산을 거친 결과는, 정리하자면 다음과 같은 수식으로 표현할 수 있다.
행렬의 크기
입력 문장의 길이 : seq_len
문장 행렬의 크기 : (seq_len, d_model) -> 이 문장 행렬을 통해 Q,K,V 행렬을 구한다
Q & K 벡터의 크기 : d_k
V 벡터의 크기 : d_v
- Q 행렬 : (seq_len, d_k)
- K 행렬 : (seq_len, d_k)
- V 행렬 : (seq_len, d_v)
이에 따라, 자동으로 weight 행렬의 크기도 정해진다
- Wq 행렬 : (d_model,d_k)
- Wk 행렬 : (d_model,d_k)
- Wv 행렬 : (d_model,d_v)
( 논문에서 d_k와 d_v는 ‘d_model / num_head’로 동일하다 )
“ 결과적으로, Attention Value 행렬(a)의 크기는 (seq_len, d_v)이다! “
(2) Multi-head Attention
여러개의 head를 사용하는 이유 :보다 다양한 특징을 capture하기 위해서이다.
( num_heads 개수 만큼의 head를 사용 )
.
하나의 head가 내뱉는 attention vector의 크기는 d_model/num_heads이다.
이러한 num_heads개의 head들이 병렬적으로 Attention을 동시에 수행한다.
이와 같이 병렬 attention을 모두 시행한 이후, attention head들을 전부 concatenate한다.
( 연결된 attention head 행렬의 크기 : (seq_len, d_model) )
.
이렇게 연결된 attention head들에, 가중치 행렬(Wo)를 곱해서 Multi-head Attention Matrix를 생성한다
.
Multi-head Attention에 등장한 weight matrix 정리
- 1 ) Wq, Wk, Wv
- 2 ) Wo ( attention head 생성 후, 이에 곱하는 weight matrix )
weight matrix (Wq,Wk,Wv)의 값이 8개 Attention Head마다 모두 다르게 됨!
7. Encoder/Decoder의 Position-wide FFNN
행렬의 크기
- 위 그림에서의 x는 앞에서 구한 Multi-head Attention의 크기와 같은 행렬이다
- W1의 shape : (d_model, d_ff)
- W2의 shape : (d_ff, d_model)
여기에서 사용되는 parameter들 (W1, b1, W2, b2)는 문장 별로 모두 동일(서로 share)하지만, Encoder층 마다는 다른 값을 가진다. 아래 그림을 보면, 지금까지의 연산이 어떻게 이루어지는지 쉽게 이해할 수 있다.
.
8. Masking
2가지의 Masking이 존재한다.
- 1) Encoder & Decoder에서 모두 수행하는 masking : 최대 문장 길이에 미치지 못해 남는 공간인 padding에 masking을 하는 것.
- 2) Decoder에서, 뒷 부분 cheating을 방지하기 위해 수행하는 masking
Attention에서, decoder가 encoder의 hidden state들을 얼만큼 참고하기 위함을 계산하는 과정에서, 아래와 같이 attention score를 구한 뒤, softmax를 통해 최종적으로 참고 비율을 결정하였다.
.
하지만, 여기서 마지막 문장 단어의 뒷 부분 ( < pad >를 ) masking을 하기 위해 ( = 즉 참고하지 말아야 할 부분을 알려주기 위해 ), 매우 작은 음수 값 (-무한대)를 부여하여 softmax의 결과값이 0에 가깝도록 유도한다.
.
9. Residual Connection & Layer Normalization
아래 그림과 같이, Add와 Normalization의 과정이 추가된다.
1) Residual Connection
ResNet을 공부한 적이 있다면 잘 알 것이다. 입력 x와, 이를 input으로 나온 어떠한 함수값 F(x)를 더한 함수 H(x)를 의미한다. ( 여기서 F(x)는 Transformer의 sub layer가 된다 )
아래와 같이 (1)멀티 헤드 어텐션의 입력과 (2)멀티 헤드 어텐션의 결과가 더해진 다음에 뒤로 넘겨진다.
.
2) Layer Normalization
\(L N=\text { Layer } \operatorname{Norm}(x+\text { Sublayer }(x))\).
.
정규화 : \(\hat{x}_{i, k}=\frac{x_{i, k}-\mu_{i}}{\sqrt{\sigma_{i}^{2}+\epsilon}}\).
정규화 이후, 학습가능한 parameter \(\gamma\)와 \(\beta\)를 도입한다.
\(l n_{i}=\gamma \hat{x}_{i}+\beta=\text { Layer } \operatorname{Norm}\left(x_{i}\right)\).
10. [Attention 2] Decoder의 Masked Self-attention
6.[Attention 1] Encoder의 Self-attention와 동일하나, ( Q=K=V )
decoder의 경우 해당 단어 “뒷 부분은 참고 하면 안된다”는 점에서, ㅊ해당 단어 뒷 부분은 모두 masking**을 해준다는 유일한 차이점이 있다.
.
11. [Attention 3] Decoder의 Encoder-Decoder attention
[Attention 1]과 [Attention 2] 모두 Q=K=V인 반면, Encoder-Decoder Attention의 Q,K,V는 :
-
Q : decoder의 hidden state
-
K=V : Encoder의 hidden state
.