본 페이지에서는 Transformer의 등장배경과 특징에 대해서 말하고자 합니다.
본 논문은 Transformer라는 모델을 발표를 한다.
기존의 성능이 좋은 NLP 모델들은 Encoder-Decoder 구조를 가진 모델을 많이 사용하며 RNN,CNN등을 사용하곤 했다.
Transformer는 기존의 모델들과는 다르게 거의 Attention 매커니즘만을 사용하는 모델이다. 또한 병렬처리를 늘려 GPU 활용도를 높였고 이는 성능 향상과도 관련 되어있다.
이 절에서는 간단하게 RNN의 문제점과 Attention의 장점을 말하고자 합니다.
RNN은 Sequence를 읽어들이면서 시점의 입력과 이전 은닉상태 을 사용해 은닉상태 를 생성해낸다.
이런 방식은 학습 중에 병렬성을 배제하게 되는 특징이 있고, 이 때문에 문장이 길어질 수록 일괄처리하는 데에 메모리 제약이 발생된다.
또한 장기 의존 문제로 인해 문장이 길어지면 학습이 잘 되지 않는 경우가 발생한다.
Attention 매커니즘은 Sequence 모델에서 굉장이 중요해졌다.
RNN과 같이 사용하는 경우 입출력 길이가 길어진다고 하여도 현재 출력 시점에서 출력할 단어와 입력 문장 내의 단어들 사이에 연관성을 판단하여 출력 단어에 대한 정확성을 높인다.
Transformer에서는 이런 Attention 메터니즘만을 이용해 입출력 사이의 전체적인 연관성(dependencies)를 판단하도록 모델을 구성했다.
Transformer는 기존의 Sequence 모델들과 동일하게 다음과 같은 Encoder-Decoder 구조를 가진다.
Transformer는 입력 을 으로 매핑한다.
주어진 z애 대해서 출력 Sequence 을 출력한다.
모델의 구조는 다음과 같다.
좌측은 Encoder 부분 우측은 Decoder 부분이다.
각 설명은 다음과 같다.
Encoder:
6개의 레이어를 쌓은 것으로 각각의 레이어는 2개의 Sub 레이어로 이루어져 있다.
Normalization 방법은 레이어 normalization을 사용한다.
모든 embedding 레이어를 포함한 sub 레이어 모두 출력 차원의 수 이다. (Residual connection까지 고려하기 때문에 차원의 수를 고정함)
Decoder:
6개의 레이어로 이루어져 있고 Encoder와는 다르게 3개의 Sub 레이어로 이루어져 있다.
Decoder의 Multi-Head Attention은 Encoder의 출력에 대해 Multi-Head Attention(MHA)을 한다.
Decoder 에서는 Encoder와 다르게 현시점의 Decoder가 이후의 Sequence에 영향을 받지 않도록 Masked Multi-Head Attention을 고안한다.(이 방식은 이후에 자세히 설명 하도록 하겠습니다.)
Attention 함수는 Query와 Key-Value 페어 집합을 출력으로 매핑하는 것으로 설명한다.
출력은 Value들의 가중합으로 계산된다.
이때 각 가중치는 Query와 그에 대응하는 Key에 대한 특정한 함수로 계산된다.
우선 다음으로 넘어가기 전에 Query,Key,Value에 대해서 간단히 알고가면 이후에 이해하기 편할 것 같습니다.
각각의 설명은 다음과 같습니다.
Query : 현재 시점에서 출력에 영향을 줄 벡터
Key : Query를 통해 연관성을 찾을 목표 단어들에 대한 정보와 문맥 정보
Value : 목표 단어들의 단어 정보에 대한 벡터
Decoder의 MHA 레이어의 동작 과정을 예시와 함께 살펴보면 다음과 같습니다.
Query : Masked MHA 레이어의 출력 벡터들
Key : Encoder의 출력 벡터들(단어에 대한 정보와 함께 문맥에 대한 정보도 포함)
Value : Encoder의 출력 벡터들(단어에 대한 정보만 포함)
위의 사진에서 좌측표를 설명하면 다음과 같다.
Query와 Key는 차원을 가지고 있고 Value는 차원을 가지고 있다
Query와 모든 Key들에 대해서 Dot product를 진행한다.
해당 결과의 값들을 로 나눈다.
Mask 연산의 경우 이후 Masked MHA에 대해서 다루겠습니다.
Softmax를 적용하여 각 Value에 대한 가중치를 얻어낸다.
해당 가중치를 통해 Value 행렬과 Dot Product를 진행한다.
Query,Key,Value들의 각 집합을 행렬 Q,K,V라고 하면 Attention 연산은 다음과 같다.
주로 사용되는 Attention 함수는 Additive attention과 Dot-product attention이 있다.
두 함수는 이론적으로 복잡도는 비슷하나 Dot-product attention이 조금 더 빠르고 실제 사용할 때 공간효율성이 더 좋다.
가 작을 때는 두 함수들은 비슷하게 작동하나 큰 값일 때는 로 Scaling 해주지 않으면 Additive attention의 성능이 더 좋다.
이 이유는 Dot-product의 경우 값이 매우 커지게 되는데 이는 Softmax 함수의 미분값이 매우 작아지도록 하게 하여 학습 성능이 낮아지게 된다고 생각한다고 한다.
이 이유 때문에 로 Scaling 해주어 Dot-product의 단점을 보완하고 효율성에 대한 장점을 사용할 수 있게 한다.
Dot Product의 값이 매우 커지는 이유?
q와 k가 독립적인 무작위 변수이면서 평균이 0이며 분산이 1이라고 가정 하면
Dot Product 함수 는 평균 0 분산 를 가지게 된다.
차원의 Keys,Values,Queries에 대해 Attnetion을 한번만 진행하는 것보다 Queries,Keys,Value 들을 h번 다르게 각각 차원으로 Linearly project 하는 것이 더 좋다는 것을 알아냈다.
이러한 Quries,Keys,Values 들을 Attention 함수를 병렬적으로 적용하고 차원의 벡터들을 얻고 Concatenate하여 다시 Project 하여 최종 Value를 얻어낸다.
이는 Fig2에 우측에 설명되어 있다.
이러한 Multi-Head Attention은 모델이 다른 위치에 있는 다른 Representation Subspace로부터 공통적으로 정보에 Attend 할 수 있도록 한다.
이를 수식으로 표현하면 다음과 같다.
본 논문에서 로 지정했고 또한 로 사용했다.
각각의 Head의 차원의 수를 줄이면서 전체 Computational cost는 Single-Head Attention와 비슷해졌다.
이 절에서는 Transformer에서 사용한 MHA방법에 대해서 설명합니다.
이때 Encoder는 RNN계열의 Encoder Decoder와는 다르게 모든 개의 입력 Token을 로 임베딩 후 Positional Encoding 작업하여 로 변환 후 레이어의 입력으로 넣는다.
Multi-Head Attention in Decoder
Query : Decoder의 Masked Multi-Head Attention 의 출력 ( )
Key, Value : Encoder의 최종 출력 ( )
이 경우에는 Decoder에서 Encoder에 대하여 Attend 할 수 있도록 합니다.
Multi-Head Attention in Encoder
Query,Key,Value : Encoder 첫 입력 혹은 이전 레이어의 출력 ( )
Encoder의 첫 레이어의 MHA : 개의 Token(입력 전체)을 로 Embedding 한 후 Positional Encoding 한 후 크기를 입력으로 받는다.(기존의 RNN과는 다름)
Encoder의 이후 레이어의 MHA : 이전 레이어의 출력
이 경우에는 이전 레이어의 출력(혹은 첫 입력)에 대해서 Encoder들의 단어들과 자신을 포함한 모든 단어에 Self attention을 가능하도록 합니다.
Masked Multi-Head Attention in Decoder
Query : 현재 Decoder의 입력
Key, Value : Decoder 첫 입력 혹은 이전 레이어의 출력
Decoder의 출력 단어들에 대한 Self attention이 가능하도록 합니다.
1,2,3 각 단계는 다음 그림에서 표시한 위치와 같다.
Encoder,Decoder 내부에 존재하는 각 Feed Forward 레이어는 다음과 같이 수식으로 나타낼 수 있다.
간단히 말하면 Fully Connected 레이어를 지난 후 ReLU를 적용한 뒤 다시 Fully Connected 레이어를 지나는 것이다.
의 차원은 이며 첫 Fully Connected 레이어의 출력은 이며 이후 두 번째 Fully Connected 레이어의 출력은 다시 이다.
다른 모델들과 유사하게 입력 Token 에 대해서 의 차원으로, 출력 Token에 대해서 차원으로 변환하는 학습된 Embedding을 사용한다.
또한 Decoder에서 출력을 내기 위해 linear projection과 softmax 함수를 통해 다음 출력 Token에 대한 확률 값을 얻어낸다.
두 학습된 Embeddings와 softmax 이전의 linear projection는 서로 가중치를 공유한다.
Embedding 레이어에서는 위의 가중치와 함께 을 곱한다.
기존의 RNN과 CNN과는 다르게 Attention 매커니즘만을 사용하기에 Sequence의 순서에 대한 정보를 알 수 없다.
이 때문에 순서에 대한 정보를 넣어주기 위해 Positional Encoding을 사용한다.
입력 Embedding에 Positional Encoding들을 더해주는데 Positional Encoding들의 차원은 로 동일하다.
이를 구현하기 위해 여러 함수를 사용해도 되는데 본 논문에서는 Sine함수와 Consine 함수를 사용했고 그 식은 아래와 같다.
는 단어의 위치이고 는 차원내에서의 위치를 의미한다.
이 절에서는 제가 이해한 내용을 바탕으로 추가적으로 설명하겠습니다.
우선 간단히 Transformer 모델의 동작과정을 보면 다음과 같습니다.
추론과정에서는 이전 Decoder의 출력 결과가 Decoder Input tokens에 추가됩니다.
입력 토큰들은 Positional Encoding 후에 이전 Decoder의 출력과 함께 현재 Decoder에 입력으로 들어가 Masked MHA 레이어의 입력으로 들어갑니다. 이때 추론과정에서는 Masking 연산은 하지 않습니다.
기존의 Attention 매커니즘과 달리 Multi-Head Attention 매커니즘의 의미를 살펴봅니다.
벡터는 숫자들을 통해 정보를 담는라는 개념을 가지고 살펴보겠습니다.
인 경우를 살펴보면 다음과 같다.
512 길이의 벡터로 이루어진 Query,Key,Value에 대해서 512의 길이에 대한 정보를 조합해 64개의 벡터를 8개를 얻어낸다.
이 8개의 벡터는 기존 벡터의 정보들을 조합해 새로 얻어낸 각각의 정보를 64길이의 벡터로 표현한 것이다.즉 , 8개의 벡터는 각각 서로 가지고 있는 정보가 다르다.
이러한 8개의 벡터는 Attention 과정에서 특정 정보에 대한 Attention을 하게 된다는 것이다.
이 방식이 왜 기존의 단일 Attention보다 성능이 좋은지를 간단하게 예시를 들면 다음과 같다.
비슷하게 생긴 세 사람에 대한 유사도를 본다고 가정 한다.
이때 세 사람 중 두 사람은 쌍둥이라고 한다고 하며 유사도를 보는 기준을 다음과 같다고 한다.
특징1 | |||||||
---|---|---|---|---|---|---|---|
눈 | 코 | 입 | 귀 | 손 | 발 | 무릎 | 어깨 |
위의 특징을 Attention 연산을 한다고 하면 전체적인 모습을 보고 세사람의 유사도를 찾는다고 하는 것이고
세사람의 유사도 결과는 비슷하다고 나올 것이다.
하지만 다음으로 나누어 보면 어떨까?
특징1 | 특징2 | 특징3 | 특징4 |
---|---|---|---|
눈+코+입+귀 | 손+어깨 | 발+무릎 | 손+발+무릎+어깨 |
위 경우는 인 경우이다.
첫번째 행부터 각각 얼굴 , 팔 , 다리 , 상하체에 대한 정보를 나타낸다고 쉽게 알 수 있다.
각각의 특징에 대해서 Attention 연산을 한다고 하면 결국 얼굴,팔,다리,상하체 각각에 대한 유사도를 구하는 것이다.
이 경우 각각의 특징들을 더 자세히 보기 때문에 쌍둥이에 대한 유사도가 높게 나올 것이다.
실제로는 여러 특징들이 결합되어 고차원의 공간을 형성하게되고 MHA과정에서 여러 Subspace로 나누어 Attention을 진행한다.
방향성만 알고 있으면 좋을 것 같다.
추론과정과는 달리 학습과정에서는 Masking 연산을 처리해야 합니다.
이 이유는 다음과 같습니다.(아래의 예시에서 Multi-Head Attention이 아닌 단일 Attention을 사용합니다.)
학습 과정이 아닌 추론과정에서는 Decoder의 입력에 이전의 출력과 현재까지의 출력들을 담고 있는 행렬을 입력으로 받습니다.
i번 째 Decoder의 이전 출력(Query에 해당 됨)은 크기의 행렬이고 출력들을 담고 있는 행렬(Key,Value에 해당 됨) 크기는 (\<sos>의 임베딩 벡터 포함) 입니다.
이때 Query와 Key에 대한 행렬곱을 진행할 경우 크기의 벡터가 나오게 됩니다.
추론과정과는 달리 학습과정은 Encoder와 동일하게 Decoder에 목표 단어(학습시 출력해야할 단어)를 알고 있기에 전부 집어넣게 됩니다.
즉, 출력 문장의 길이가 이라면 크기의 행렬이 Decoder의 Masked MHA 레이어에 들어가게 됩니다.
이 경우 Query와 Key의 행렬곱의 결과 크기가 인 행렬을 가지게 됩니다.
이 경우의 문제점은 문장에서 번째에 위치하는 단어가 실제로 추론 과정에서는 몰랐을 ~ 위치에 해당하는 단어 사이의 단어와의 관계도 알 수도 있게 됩니다.
이 과정에서 Auto Regressive한 특성이 파괴될 수도 있게 되어 이를 방지하고자 Masking 연산을 진행합니다.
Masking 연산 전에는 다음과 같습니다.
실제로 1행에 있는 \<sos>는 나는,너를,사랑해,\<eos>와의 연관성을 몰라야 합니다.
따라서 Softmax 연산에 값이 반영되지 않도록 관련없는 단어들과의 연관값을 다음과 같이 로 변경해줍니다.
이때 이기 때문에 Softmax 함수에 반영되지 않는다.
이후 Softmax 연산을 진행하면 다음과 같습니다.
이후 Value 와의 행렬곱을 하게 되면 이후의 단어들과의 연관성을 배제한 크기의 가중합 행렬이 출력으로 나오게 됩니다.