본문 바로가기
실습 & 활동/LG Aimers

Module 7. 시계열 데이터 및 AI 모델 성능 최적화 - 트랜스포머 기반의 시계열 데이터 회귀(2)

by sim0609 2023. 2. 4.

self-attention 절차

Step 1

Step 1: 입력 벡터에 대해서 세 가지의 벡터를 생성 (Query, Key, Value)

 

Query: 어떤 단어가 다른 단어들하고 무슨 관계가 있는지를 알고싶은 질의 대상이 되는 단어

(다른 단어들을 고려하여 표현하고자 하는 대상이 되는 현재 단어에 대한 임베딩 벡터)

Key: Query가 들어왔을 때 다른 단어들과 매칭을 하기 위해 사용되는 레이블로 사용되는 임베딩 벡터

Value: Key와 연결된 실제 단어를 나타내는 임베딩 벡터

 

 

실제로 이러한 세가지 vector는 주어져 있는게 아닌 Query, Key, Value에 대응하는 행렬을 곱해서 생성함

그리고 W_Q, W_K, W_V(실제 transformer를 통해 학습시키는 부분)는 data를 통해서 학습을 하는 대상임

 

즉, 실제 embedding이 있는 원래 data는 차원 수가 512차원이라면 original transformer에 대응하는 Query, Key, Value 역할을 하는 vector들의 크기를 512차원보다는 조금 더 짧은 차원으로 사용

 

 

Step 2

Step 2: 지금 표현하고자 하는 단어(Q)에 대해 어떤 단어들을 고려해야 하는지(K)를 알려주는 스코어 산출

→ 여기서 스코어를 계산하는 방법은 Q와 K를 곱한 후 소프트맥스 함수를 취해야 함

 

 

예를 들어, thinking이라는 단어가 들어왔을 때 thinking과 주로 함께 봐야하는 단어들이 무엇인지를 설명하기 위해서 우선 내가 가지고 있는 query는 "나는 thinking이라는 단어를 갖고 있는데 나 뭐봐야 돼?"라는 질문이고, 거기에 대해 thinking이 key vector도 가지고 있으니까 thinking이라는 vector를 보려면 점수가 112점이고, machine에 대한 vector를 보기 위한 점수는 96점인걸 답 해줌

 

 

Step 3 & Step 4

Step 3: Step 2에서 계산한 스코어를 √d_k (= 8, in the original paper since d_k = 64)로 나눠줌 

이 과정을 통해 gradient 전파가 보다 안정적으로 수행됨

 

Step 4: Step 3의 결과물을 이용하여 소프트맥스 함수를 적용하여 해당 단어에 대한 집중도를 산출

 

즉, 위의 예시를 이어서 설명하자면 내가 thinking이라는 단어를 가지고 있고 "어떤 단어를 잘 봐야 해?"라고 했을 때 "thinking을 잘 봐야 해"라고 하는게 88%, "machine이라고 하는 바로 옆 단어를 봐야 해"가 12%라는 뜻임

 

 

이걸 통해 산출된 확률 값이 주어져 있으면 이걸 key value하고 곱해서 출력으로 반환하게 됨

 

Step 5 & Step 6

Step 5: Step 4에서 산출된 확률값과 해당 단어의 Key 값을 곱함

Step 6: Step 5에서 산출된 모든 값들을 더해서 출력으로 반환

→ 0.88과 v1을 곱하고 0.12와 v2를 곱해서 선형 결합한 것이 z1(첫 번째 encoding 블록의 output)임

 

 

실제로는 이 과정이 모두 행렬 연산으로 수행됨: Matrix calculation of self-attention

 

 

self-attention 예시

Create Query, Key, and Value Vectors

아래 그림처럼 각 X(X1, X2, X3, X4)들과 W_Q, W_K, W_V의 vector들을 곱하면 각 단어들에 대한 query, key, value를 얻을 수 있음

 

 

Score

첫번째 query(q1)가 들어오고 네 가지 단어들에 대해서 key를 봤을 때, X1(아래 그림에서는 q1가 동일한 단어)을 20% 집중하고, X2를 10% 집중하고, X3를 50% 집중하고, X4를 20% 집중하는 방식으로 학습이 됨

 

즉, q1 가진 의미를 이해하기 위해선 X1(X1과 q1은 같은 단어)을 보는 것도 중요하지만 X1 다음에 들어오는 단어들 또한 굉장히 집중해서 봐야한다는 것이 self-attention이 우리에게 알려주는 정보임

 

 

Sum

이렇게 해서 attention의 score가 계산되면 기존에 가지고 있던 value vector들과 선형 결합을 해서 최종적으로 Z1이라고 하는 첫번째 attention의 output을 만들어내야 함

 

여기서 X1과 Z1은 바로 연결되어 있고 Z1의 위치는 그대로 순차적인 sequence의 위치를 유지하면서 올라감

 

 

위에서 했던 동일한 작업(Score, Sum)을 모든 입력 토큰에 대해 수행하면 X1이 Z1으로 바뀌고, X2는 Z2,  X3는 Z3, X4는 Z4로 바뀌며 각각이 가지고 있는 위치를 그대로 유지하면서 정보가 처리됨

 

 

Multi-headed attention의 필요성

: 매우 복잡한 문장구조에서 특정 단어가 어떤걸 지칭하는지 찾아볼 때, 그 특정 단어를 의미하는게 단어일 수도 있고, 다른 문장에서의 구일 수도 있기 때문에 여러가지를 동시다발적으로 봐야 함

 

→ 이런 경우 attention을 한 번만 걸어주는게 아니라 여러가지 attention을 동시에 걸어줘야 함

 

Multi-headed attention

한 Query 토큰에 대해서 다양한 관점으로 표현할 수 있는 능력을 제공함

 

아래 그림에서 볼 수 있듯 똑같은 하나의 단어에 대해서 attention을 여덟 개를 걸어 똑같은 단어를 보는데 있어서 어디에 더 집중하고, 어디에 덜 집중할지 학습을 통해서 조정 가능함

 

 

이렇게 어텐션 결과물들은 병합(concatenation) 후에 가중치 행렬(W0도 학습 대상이 됨)과의 연산을 통해 원래 입력 차원과 동일한 차원의 출력 벡터를 생성하게 되는게 multi headed attention의 최종 결과물임

 

 

Multi-headed attention 최종 도식

최종 정리하자면, input X가 있을 때 여러 개의 attention head(Z0, Z1, ... ,Z7)들을 통해서 attention이 결합된 결과물들이 나오는 것이고 W0와 곱해서 원래 차원과 동일한 output으로 만들어냄

→ 이것이 한 번의 attention 블록임

 

 

그렇기 때문에 똑같은 attention을 한다고 하더라도 아래 그림처럼 head가 두 개일 경우에 it이 지칭하는 객체뿐만 아니라 객체의 상태 또한 알 수 있음

→ 첫 번째 주황색 attention은 it이 지칭하는 객체(the animal)에 집중하고 있음

→ 두 번째 초록색 attention은 객체(the animal)의 상태에 집중하고 있음

 

이렇게 attention head를 더 많이 사용한다면 객체에 대한 다양한 정보를 얻을 수 있음