Transformer
0. ML 모델 이해를 위한 팁
- 다음 순서를 따르는 것이 복잡한 ML 모델을 이해하는 데 도움이 된다.
(1) 모델이 풀고자 하는 문제를 파악한다. (분류, 생성, …)
(2) 훈련 단계가 아니라 추론 단계부터 먼저 이해한다. 즉, ‘이미 학습이 이루어진’ 모델이 어떤 입력을 받아 어떤 출력을 내는지를 먼저 이해한다.
(3) 훈련 단계에서는 모델의 어떤 파라미터가 학습이 이루어지는지(구조가 복잡한 모델에서는 입력으로 주어지는 데이터와 파라미터가 헷갈리기 쉽다), 그리고 그 파라미터가 어떤 방식으로 학습이 이루어지는지(=어떤 에러함수를 사용하는지)를 이해한다.
1. transformer 이전 모델들
- RNN: 시간에 따라 변화하는, 길이가 있는 데이터를 처리하는 인공신경망으로서 가장 처음 제시된 것. 데이터의 길이가 길어지면 앞 데이터와 뒤 데이터 사이의 의존성을 모델링하기 어렵고, 연산에 오랜 시간이 걸린다는 단점이 있다.
- TextCNN: 기존 CNN과 같은 방식으로 신경망을 구성하되 입력 데이터로 텍스트를 받는 CNN. RNN보다는 훨씬 빠른 성능을 보인다. 그러나 긴 데이터의 앞뒤 사이 의존성을 처리하는 성능은 훨씬 나쁘다. 다만 텍스트 분류 문제에서는 나쁘지 않는 성능을 보이는 경향이 있다.
2. transformer의 개요
- 2017년 구글에서 ‘Attention is all you need’라는 제목의 논문으로 처음 소개한 모델. 자연어처리를 하는 인공신경망 모델으로서는 전과 다른 혁신적인 수준의 성능을 보여 NLP의 역사에서 매우 중요한 모델로 여겨진다. 현재 널리 쓰이는 BERT, GPT가 이 transformer에서 파생된 모델이다.
- RNN, CNN과는 전혀 다른 구조를 가지며, 오직 attention이라는 구조만으로 텍스트를 처리한다. 성능이 뛰어나다는 것 외에도, RNN과는 달리 병렬화가 용이하다는 장점이 있다.
- transformer는 순차적 입력에 대하여 순차적 출력을 반환하는 모델로서, 지도학습 방식으로 훈련한다.
3. transformer의 구조
1) 개요
- 크게 encoder와 decoder 두 부분으로 나뉜다. 입력 데이터가 encoder를 통과하여 만들어진 정보가 decoder에 전달되며, decoder는 이 정보를 통해 출력 데이터를 만들어 반환한다.
-
encoder: 똑같은 구조가 여러 겹의 층으로 쌓여 있으며(단 각 층의 파라미터가 갖는 값은 서로 다르다), 입력 데이터가 가장 앞의 층으로 입력되어 그 결과가 바로 다음 층의 입력으로 전달되는 과정이 순차적으로 반복된다.
-
decoder: encoder와 마찬가지로 똑같은 구조가 여러 겹의 층으로 쌓여 있다. 또 encoder에서 만들어진 출력이 decoder의 가장 앞의 층으로 입력이 된다는 점까지도 같으나, 그 다음층으로 넘어갈 때 바로 앞의 층에서 만들어진 입력과 함께 encoder에서 만들어졌던 그 출력이 또 바로 다음 층의 입력으로 주어진다는 점이 차이가 있다.
- 에러함수로는 cross entropy를 사용한다.
2) encoder
- 크게 self-attention 모듈 부분과 feed forward 모듈 부분으로 나뉘며, 각각 모두 내부에 신경망을 갖고 있다. 여러 단어로 이루어진 문장이 encoder의 입력으로 주어진다 할 때, encoder를 거친 결과 문장은 입력으로 주어진 문장과 같은 단어 개수를 갖고 있다.
-
self-attention: encoder의 입력으로 들어오는 단어 벡터는 먼저 self-attention 모듈의 입력이 된다. self-attention은 단어의 의미를 이해할 때 그 단어만 사용하는 게 아니라 그 주변 문맥을 사용한다. 입력 단어 벡터는 self-attention을 거쳐 그 입력 단어 벡터 주변 단어 벡터들의 문맥을 모두 반영한 새 단어 벡터가 된다. (새 단어 벡터를 만들 때 주변에 있는 단어 중 더 관련이 깊은 단어 벡터에 가중치를 곱한 값을 더한다. 예를 들어 문장의 it이 가리키는 단어가 apple이면, apple의 단어 벡터에 가중치를 곱한 값을 더해 it의 새 단어 벡터를 만든다.)
-
feed forward: self-attention의 출력이 곧바로 feed forward의 입력이 된다. self-attention과 달리, 입력으로 들어오는 단어 벡터들이 서로 주변에 있다 하여 이를 서로 값 계산에 반영하지는 않고 독립적으로 입력 단어 벡터를 처리하여 출력 벡터를 반환한다. (따라서 완전한 병렬화가 가능하다.)
-
positional encoding: encoder의 내부 구조상으로는 입력으로 주어지는 문장의 각 단어가 문장 내에서 어떤 위치에 있는지에 관한 정보를 처리하는 내용이 없기 때문에, encoder에 입력 데이터를 넣을 때 각 임베딩 벡터에 각 임베딩의 문장 내에서의 위치에 관한 정보를 담고 있는 벡터를 더해 그 결과를 encoder의 입력 데이터로 한다. 이처럼 위치정보를 담은 벡터를 더하는 것을 postional encoding이라 한다.
-
residual: CNN의 ResNet과 마찬가지로 self-attention과 feed forward는 residual block 구조를 갖는다. 즉, self-attention과 feed forward의 결과에 self-attention과 feed forward의 입력으로 주어진 벡터를 더한 값을 다음 구조의 입력으로 전달한다.
3) self-attention
- self-attention 하나에는 3개의 가중치 행렬 \(W^Q, W^K, W^V\)가 있다. self-attention에 하나의 임베딩이 입력으로 들어오면, 이 임베딩에 세 가중치 행렬을 각각 곱해 세 개의 벡터 \(q, k, v\)를 만든다. (각각을 query, key, value 벡터라 한다.)
-
임베딩 벡터의 차원을 흔히 d, query, key, value 벡터의 차원을 흔히 h라 한다. (query, key, value 벡터 쌍을 구성하는 self-attention 한 열을 head라 하며, 보통 모델의 성능 향상을 위해 여러 개의 head를 사용한다.)
-
현재 많은 transformer 파생 NLP 모델에서 d=512, h=64를 사용한다.
- 어떤 행렬 \(ATT\)의 각 성분이 \(a_{i, j}\)(단, \(i, j\)는 입력으로 들어오는 문장의 단어 개수 \(n\) 이하 자연수)이며, 이때 \(a_{i, j}\)는 맥락상 \(i\)번째 단어에 미치는 \(j\)번째 단어의 영향의 크기라 하자. 그리고 그 크기는 (1)\(i\)번째 단어에 해당하는 query 벡터와 \(j\)번째 단어의 key 벡터의 내적(=\(q_i^T k_j\))으로 계산한 후 (2)\(i\)번째 단어에 관하여 softmax 함수를 통해 계산한 값으로 정의하자.
- 어떤 임베딩 \(x_i\)가 self-attention을 거쳐서 출력하는 벡터 \(z_i\)는 \(\sum_j a_{i, j} v_j^T\)으로 하기로 한다.
4) decoder
4. BERT(bidirectional representations from transformer)
- 2018년 구글에서 발표한 transformer 기반 모델. transformer의 encoder 부분만으로 이루어져 있어, 맥락이 반영되지 않은 임베딩이 입력으로 들어오면 각 임베딩을 전체적 맥락을 반영한 임베딩으로 변환하는 모델이다. BERT를 거친 임베딩을 추가적인 신경망에 입력하여 원하고자 하는 과제를 수행할 수 있다. (이처럼 사전학습된 모델을 사용하는 것을 transfer learning이라 하며, 특히 사전학습된 모델에 새로운 신경망을 추가하여 원하는 과제를 수행하게 하는 것을 fine tuning이라 한다.)
- BERT는 transformer의 encoder에 추가적인 기법을 도입하여, 적은 양의 데이터로도 효과적인 성능을 낸다. 구체적으로 다음 부분에서 transformer와 다른 특징이 있다.
-
MLM(masked language model): 입력 문장에서 임의로 토큰을 버리고(mask), 그 토큰을 예측하는 방식으로 모델을 학습한다.
-
NSP(next sentence prediction): 두 문장이 입력으로 주어질 때, 두 문장의 순서가 어떻게 되는지를 맞히는 방식으로 모델을 학습한다.