산 넘어 산 개발일지

[논문 리뷰] GPT-1 리뷰 본문

논문 리뷰/NLP

[논문 리뷰] GPT-1 리뷰

Mountain96 2022. 10. 14. 00:55

1. 배경

(이미지 출처 : https://github.com/pilsung-kang/Text-Analytics/blob/master/08%20Seq2Seq%20Learning%20and%20Pre-trained%20Models/08-4_GPT.pdf)

 

 

 

당시 Unlabeled dataset은 6백만개가 넘는 글과 35억개가 넘는 단어들로 넘쳐났지만, Labeled dataset은 너무나 부족한 상황이었다. 따라서 Unlabeled dataset으로 의미 있는 언어 정보를 학습하는 모델이 필요했다.

 

Unlabeled dataset으로 언어 정보를 학습한 모델의 장점

  1. 시간 비용이 많이 드는 추가적인 labeling작업을 대체하여 학습에 사용할 수 있음.
  2. 지도학습 하기에 충분한 데이터셋이 있다면, unlabeled dataset에서 학습한 정보들로 성능을 향상시킬 수 있음.

또한, 당시 많은 연구들에서 word embedding과 같은 단어 레벨의 정보를 사용하여 성능 향상을 보였다는 것이 많았다. 그러나 저자들은 이보다 더 높은 레벨의 정보들을 얻고자 하였다. (Phrase-level 혹은 sentence-level embedding)

unlabeled data로부터 단순히 단어 레벨의 정보를 넘어서 더 많은 정보를 얻는 것은 다음 두 가지 이유에서 어려운 점이 있다. (단어 레벨

  1. 어떤 목적함수가 가장 효과적인지를 모름.
  2. target task에 전이학습을 할 때 어떤 방법이 가장 좋은지에 대한 공식적인 합의가 아직 없음.

물론 당시에도 전이학습에 관한 개념이 있었지만, 대체로 복잡한 방법들을 통해 기존 모델 구조를 뒤바꾸는 형태로 학습이 이루어졌다.

따라서 논문 저자들은 unlabeled dataset에서 학습한 언어 모델을 만들고, 이 언어 모델 labeled dataset을 사용해 모델 구조의 변환을 최소화하면서 전이학습을 하고자 하였다.

 

1-1. Generative VS Discriminative

Discriminative

데이터 X가 주어졌을 때 Y로 분류될 조건부확률 \(\mathcal{p}(Y|X)\)을 높이는 방식으로 학습한다. 지도학습에 속하며, 우리가 흔히 아는 분류 문제가 이에 속한다. 조건부확률을 올리기 위해 모델은 Decision Boundary를 만들도록 학습이 이루어진다. 학습 데이터의 양이 많다면 충분히 좋은 성능을 내고, generative에 비해 가정이 단순하다.

Generative

데이터 X의 분류를 학습하기보다는 분포를 학습하는 개념이다. \(\mathcal{p}(Y|X)\)를 구하는 것은 동일하지만, 데이터 X가 주어졌을 때 베이즈 법칙을 사용하여 \(\mathcal{p}(Y), \mathcal{p}(X|Y)\)를 이용해 \(\mathcal{p}(Y|X)\)를 도출한다. label에 대한 정보가 있으면 지도학습, 없으면 비지도학습으로 사용할 수 있다. Generative 모델은 Discriminative 모델에 비해 가정이 많고, 이 많은 가정이 모두 현실에 맞기는 어렵다보니 일반적으로 Discriminative 모델에 비해 성능이 떨어진다. 다만 가정의 수가 많은 만큼 충분히 많은 가정들을 만족한다면 성능이 좋고 outlier에도 크게 영향을 받지 않는 모델이 만들어진다. 또한, Generative는 분포를 학습하므로 이 분포를 이용해 데이터 X를 샘플링할 수 있다.

 

 

2. 학습 방식

2-1. Transformer Block

Attention is All you need에서 나온 Transformer와는 다르게, GPT에서는 Transformer의 Decoder만 사용했으며 Decoder 구조에도 차이가 있다.

기존 Transformer decoder의 구조에는 Masked Attention과 Encoder에서 정보를 받아서 attention을 수행하는 encoder-decoder attention이 있었지만 이 부분이 사라졌다. 따라서 GPT-1에서 사용하는 Transformer block은 다음과 같다.

(이미지 출처 : Jay Alammar https://jalammar.github.io/illustrated-gpt2/)

GPT-1에서는 위 그림과 같은 디코더 블록을 12개 쌓아서 transformer_block을 만들었다.

 

GPT-1은 목적함수로 우도(likelihood)를 최대화하는 방법으로 모델을 학습한다.

 

2-2. Unsupervised pre-training

pre-training의 목적은 파라미터들의 좋은 initial 값 찾기이다. 또한, 사전학습을 사용한 모델은 사전학습 없이 직접 task에 특화된 모델보다 일반화 성능이 우수한데, 이는 사전학습이 Regulaization처럼 작용하기 때문이다.

ELMO와의 비교

ELMO는 GPT 이전에 성공적이었던 언어 모델 중 하나이다. 

  ELMO GPT-1
구조 LSTM Transformer Decoder
방향 양방향(Bi-Directional) 단방향(Forward) + masking

GPT-1에서는 LSTM이 아닌 Transformer의 디코더를 사용함으로써 긴 범위의 언어 정보를 사용할 수 있게 함으로써 Long term dependency를 해결하였고 다양한 Task에서도 더욱 좋은 성능을 보여주었다.

 

\[\mathcal{L_1}(\mathcal{U})=\sum_ilog\mathcal{P}(u_i|u_{i-k},\ldots,u_{i-1};\Theta)\]

unsupervised pre-training은 위 \(\mathcal{L}_1\)을 최대화하는 방식으로 학습하며, 이때 \(\mathcal{U}\)는 토큰들의 집합 \(\{u_1,\ldots,u_n\}\)을 의미힌다. \(k\)는 context window의 크기를 의미하며, 이를 통해 i번째 토큰을 볼 때 이전 토큰들 중 최대 k개의 토큰만을 본다는 것을 알 수 있다.

\(P(u)\)를 구하는 식은 위와 같다. 먼저 변수들은 다음과 같다.

  • \(U=(u_{-k},ldots,u_{-1})\)
  • \(W_e\) : Token embedding matrix
  • \(W_p\) : Position embedding matrix
  • \(n\) : layer 개수

즉 U가 입력으로 들어오면 \(W_e\)를 통해 벡터로 임베딩되고 \(W_p\)로 위치정보를 더하여 \(h_0\)을 구한다. 이때 \(W_p\)는 Sinusoid가 아닌 학습된 position embedding이다. 이후 transformer_block을 통과하여(12개의 block) \(h_l\)을 계산하며 최종적으로 \(h_n\)이 계산된다. 토큰 임베딩에 썼던 \(W_e\)의 Transpose를 \(h_n\)에 곱한 뒤(왜 곱하는 걸까요..) softmax를 취해줌으로써 \(P(u)\)를 구할 수 있다.

 

2-3. Supervised fine-tuning

unsupervised pre-training이 끝난 뒤 task에 맞는 지도 학습을 진행하며, 학습 과정에서 기존에 구한 parameter들을 해당 task에 맞게 업데이트하게된다. fine-tuning을 위한 목적함수는 \(L_2\)로 나타내며 이를 최대화하는 방식으로 학습이 진행된다.

  • \(\mathcal{C}\) : task를 위한 데이터셋. \(\{x^1,\ldots,x^m\}\) 의 토큰들로 이루어진 input들이 포함된다.
  • \(h_l^m\) : 사전학습된 모델의 마지막 transformer block을 통과한 출력값
  • \(W_y\) : y를 예측하기 위한 선형변환 matrix

즉 이전에 학습한 사전학습 모델에 \(\{x^1,\ldots,x^m\}\)을 입력으로 넣는다. 이후 마지막 transformer block에서 나온 출력값 \(h_l\)을 여기서는 사전학습에서의 출력값과 구분을 위해 \(h_l^m\)으로 표시하였다. 이 \(h_l^m\)을 \(W_y\)와 곱하고 softmax를 취하여 \(L_2\)를 구한다. 

따라서 전이학습을 위해 모델에 여러 복잡한 작업을 가했던 과거 연구들과는 달리, GPT에서는 \(W_y\)delimiter 토큰을 위한 embedding만 학습하면 된다는 장점이 있다.

Auxiliary training objectives(보조학습목적함수)

이때 데이터셋 \(\mathcal{C}\) 을 사용하여 구한 \(L_2\)와 사전학습에 사용된 모델을 그대로 사용하여 구한 \(L_1\)을 사용하면 일반화 성능이 증가하고 학습이 빨라진다. 이를 저자들은 Auxiliary training objective라고 부르며, 이때 \(L_1\)을 구할 때에도 똑같은 데이터셋 \(\mathcal{C}\) 을 사용함에 유의한다.

따라서 supervised fine-tuning시 최적화해야 할  목적함수는 \(L_3\)이다. \(\lambda\)는 \(L_1\)을 얼마나 반영할지에 대한 가중치이다.

 

2-4. Input transformation(traversal-style approach)

GPT는 연속된 시퀀스 데이터들로 학습되었지만, task마다 input이 구조적인 특징을 지니는 경우도 있다. 가령 QA의 경우 context document와 question, 그리고 answer가 필요하다. 기존 연구들에서는 이런 task를 위해 input을 변형하기보다는 사전학습 모델 위에 여러 복잡한 구조를 쌓았다. 그러나 GPT에서는 input에 토큰들을 추가하고 모델의 출력값에 다양한 연산을 추가하여 이를 해결하였다.

공통

  • 모든 입력의 시작과 끝에는 <s>, <e> 토큰을 추가하여 시퀀스의 시작과 끝을 알린다.
  • delimiter token으로 $을 쓴다. 보통 문장을 구분할 때 사용된다.

Textual Entailment(Natural Language Inference)

두 문장이 주어졌을 때 두 문장간의 관계를 분류하는 task이다.

한 문장이 다른 문장을 수반하는지(동일한 의미인지)(entailment), 두 문장이 모순되는지(contradiction), 아니면 아무 관계도 없는지(neutral)에 대해 분류한다.

두 문장 중 한 문장을 premise(전제) \(p\), 다른 문장을 hypothesis(가정) \(h\)라 할 때, 두 문장을 delimiter를 사이에 두고 concat하여 \([<s>,p_1,\ldots,p_n,$,h_1,\ldots,h_n, <e>]\) 를 입력으로 사용한다.

Semantic Similarity

두 문장의 의미가 유사한지를 분류하는 작업이다. 예를 들어 "나는 인셉션 영화를 제일 좋아한다" 라는 문장과 "내가 가장 재미있게 본 영화는 인셉션이다" 라는 문장은 유사한 문장이다.

유사한 문장 간에는 어떤 문장이 먼저 오든지 상관없이 결과값이 일정하므로 문장의 순서가 결과에 무관하다. 따라서 문장 A, B가 오는 상황과 B, A가 오는 상황 모두에 대해 학습을 진행한다. 이를 위해서 두 개의 input을 준비한다.

  • input1 : \([<s>, a_1, \ldots,a_n,$,b_1,\ldots,b_m,<e>]\)
  • input2 : \([<s>, b_1, \ldots,b_m,$,a_1,\ldots,a_n,<e>]\)

이후 transformer를 거친 뒤의 출력을 \(h_1\), \(h_2\)라 한다면 이들을 합하여 linear layer에 넣는다.(즉 위 supervised fine-tuning 식의 \(h_l^mW_y\)에서 \(h_l^m=h_1+h_2\)인 것이다.

QA

QA에서는 데이터가 context document \(z\), question \(q\), 그리고 가능한 answer들의 집합인 \(\{a_k\}\)으로 이루어져 있다. 이를 input으로 사용하기 위해 \(z\), \(q\), delimiter, \(a_k\)를 concat 해서 사용하는데, answer의 개수가 n개라면 answer만 바뀌고 나머지는 똑같은 input이 n개가 사용된다. 

  • input 1 : \([<s>,z_1,\ldots,z_l,q_1,\dots,q_m,$,a_1,<e>]\)
  • input 2 : \([<s>,z_1,\ldots,z_l,q_1,\dots,q_m,$,a_2,<e>]\)
  • input n : \([<s>,z_1,\ldots,z_l,q_1,\dots,q_m,$,a_n,<e>]\)

이렇게 n개의 input이 각각 독립적으로 transformer에 입력되고 linear layer까지 수행된다. 이후 linear layer에서 출력된 n개의 output에 softmax를 적용하여 확률분포로 만든다.

 

 

3. 분석

3-1. layer 개수에 따른 변화

사전학습 모델에 사용된 layer 개수(transformer block 개수인 듯 하다)에 따라 모델의 성능을 관찰한 결과이다. RACE, MultiNLI 데이터셋에서 모두 layer가 늘어남에 따라 정확도가 높아짐을 확인할 수 있고, 12개의 layer부터는 크게 성능이 좋아지지 않고 수렴했다.

3-2. fine tuning의 update를 점진적으로 진행했을 때의 결과

비지도 사전학습으로 모델을 만든 뒤, 각 task에 대해 fine-tuning을 했을 때 파라미터들을 점진적으로 업데이트함에 따라 나타나는 성능을 보여준다. 일반적으로 많이 업데이트할 수록 성능이 높아진다.

이에 대해 어떤 분들은 "zero-shot VS fine-tuning을 비교하여 fine-tuning의 우수함을 보여주는 자료다" 라고 하시고, 어떤 분들은 "LSTM과 비교했을 때 우수한 성능을 보여주는 자료다"라고도 하시는데, 어떤 것이 맞는지는 잘 모르겠다.

 


참조

https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf

https://jalammar.github.io/illustrated-gpt2/

Comments