본문 바로가기
  • Deep dive into Learning
  • Deep dive into Optimization
  • Deep dive into Deep Learning
Deep dive into Deep learning

Deep dive into Deep learning Part 25 : Transformer

by Sapiens_Nam 2023. 6. 24.

 

 

모바일 앱 환경에서는 latex 수식이 깨져 나타나므로 가급적 웹 환경에서 봐주시길 바랍니다.

 

오늘은 트랜스포머 (Transformer)에 대해 설명하고자 한다.

Transformer는 Encoder와 Decoder로 이루어져 있으며 각각이 N개로 쌓인 구조를 하고 있다.

Transformer 구조

 

위 그림에서 좌측이 Encoder이고 우측이 Decoder이며 각각 $N_x$개 쌓여있는 구조이다.

( Original Transformer인 'Attention is all you need'에서는 $N_x = 6$이다.)

각 Encoder의 결괏값이 그 다음 Encoder의 input으로 들어가며, 맨 마지막 Encoder의 결괏값이 입력 데이터 (eg : 문장)에 대한 representation vector이고 이 값이 '모든' Decoder의 input으로 들어간다.

여기서 '모든'이라는 말이 붙었는데 이는 예를 들어, 6개의 Decoder가 있다면 이 Decoder 전부 마지막 Encoder의 결괏값을 input으로 받는다는 의미이다.

즉, 2번째 Decoder는 1번째 Decoder의 output과 Encoder의 output을 동시에 받을 것이다.

 

우선, Encoder부터 살펴보자.

 

Encoder에서 가장 핵심이 되는 연산인 'Multi-Head Attention'은 지난 번 글에서 살펴보았으므로 넘어가겠다.

https://kyteris0624.tistory.com/60

 

Deep dive into Deep learning part 24 : RNN(5)

모바일 앱 환경에서는 latex 수식이 깨져 나타나므로 가급적 웹 환경에서 봐주시길 바랍니다. 오늘부터 두 번에 걸쳐 Transformer에 대해서 이야기를 하고자 한다. 현재 Transformer는 다양한 분야에서

kyteris0624.tistory.com

 

그 다음 Add와 Normalization 연산이 있는데 여기서 Add는 ResNet의 Residual connection을 생각하면 된다.

즉, Multi-Head Attention layer의 input값과 output값을 서로 연결해서 더해주는 것이다.

그 다음 두 번째 Add는 Feed forward의 input값과 output값을 서로 연결해서 더해주는 것이다.

이에 대해서 ResNet에 대해 설명할 때 자세하게 다루었으므로 여기서는 넘어가도록 하겠다. 아래 글을 참고하기 바란다.

https://kyteris0624.tistory.com/40

 

Deep dive into Deep learning part 15. CNN(3)

모바일 앱 환경에서는 latex 수식이 깨져 나타나므로, 가급적 웹 환경에서 봐주시길 바랍니다. 오늘은 ResNet, DenseNet에 대한 설명을 하고자 한다. 우선, 이 ResNet에 대해 이야기하기 전에 'Gradient vanis

kyteris0624.tistory.com

 

 

그리고 Normalization 연산은 layer normalization을 의미한다.

이 또한 이전의 글에서 설명하였으므로 여기서는 넘어가도록 하겠다. 아래 글을 참고하기 바란다.

https://kyteris0624.tistory.com/48

 

Deep dive into Deep learning part 19 : Regularization(4)

모바일 앱 환경에서는 latex 수식이 깨져 나타나므로, 가급적 웹 환경에서 봐주시길 바랍니다. 오늘은 Regularization의 마지막 글 Batch normalization, Layer normalization에 대한 이야기이다. 둘의 기저에 깔

kyteris0624.tistory.com

 

그리고 Feed forward network 부분은 2개의 dense layer와 ReLU activation function으로 이뤄져 있는 일반적인 신경망이다.

 

다음으로 또 중요한 요소 중에 하나가 위치 인코딩 (Positional Encoding)인데 RNN에서는 필요가 없는데 Transformer에서는 이것이 왜 필요할까?

RNN은 시간 순서에 따라 sequence data의 입력이 들어간다. 즉, 'I am a robot'라는 문장이 있다면 $t=1$일 때 'I', $t=2$일 때, 'am', $t=3$일 때 'a' 이러한 방식으로 시간 순서에 따라 들어가기 때문에 위치 정보가 별도로 요구되지 않는다.

즉, 'I'에 대한 연산이 끝나야 그 다음 'AM'에 대한 연산을 진행할 수 있고, 이것이 끝나야 'a'에 대한 연산을 진행할 수 있다. 

하지만, Transformer는 이러한 순환 구조 (recurrent)를 따르지 않고, 문장 안에 있는 모든 단어들을 병렬 형태로 입력한다.

즉, 입력된 문장이 병렬로 한 번에 처리가 되므로 계산이 빨라진다. 하지만, 신경망이 단어의 순서를 알 수 없으므로 이를 별도로 처리해주어야 한다.

그리고 당연히 문장의 의미를 제대로 이해하기 위해서는 단어의 순서 (문장 속 해당 단어의 위치 정보)는 매우 중요하다.

처음에 우리는 문장에 각 단어의 임베딩 값을 얻는다. 

이 임베딩 행렬에는 단어의 의미가 들어있지만, 단어의 위치는 포함되어져 있지 않다.

그래서 Transformer는 단어의 위치정보를 별도로 인코딩하여 이를 임베딩 행렬에 더해주는 연산을 취해준다.

그러면 어떻게 Positional encoding을 통하여 위치 정보를 담고 있는 vector들을 생성하여 이들을 더해줄까?

 

Transformer 저자들은 'Sinusoidal function' 즉 사인 함수를 활용하였다.

$\sin (x)$는 $-1$과 $1$ 사이의 값을 반복하는 주기함수이다. 계산은 다음과 같이 이뤄진다.

 

$P(pos, 2i) = \sin (\frac{pos}{1000^{2i / d_{model}}})$

$P(pos, 2i + 1) = \cos (\frac{pos}{1000^{2i / d_{model}}})$

 

여기서 pos는 문장에서 단어의 위치, i는 해당 위치의 임베딩을 의미한다.

i의 값이 짝수일 경우에는 사인 함수를 홀수인 경우에는 코사인 함수를 활용하는데 이를 바탕으로 positional encoding matrix는 다음과 같이 계산된다.

 

https://machinelearningmastery.com/a-gentle-introduction-to-positional-encoding-in-transformer-models-part-1/

 

위 positional encoding matrix는 의미 정보를 담고 있는 embedding matrix와 덧셈연산을 수행해주고 이제 이것이 input으로 들어가게 된다.

 

다음은 Decoder이다.

 

첫 번째 Decoder의 input으로 들어가는 것은 정답 (label)에 해당하는 문장이 embedding matrix로 변환되어서 들어가고 (마지막) Encoder의 output이 함께 들어가게 된다.

그런데 이때 Embedding matrix (+ positional encoding matrix)가 Decoder의 첫 번째 layer에서 Attention 연산이 이뤄질 때, 'Masked' Multi-head Attention연산이 이뤄지는데 왜 마스크된 attention 연산이 이뤄지는 것일까?

Multi-head Attention에서는 각 head별로 $K$ (Key), $Q$ (Query), $V$ (Value) 행렬들을 활용해 연산이 이뤄진다.

Decoder의 input은 정답에 해당하는 문장으로서 이를 생성해내는 것이 관건이다.

만약 Encoder의 input으로 들어간 문장이 'I am a robot'이라면 이를 한국어로 번역한 '나는 로봇이다.'가 Decoder에서 생성되어져야 하고 이것이 label에 해당한다.

그런데 앞서 이야기하였듯이 RNN과 달리 Transformer는 문장 속 단어 전체를 병렬적으로 입력으로 받기 때문에 현재 시점에서의 단어를 생성하는데 있어 미래 시점의 단어까지도 참고할 수 있는 현상이 발생한다.

즉, '나는'이라는 단어를 예측/ 생성하는 시점에서 입력으로 RNN은 '<sos>, '나는'만 input으로 받았지만, Transformer는 <sos>, '나는', '로봇이다.'를 input으로 받기 때문에 뒤의 시점의 단어 '로봇이다'를 참고하여 생성하게 되고 이는 디코더의 학습이 제대로 이뤄지지 못하게 만들 수 있다.

 

그래서 디코더에서는 현재 시점보다 미래에 있는 단어들을 참고로 하지 못하도록 이에 대해서는 마스킹 처리를 한다.

그렇다면 마스킹 연산을 어떻게 수행할 수 있을까? 

앞선 글에서 Attention 연산은 $Q, K, V$에 대해 다음과 같이 이뤄진다고 하였다.

 

$Z = softmax(\frac{QK^T}{\sqrt{d_k}})V$

 

Softmax 함수를 적용하기 전에 마스킹 처리를 진행하면 다음과 같이 된다.

 

 

여기서 I am a boy에서 I에 해당하는 단어를 예측 (생성)할 때는 'am', 'a', 'boy'에 해당하는 부분과의 attention 연산값은 전부 masking 처리가 되어져 있으며, am에 해당하는 단어를 예측 (생성)할 때는 'a' 'boy'에 해당하는 부분과의 attention 연산값이 masking 처리가 되어져 있다.

이때 음영처리된 부분의 값은 $- \infty$이며 실제로 구현할 때는 $e^{-9}$정도로 처리해준다.

즉, am에 해당하는 단어를 생성 (예측)할 때는 'a', 'boy'라는 단어를 참조하지 못하도록 막아준 것이다.

위와 같이 마스킹 처리가 된 행렬에 softmax 함수를 적용해주고 최종적으로 Value matrix (V)와의 연산을 통해 Attention matrix를 생성한다. 

Multi-Head Attention이므로 이러한 방식으로 h개의 Attention matrix를 구한 후 이들을 concatenate해주고, output matrix와의 곱을 통해 최종적인 행렬이 나오게 된다.

 

이 행렬에 대해서 Multi-Head attention연산을 한 번 더 수행해주는데, 이 때 입력 행렬은 2개이다.

하나는 이전 Masked multi-head attention 연산의 결괏값이고 (중간의 add와 normalization은 인코더와 동일한 방식이므로 생략하자) 다른 하나는 인코더의 표현값이다. (즉 마지막 인코더의 output을 input으로 받는다.)

그래서 이 layer를 다른 표현으로 'Encoder-Decoder attention layer'라 한다.

 

이때 인코더 표현값을 활용해서 $K$, $V$를 생성하고, 이전 Masked attention layer의 결괏값을 활용해 $Q$를 생성한 다음 이들을 활용해 Attention 연산을 수행해준다.

그렇다면 왜 이러한 방식을 취해주었을까?

Self-attention의 첫 번째 연산은 $Q$와 $K$를 내적 연산해주는 것이다. $Q K^T$의 첫 번째 행을 생각해보면 query vector와 모든 key vector 사이의 내적 연산이 이뤄지고 이는 결국 정답이 되는 target 단어와 Encoder의 표현 벡터 (즉, 입력 문장의 모든 단어) 사이의 유사도를 계산해주는 것으로 해석할 수 있다.

즉, 'I am a boy'를 '나는 남자 아이다.'라는 문장으로 번역하는 것을 생각해보면 '남자'라고 하는 단어와 'I', 'am', 'a', 'boy' 모든 단어 사이의 유사도를 계산해주는 것이고 만약 학습이 잘 이뤄진다면 '남자'라고 하는 단어는 'boy'라고 하는 단어와의 attention 값이 가장 크게 나올 것이다.

즉, 생성 문장의 단어들과 입력 문장의 단어들 사이의 관계성을 학습시키기 위해 위와 같은 방법을 선택한 것이다.

 

마지막으로 Decoder의 Linear layer는 디코더의 역할은 입력 단어를 바탕으로 다음 단어를 예측 (생성)하는 것이고 현재 가지고 있는 어휘 사전 중에서 가장 가능성이 높은 단어를 출력해주어야 한다.

이를 위해 linear layer와 softmax를 거쳐주는 것이다.

총 $N_x$개의 Decoder에서 이러한 연산이 반복적으로 이뤄지고 가장 마지막 decoder의 output은 우리가 원하는 문장이 생성된 결과가 나오게 된다. (학습이 잘 이뤄졌다면.)

 

이로서 Transformer의 구조와 연산 등에 대해서 살펴보았다.

다음 글에서는 GAN에 대한 설명을 진행하도록 하겠다.

728x90

댓글