[reference 및 figure 출처]
https://nlpinkorean.github.io/illustrated-transformer/
https://arxiv.org/pdf/1706.03762.pdf
https://www.youtube.com/watch?v=mxGCEWOxfe8
[Transformer 이전의 자연어 번역 모델/ attention 모듈 개념]

RNN을 이용해서 input 인 문장을 하나의 context vector로 압축을 한다. 즉 마지막 input sequence의(혹은 마지막 time step) hidden state라고 생각하면 될 것 같다. 이 context vector는 decoder에서 0 시점의 (0 time step) hidden state로 이용된다. 이후론 인코더와 마찬가지로 RNN을 진행한다. 언제까지? 다음 output이 <eos>로 예측될 때까지.
(*eos end of sentence)
(*sos start of sentence)
하지만 문제점이 있다.
(1) 긴 문장을 고정된 길이의 context vector로 '압축'을 하다보니, 정보 손실이 크다.
(2) 기울기 소실의 문제점을 극복하지 못한다.
따라서 이를 극복하고자 나온 것이 Attention 메커니즘이고, 도식화하면 아래와 같다.
인코더와 디코더를 context vector로 연결하는 것이 아니라 attention mechanism을 이용한다. 어텐션을 한 문장으로 설명하자면 '다음에 올 단어는 input sequence 중에서 관련이 있어 보이는 애를 우선적으로 고려해서 예측해봐야겠다' 이다. 그럼 연관성이 높은 애들은 어떻게 찾느냐? attention score이 그 기준이 된다.
디코더에서 t 시점의 output을 예측할 때 사용하는 값은
(1) 현 시점의 input vector(t-1상태의 output vector)
(2) 전 시점의 hidden state(st−1로 notation 하겠다)
(3) 그리고 attention score
이렇게 3가지 이다.
그렇다면 attention score는 어떻게 구하느냐?
(1) encoding의 모든 hidden state와 st−1를 곱한다.
(2) (1)에서 계산된 값에 softmax 함수를 거쳐서 확률값을 구한다 : 어탠션 스코어 (아래 그림에서 바그래프 처럼 생긴 것)
(3) 이렇게 나온 벡터와 각 시점의 hidden state를 곱한 값들을 더한다 : 어탠션 분포 (아래 그림에서 삼각형)
(4) 위에서 계산한 값과 현 시점의 hidden state(st)를 concatenate한다. (아래 그림에서 다이아몬드)
(5) 이 concatenate한 벡터를 가중치 행렬과 곱해준다. (아래 그림에서 dense)
(6) tanh에 (5)의 값을 넣어준다.
(7) 출력값

(위 설명에서는 쿼리, 키, 벨류 값이 빠져있다. 그래서 간략한 설명이다.)
[Transformer 모델의 배경]
초록에서 sequence transduction model 을 언급했는데 이는 언어 모델링이나 기계 번역 같은 과제들을 수행하는 대표주자 RNN, LSTM, GRN 들을 뜻한다. 기계 번역은 어떤 과제인지 알 것이고, 언어 모델링은 그 쓰임새를 알면 이해하기 쉽다. 오탈자 검색이나 검색어 자동 완성, 즉 특정 character를 예측하는 것이 언어 모델링이 이용한 기능이다.
RNN의 구조를 떠올려보면 아래와 같다.

yt를 예측하기 위해선 t-1 시점의 hidden state인 ht−1와 입력 벡터 xt를 input으로 이용한다. 하지만 hidden state를 계산하기 위해서는 t-2시점의 hidden state가 필요하고 또 그 전의 h-3, 이런 식으로 쭉쭉 거슬러 올라간다. 그렇기 때문에 기존 RNN 구조에서는 병렬화가 불가능했다. 왜? 전 단계의 정보가 필요하니까! (*병렬화가 중요한 이유는 한 번에 처리할 수 있다는 장점 덕분이다. 전 단계가 끝나야 다음 단계를 수행할 수 있는 게 아니고, 모든 단계를 동시에 각각 수행할 수 있으니까! 독립적이라고 말해도 될까. 하여튼 이러면 GPU를 이용할 수 있고 GPU의 힘을 얻어 더 빠르게 더 빠르게 계산할 수 있다.)
factorization trick, conditional computation 등을 이용함으로써 모델의 성능을 개선하고자 했지만, 근본적인 RNN의 한계를 극복하지는 못했다.
Attention 메커니즘은 입력과 출력의 순서와 상관없이 의존성을 학습할 수 있었기에(입력과 출력에 상관없이 항상 모든 hidden state를 고려하는 attention 메커니즘의 특징을 떠올리면 좋을 것 같다) 여러가지 task에서 이제 필수적인 메커니즘이 되었지만 여전히 recurrent network에 기대고 있다.
그래서 Transformer에서는 철저하게 attention 매커니즘을 사용함으로써 입력과 출력 사이의 전역 의존성을 끌어내고자 한다. 이를 통해 transformer에서는 병렬화가 가능해지고, 여덟개의 p100 GPU를 이용함으로써 더 좋은 성과를 이끌어낼 수 있었다.
Attention is all you need
초록Abstract
대부분의 sequence transduction model들은 인코더와 디코더가 있는 RNN 구조를 사용했다. 여태까지 최고의 성능을 내는 것은 attention 메커니즘을 이용해서 인코더와 디코더를 연결한 모델이다. 한편, 본 논문의 저자는 Transformer라고 하는, 순수하게 attention 메커니즘만을 이용해서 인코더와 디코더를 연결한 모델을 고안해낸다. 여기서 중요한 부분은 RNN(혹은 CNN) 구조로부터 완전히 벗어났다는 점이다. (dispensing with recurrence and convolutions entirely) 이러한 아키텍쳐를 구현함으로써 질적으로도 뛰어날 뿐 아니라, 계산의 병렬화를 가능하게 하여 훈련 시간의 단축이라는 쾌거를 이루어낼 수 있었다.
[Transfomer 의의]
"interpretable"하다는 것이다. 앞에서 봤듯이 self-attention은 여러 번 시행하게 되는데(multi-head) 이때, 각 head 마다 기능이 다를 뿐 아니라, 대부분이 syntactic하고 semantic한 문장 구조와 관련된 task도 잘 수행한다는 것이다. 부록에 있는 내용을 슬쩍 가져와보겠다.

왼쪽과 오른쪽은 각각 laye5와 6의 self0attention 인코더에서 가져온 다른 head라고 한다. 보면 서로 다른 방식으로 문장 구조에 접근하고 있다. 이 말인즉슨, 문장의 구조와 관련된 서로 다른 역할을 수행하고 있다는 것이다.
[Transformer 모델 도식화]
Transformer는 이런 인코더와 디코더를 6개씩 쌓은 구조이다.

각각 인코더와 디코더 내부는 아래와 같다.

각각을 자세히 살펴보자.

encoder: 위의 사진처럼 생긴 동일한 6개의 encoder가 쌓여있다. 각 encoder에는 2개의 sub-layer가 딸려있는데, 사진을 통해서 알 수 있듯이 multi-head self-attention과 pointwise FC feed-foward layer이다. feed - foward layer는 순전파라고 생각하면 편하더라. 이때 이 sub-layer는 residual 하게 연결하며 layer normalization을 시행한다.
수식으로 표현하면 쉽다. LayerNorm을 함수 g(x)라고 하자. 그러면 g(x+Sublayer(x)) 이런 식이다. residual하게 x와 sub-layer를 거친 output을 더해서 normalization을 시행한다. 한편 residual한 connection이 제대로 작동하게 하기 위해서 output과 input의 차원을 동일하게 설정한다! dmodel=512 그 차원은 512로 설정한다.

decoder: 디코더 역시 6개의 동일한 decoder를 쌓아 올린 것이다. 대신 디코더에서는 하나가 더 추가된다: Masked multi-head attention 이다. 왜 이게 필요하느냐?
ex. I'll go to school tomorrow.
라는 문장을 번역하면 나는 내일 학교를 가겠다. 가 될 것이다. 이건 인간번역이고, 기계번역을 상상해보자.
만약 지금 '나는 내일'까지 output을 출력했고 다음으로 '학교를'을 출력해야 할 때라고 생각하자. 그럼 디코더는 '가겠다'라는 sequence는 고려할 수 없다. 그러니까 지금까지 출력된 값들만 고려할 수 있다는 것이다. 따라서 현재 스텝 이후의 input sequence를 masking을 해준다.
즉, predictions for position i can depend only on the known outputs at positions less than i
[Self-attention 의 개념]


위 사진을 참고하면 알 수 있겠지만, 쿼리, 키 value 도 결국은 sequence를 의미한다. (다만 위의 그림은 encoder의 self-attention layer이니 decoder의 masked self-attention이나 encoder-decoder attention layer은 스스로 상상해보면 좋을 것 같다... ㅎㅎ)
decoder와의 차이는 쿼리가 decoder의 input sequence이고, 키와 value는 encoder의 output이다. 섹션 3.2.3에서 나온다.
다만 논문의 흐름은 부수고 잠깐 내가 개입해서 왜 쿼리, 키, value 값들로 이런 많은 연산들을 하는지 내가 이해한 바로는,,
쿼리와 키 값을 곱하고 소프트맥스에 넣는 과정까지가 상관관계를 구하는 것과 유사하다는 인상을 받았다.
그래서 자기자신과의 attention score는 굉장히 높다! 당연하다. 기계 번역시에 내가 hi라는 단어를 번역할 것이라면 hi에 주목하는 것이 맞다. 하지만 그 외에도 추가로 참고하면 좋은 단어가 있다면 상관성이 높게 나타나야 하고 이가 곧 높은 attention score를 얻는 다는 뜻이다.
attention은 쿼리와 key-value 쌍을 output에 매핑한다고 설명할 수 있다. 이때 기억할 것은 쿼리, key-value그리고 output 모두 벡터이다.
output은 value들의 가중합으로 계산된다. 그럼 이때 가중치는 어디서 나왔느냐? 이것들은 쿼리와 이에 상응하는 key 사이의 compatibility function을 통해서 계산된다. compatibility function이란 무엇인가,,, 3.2.1에서 고민해보자!
$Attention(Q,K,V) = softmax(\frac{QK^{T}}{\sqrt{d_{k}}})V$
[Multi-Head Attention 개념]
단순히 어탠션 함수를 시행하는 것 보다는, 쿼리, 키 그리고 value를 h번 학습된 각기 다른 선형 projection을 이용하면 더 효율적이었다고 한다. 그래서 h번 projection을 하고, concatenate(이어 붙임)한 후에 다시 projection을 했다고 한다.
Multi head가 무엇인가? 아래 그림을 보면 이해가 쉽다. 독립적으로 서로 다른 어탠션 head를 계산을 뜻한다!

위에서 보이는 것처럼 $z_{0}$ 이런 친구들은 나중에 한꺼번에 하나의 행렬로 합쳐진다. 그 후에는 아래의 그림처럼 linear 한 layer를 거친다.

Multi-head attention을 시행함으로써 얻는 장점은 무엇인가?
jointly attend to information from different representation subspaces at different positions.
$MultiHead(Q,K,V) = Concat(head_{1}, head_{2}, \dots, head_{h}) W^{O}$
이때 $head_{i} = Attention(QW^{Q}_{i}, KW^{K}_{i}, VW^{V}_{i})$
이때 h는 8로 설정했는데, total 계산 비용은 single-head attention을 한 것과 크게 차이가 없었다. 왜냐하면 다 계획이 있거든! 이를 위해서 $d_{k} = d_{v} = d_{model}/h = 64$를 각 head의 차원을 축소시켰다.
- "encoder-decoder attention" layer에서 쿼리값은 전 디코더 layer의 값이고, key와 value 값은 인코더의 output이다. 이렇게 쿼리, 키, value 값을 구함으로써 디코더 값을 출력할 때 항상 모든 input sequence 값을 고려하게 된다는 것이다.
- 인코더는 self-attention layer를 포함한다. 이때 쿼리, 키, value 값은 모두 동일하게 encoder의 전 layer output이다.

[Positional Encoding]
이 모델에서는 RNN이나 CNN을 사용하지 않고 있는데, 이로 인해서 transformer에서는 새로 고려해야 할 부분이 있다. 바로 지금 내가 몇 번째 sequence를 읽어들이고 있는가, 이다. 따라서 이를 함께 고려해주기 위해서는 현재 sequence의 상대적 혹은 절대적 위치를 참고해야 한다. 이가 곧 "positional encodings"이다.
이는 input을 임배딩할 때 해주게 된다. 개념적으로 표현하면 아래 그림과 같다.

실제 transformer에서 사용한 것은 sine과 cosine함수였다고 한다.

위 함수를 통해서 학습 데이터보다 긴 sequence의 데이터도 잘 처리할 수 있는 결과를 기대했다.
($\because$절대적 위치 참조가 아닌, 상대적 위치 참조라서 그렇다고 한다.)
'딥러닝 > CV 논문' 카테고리의 다른 글
| [Generation]GAN - 2부 (0) | 2022.08.09 |
|---|---|
| [Instance Segmentation] Mask R-CNN (0) | 2022.08.01 |
| [Object Detection] Faster R-CNN (0) | 2022.07.27 |
| [Classification] ResNet 요약 (0) | 2022.07.10 |
| [Object Detection] CenterNet2 요약 (0) | 2022.03.21 |
댓글