BERT 논문 리뷰

Abstract

Introduction

NLP에는 sentence-level로 처리하는 task가 있고 token-level로 처리하는 task가 있다. 이 task를 잘하기 위해 pre-training 하는 전략이 잘 먹혔다. Pre-training 하는 방법에는 크게 feature-based 방법과 fine-tuning 방법이 있다.

  • feature-based 방법은 task-specific한 architecture를 사용하는 방법이다. pretrain 한 representation을 additional feature로 넣는 방법이다. 논문에서도 그닥 언급을 안하는 게 BERT와 방향성이 달라서인지 feature-based 방법이 별로여서인지 잘 모르겠다.
  • fine-tuning 방법이 BERT가 사용하는 방법인데 이전 SOTA였던 GPT도 이 방법을 사용한다. 이 방법은 task-specific한 parameter를 최소화해서 finetuning하는 방법이다.

GPT가 이 논문에서 개선했다고 말하고 싶은 주요 대상이다. GPT는 unidirectional 한 모델을 사용한다. 즉 모든 토큰은 이전 토큰만 참고할 수 있는 것이다. auto-regressive하다고 이해하면 더 이해가 빠를 것이다. 다음 그림에서 OpenAI GPT를 보면 각 layer에서는 이전 input에 대한 정보만 참조하는 것을 볼 수 있다. 하지만 BERT의 경우 이전, 이후의 정보를 모두 활용한다. unidirectional은 token-level에서 큰 단점이 된다.(어떤 근거로?)

BERT의 핵심은 다음 세 가지이다.

  1. unidirectional이 아닌 bidirectional
  2. masked language model과 next sentence prediction task를 이용한 pretraining
  3. 대규모 데이터셋을 통한 pretraining —> task-specific한 데이터셋에 대해 finetuning

그래서 얼마나 잘하나보면 다음과 같이 겁나 잘한다. 모든 GLUE task에서 SOTA를 달성했다.

SQUAD 데이터셋에서도 마찬가지로 SOTA

Named Entity Recognition task인 CoNLL-2003 데이터셋에서도 SOTA

SWAG(Sentence-pair completion task) 에서도 SOTA

BERT

모델 구조는 위 그림과 같다. 이 논문을 보려면 transformer는 기본적으로 알고 있어야한다. BERT의 네트워크 구조는 deep 하게 transformer를 쌓은 것이다. 여기서 이 transformer가 모든 layer에서 왼쪽 오른쪽 정보를 모두 활용하는 것이다. BERT의 구조를 표현하는 기호는 L(네트워크 깊이, transformer layer를 몇 개를 쌓았나), H(hidden size), A(self-attention head) 이다. 논문에서는 2개의 네트워크 구조를 제안한다. 작은 놈과 큰 놈

  • BERTBASE: L=12, H=768, A=12, Total Parameters=110M
  • BERTLARGE: L=24, H=1024, A=16, Total Parameters=340M

데이터는 다음과 같이 전처리하면 된다. BERT를 학습시킬 때 next sentence 인지 아닌지 판단하는 걸로 학습하기 때문에 하나의 입력 데이터는 두 개의 문장으로 이루어진다. 이 때, 두 개의 문장은 꼭 실제 문장 단위가 아니어도 된다. 각 문장이 token으로 바꾸는 게 tokenizer가 하는 일이다. 단어를 있는 그대로 모두 embedding으로 바꾸면 너무 네트워크 크기가 커진다. 따라서 token의 개수를 줄이는 과정이 필요한데 여기서는 WordPeice를 통해 token의 개수를 30,000개로 제한한다. 문장 길이는 최대 512 토큰으로 제한한다.

이 입력 데이터를 뉴럴넷에 집어넣기 위해 representation으로 바꿔야한다. 보통 NLP에서 하듯이 embedding으로 변환하는 과정이다. Input representation으로는 하나의 토큰 자리에 세 가지 embedding이 들어간다. 첫 번째는 token embedding으로 일반적인 word embedding을 떠올리면 될 것 같다. 그리고 두 번째는 segment embedding이다. 두 개의 문장을 입력으로 넣는데 뉴럴넷이 두 개의 문장이라는 것을 구분할 방법이 필요하다. 따라서 첫 번째 문장인지 두 번째 문장인지에 대해 embedding을 한다. 그리고 세 번째는 position embedding 인데 transformer에서 position encoding 할 때와는 다르게 각 위치에 대한 embedding을 학습한다.

코드로 본다면 다음과 같이 세 embedding을 구하고 합친다. 합치는 연산은 단순 합이다. embedding dimension은 모두 동일하다.

input 토큰 중 첫번째 토큰은 [cls] 토큰으로 classification task일 때 사용하는 token 이다. 문장 사이와 input의 마지막에는 [sep] 토큰을 사용한다. input 이후의 모델 구조는 transformer이기 때문에 여기서는 설명을 생략한다. 간단히 embedding을 통과한 이후에 transformer로 들어간다라고 생각하면 된다.

Masked LM

BERT 모델을 pretrain 할 때는 두 가지 task로 학습한다. 그 중에 첫 번째가 masked lm이다. 왜 이 두 가지 task를 정했는지는 모르겠다. bidirectional한 모델에 맞는 task를 고른거지 싶다. 이 task는 input sequence의 15%를 random으로 mask를 씌우고 그 자리에 있던 원래 token을 맞추는 것이다.

이 때, 단순히 다 mask를 씌우지 않는다. 다음과 같이 세 가지 방법을 사용한다. 이렇게 하는 이유는 pretrain 한 다음에 finetuning을 하기 때문이다. pretrain 할 때는 항상 입력에 mask가 있고 finetuning을 할 때는 mask가 전혀 없다. 이러한 차이가 있기 때문에 그 자리를 항상 mask로 바꾸는 게 아니라 다른 단어로 채우는 것이다.

  1. Randomly 80% of tokens, gonna be a [MASK] token
  2. Randomly 10% of tokens, gonna be a [RANDOM] token(another word)
  3. Randomly 10% of tokens, will be remain as same. But need to be predicted.

코드로 보면 다음과 같다. 15 퍼센트의 확률로 위 3가지의 방법으로 그 자리를 채운다.

BERT 모델의 출력으로 sequence 길이만큼이 나올텐데 그 중에서 mask가 있는 자리의 출력값만 사용한다. fully connected layer를 사용해서 vocab 크기 만큼의 softmax 출력을 내보낸다.

Next Sentence Prediction

두 번째 pretrain task는 다음 sentence를 예측하는 것이다. 데이터셋에서 각 샘플은 2개의 문장으로 구성되어있다. 50 퍼센트의 확률로 2개의 문장에서 뒤의 문장을 다른 문장으로 바꿔치기 한다. 그 다음에 다음 문장이 맞는지 안맞는지로 binary classification 하는 것이다. 이 task를 하는 이유는 pretrain model을 token-level의 task에만 활용할 것이 아니라 sentence-level에도 활용하고 싶기 때문이다. 이 task를 통해 BERT 모델은 문장 사이의 연관성에 대해서 학습할 수 있다.

Pre-training Procedure

학습 데이터로는 BooksCorpus와 English Wikipedia를 사용했다. Masked LM loss와 Next Sentence Prediction loss를 더해서 학습한다. 구체적인 사항은 다음과 같다.

  • We train with batch size of 256 sequences
  • for 1,000,000 steps, which is approximately 40 epochs over the 3.3 billion word corpus.
  • We use Adam with learning rate of 1e-4, β1 = 0.9, β2 = 0.999, L2 weight decay of 0.01,
  • learning rate warmup over the first 10,000 steps, and linear decay of the learning rate.
  • We use a dropout probability of 0.1 on all layers.
  • We use a gelu activation (Hendrycks and Gimpel, 2016)
  • Training of BERT BASE was performed on 4 Cloud TPUs in Pod configuration (16 TPU chips total).5 Training of BERT LARGE was performed on 16 Cloud TPUs (64 TPU chips total). Each pre-training took 4 days to complete.

Fine-tuning Procedure

BERT 모델은 token-level의 task에도 sentence-level의 task에도 활용할 수 있다. sentence-level의 task는 sentence classification이다. token-level task는 question answering, Named entity recognition이다. classification을 할 때는 맨 첫번째 자리의 transformer의 output을 활용한다. 그리고 question answering의 경우는 첫 번째 문장에 question, 두 번째 문장에 paragraph를 넣어서 입력 데이터를 만든다. 정답을 만드는 과정은 다음 수식과 같다. 네트워크가 맞춰야 하는 것은 answer가 paragraph에서 어디서 시작해서 어디에서 끝나는 지이다. 따라서 start vector와 end vector만 학습하면 된다. start vector는 transformer의 dimension의 크기를 가진다. paragraph의 각 위치 마다의 output인 T와 start vector를 dot product해서 softmax를 취한다. end vector도 마찬가지로 probability를 구하고 정답과 cross-entropy를 취해서 학습한다.

참고 자료

레딧 bert 관련 토론: https://www.reddit.com/r/MachineLearning/comments/9nfqxz/r_bert_pretraining_of_deep_bidirectional/




© 2018. by Woongwon Lee

Powered by dnddnjs