BERT: Bidirectional Encoder Representations from Transformers

euijune·2023년 8월 22일
0

Paper review

목록 보기
7/7

Introduction

BERT는 이름에서 알 수 있듯 transformer의 encoder 구조만을 사용해 bidirectional model을 만들었다.

논문에서는 “deep”이라는 글자를 강조하고 있다. 기존 language representation model들과 다르게, 자신들의 모델 구조가 진정한 bidirectional representation을 가능하게 했다라는 의미에서 deep이라는 단어를 사용한 것이라 추측한다.
일단 BERT모델을 사전학습 시키면 architecture의 구조를 바꾸지 않고 fine-tuning만으로도 여러 NLP task에 적용할 수 있어 개념적으로 단순하지만 그럼에도 SOTA를 달성할 만큼 강력한 모델이라고 한다.

BERT는 모델을 먼저 pre-train한 뒤, down-stream task에 fine-tuning하는 방식을 채택했는데, BERT에서 사용한 Language model pre-training은 전제가 주어졌을 때 가설이 논리적으로 따르는지를 검증하는 natural language inference, 원문을 쉽게 풀어내는 paraphrasing 등의 sentense-level 수준부터 question-answering 등의 token-level에 이르기 까지 많은 NLP task에서 효과를 보여왔다.

pre-train된 모델을 down-stream task에 적용하는 방법에는 크게 두 가지가 있었는데, 첫번째가 Feature-based방식이다.

이의 대표적인 예는 ELMo로, pre-trained model을 additional feature로 사용해 각각의 task마다 architecture의 구조를 변경하는 task-specific architecture를 사용한다.

두번째 방식인 fine-tuning을 사용한 대표 모델로는 GPT가 있다.
GPT는 task-specific parameter의 수는 최대한 줄이고, 모든 pre-train parameter들을 조금씩만 바꿔 downstream task를 학습한다. 하지만 ELMo, GPT같은 unidirectional 모델은 pre-trained representation의 성능을 온전히 이끌어내지 못한다.

GPT는 transformer의 Decoder 구조만을 사용하기 때문에, 모든 token이 이전 token과의 attention만을 계산하는 masked self-attention을 사용하므로 문장단위, token단위 task에서 성능이 좋지 않다.

ELMO는 BiLSTM을 사용하지만, 그림에서 보이는 것처럼 left-to-right, right-to-left 단방향 LSTM 두개를 덧셈연산만으로 합친 것이기 때문에 결국 unidirection모델과 다를게 없다.

그렇기에 ‘deep’ bidirectional context가 중요하며, 이를 충족하는것이 BERT라고 논문에서는 설명하고 있다. BERT는 Masked-language model을 사용하여 앞서 언급한 단방향 모델의 제약을 극복할 수 있었다.

논문에서는 아래와 같은 contribution을 제시한다.

related work에서는 pre-training general language 모델의역사를 짧게 review한다.

  • Unsupervised Feature based approaches
    단어를 표현하는 방법에는 신경망 구조를 이용하는 Neural과 머신러닝 방법을 사용하는 Non Neural방법이 존재한다.
    단어를 임베딩하는 방식도, 처음에는 pretrain없이 scratch부터 바로 학습을 진행하다가, word embedding에 pre-train을 적용시키고 이후 sentense또는 paragraph embedding까지 연구가 이어졌다.
  • Unsupervised Fine-turning approaches
    초기 연구는 unlabeled text로부터 word embedding parameter를 pre-train하는 방향으로 진행되었다.
    좀더 최근에는, unlabeled text로부터 sentence 또는 document encoder를 pretrain하게 되었으며, 이를 supervised downstream task에 fine-tuning하는 연구가 진행되었다.
    이러한 방식의 장점은 적은 수의 parameter로도 학습이 가능하다는 것이고, GPT가 이러한 방식을 사용해 sentence-level task에서 SOTA를 달성할 수 있었다.
  • Transfer Learning from Supervised Data
    딥러닝을 처음 접하면 흔히 이미지를 class를 찾는 classification model을 만들곤 한다. 이때, ImageNet으로 pre-train한 모델을 ine-tuning하는 것이 바로 여기에 해당한다.
    NLP에서도 동일하게 적용이 되는데, Natural language inference, machine translation과 같이 많은 데이터셋을 필요로 하는 supervised task로부터 전이학습을 하는것이 효과가 있음을 보여주는 연구가 존재한다.

BERT Framework


BERT는 pre-training, fine-tuning 두 개의 step으로 구성된다.
pre-training에서는 unlabeled data를 가지고 각기 다른 task(NSP, MLM)를 동시에 사전학습한다.
fine-tuning에서는 pre-training에서 사용된 parameter 모두를 labeled data를 사용해 fine-tuning 한다. 이때, 각각의 downstream task는 동일한 pre-trained parameter로 초기화되고 맨 윗단의 output layer만 다른 출력을 내도록 fine-tunning되는데, 이것이 BERT의 특징이다.


BERT의 아키텍처는 Transformer의 encoder를 bidirectional하게 만든 다음 여러 층을 쌓은 구조이다. 우측그림의 Trm하나가 bidirectional encoder 하나에 대응한다. 왼쪽은 transformer의 encoder를 가져온것인데, BERT에서는 attention을 할 때 이전 토큰뿐만 아니라 이후 token까지 attention한다는 차이 정도만 존재한다.

논문에서는 실험을 진행할 때 BERT base와 BERT Large를 아래와 같은 구조로 설계했다.

  • BERT base
    L = 12, H = 768, A = 12, # of tot. param = 110M
  • BERT Large
    L = 24, H = 1024, A = 16, # of tot. param = 340M

L이 transformer에서 block수에 해당하는 것으로, encoder가 몇 개 쌓여있는지를 나타낸다. H는 hidden size이고 A는 self-attention head의 수로, transformer에서의 multi-head attention에 해당하는 파라미터이다.

BERT base는 당시 GPT모델과 비교를 위해 GPT와 동일한 param을 갖도록 설계되었다는 특징이 있다.


BERT의 pre-train과정을 살펴보기 이전에, 입력으로 들어가는 데이터에는 어떤 처리를 하는지부터 살펴보자.

I/O Representation

BERT가 다양한 down-stream task에 이용되기 위해서는, input representation이 하나의 문장이 들어올 때와 한 쌍의 문장이 들어올 때 모두를 명백하게 잘 표현해야 한다.

이때 ‘sentence’는 언어학적으로 말이 되는 문장 뿐만 아니라, 임의의 계속 이어지는 텍스트들의 집합이 될 수 있다. 즉, 하나의 ‘sentence’안에 우리가 일반적으로 생각하는 문장이 여러개 들어가 있을 수도 있다.

BERT는 WordPiece embedding을 사용하는데, 모든 sequence의 첫 번째 token은 [CLS] (classification token)이다. 이 토큰과 상응하는 마지막 hidden state C가 classification task를 해결하기 위해 sequence representation을 집계하는데 사용된다. [SEP] 는 두 문장을 구분하기 위한 special token이다.

BERT는 위에서 서술한 WordPiece embedding 이외에도 두개를 더 사용해 총 3개의 embedding을 input embedding으로 사용한다.

Segment Embedding은 [SEP]토큰을 기준으로, 첫번째 문장에는 0을, 두번째 문장에는 1을 시퀀스 길이만큼 부여하여 문장을 구분하기 위한 임베딩이다.

그다음은 positional embedding 이다.

position embedding을 설명하기 앞서, transformer에서는 positional ‘encoding’을 사용했는데, 각 단어(token)의 위치마다 고유한 벡터를 만들어 내는 적절한 함수를 이용해, 문장에서 각 단어의 위치를 설명하는 위치 임베딩 벡터를 만든 뒤, 단어 임베딩 벡터에 더하는 방식으로 사용했다.

BERT는 convolution을 사용하지 않고, RNN과 같은 recurrence도 사용하지 않고 입력 sequence를 한번에 처리하기 때문에 token의 위치를 전달하기 위한 임베딩이 필요하고, 그것이 positional embedding이다.

BERT에서 사용한 position embedding은 positional encoding처럼 임베딩 함수가 미리 정해져 있는 것이 아니라, 따로 임베딩층을 구성하여 위치 임베딩 또한 학습한다는 점에서 차이가 있다.

torch 라이브러리에서는 Enbedding layer를 만드는 함수를 제공하는데, 이처럼 임베딩층도 학습가능한 layer로 만드는 것이 position encoding과 positional embedding의 차이다.

pytorch에서 position embedding의 사용 예를 보면,
예를 들어 입력 sentence가 token화를 거쳐 13개의 token으로 바뀌었을 때, position embedding을 거치면 이와 같이 된다.

마지막 임베딩이 앞에서 말했던 wordpice embedding에 해당하는 토큰 임베딩이다. WordPiece embedding은 3만 개의 단어로 이루어진 사전으로부터 토큰을 임베딩하는 방식으로, 제한적인 vocabulary units, 정확히는 의미를 가진 최소의 subwords units 으로 모든 단어를 표현하는 임베딩이다.

이것이 왜 필요한지는 다음의 상황을 생각해보면 알 수 있다.
예를 들어, 수백만개의 단어를 포함하는 데이터를 표현하기 위해서 단어 개수 만큼의 차원을 지닌 벡터 공간을 이용한다면 차원이 크거나 모델이 무거워지고, 결국 학습에 소요되는 cost가 커지고 학습 속도가 느려지는 등의 문제가 발생한다. 이를 해결하기 위해서는 제한된 개수의 단어를 이용해야 하지만, 자주 이용되지 않는 수 많은 단어들을 무시하면 미등록단어 문제(OOV)가 발생한다.

그래서 WordPiece embedding은 자주 사용되는 단어를 subword unit으로, rare word는 자주 발생하는 unit으로 분리한다. 위 예제는 wordpiece embedding을 처음 제시한 논문에서 가져온 예제인데, 단어 사전에서 makers는 자주 사용되는 단어라 그대로 unit으로, Jet은 희귀한 단어라 자주 사용되는 J, et로 분리된 것을 볼 수 있다.

.
wordpiece embedding에 관한 더 자세한 내용이 잘 정리된 글이 있어 첨부한다. https://lovit.github.io/nlp/2018/04/02/wpm/


이제 최종적인 BERT의 Input Embedding을 보면 앞서 말한 3가지 embedding을 합하여 input embedding으로 사용하는 것을 볼 수 있다.

Pre-training BERT

Task #1: Masked-Language Modeling (MLM)


여기기부터는 BERT의 pretrain part를 설명한다. 논문에서는 pre-train을 통해 학습하는 task가 MLM, 그리고 NSP인데 첫번째로 Masked language modeling, 줄여서 MLM을 설명하는 부분이다.

MLM은 pretraining의 첫번째 task로, 입력 token의 일정 비율을 [mask]라는 토큰으로 대체하고, 모델은 [mask] token의 원본을 예측하는 것이다.

masking을 하는 이유는 이전까지의 모델들이 사용한 단방향 모델의 구조상의 문제점 때문이다. 이전 conditional language model들은 left-to-right또는 right-to-left로 한쪽 방향으로밖에 학습할 수 없었다. 그런데 여기에 bidirectional conditioning을 하게 되면 각각의 단어가 간접적으로 자기 자신을 볼 수 있게 된다. 따라서 그것을 방지하고자 아예 처음부터 단어를 볼 수 없도록 masking을 하는 것이다.

논문에서는 많은 실험을 통해, [mask]로 바꾸는 비율은 15%가 적당하다고 제시한다. 이것을 통해 BERT는 [mask]주변 문맥을 양방향으로 탐색하며 원래 단어를 예측하는데, 여기서 한가지 mismatch가 발생한다. 이후 설명하게 될 fine-tuning 과정에서는 [mask] token이 발생하지 않는다는 것이다.

그래서 논문에서는 어떤 token이 [mask]로 바뀌었을때, 다시 그중 10%는 [mask]대신 random word로, 나머지 10%는 [mask]로 바꾸지 않고 원래 단어를 그대로 유지하는 방식을 채택하여 이러한 mismatch를 줄이고자 했다.

Task #2: Next Sentence Prediction (NSP)

기존의 pre-trained language model들은 문장 사이의 관계를 고려하는 고수준의 작업들에서 상대적으로 좋은 성능을 보이지 못했다. pre-training 단계에서 문장 사이의 관계를 포착할 수 있는 능력을 따로 학습하지 않기 때문
인데, 따라서 BERT는 MLM에 더하여 pre-training 단계에서부터 문장사이의 관계를 포착하도록 하는 NSP task를 동시에 진행한다.


BERT는 두 개의 문장을 준 후에 이 문장이 이어지는 문장인지 아닌지를 맞추는 방식으로 훈련한다. 이를 위해 50:50 비율로 실제 이어지는 두 개의 문장과 랜덤으로 이어붙인 두 개의 문장이 주어지고, 이를 각각 Sentence A, Sentence B라고 하였을 때 이 그림은 문장의 연속성을 확인한 경우 isnext라는 라벨이 붙은것과 그렇지 않은 경우 notnext라는 라벨이 붙은 것을 확인 할 수 있다.

이 과정에서는 첫번째 토큰인 [CLS] 토큰을 활용하여 output layer에서 [IsNext], [NotNext]를 예측하도록 학습한다.

이렇게 [CLS] 토큰을 활용하여 NSP 작업을 수행하는 과정을 통해 BERT 모델은 문장 간의 관계를 학습하고, 문맥을 이해하는 능력을 향상시킨다. 이후 fine-tuning 단계에서는 이러한 학습된 능력을 다양한 downstream task에 활용하여 성능을 올린다.

Fine-tuning BERT

bert는 각각의 다른 자연어 task 처리를 위해서 따로 fine-tuning이 필요하다. 이처럼 fine-tuning은 내가 수행하고자 하는 down-stream task에 따라 조금씩 input의 형태가 달라진다.

첫 번째는 sentence pair classification task이다. 대표적인 태스크로 자연어 추론(Natural Language Inference, NLI)이 있다. NLI는 두 문장이 주어졌을 때, 하나의 문장이 다른 문장과 논리적으로 어떤 관계에 있는지를 분류하는 것이다. 이러한 태스크의 경우에는 입력 텍스트가 1개가 아니므로, 두 개의 문장을 SEP 토큰으로 구분해서 BERT에 입력하여 출력값의 첫번째 CLS 토큰이 두 문장의 관계를 나타내도록 학습시킨다.


두 번째는 single sentence classification task이다. 쉽게 생각하면 영화 리뷰 감성 분류와 같이 입력된 문서에 대해서 분류를 하는 유형으로 텍스트 분류 문제를 풀기 위해서 [CLS] 토큰의 위치인 출력층 위에 밀집층(Dense layer) 이라고 불리는 층들을 추가하여 분류에 대한 예측을 하게 된다.

Dense Layer는 [CLS] 토큰의 임베딩을 받아 해당 문장이 어떤 분류에 속하는지 예측하도록 한다.


세 번째는 question answering task이다.
BERT로 QA를 풀기 위해서는 질문과 본문이라는 두 개의 텍스트의 쌍을 입력받아야 한다. 이 태스크의 대표적인 데이터셋으로 SQuAD가 있습니다. 이 데이터셋을 푸는 방법은 질문과 본문을 입력받으면 본문의 일부분을 추출해서 질문에 답변하는 것입니다.

구체적으로는, 주어진 본문과 질문을 합쳐서 하나의 입력으로 만든다. 이때, [SEP] 토큰을 사용하여 본문과 질문을 구분한다. 문맥 안에서의 질문 응답 작업을 위해서는 [CLS] 토큰의 임베딩을 활용하여 정답의 시작과 끝 지점을 예측해야 한다.

모델은 입력으로 주어진 본문과 질문에 대해 [CLS] 토큰의 임베딩을 활용하여 정답의 시작과 끝 지점을 예측하도록 학습되고 이러한 학습된 모델은 시작과 끝 지점을 예측하고, 이를 기반으로 정답을 찾아낼 수 있게 되는 것이다.

마지막으로 single sentence tagging task이다.
대표적으로 문장의 각 단어에 품사를 태깅하는 품사 태깅 작업과 개체를 태깅하는 개체명 인식 작업이 있다. 출력층에서는 입력 텍스트의 각 토큰의 위치에 밀집층을 사용하여 분류에 대한 예측을 하게 된다.

profile
경희대학교 컴퓨터공학과

0개의 댓글