새소식

부스트캠프 AI Tech 4기

[NLP] 8. Transformer

  • -

Transformer : Multi-Head Attention

self-attention 모듈을 좀 더 유연하게 확장한 모듈

 

$W_{Q}$, $W_{K}$, $W_{V}$가 각각 하나씩만 존재하는 것이 아니라 위의 그림에서처럼 여러 버전의 행렬들이 존재한다.

서로 다른 버전의 attention 개수만큼 동일한 query 벡터에 대한 서로 다른 버전의 encoding 벡터들이 나온다.

이 encoding 벡터들을 모두 concat하여 해당 query 벡터에 대한 최종적인 encoding  벡터를 얻게 된다.

 

여러버전의 attention을 수행하기 위한 선형변환 matrix들을 서로 다른 head라고 부른다.

→ 여러 버전의 attention을 수행한다는 뜻으로 Multi-Head Attention이라고 부른다.

 

동일한 sequence가 주어졌을 때에도 어떤 특정한 query word에 대해서 서로 다른 기준으로 여러 측면에서의 정보를 뽑아와야 될 필요가 있을 수 있다.

 

여러문장으로 이루어져있긴 하지만 어떤 하나의 sequence 로서 볼 수있는 다음과 같은 문장이 있다고 가정하자.

“I went to the school” 그 다음엔 “I studied hard” 그 다음엔 “I came back home” 그 다음엔 “I took the rest” 이렇게 여러 문장으로 이루어진 sequence가 있다.

첫번째로 주어진 “I” 라는 query word 에 대한 encoding을 수행을 하기 위해서는 먼저 그 “I” 라는 주체가 한 행동을 중심으로 즉, “went”, “study” , “came back home” , “took the rest” 과 같은 주체가 하는 행동을 중심으로 하는 정보를 뽑아올 수 있게 되고

또 다른 측면에서는 “I” 라는 주체가 존재하던 장소의 변화 가령 “to the school” , "home"과 같이 장소의 해당하는 정보를 또 뽑을 수 도 있다.

→ 이런 방식으로 서로 다른 측면의 정보를 병렬적으로 뽑고 그 정보들을 다 합치는 형태로 attention 모듈을 구성한다.

→ 각각의 Head가 이런 서로 다른 정보들을 상호 보완적으로 뽑을 수 있다.

 

 

두 단어로 이루어진 sequence 에 대해서 2개의 서로 다른 Head 가 존재한다라고 가정한다면

동일한 $X$ matrix 에 대해서 각각의 head 별로 존재하는 선형 변환 matrix를 통해서 얻어지는 각각의 Query, Key, Value vector들을 가지고 각각의 head 내에서의 encoding vector 결과값을 얻는다.

 

 

head가 총 8개가 있다고 할 때, 각 head 별 3차원 vector의 output 을 얻었다면

그것을 모두다 concat을 하면 총 24차원(각 head에서 나온 Value vector의 차원과 총 head의 개수의 곱)으로 이루어지게된다.

 

그리고 각 row 벡터는  “Thinking”, “Machines” 에 해당하는 각각의 vector이다.

 

concat한 후에는 특정한 dimension 으로 줄여주는 Linear operation을 수행하게 된다.

위 그림에서는 24 dimension의 vector를 4차원의 vector를 최종적으로 얻게 하는 24 x 4 에 해당하는 선형변환 layer를 하나 더 두어 최종 output을 얻어낸다.

 

 

 

 

 

Transformer : Block-Based Model

Transforemr 모델에서는 핵심모듈인 Multi-Head attention에 추가적인 여러 후처리를 거쳐서 하나의 모듈을 구성한다.

 

 

추가적인 연산으로는 residual connection이라고 부르는 Add operation을 수행한 후 추가적으로 layer normalization을 수행하게 된다.

그리고서 Feed Forward network를 통과하고 추가적으로 residual connection 및 layer normalization 을 수행한다.

 

▮ residual connection (Add)

residual connection은 computer vision에서 깊은 layer의 Neural net을 만들 때 gradient vanishing 문제를 해결하여 학습을 안정화 시키면서 layer를 계속 쌓아감에 따라 더 높은 성능을 보일 수 있도록 하는 기법이다.

 

 

"I" "study" "math"에 해당하는 2차원 입력벡터가 있다고 가정하자.

"I" 벡터의 경우 [-1, 4]이고 Multi-Head attention을 통과해서 나온 output 벡터는 [2,3]이라고 할 때,

이 2개의 벡터를 residual connection에 의해서 [1+2, -4+3] = [3, -1]이라는 "I"에 대한 최종적인 encoding 벡터를 얻어낸다.

 

결국 만들고자 하는 벡터가 [3, -1]라고 하면

Multi-Head attention 모듈에서는 입력값 대비 만들고자하는 벡터에 대한 차이값만을 만들어주어야한다.

이런 과정을 통해 gradient vanishing 문제도 해결하고 학습을 안정화 시키게 된다.

 

Residual connection을 적용하기 위해서는 입력 벡터 [1, -4]와 encoding의 output 출력 벡터 [2,3]의 dimension이 동일해야한다. 그래야 dimension 별로 해당 원소값을 더해서 동일한 차원을 가진 벡터 [3, -1]을 만들어 줄 수 있기 때문이다.

→ 이러한 관점에서 Head의 수에 따른 concat된 encoding 벡터들의 차원을 Linear Operation을 통해 입력 벡터와 동일한 벡터로 변환해주는 과정이 필요한 것이다.

 

 

 

 

▮ Layer Normalization

  • 딥러닝에서 다양한 normalization 기법들이 존재한다.
  • Batch Norm, Layer Norm, Instance Norm, Group Norm
  • 기본적으로 여러 normalization layer는 주어진 다수의 sample 들에 대해서 그 값들의 평균을 0 그 분산을 1로 만들어 준 후 우리가 원하는 평균과 분산을 주입할 수 있도록 하는 선형변환으로 이루어진다.

 

Batch Norm의 경우, 예를 들어 아래와 같은 Neural Network가 있다고 생각해보자.

batch_size가 3이라면 입력 layer에 3차원 벡터를 총 3개 넣어줄 것이고, Forward Propagation 시 빨간색 네모로 둘러쌓인 node에서 계산되는 값이 batch_size 3개의 각 data instance에 대해서 3, 5, -2가 나왔다고 가정하자.

 

이 특정 layer 의 특정 node 에서 발견된 이 값들에 대해서 이 값들이 어떤 값들이었든지 간에 이 값들의 대한 평균을 0 그리고 분산을 1로 만들어주는 변환을 수행할 수 있다.

 

 

즉, 이 과정은 원래 가지던 값들의 평균과 분산이 무슨 값이었든 간에 그 정보를 버리고 표준화된 평균과 분산인 0과 1로 만들어주는 이런 과정으로 해석할 수 있다.

 

예를들어, $ 이라는 연산을 수행하는 경우 이 값들이 각각의 $x$ 자리에 들어가서 해당하는 $값으로 변환이 되는데

변환 이전에 $의 평균과 분산이 0 과 1이었다면, 변환을 한 후에는 평균은 3이 되고 분산은 4가 된다.

그리고 $

학습과정에서 이 특정 node에서 발견되어야 하는 값에 가장 최적화된 평균과 분산을 원하는 만큼 가지도록 조절할 수 있는 방식으로 동작한다.

 

 

 

Layer Norm도 Batch Norm 과 유사하게 첫번째 단계에서는 어떤 주어진 sample 들에 대한 평균과 분산을 0과 1로 만들고 그 다음엔 원하는 평균과 분산을 주입하는 2단계로 이루어져 있다.

 

“thinking”, “machines” 라고 주어진 두 단어로 이루어진 sequence 에 대해서 해당하는 encoding vector가 각각 4차원으로 나타나 있다고 생각해보자.

1차적으로 각 word 별로 특정 layer에서 발견되는 4개의 node들의 값들을 모아서 그 값들의 평균과 표준편차를 구하고 그 값을 각각 0과 1로 만들어주는 변환을 수행한다.

 

2번째로 우리가 원하는 평균과 분산을 주입하기 위한 Affine transformation 즉, $라는 연산을 수행을 할 때는 각각의 a, b 한 세트를 각 node 별로 여러 단어의 대해서 공통적인 변환을 적용해주게 된다.

즉, column vector를 기준으로 standardization 평균을 0, 분산을 1로 만들어주는 과정을 수행했다면

그 다음에는 각 node 별로 동일한 Affine transformation을 변환을 수행하게 된다.

 

Layer Normalization 큰 틀에서는 Batch Norm처럼 학습을 안정화하고 최종적인 성능을 좀 더 끌어올리는데에 중요한 역할을 한다고 볼 수 있다.

그렇게 변환을 완료한 후에는 다시 word 별 encoding vector를 추가적인 Fully Connected Layer 하나를 통과시켜서 각 word 의 encoding vector를 변환하고 그 다음엔 또 동일하게 residual connection을 통해서 output과 더해주고  Layer Normalization 을 통해서 원하는 평균, 분산을 주입하는 방식하는 과정을 거친다.

Transformer에서 제안한 Self-Attention 모듈을 포함한 전체적인 하나의 block

 

또한  “I study math” 각각의 단어에 대한 입력 벡터가 주어졌다면 residual connection에 의해서 최종적인 출력값은 나오는 것은 동일한 차원을 가지는 2차원의 여전히 “I study math” 각각의 단어에 대응하는 encoding 벡터가 된다.

 

 

 

Transformer : Positional Encoding

만약 self-attention 기반으로 주어진 sequence를 encoding 하는 경우,

"I" "go" "home" 과   "home" "go" "I" 의 순서로 encoding을 했다면,

Sequence의 순서가 뒤바뀐 두개의 "I" 의 encoding output vector은 동일한 결과가 나올 것이다.

 

attention 모듈을 수행할 때 Key, Value pair 들은 순서에 전혀 상관없이 각 Key 별로 주어진 Query 와의 attention 유사도를 구하고 해당 Value vector에 가중치를 부여해서 가중합을 함으로써 주어진 Query vector에 대한 Encoding vector를 얻어낸다.

가중평균을 낼 때 이 Value vector들은 교환법칙이 성립이 되기 때문에 최종 output vector는 전혀 차이가 없이 첫번째 위치에 있었을 때나 세번째 위치에 있었을 때의 결과가 동일하게 된다.

 

순서를 무시한다는 이 특성은 입력문장을 sequence 정보를 고려해서 encoding 을 하지 못하고,  순서를 고려하지 않는 집합으로 보고 각 집합에서의 원소의 encoding 을 얻는 과정이라고 볼 수 있다.

 

RNN 은 자연스럽게 sequence를 인식하고 그를 구별해서 vector encoding을 얻어낼 수 있는 기법이지만 Transformer 혹은 self-attention 모델은 그 순서정보를 반영할 수가 없는 한계점을 가지게 된다.

→ 그래서 등장한 것이 Positional Encoding이다.

 

 

예를 들어 "I go home"에서 "I"가 가지는 3차원 입력벡터 [3, -2, 4] 가 있다고 생각해보자

"I"라는 단어가 전체 sequence에서 첫번째 위치에 등장했다는 것을 표현하기 위해 첫번째 dimension에 1000이라는 숫자를 더해볼 수 있다. [1000, -2, 4]

 

만약 "I"가 세번째 위치인 경우는 세번째 dimension에 1000이라는 숫자를 더해주게 된다. [3, -2, 1004]

이 2개의 벡터는 같은 입력벡터로 시작했다고 하더라도 그 위치에 따라 서로 다른 값을 가지게 된다.
즉, 여기서 핵심 아이디어는 각 순서를 규정할 수 있는/각 순서를 특정지을 수 있는 Unique한 서로 다른 순서간의 구별이 되는 특정한 상수 벡터를 각 순서에 등장하는 word 입력 벡터에 더해주는 것이다.

 

 

Transformer에서는 위의 예시처럼 단순한 정수를 더하지는 않고, 위치에 따라 구별할 수 있는 벡터를 $과 $ 등으로 이루어진 주기함수를 사용하여 위치를 나타내는 벡터로 사용하게 된다.

 

 

순서를 구별하지 못한다는 self-attention 모듈의 기본적인 한계점을 Positional Encoding을 이용해 위치별로 서로 다른 vector가 더해지도록 함으로써 위치가 달라지면  출력 encoding vector도 달라지도록 하는 방식으로 순서라는 정보를  Transformer 모델이 다룰수 있도록 하였다.

 

 

 

 

Transformer : Warm-up Learning Rate Scheduler

일반적으로 gradient descent 알고리즘인 Adam 등의 과정을 통해 최적화를 수행하는 과정에서 사용되는 learning rate 라는 하이퍼파라미터를 학습 하는 과정동안 하나의 고정된 값으로서 사용을 한다.

그러나 보다 더 모델의 성능을 올릴 수 있도록 learning rate 값도 하이퍼파라미터로 설정하여 학습중에 적절히 변경해서 사용하는 것을 learning rate scheulding 이라고 한다.

 

초반에는 learning rate를 굉장히 작은값으로 사용한다.

작은 값을 사용해서 원래 해당 gradient 값이 클 때 적절하게 작은 learning rate 값이 곱해짐으로써 너무 큰 보폭이 발생되는 것을 방지한다.

 

 

그러다가 어느정도 iteration이 진행되면 완만한 구간에 도달할 수 있는데 optimal point가 아직 멀리 있을 수 있기 때문에 동력을 주는 차원에서 점차로 learning rate를 iteration에 비례해서 올려주게 된다.

 

 

 

만약 큰 learning rate를 통해 빨리 도착하여 global minima 바로 왼쪽에 도달했다면

여기서 큰 learning rate를 계속 사용한다면 보폭이 큼으로 인해 정확한 지점에 도착하지 못한다.

따라서 이러한 상황에서는 global minima에 잘 도달할 수 있도록 learning rate를 점차 줄여주는 형태로 진행된다.

 

이렇게 learning rate scheduling을 사용했을 때 경험적으로 transformer 모델이 여러 task에서 좀 더 좋은 성능을 낸다.

 

 

 

 

Transforemr Encoder High-Level View

 

 

 

 

1. "I" "go" "home" 문장이 주어지는 경우 각각에 해당하는 embedding 벡터를 입력으로 준다.

2. 각 position 별로 해당 positional encoding 벡터를 더해준다.

3. Multi-Head Attention에 Query Key Value 벡터셋을 입력으로 주고 residual connection, layer normalization 후 추가적인 Feed forward layer를 통과시킨 후에 residual connection, laeyr normalization으로 이루어진 block을 N개 통과시킨다.
(이 때 각 block간에는 제각각 독립적인 파라미터를 갖는다.)

4. 최종 output으로  각 word 별 encoding 벡터를 얻게 된다.

 

 

 

 

 

 

 

 

Transforemr : Decoder

"I go home"을 "나는 집에 간다"라는 문장으로 번역하는 경우를 생각해보자.

<SoS>를 입력하면 "나는"이라는 단어가 나와야하고,

"나는"을 입력하면 "집에"라는 단어를 예측해야한다.

 

따라서 학습 과정에서 decoder의 입력값으로 "<SoS>" "나는" "집에" sequence를 각각의 embedding 벡터로 주게 된다.

그러면 Positional encoding을 거친 후 Masked Multi-Head Attention으로 encoding, residual connection, layer normalization을 거쳐 output sequence를 encoding하는 과정을 거친다.

→ 이 과정은 Seq2Seq with attention 모델의 decoder에서 hidden state vector를 뽑는 과정에 해당한다.

 

"<SoS>" "나는" "집에"에 해당하는 encoding 벡터가 decoder의 hidden state vector로 얻어졌다면,

그 다음에 다시 Multi-Head attention에 입력으로 주어진다.

그러나 여기에서는 decoder에서 만들어진 hidden state 벡터가 Query로 사용되고, encoder 단의 최종 출력 벡터가 Key와 Value로 사용된다.

 

해당 Multi-Head attention 부분이 seq2seq with attention에서 추가적인 attention 모듈 역할을 한다.

Query vector를 decoder hidden state vector로 놓고 encoder의 hidden state vector들에 가중치를 걸어서 어떤 정보를 가져올지 선정한다.

그 이후에는 다시 residual connection과 layer normalization을 거치고 추가적으로 feed forward layer, 그 다음엔 residual connection, layer normalization을 통해 “ 나는 집에" 에 해당하는 각각의 vector가 decoder의 최종 encoding vector 로서 나오게 된다.

 

 

residual connection에 의해 decoder의 문장에 대한 정보를 가지고 있음과 동시에

encoder에서 주어진 vector에 대한 정보를 각각의 decoder에 해당하는 매 timestep마다 필요한 정보를 가져와서 그 정보를 잘 결합한 vector가 된다.

 

최종적으로 각각의 vector에 linear transformation을 걸어서 target language에 해당하는 vocabulary size만큼의 vector를 생성한다.

 

 

 

 

Transforemr : Masked Self-Attention

"<SoS>" "나는" "집에"라는 단어에 대해 Self-Attention 모듈을 수행하는 경우 $QK^T$를 계산하게 되면

"<SoS>"를 Query 벡터로 설정했을 때, "<SoS>"와 key벡터 <SoS>와의 유사도, key벡터 "나는"과의 유사도, key 벡터 "집에"와의 유사도 정보를 담고 있다.

 

그러나 이렇게 각 단어가 나머지 모든 단어들에 대한 정보를 담게되면 예측 task를 제대로 수행할 수 없다.

<SoS>가 주어져있고 "나는"이라는 단어를 예측해야 할 때,  학습 당시에는 배치 프로세싱을 위해 "나는" "집에"라는 단어를 입력으로 동시에 주긴 하지만, 

<SoS>를 Query로 사용해서 attention 모듈을 수행할 때는 Key Value에서 "나는", "집에"라는 단어는 제외해주어야한다.

 

 

따라서 softmax를 취해준 이후에 접근해서는 안되는 부분은 0으로 후처리를 해주어야 한다.

그 다음에는 다시 row 별로 합이 1이 되도록 normalize를 수행한다.

(첫번째 row에서 0.91을 전체 합 0.91로 나누면 1이 된다.)

 

즉, Decoder의 Masked self-attention의 masked의 의미는 보지 말아야 하는 단어에 대한 attention의 가중치를 0으로 만들어주고 그 이후 Value vector와 가중평균을 내는 방식으로 attention을 변형한 방식이다. 

728x90
Contents