Transformer: Attention is all you need
이 블로그에 대한 글을 노션AI가 요약하면 아래와 같습니다. 세상을 바꾼 논문에 대해서 차근 차근 정리해본 글입니다.
Transformer는 관계 정보를 포함한 형태로 변환하는 매커니즘으로, Self-Attention을 사용합니다. 이를 통해 토큰 간의 관계를 조금씩 담고 있는 새로운 토큰을 생성합니다. Multi-head Self-Attention은 여러 개의 헤드로 분할하여 계산하고, 각각의 출력 벡터가 Feed-forward Layer의 입력이 됩니다. Transformer 모델은 인코더와 디코더로 구성되며, Layer Normalization과 residual connection을 사용하여 안정화시키고 학습을 가속화합니다. 마지막으로, 디코더는 auto-regressively 방식으로 이전의 자기 자신을 사용하여 현재의 자신을 예측합니다.
Transformer가 등장하게 된 이유는 기존에 사용하던 순환과 합성곱을 사용하는 네트워크에서는 병렬처리가 불가능했기 때문에 오로지 attention만 사용하여 이러한 문제를 해결하려고 했습니다. 결론적으로 attention을 활용하여 병렬처리가 가능한 네트워크를 만들었고, 기존에 비해 더 좋은 성능과 적은 학습시간을 달성할 수 있었습니다.
우선 Transformer의 핵심 아이디어는 “세상을 기준으로 나를 다시 정의 하는 것”에서 출발했습니다. 한 사람에 대해서만 바라보는 것이 아니라 서로간의 관계에 대한 정보를 포함하여 다시 정의하겠다는 것입니다.
여기서 “다시 정의하는 것”은 관계 정보를 포함한 형태로 변환(Transformation) 하는 것 이기 때문에 이 매커니즘을 Transformer라고 합니다.
위 그림과 같이 각 각 다른 정보를 가지고 있는 토큰(이미지)을 모두 Transformer Block에 넘긴다면 서로간의 정보를 조금 씩 담고 있도록 Transformation됩니다. 이 과정에서 Attention 매커니즘을 적용합니다.
여기서 사용되는 Attention(Self-Attention)은 기존(t시점의 디코더의 hidden state와 모든 시점 인코더의 hidden state로 Attention score를 계산하는 방법)의 방법과 달리, 스스로를 각각 Wq, Wk, Wv 가중치로 분할하여 기존 토큰보다 작은 차원의 Q, K, V를 생성합니다. 이때 각각의 가중치는 모든 토큰에서 똑같이 작동합니다. 이 방법은 Self-Attention이라고 합니다. (Wq, Wk, Wv는 서로 다르게 학습된다.)
(각자가 한번씩 주인공이 되면서 다른 토큰과의 관계를 포함하도록 계산한다.)
위 그림으로 다시 보면, X3를 Q3, K3, V3로 분할한 후, Q3와 Kn으로 각각 내적(유사도 구하기)하여 Vn의 가중치를 각각 구해서 더하면 주변의 정보를 포함하여 변환(Transformation)된 새로운 토큰 Z3이 생성됩니다. 여기서 W0를 마지막에 곱해주는 이유는 X와 같은 차원으로 맞춰주기 위함입니다.
이 과정을 행렬 수식으로 표현하면 다음과 같습니다.
Q[2, 3] * KT[3, 2]을 하게되면 Attenion Score (가중치)행렬[2, 2] 이 나오게 되고, 이를 다시 V[2, 3]과 곱하면 각각의 관계 정보를 포함하고 있는 Z[2, 3]가 생겨납니다. (여기서 dk는 차원이 늘어나지 않도록 정규화 해주는 것인데 처음에 했던 사람이 이렇게 했고, 그렇게 중요한 것은 아니라고 합니다.)
(사실 Q, K와 V, Z끼리만 차원이 같으면 되는데 보통은 다 같은 차원을 사용한다고 합니다.)
이런 방식으로 변환 과정을 거친다고 해도, 결국 자기 자신의 정보를 가장 강하게 가지고 있을 것 입니다. 그렇기 때문에 이 과정을 여러번 거치는 것이 핵심입니다. 이 Tansformer 구조에 Classifier를 붙이면 분류 모델이 되는 것이고, Regressor를 붙이면 예측 모델이 되는 것 입니다.
마지막으로 생성된 토큰들을 모두 평균내서 사용할 수 도 있지만. 각각의 가중치를 고려하는 것이 아니기 때문에 모든 tesk에서 잘 작동하지는 않습니다. 따라서 이 과정에서 또다시 Attention을 사용합니다.(괜히 Attention is all you need가 아닙니다.)
그 방법은 아래 그림과 같이 [CLS](Special Classification token) 라고 부르는 더미 토큰을 하나 추가하는 것입니다.
아무런 의미가 없는 [CLS]토큰으로 Self-Attention을 진행하게 된다면, 모든 토큰에 대해서 공평한 관계를 가지고 전체 정보를 담게 됩니다.(판사와 비슷한 느낌입니다.)
Token-level prediction은 영상과 같이 프레임 단위에서 예측을 진행하는 경우에 사용됩니다. Sequence-level prediction은 문장 전체 정보가 필요한 예측에서 사용됩니다.
이제 Transformer 모델의 내부를 자세히 들여다봅시다.
Transformer의 input은 sequence로 들어옵니다.(여러개의 토큰), 텍스트의 경우 임베딩된 Vector들을 input으로 받습니다.(논문에서는 512차원 임베딩)
트랜스포머 이전에는 RNN과 LSTM으로 구성된 방법들이 주로 사용되었는데, 이들은 순차적으로 문장을 처리하는 특징을 지니고 있습니다. 즉 Input에 입력되는 순서대로 RNN 또는 LSTM 모델 내에서 처리가 되는 방식을 말합니다. 다시 말해 앞의 연산이 끝나야 뒤의 연산을 진행할 수 있기 때문에 연산 속도가 매우 느리다는 문제가 있습니다.
하지만, transformer는 병렬적으로 연산을 처리하여 이 문제를 해결합니다. 하지만 그렇게되면 단어의 순서 정보를 잊어버릴 수 있습니다. 그래서 제안된 방법이 Positional Encoding입니다. (비슷한 위치에 대한 정보를 연산에 포함시키겠다.)
여기서 두 가지를 고려해야됩니다.
- 모든 위치값은 시퀀스의 길이나 Input에 관계없이 동일한 식별자를 가져야 한다. 따라서 시퀀스가 변경되더라도 위치 임베딩은 동일하게 유지될 수 있다.
- 모든 위치값은 너무 크면 안된다. 위치값이 너무 커져버리면, 단어 간의 상관관계 및 의미를 유추할 수 있는 의미정보 값이 상대적으로 작아지게 되고, Attention layer에서 제대로 학습 및 훈련이 되지 않을 수 있다.
이러한 조건을 고려했을 때에는 sine & cosine 함수가 적합합니다. 하지만, 이 함수들은 주기함수기 때문에 토큰들의 위치 벡터값이 같은 경우가 생길 수 있습니다.
positional encoding은 스칼라값이 아닌 벡터값으로 단어 벡터와 같은 차원을 지닌 벡터값이기 때문에 마지막 차원이 채워질 때 까지 서로 다른 frequency를 가진 sine & cosine을 번갈아가며 계산하다 보면 결과적으로 충분히 서로 다른 positional encoding 값을 지니게 됩니다.
수식으로 표현하면 위 그림과 같습니다. 여기서 pos는 position, i는 차원을 의미합니다. 첫 번째 차원은 값이 자주 바뀌고, 마지막 차원으로 갈 수록 값이 거의 안바뀌게 되면서, 값이 겹치지 않도록 설계 돼 있습니다.
(4차원 짜리 토큰 2개가 입력됐을 때 3차원짜리 토큰 두개로 차원을 줄여준다.) X[2,4] 벡터를 Wq[4, 3]벡터로 곱해주어 Q[2, 3] 벡터로 분할하여 줍니다. 이 때 Wq, Wk, Wv는 모든 토큰에 대해서 같은 가중치를 사용합니다.
Multi-head Self-attention은 “다양한 시점에서 문맥을 이해하기”위해 Self-attention과정에서 head의 갯수만큼 분할하여 계산하고 Z를 여러개 만들어냅니다.
(논문에서는 8개의 head) 위 그림과 같이 Z0 ~ Z7을 붙이고, Wo와 계산해주면 원래 구하려고 했던 크기의 Z를 구할 수 있습니다.
전체 그림으로 보면 다음과 같습니다.
멀티 헤드 어텐션의의 개별 출력 벡터가 Feed-forward Layer의 입력이 됩니다.
토큰간의 상호작용이 아니라, “나 자신에 대해서 나를 더 잘 알 수 있도록” 각 토큰간의 학습을 진행합니다. 일반적인 2층짜리 딥러닝입니다.(ReLU 활성화 함수)
또한, residual connection(인코더 부분에 있는 건너뛰기 연결)은 아주 deep한 신경망에서 하위 층에서 학습된 정보가 데이터 처리 과정에서 손실되는 것을 방지하기 위한 방법입니다.(vanishing or exploding)
Layer Normalization은 딥러닝에서 널리 사용되는 기법 중 하나로, 특히 Transformer 모델과 같은 복잡한 아키텍처에서 중요한 역할을 합니다. 이 기법의 주된 목적은 학습 과정을 안정화시키고 가속화하는 것입니다.
각 활성화 값은 평균을 뺀 후, 분산의 제곱근으로 나누어져 정규화됩니다. 이 과정은 활성화 값들이 평균이 0이고 분산이 1인 분포를 갖도록 만듭니다
이후 이러한 인코더를 여러층을 쌓아서 더욱더 문맥을 잘 이해할 수 있도록 합니다.
auto-regressively는 과거의 자기 자신을 사용하여 현재의 자신을 예측한다는 의미입니다. 디코더의 input과 output의 토큰의 갯수는 똑같아야 합니다. 따라서 출력 길이를 미리 정해서 [SOS] 토큰으로 시작하는 sequence로 입력합니다. 이 때, 아직 생성되지 않은 부분에 [PAD] 토큰으로 채웁니다.
이 때 사용되는 행렬이 삼각행렬입니다. 0이 아닌 행렬에 대해 -무한대의 값을 적용해서 attention과정에서 영향을 받지 않도록 합니다.
(→ 추론할 때는 굳이 마스킹 할 필요가 없고, 최대 길이 이전에 [EOS] 토큰이 생성될 때 까지 반복)
현재 시점 디코더의 Q, 인코더의 K, V로 attention을 진행합니다. 기존의 seq2seq구조와 비슷합니다.
이후 인코더와 똑같이 N번 반복한 후 Linear Layer로 생성 가능한 모든 토큰중에 하나를 분류하고 softmax를 거칩니다. 이때 cross-entropy와 같은 loss를 가지고 학습합니다.(이 모델의 모든 W의 값을 미분했을 때의 값을 가지고 학습을 하는 것입니다.)
이러한 복잡한 과정을 거쳐서 각 토큰에 대해 관계정보를 포함시켜 추론을 용이하게 만든 구조가 Transformer이고 이 과정에서 Attention 매커니즘을 다양하게 적용하여 만들었기 때문에 논문 이름이 Attention is all you need입니다. 이후 Attention의 성능을 높이거나, 최적화 시키는 방향으로 AI가 발전하고 있습니다. (아직까진 Attention이 SOTA..)