Transformer

Lucia·2023년 7월 25일
0

Article.log

목록 보기
4/4

논문링크: Attention Is All You Need

이번 논문은 Transformer 모델에 관한 논문입니다.
기존에 RNN 계열에서 벗어나 Attention으로만 모델을 구성한 논문으로 활용도가 높은 모델입니다.
NLP에 대한 배경 지식이 많이 부족하여 공부하는데 시간이 오래 걸렸는데,
유튜브에 동빈나님께서 올려주신 영상을 보고 많은 도움을 얻었어요.
다른 논문 리뷰와는 다르게 제가 이해하기 편한 순서로 재구성을 하였으니 이점 참고바랍니다.
또한 모델의 구조까지 정리하였습니다. 추후에 training, result 부분까지 정리할 수 있도록 노력해보겠습니다!

참고링크: 동빈나님의 트랜스포머 논문 리뷰


Abstract

  • Recurrent(반복)과 합성곱을 사용하지 않고, 오직 attention만을 사용하는 새로운 구조인 트랜스포머를 제안한다.
  • WMT 2014 영어-독일어 번역에서 28.4 BLEU를 달성하여 기존 최고 결과보다 2 BLEU 이상 향상되었다.
  • WMT 2014 영어-프랑스어 번역에서 BLEU 41.8을 달성했다.
  • 트랜스포머든 대규모 혹은 소규모 학습 데이터 기반의 영어 구분 분석에서도 높은 성능을 보이며, 다른 과제들에도 일반화가 가능하다는 것을 보여준다.

1. Introduction | 2. Background

이 절에서는 기존의 Sequence 모델에 한계가 있으며, 이를 트랜스포머는 극복할 수 있다고 설명한다.
배경이 되는 Seq2seq 모델의 구조와 한계를 정리해보았다.

  • 기존 Seq2seq 모델: 인코더-디코더 구조
    • 인코더에서 입력 시퀀스를 하나의 벡터로 압축한다.
    • 디코더는 벡터를 통해 출력 시퀀스를 만든다.
  • 이러한 인코더가 입력 시퀀스를 하나의 벡터로 압축하는 과정에서 나타나는 단점
    • 입력 시퀀스의 정보가 일부 손실된다.
    • 병목현상이 발생한다.

  • 이를 보정하기 위해 Attention이 사용되었으나, 트랜스포머는 RNN을 보정하는 용도가 아닌, attention만으로 인코더와 디코더를 만들었다.

3. Model Architecture


Figure 1: 트랜스포머의 구조

이 절에서는 원래 논문의 순서와는 다르게, 모델의 구조를 입력이 들어와서 출력이 나오는 과정으로 정리한다.

기본 구조 먼저 보고 넘어가자면,
기존 seq2seq 구조처럼 시작 < sos >를 입력으로 받아 종료 < eos >가 나올 때까지 연산을 진행하며, 인코더-디코더 구조는 유지하고 있다.

  • 입력 단어들이 하나로 쭉 연결되어 한 번에 입력을 받고, 결과 값을 구한다.
  • 위치에 대한 정보를 한번에 넣어, 인코더를 거칠 때마다 병렬적으로 출력값을 구할 수 있기 때문에 계산 복잡도가 낮다.
  • 다만, 출력값을 내보낼 때는 디코더를 여러 번 사용하여 < eos >가 나올 때까지 반복하도록 한다.
  • context vector로 압축하는 과정이 생략된다.

그리고 트랜스포머에서 핵심이 되는 Attention은 세 종류로 되어 있다.
위의 이미지에서 빨간색 화살표로 표시된 부분이다.
1. Encoder Self-Attention
2. Masked Decoder Self-Attention
3. Encoder-Decoder Attention

  • Self-Attention: 쿼리, 키, 벨류의 출처가 동일한 경우다.(인코더 내부, 디코더 내부에 위치)
  • Encoder-Decoder Attention: 쿼리가 디코더 벡터인 반면, 키와 벨류는 인코더 벡터이므로 셀프 어텐션이라 부르지 않는다. 인코더와 디코더를 연결하는 어텐션이라고 생각하면 된다.

이런 기본 내용만 짚고, 데이터가 들어오는 것부터 차근차근 봐보자.

3.1. Positional Encoding

  • 기존 모델은 RNN 특성으로 각 단어의 위치 정보를 가질 수 있었다.
  • 그러나 트랜스포머는 단어를 순차적으로 입력받지 않기 때문에 Positional Encoding으로 위치정보를 알려준다.

  • 위치 정보를 가진 값을 만들기 위해 사인함수와 코사인 함수를 사용한다.
    PE(pos,2i)=sin(pos/100002i/dmodel)PE_{(pos, 2i)} = \sin(pos/10000^{2i/d_{model}})
    PE(pos,2i+1)=cos(pos/100002i/dmodel)PE_{(pos,2i+1)} = \cos(pos/10000^{2i/d_{model}})
    • 사인 함수와 코사인 함수의 값을 임베딩 벡터에 더하여, 단어의 순서 정보를 알려준다.
    • pospos: 입력 문장에서의 임베딩 벡터의 위치
    • ii: 임베딩 벡터 내의 차원의 인덱스
    • 인덱스가 짝수일 때는 사인 함수를, 홀수일 때는 코사인 함수를 사용한다.
    • dmodeld_{model}: 모델의 차원으로 논문에서는 512를 사용한다.

3.2. Encoder

데이터가 Positional Encoding을 통과하면 2개의 서브층을 만나게 된다.

  • Multi-Head Attention
    • 인코더 파트에서 사용하는 어켄션은 Encoder Self-Attention이라고 부른다.
    • 멀티 헤드 셀프 어텐션은 셀프 어텐션을 병렬적으로 사용했다는 의미다.
      (이 부분은 밑에서 더 자세히 정리하자.)
    • 각 단어가 서로에게 어떤 연관성을 갖고 있는지, 어텐션 스코어를 구해 연관 정보를 학습한다.
  • Feed Forward
  • 두 레이어에은 Residual connection이 있고, 각 레이어 이후 정규화를 적용한다.
    • Residual connection을 용이하게 만들기 위해 모든 차원은 512로 한다.
  • 이러한 레이어 스택이 N번 반복되며, 논문에서 N = 6이다. 단, 각 스택마다 attention, feed forward 레이어의 파라미터는 서로 다르다고 나와있다.

3.2.1. Encoder Self-Attention

Multi-Head Attention을 설명하기 위해,
셀프 어텐션이 무엇인지 보고 → 어텐션의 입력 요소 부터 → 하나의 어텐션 스코어를 구하는 방법을 살펴본 후 → 멀티 헤드 어텐션까지의 순서로 정리한다.

  • Self-Attention의 이점
    : 셀프 어텐션을 통해 단어 간의 유사성을 구하여 연관성을 찾는다.

    it이 의미하는 것은 셀프 어텐션을 통해 the, tree, it과 연관되어 있음을 찾는다.
  • Attention을 위한 세 가지 입력 요소: 쿼리(Query), 키(Key), 값(Value)
    • 예) 'I love you' 문장에서 'I'가 쿼리일 때, 'I', 'love', 'you'는 키가 된다.
    • 물어보는 대상과 다른 단어들이 얼마나 연관성을 가지는지 측정한다.
  • Q, K, V 벡터 구하기
    • 인코더의 초기 입력인 dmodeld_{model}의 차원(512)를 가지는 단어 벡터들로부터 Q 벡터, K 벡터, V 벡터를 얻는다.
    • dmodeld_{model}보다 적은 차원을 가지며, 논문에서는 64차원으로 변환하였다.
    • dmodeld_{model}num_heads로 나눈 값을 Q, K, V 벡터 차원으로 결정한다. 논문에서 num_heads는 8이다.
    • 각 가중치 행렬의 크기: dmodel×(dmodel/d_{model}\times(d_{model}/num_heads)
  • Scaled Dot-Product Attention
    • Q, K, V 벡터를 구했다면,
      각 Q 벡터는 모든 K 벡터에 대해서 attention score를 구하고,
      softmax를 취하여 어텐션 분포를 구한 뒤,
      V 벡터를 가중합하여 어텐션 값을 구한다.
    • 이 과정을 모든 Q 벡터에 대해 반복한다.
    • Attention(Q,K,V)=softmax(QKTdk)VAttention(Q, K, V) = softmax({{QK^T}\over \sqrt d_k})V

      이는 행렬 연산을 사용하면 일괄적으로 계산이 가능하다.
  • Multi-Head Attention
    MultiHead(Q,K,V)=Concat(head1,...,headh)WOMultiHead(Q,K,V) = Concat(head_1, ..., head_h)W^O
    • h(Head의 개수)개로 입력값을 구분한다.
      • h개의 서로 다른 쿼리, 키, 벨류로 구분된다.
      • 이렇게 하는 이유는, 서로 다른 h개의 attention 컨셉을 병렬적으로 학습하도록 만들어, 다양한 특징을 학습할 수 있도록 유도하려는 것이다.
    • 이후 concat 연산을 한다.
    • 마지막으로 또 다른 가중치 행렬 WOW^O를 곱한다.
  • Padding Mask
    • 이 때 무의미한 단어의 유사도를 구하지 않도록 마스킹을 한다.
    • 어텐션 스코어 행렬에서 마스킹 할 부분에 매우 작은 음수값을 넣어준다.
    • softmax를 지나면, 해당 위치는 0이 되기 때문에 이후에는 반영되지 않는다.

3.2.2. Position-wise Feed-Forward Networks

  • FFNN(x)=MAX(0,xW1+b1)W2+b2FFNN(x) = MAX(0, xW_1+b_1)W_2+b_2
    • F1=xW1+b1F_1 = xW_1+b_1
    • 활성화 함수 ReLU F2=max(0,F1)F_2 = \max(0, F_1)
    • F3=F2W2+b2F_3=F_2W_2+b_2
    • x: 멀티 헤드 어텐션의 결과로 나온 행렬 (seq_len, d_model) 크기
    • W: 가중치 행렬로 W1은 (d_model, d_ff)크기를, W2는 (d_ff, d_model) 크기를 가진다.
    • dffd_{ff}: 2,048
  • W1, b1, W2, b2는 하나의 인코더 층 내에서는 동일하게 사용되지만, 인코더 층마다는 다른 값을 가진다.
  • 한 인코더 층을 지난 행렬은 여전히 인코더 입력이었던 (seq_len, d_model) 크기를 유지한다.
    • (seq_len, d_model) x (d_model, d_ff) → (seq_len, d_ff) x (d_ff, d_model) → (seq_len, d_model)

3.3. Decoder

인코더와 마찬가지로 레이어가 N번 반복되며, 논문에서 N = 6으로 설정했다.

구성

  • Masked Decoder Self-Attention
  • Encoder-Decoder Self-Attention
  • Residual connection, Normalization

3.3.1. Masked Decoder Self-Attention

  • 인코더의 첫 번째 멀티-헤드 어텐션과 동일한 연산을 수행하지만, 다른 점은 Look-Ahead Mask를 수행한다는 것이다.
  • Look-Ahead Mask
    • RNN 계열의 모델은 입력 단어를 순차적으로 입력받으므로, 현재 시점을 포함한 이전 시점의 단어들만 참고할 수 있었다.
    • 그러나 트렌스포머는 입력을 한 번에 받으므로, 미래 시점의 단어까지 참고하는 현상이 발생한다. 이를 방지하고자 도입한 것이 look-ahead mask다.

3.3.2. Encoder-Decoder Attention

  • 인코더의 마지막 출력 행렬로부터 키와 벨류를 얻는다.
  • 쿼리는 디코더의 첫 번째 서브층의 행렬로부터 얻는다.

이 논문은 사실 ViT를 구현하고 싶어서 먼저 읽었는데, 얼른 ViT도 공부하고 구현하고 싶네요!
읽어주셔서 감사합니다. 틀린 내용이 있다면 댓글로 알려주세요!
감사합니다. 😊

profile
Data Scientist

0개의 댓글