본문 바로가기

AI/NLP Paper

[NLP] Attention Is All You Need 리뷰

Introduction

LSTM, GRU 같은 순환 신경망은 language modeling과 기계 번역 분야에서 SOTA의 자리를 굳건하게 지키고 있었습니다. 

 

Recurrent 모델은 기본적으로 input과 output sentence의 symbol위치에 따라서 계산을 고려합니다. position을 계산 step에 aligning 하면서 hidden state의 시퀀스 $h_t$를 이 전 hidden state $h_{t-1}$과 position $t$에서의 input을 이용하여 생성합니다.

 

이것은 본질적으로 training examples에서의 병렬화를 막고, batching across examples에서의 메모리 제한을 두게 됩니다. 이 문제를 해결하기 위해 많은 노력이 있었지만, sequential 계산의 근본적인 문제는 여전히 남아있습니다.

 

이에 논문에서는 Transformer를 소개합니다. Transformer는 순환 신경망 사용을 피하고 전적으로 attention mechanism에 의존합니다. 또한 Transformer는 더 많은 병렬화를 가능하게 하고 번역 성능에서 새로운 SOTA를 달성했습니다.

 

Model Architecture

대부분의 neural sequence transduction 모델은 encoder-decoder 구조를 가지고 있습니다. 

 

encoder는 input sequence $(x_1, \cdots, x_n)$을 연속적 표현인 $\mathbf{z} = (z_1, \cdots, z_n)$으로 바꾸고, decoder는 이 $\mathbf{z}$를 이용하여 output sequence $(y_1, \cdots, y_m)$를 만들어냅니다. 각 step마다 이 전 step에서 만들어진 symbol과 새로 들어온 input을 이용하여 다음 단계의 symbol을 만들어내는 방식입니다.

 

Transformer의 전체적인 구조는 위와 비슷하지만 self-attentionpoint-wise를 쌓고, encoder와 decoder에 fully connected layers를 사용했습니다.

 

Encoder and Decoder Stacks

Encoder

 

인코더는 $N = 6$의 독립적인 layers의 결합으로 이루어져 있습니다.  각 layer는 두 개의 sub-layer를 가지고 있는데, 하나는 multi-head self-attention mechanism이고, 다른 하나는 position-wise fully connected feed-forward network입니다.

 

또한 residual connection을 각 2개의 sub-layer에 적용한 뒤 layer normalization을 진행해줍니다. 즉, 각 sub-layer의 output은 $\text{LayerNorm}(x + \text{Sublayer}(x))$이고 $\text{Sublayer}(x)$는 sub-layer자체 함수입니다. 그리고 이 residual connection을 원활하게 하기 위해 모델의 모든 sub-layer와 embedding layer의 output dimension을 $d_{\text{model}} = 512$로 맞춰줬습니다.

 

Decoder

 

디코더도 인코더와 같이 $N = 6$의 독립적인 layer로 이루어져 있습니다. 인코더에 있는 2개의 sub-layer에 추가로 디코더에서는 3번째 sub-layer가 있는데, 이는 인코더의 output과 합쳐진 multi-head attention입니다.

 

또, 인코더와 마찬가지로 residual connection이 각 sub-layer에 적용되고 layer normalization이 뒤따라옵니다.

 

마지막으로 self-attention sub-layer를 수정해줬습니다. 마스킹을 사용하여 $i$번 째 position에 대한 예측이 $i$보다 이전의 position에서의 output에만 의존하도록 만들어줬습니다.

 

Attention

Attention function은 query와 key-value 쌍의 집합을 하나의 output으로 mapping 하는 함수입니다. 이때의 query, keys, values, output은 모두 vector입니다. 

 

output은 각 value의 가중 합으로 계산되고, 이때의 가중치는 query와 그에 해당하는 key를 compatibility function을 통해 계산한 값입니다. 

 

Scaled Dot-Product Attention

논문에서 말하는 특별한 attention인 Scaled Dot-Product Attention(Figure 2. 왼쪽)에서의 input은 query, key(dimension $d_k$)와 value(dimension $d_v$)를 포함합니다. 계산을 할 때는 query를 모든 key와 dot product 해 준 뒤, 각각을 $\sqrt{d_k}$로 나눠줍니다. 그다음 softmax function을 통과하여 value에 대한 가중치를 얻습니다. 

 

실제로는 query, key, value를 각각 행렬 $Q, K, V$로 묶어서 계산하게 됩니다.

$$\text{Attention}(Q, K, V) = \text{softmax}(\frac{QK^T}{\sqrt{d_k}})V$$

가장 많이 사용되는 두 개의 attention 함수는 additive attentiondot-product attention입니다. dot-product attention은 scaling factor $\frac{1}{\sqrt{d_k}}$가 없다는 것을 제외하면 논문에서의 알고리즘과 동일합니다. additive attention은 하나의 hidden layer를 갖고 있는 feed-forward network를 사용하는 compatibility function으로 계산합니다. 이 두 개의 방법은 이론상의 복잡도는 비슷하지만, dot-product attention이 훨씬 빠르고, 공간 효율도 더 좋습니다. 

 

그런데 dot-product attention의 특성상 $d_k$의 절댓값이 커지게 되면 softmax 함수의 기울기를 너~무 작게 만드는 문제가 생길 수 있기 때문에, $\frac{1}{\sqrt{d_k}}$를 사용해줍니다.

 

Multi-Head Attention

$d_{\text{model}}$차원의 keys, values, queries를 단일 attention function으로 계산하는 것보다 각각을 $d_k, d_k, d_v$차원으로 서로 다른 방법의 linear projection을 사용해줍니다. 그리고 이를 $h$번 진행합니다. (Figure 2. 오른쪽) 이렇게 $h$개의 attention 함수를 병렬 처리하고, 결과를 모두 concatenate해준 다음 한 번 더 project 해줍니다.

 

Multi-head attention은 다른 position에서의 representation subspaces로부터 온 정보를 jointly attend 할 수 있게 해 줍니다. 

\begin{align} & \text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \cdots, \text{head}_h)W^O \\ & \text{head}_i = \text{Attention}(QW_i^Q, KW_i^K, VW_i^V) \end{align}

  • $W_i^Q \in \mathbb{R}^{d_{\text{model}} \times d_k}$
  • $W_i^K \in \mathbb{R}^{d_{\text{model}} \times d_k}$
  • $W_i^V \in \mathbb{R}^{d_{\text{model}} \times d_v}$

 

여기서 $h = 8$만큼 병렬화를 진행했습니다. 따라서 각 $d_k = d_v = d_{\text{model}} / h = 64$입니다. 이렇게 차원을 줄였기 때문에 전체 계산 비용은 full dimensionality single-head attention과 같습니다.

 

Applications of Attention in out Model

Transformer에서는 multi-head attention을 세 개의 다른 방법으로 사용합니다.

 

  • encoder-decoder attention layer에서 query는 이 전의 decoder layer에서 온 값이고, key와 value는 encoder의 output으로부터 가져온 값입니다. 이는 decoder의 어느 position에서든지 input sequence의 모든 positions를 참고할 수 있게 해 줍니다. 

  • 인코더의 self-attention layer에서는 모든 keys, values, queries를 같은 장소에서 가져옵니다. 이 경우에는 이 전 encoder layer에서의 output이 됩니다. 인코더의 각 position은 인코더의 이전 layer의 모든 position을 참고할 수 있습니다.

  • 유사하게, 디코더의 self-attention layer는 디코더에서의 각 position에서 이 전부터 지금까지의 모든 position을 참고할 수 있게 합니다. 여기서 leftward information flow를 보존해야 할 필요가 있습니다. 그래서 잘못된 연결에 대해서는 softmax의 input으로 들어갈 때 $-\infty$로 마스킹해줍니다. 

마지막 leftward information flow가 잘 이해가 안 됐는데, 앞에서 decoder에서 $i$번 째 position에 대한 예측을 $i$보다 이전 position에 대한 정보를 이용한다고 했는데 아마 거기에 대한 설명인 것 같습니다. 

 

Position-wise Feed-Forward Networks

encoder와 decoder의 각 layer에는 fully connected feed-forward network를 가지고 있습니다. 이는 두 개의 선형 변환으로 이루어져 있고, 그 사이에 활성화 함수로 ReLU를 사용합니다. 

$$\text{FFN}(x) = \text{max}(0, xW_1 + b_1)W_2 + b_w$$

position이 다르더라도 선형 변환 방식은 동일합니다, 하지만 layer에서 layer를 넘어갈 때마다 사용되는 파라미터는 달라집니다.  이 방식은 필터 사이즈가 1인 두 번의 합성곱 연산을 진행한다고 설명할 수도 있습니다. input과 output의 차원 $d_{\text{model}} = 512$이고, inner-layer의 차원 $d_{ff} = 2048$입니다. 

 

Embedding and Softmax

다른 sequence transfuction 모델과 비슷하게, Transformer도 학습된 임베딩을 사용하여 input token과 output token을 $d_{\text{model}}$차원의 벡터로 변환합니다. 또한 학습된 선형 변환과 softmax 함수를 사용하여 decoder의 output을 이용해 next-token의 확률을 예측합니다. 논문의 모델에서는 두 개의 임베딩 레이어와 softmax적용 전에 선형 변환을 할 때의 가중치를 공유합니다.(Figure 1. 에서의 각 Embedding layer와 제일 마지막 softmax전에 있는 linear transformation)

임베딩 레이어에서는 이 가중치들을 $\sqrt{d_{\text{model}}}$을 곱해줍니다.

 

Positional Encoding

Transformer는 recurrence나 convolution이 없기 때문에, sequence의 순서를 사용하도록 만들기 위해서는 sequence에 있는 token과 관련이 있는 position에 대한 정보를 넣어줘야 합니다. 이를 위해서 positional encodings를 encoder와 decoder 아래쪽에 있는 embedding에 추가해줍니다. positional encoding은 임베딩과 같은 차원인 $d_{\text{model}}$의 차원을 갖고 있습니다. 그래서 두 개가 서로 더해질 수 있는 것입니다.

 

positional encoding을 하기 위한 방법에는 여러 가지가 있지만 논문에서는 sine과 cosine을 사용했습니다.

 

\begin{align} \text{PE}_{(pos, 2i)} &= \sin(pos / 10000^{2i / d_{\text{model}}}) \\ \text{PE}_{(pos, 2i+1)} &= \cos(pos/10000^{2i/d_{\text{model}}}) \end{align}

위 식에서 $pos$는 position이고 $i$는 차원을 의미합니다. 

 

Why Self-Attention

이 절에서는 self-attention layer와 널리 쓰이는 recurrent layer와 convolution layer를 다양한 관점에서 비교해봅니다. self-attention사용에 대한 명분(?)을 얻기 위해서는 3가지를 고려해야 합니다.

 

  1. 각 layer당 전체 계산 복잡도
  2. 병렬화하여 처리할 수 있는 계산의 양(필요한 sequential operation의 최소한의 개수로 측정합니다.)

  3. The path length between long-range dependencies

계산 복잡도의 관점에서 Self-Attention과 Recurrent를 비교하면 $n < d$일 때 Self-Attention의 계산 복잡도가 더 낮아집니다. 이는 거의 대부분의 경우에서 나타나는 현상으로 웬만해서는 Self-Attention이 계산 복잡도 면에서는 더 낫다고 볼 수 있습니다. 그리고 아주 긴 문장에 대한 성능도 높이고 싶어서 각각의 output position에서 모든 input sequence를 고려하지 말고 주변 $r$개만 고려하도록 제한을 뒀습니다. 하지만 이는 Maximum Path Length를 늘리는 단점이 있어서 추 후에 연구를 더 해야 할 것입니다.

 

이 외에도 Self-Attention이 좀 더 설명 가능한 모델을 만든다는 장점이 있습니다. 각각의 multi-head attention이 다른 task를 수행하는 것을 배우는 것뿐만 아니라, sentence에서 syntactic, semantic 구조에 대한 반응이 보이는 것을 알 수 있습니다.

Training

이 절에서는 Transformer를 훈련할 때의 파라미터나 데이터에 대한 설명이 있습니다.

Training Data and Batching

450만 개의 sentence pair를 포함하는 WMT 2014 English-German dataset을 사용했습니다. 각 문장들은 byte-pair encoding을 이용해서 인코딩해주고 37000개의 공유되는 source-target 단어장을 만들어줍니다.

 

English-French에서는 3600만 개의 sentence와 32000개의 word-piece 단어장을 만들었습니다.

 

Sentence pairs는 비슷한 sequence 길이를 가진 pair끼리 묶어줍니다.(batch 처리) 각각의 training batch는 대략 25000개의 source token과 25000개의 target token을 포함하는 sentence pair로 묶었습니다.

 

Optimizer

Adam을 사용했고 파라미터로 $\beta_1 = 0.9, \beta_2 = 0.98, \epsilon = 10^{-9}$를 사용합니다. 그리고 learning rate는 아래 식을 이용해 계속해서 변화시키며 사용해줍니다.

$$lrate = d_{\text{model}}^{-0.5} \cdot \min(step_num^{-0.5}, step\text{_}num \cdot warmup\text{_}steps^{-1.5})$$ 

learning rate는 처음에는 $warmup\text{_}steps$ 에 선형적으로 비례하여 증가하지만, 그다음부터는 일정 비율에 따라 감소하게 됩니다. $warmup\text{_}steps = 4000$을 사용했습니다.

 

Regularization

regularization 방법으로는 3가지 방법을 사용했습니다.

  • Residual Dropout

각 sub-layer의 output이 다음 sub-layer의 input으로 들어가거나 normalized 되기 전에 dropout을 진행해줍니다. 또한, 임베딩과 positional encodings를 더하는 부분에서도 dropout을 적용해줍니다. dropout 비율로는 $P_{drop} = 0.1$을 사용했습니다.

  • Label Smoothing

label smoothing은 $\epsilon_{ls} = 0.1$을 사용하여 적용해줬습니다. 이 방법을 사용하면 perplexity에는 안 좋지만, 정확도와 BLEU 점수는 올랐습니다.

 

Conclusion

이번 논문에서는 Transformer를 소개했습니다.

 

Transformer는 encoder-decoder 구조에서 가장 많이 쓰이던 recurrent layers를 multi-headed self-attention으로 대체하여 온전히 attention만을 기반으로 한 첫 번째 sequence transduction모델입니다.

 

translation task에서 Transformer는 기존의 recurrent나 convolutional layer기반의 모델들에 비해 확연히 빠른 학습 속도를 보였습니다. 뿐만 아니라 translation task에서의 새로운 SOTA를 달성했습니다.