brunch

You can make anything
by writing

C.S.Lewis

by Tristan Feb 23. 2020

BERT란 무엇인가?

- Attention Is All You Need!

BERT의 기본 구조 (출처 : http://jalammar.github.io/illustrated-bert/)

위의 그림에서와 같이 BERT는 구글에서 개발한 자연어 처리 신경망 구조이며

기본구조는 아래의 Transformer라는 구조에서 Encoder를 적층시켜 만들었다.

Transformer의 구조 (출처 : http://jalammar.github.io/illustrated-transformer/)

BERT는 이 구조를 기반으로 다음과 같은 Task를 학습시켰다.

   1. 다음문장 예측(NSP)

   2. 문장에서 가려진 단어(토큰)을 예측(MLM)


    위와 같은 학습을 시킨 뒤 학습시킨 이 모델을 가지고 다른 특수한 자연어 처리 문제를 위해서 학습을 시키면 빠른 속도로 좋은 결과를 낸다. BERT란 자연어 처리에 있어서 일반적인 문제에 빠르게 적용가능한 전이학습 모델을 만든 것이다.


Self-Attention 알고리즘

    Transformer에서 가져온 중요한 구조는 Self-Attention 알고리즘이다. BERT의 Encoder Layer는 다음과 같이 두 가지로 나뉜다. Feed Forward 부분은 그저 Dense Layer를 각각의 토큰에 대해서 취한 결과를 내놓는 것이다. 따라서 Encoder의 핵심은 Self-Attention 부분에 있다.

Self-Attention은 진정으로 Bidirectional한 학습을 위해서 한쪽 방향에서 다른쪽 방향으로 토큰을 처리하는 부분이 없이 한번에 Contextual한 정보를 얻는 방식으로 BERT 모델이 성공적으로 자연어 처리를 할 수 있게 하는 핵심 구조이다. Self-Attention은 한 단어와 나머지 다른단어의 관계정보를 처리할 수 있도록 하기 위해 존재한다.


출처 : http://jalammar.github.io/illustrated-transformer/

 Self-Attention의 과정을 간단하게 설명하면 다음과 같다.

1. 입력된 토큰에 대해서 각각 독립적으로 학습가능한 Query, Key, Value라는 벡터를 할당한다. 

2. 먼저 한 토큰의 Query와 나머지 토큰의 Key값을 모두 곱한다. 결과는 각 토큰별로 1개의 실수로 나온다.(Score란이 이것을 의미)

3. 이 곱한 값들을 8로 나눈다. (필자는 이것의 특별한 이유는 찾지 못했으나 결과가 좋아진다고 알고 있다.)

4. 그 뒤 Softmax를 통해서 각 토큰별로 할당된 8로 나누어진 Score값을 확률적으로 바꾸어 모두 합이 1이 되도록 한다.

5. Softmax를 통해 확률화된 값을 각각의 토큰의 Value값과 곱한다.

6. 위에서 계산된 결과로 나온 확률과 곱해진 Value값을 모두 더한 값이 1토큰에 대한 Attention 결과값이다.


위의 과정을 토큰마다 반복하면 1개의 Head를 갖는 Self-Attention이 된다. BERT에서는 Contextual한 정보를 다양한 차원에서 처리하기 위해서 Multi-Headed Self-Attention을 하는데 이것은 그저 Query, Key, Value를 여러개로 늘려서 같은 계산을 반복하는 것이다.


Input Of BERT

BERT의 Input과 Output은 위와 같다. 3가지의 요소를 입력해줘야한다.


 먼저 각각의 단어를 자주 등장하는 단어의 부분으로 쪼개서 ##을 붙혀 Tokenization을 한다. (예컨데 위에서 playing = play + ##ing) 맨 첫단어가 아닌 부분단어일 경우 ##을 붙히지 않는다. 이러한 방식을 WordPiece방식이라고 한다. 자세한 내용은 다음 링크를 참조바란다. 

두번째는 Segment Embedding으로 문장을 2개 입력하는데 2개의 문장을 구분하기 위해서 보통 [CLS]에서 첫번째 [SEP]까지 0을 넣고 그 다음 토큰부터 두번째 [SEP]까지 1을 넣는다. (Fine-Tuning시 문장이 1개라면 모두 같은 숫자 0으로 놓는다.)


세번째는 Positional Embedding이다. 이 부분은 BERT가 학습시에 각 토큰의 위치를 알려주기 위해서 필요하다. (맨 아래 참고 2의 링크를 확인해보면 Positional Embedding에 대해서 나와있다. 개인적인 경험으로 Kaggle에서 BERT를 이용한 코드들에서는 그냥 모두 0을 집어 넣기도 한다.)


Output Of BERT

1. 다음 문장 예측하기(NSP)

BERT는 다음문장을 예측하기 위해서 맨 첫번째 토큰인 [CLS]의 출력부에서 입력받은 첫문장이 두번재 문장과 연결되는 문장인지를 판별하는 것으로 학습시켰다. (아래 그림 참조)

2. 가려진 토큰 예측

맨 앞의 [CLS]토큰을 제외한 BERT의 각 토큰마다 개별적인 Fully Connected Layer + Softmax Layer을 거쳐 Tokenize시에 이용했던 약 30000개의 Vocab List에서 단어를 선택하도록 같은 수의 차원을 가진 백터를 출력하고 가장 큰 확률을 가진 토큰을 출력한다. 또한 BERT는 Masked가된 토큰 뿐만 아니라 Masked가 되지 않은 토큰까지 맞추도록 한다.

출처 : https://medium.com/@jonathan_hui/nlp-bert-transformer-7f0ac397f524


참고 :  

1. http://jalammar.github.io/illustrated-transformer/

2. https://medium.com/@jonathan_hui/nlp-bert-transformer-7f0ac397f524

3. http://docs.likejazz.com/bert/


브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari