Attention is all you need 리뷰

아우아우·2023년 7월 7일
0

논문 읽으며 정리

목록 보기
10/12
post-custom-banner

본 논문은 2017년 구글 리서치 팀이 NIPS 2017에서 발표한 논문으로 현재 NLP분야에서 쓰이는 bert, bart, GPT 등의 backbone으로 사용 되는 Transformer가 소개된 논문이다.

어떠한 이유로 만들어진 모델인가?

본 논문이 쓰일 당시에 SOTA모델의 경우 encoder - decoder 모델이 주로 사용이 되었으며, SOTA모델의 경우 이러한 encoder-decoder 모델에 attention을 추가하여 완성이 된 모델이였다.
이에 해당 논문을 작성한 사람들이 가지게 된 의문

  • 왜 attention 이라는 방법을 고안하였음에도 기존에 있는 방식(CNN, RNN)만 이용하지? attention이라는 방법만을 이용해서 모델을 만들어 보면 안되나? -> Transformer 모델의 탄생

기존의 방식과 비교하여 장점?

  • RNN모델 경우 다음 이미지와 같다.

문제점 1.
이와 같은 경우 긴 시퀀스가 주어지게 될 경우 앞 부분의 값이 소실 되는 문제가 존재하였다.
(gradient vanishing문제)
위의 문제와는 별개로 당시의 sota모델인 seq2seq모델의 경우 다음과 같다. 이때 Context 벡터는 고정된 크기로 이루어져 있어서 긴 시퀀스가 입력으로 주어지게 될 경우 정보가 손실되는 문제점이 존재한다.

문제점 2.
다른 문제가 존재하는데, sequential하게 처리를 한다는 특징이 존재한다. 이는 훈련 과정 중 병렬 처리를 하지 못하게 해 병목 현상이 생기게 된다. -> 느린 속도

이러한 문제점을 해결하고자 Attention is all you need에서는 기존 RNN, CNN이 사용되지 않은 트랜스포머 모델을 제안하였다.
(다시 이야기하지만 attention 기법 자체는 transformer 모델 이전에도 존재는 하였다.)

배경

기존의 모델에 대한 설명
self atention은 sequenceㅍ현을 계산하기 위해 단일 sequence의 서로 다른 위치와 관련된 attention 알고리즘이며, End2End 메모리 네트워크는 sequencealigned recurrence 대신 recurrent attention을 기반으로 하여 간단한 QnA를 해결하였다.

즉 기존 모델의 부족한 부분을 설명

본 논문에서 트랜스포머의 차이점
sequencealigned recurrence과 같은 RNN이나 CNN의 구조 없이 transformer는 self-attention 모델이다.

Transformer 모델의 구조


위의 구조와 같이 생겼으며, 왼쪽은 인코더 모델 오른쪽은 디코더 모델로 이루어져 있다.
각각 self-attention이 쌓이는 구조로 되어 있으며, ff layer를 사용하여 전체 아키텍처를 따른다.

encoder & decoder

encoder 모델의 경우 본 논문의 경우 6개의 동일한 레이어 stack으로 이루어져있다.
-> encoder 블록을 6개를 쌓았다는 의미.

encoder 블록에는 2개의 하위 계층이 있는데 위의 그림에서 보면 알 수 있듯이

  • Multi-Head attention 계층
  • Feed Forward 계층으로 이루어져 있다.

decoder 모델의 경우 encoder와 마찬가지로 6개의 동일한 layer로 이루어져 있다.
-> 똑같이 decoder block을 6개 쌓은 것을 의미

encoder 모델과의 차이점
1. encoder의 output에서 연결되는 Multi head attention이 존재한다.
(encoder 마지막 layer의 output이 decoder의 input으로 들어가게 된다, decoder의 마지막 layer의 결과물은 예측에 사용)
encoder와 연결이 된 계층이기 때문에 self-attention이 아닌 encoder-decoder attention혹은 cross attention으로 부르기도 하며, 확실한건 self-attention은 아니다.

  1. multi head attention 이 encoder와 다르게 masking된 multi head attention으로 되어 있다.
    decoder에서의 masking은 diagonal한 부분만 남기고 삼각행렬의 윗부분을 다 masking 처리를 진행한다.(구조는 동일하다.)

Attention

Attention은 query, key, value 및 output이 모두 벡터인 출력에 query 및 key와 value 쌍 집합을 매핑한다.
output은 weight의 합으로 계산되어, 각 값에 할당된 weight는 key와 query와의 함수에 의해 계산이 된다.

  • query: 입력 값, 검색어 ex) 장보기 목록
  • key : query의 값을 기준으로 찾는 대상 ex) 가격표
  • value : key가 갖고 있는 실제 값 ex) 실제 상품

query는 key들 중에서 가장 유사한 정도를 찾아서 관련이 높은 정도에 따라 value 위주로 모든 값을 가져온 뒤 가중합을 진행한다.

Encoder에 대한 상세 설명

encoder 들은 모두 같은 구조를 가지고 있으며, 내부에서는 같은 가중치를 공유한다
(단, 서로 다른 층의 encoder block 끼리는 weight를 공유하지 않는다.)

위의 그림과 같은 구조를 가지며 input으로 데이터가 올라간 뒤 self-attention을 거치고 feed forward network에 들어가게 된다. 해당 구조는 decoder에도 동일하다.

scaled Dot-Product Attention (Self attention)

논문에서는 Scaled dot-product attention이라 하며 우리에게는 흔히 self-attention이라고 한다. 본 내용에서는 self attention으로 표시한다.
self-attention은 아래의 수식을 따른다.

이는 아래의 모델 구조에서

Q(query)랑 K(key)를 Matmul(행렬곱)을 취한 뒤 scale(1dk1\over\sqrt {d_k}을 곱해준것)을 진행한다. 이후 선택적으로 Masking을 하고 softmax 함수를 거쳐서 V(value)값과 행렬곱을 취한다.
즉 다시 적으면
1. query와 key의 값을 행렬곱을 취한다.
2. scaling을 하여 1dk1\over\sqrt {d_k}을 곱해준다
3. scale된 값에 대해 선택적으로 Masking을 진행한다.
4. Masking된 값을 Softmax함수로 연산한 뒤 Value와 행렬곱을 진행한다.

  1. 행렬곱에서 나온 weighted value 벡터들을 합한다.
  • 왜 scaling을 진행하여 dk\sqrt {d_k}으로 나누어 주는 것인가?
    -> 논문에서는 QKTQ*K^T의 값이 커지게 될 경우 확률이 증대되기 때문에 이를 막고자 나누어 준 것이다.
  • masking을 선택적으로 하는 이유
    -> decoder에서 masked Multi-head Attention을 진행하기 때문이며, 이를 통해 순서가 되지 않은 데이터의 정보를 숨기게 된다.(RNN과 달리 Transformer는 데이터가 한번에 들어가기 때문이다)

  • 왜 Self-attention을 사용하는가?
    -> Self-attention으로 인하여 생성되는 새로운 벡터는 기존의 벡터보다 작은 크기를 가지게 되며, 이는 연산량의 감소 및 속도 향상에도 기여한다.
    논문에서는 이를 통하여 시간 복잡도가 다음과 같이 줄어들게 된다고 제시하고 있다.

  • query, key, value는 도대체 어떻게 구하는 것이냐?
    그림으로 표현하면 다음과 같다.

    이미지 출처: https://nlpinkorean.github.io/illustrated-transformer
    각각의 query, key, value를 구하기 위하여 각각의 weight 값을 가지고 있으며 input data와 해당하는 weight 벡터를 곱하여 query, key, value를 만들게 된다.
    (위의 이미지에서는 embedding 되어 들어오는 input 데이터가 하나의 벡터의 형태를 가지고 있지만, 여러가지의 단어가 한번에 들어오는 상황(문자열, 문장)이 들어올 경우 행렬로 나타내서 표시한다.)

Multi-Head attention

Multi head attention의 경우 위에서 설명한 self-attention을 sub-layer로 가지고 있는 특징이 있다.(이러한 이유로 self-attention이 일반적으로 먼저 설명이 된다.)

Multi Head attention을 한번에 정리한 이미지

위의 이미지를 바탕으로 설명을 하자면 다음과 같습니다.
1. Value와 Key, Query가 각각의 Linear 계층을 통과한다
2. Linear 계층을 통과한 값은 self-attention 계층을 지나게 된다.
3. 통과해서 나온 각각의 벡터(행렬)값을 이어 붙인다.(concat)
4. 이어붙인 행렬을 Linear 계층을 이용하여 통과시킨다.

  • 왜 3)을 보면 값이 여러개가 나오게 되었는가?
    -> Multi-head attention이다. head가 여러개라는 의미이며, 위의 이미지에서는 0~7까지 총 8개의 Head를 가지고 있다.(이는 encoder, decoder 모두 8개의 head를 가지고 있다는 의미다.)
    그리고 이 head들은 초기에 랜덤한 값을 가지고 있으며, 학습을 하여 갱신이 된다.

  • linear 계층은 무슨 역할을 하는가?
    -> linear 계층을 통하여 input 데이터는 2X4의 값 하나가 들어갔으나 8개의 head로 쪼개져 연산이 가능하게 끔 해준다.

  • 왜 concat해서 한번에 연산을 하는가?
    -> concat한 다음 linear 계층에서는 하나의 행렬만을 input으로 받을 수 있다. 그러면 8개를 1개로 줄여주는 방법이 필요한 것이다. 이를 위해서 다 이어붙이고 weight행렬(W0W_0)로 곱한것이다.

positional encoding

Transformer는 기존의 CNN과 RNN과는 다르게 data의 순서를 알수가 없다. 이를 해결하기 위한 방법이 positional encoding이다.
Positional encoding은 embedding 되어 있는 벡터에 위치 값을 추가하여 더하는 방법입니다.
논문에서는 아래의 함수를 이용해서 홀수인 경우와 짝수인 경우를 구분하여 cos함수와 sin 함수를 사용하여 위치에 따른 값을 구한뒤 embedding 된 벡터에 더해줍니다.

  • 왜 sin, cos함수를 이용하여 구하는 것인가?
    -> 정수값을 이용한다고 가정해보자 문장의 길이가 길어지게 되면 끝에 있는 값은 벡터가 가지고 있는 값보다 위치 정보를 저장한 값이 더 커지지 않는가?

  • 그럼 문장이 가지고 있는 단어의 수로 나누면 되지 않을까?
    -> 여러 문장이 들어오게 될 경우 각 단어가 가지게 되는 위치값은 가변적으로 다 달라지게 된다.(모든 문장의 길이가 같지는 않으니까)이러면 문제가 발생하지 않을까?

  • 그러면 위치에 대한 벡터 값을 sum 하지 말고 concat해서 별도로 길이를 길게 하면 안될까?
    -> 이는 위치정보와 단어의 의미정보가 섞이지 않아 좋긴하다. 근데 그로 인하여 생긴 메모리랑 파라미터, 그리고 학습 시간등으로 인하여 손해가 너무 크지 않을까?

Residual connection

한글로는 잔차연결이라고도 하는 부분이다. 이는 결과물로 나온 값과 input값을 더해주는 아이디어를 사용한 것이다.

  • 왜 사용하는가?
    -> 학습 난이도가 쉬워지며, 수렴이 더 잘된다.
  • 어디에 쓰였는가?

    다시 모델의 이미지를 가져 오게 되면 Add&Norm 계층의 input 데이터 중에 우회해서 들어가게 되는 값이 존재하는 것을 알 수 있다. 해당 부분이 residual connection을 이용한 것이다.

decoder에 대한 상세 설명

주요한 내용은 Encoder에서 거의 다 되었다. 그렇다면 Decoder에서 살펴 볼 것은 Encoder와 어 떠한 부분이 다른지를 보면 될 것이다.

다시 한번 되짚어보면 Encoder의 마지막 계층에서 나온 값 중에 Key와 Value가 decoder의 input으로 들어가게 된다. 그럼 Query는 어디서 받는가? 이는 이전 값을 이용해서 받게 되는 구조이다.

Masked Multi head attention

이 부분은 self-attention이랑 같은 역할을 한다. 하지만 encoder와는 다르게 이전 output에 대해서만 attend 하기 때문에 이후의 값들을 숨기는 것이 필요하다. 따라서 이를 해결하기 위하여 masking을 진행한다.
전체적인 구조는 encoder의 multi-head attention과 동일하며 softmax를 취하기 전에 step이후의 값을 숨기기 위해 masking을 한다는 것 만 차이가 있다.

multi-head attention

encoder와 똑같은 이름을 한 layer가 존재한다. 하지만 encoder와는 다른 차이가 존재하는데 해당 layer는 self-attention이 아니다.
부르는 사람에 따라 encoder-decoder attention layer 혹은 cross attention layer라고도 부르는데 해당 계층은 key와 value는 encoder에서 query는 decoder에서 연산한 값을 가져오는 계층이라고 생각하면 된다.

Linear & softmax layer

encoder와 decoder가 끝난 뒤 최종적인 output은 벡터 하나가 나오게 된다.
(모델 구조를 보면 linear 하나에 들어가므로 벡터가 하나라고 생각하면 된다.)

  • 무엇을 얻는가?
    -> decoder에서 얻은 벡터보다 더 큰 logit 벡터를 얻게 된다.
  • 그럼 왜 크기를 키우는 것인가?
    -> 학습할때 사용한 단어의 단어장 이라고 생각하면 될것이다. 즉 벡터의 크기를 단어장의 크기로 확장 시켜주는 것이다.
  • 벡터가 의미하는 값은 무엇인가?
    -> 각 단어에 대한 점수라고 생각하면 된다.

softmax 계층은 Linear 계층을 통과하여 얻은 벡터(점수)를 확률로 변환해 주는 역할을 한다.

Reference
Transformer에 대한 설명참고
논문 번역된 블로그
공부하는데 참고한 블로그

post-custom-banner

0개의 댓글