728x90
BERT?
어떤 단어를 가리고(Mask), 그것을 예측하기 위해 양방향으로 전체 문장을 분석하는 학습 모

 

BERT는 "Bidirectional Encoder Representations from Transformers"의 약자로, 이름에서 알 수 있듯이 트랜스포머 아키텍처를 사용하여 사전 학습된 언어 모델이다.

 

BERT의 가장 큰 특징은 양방향(bidirectional) 언어 모델이라는 점이다. 이전의 모델들은 문맥을 좌측에서 우측으로 순차적으로 처리하는 단방향 언어 모델이었다. 반면 BERT는 입력 문장의 모든 단어를 동시에 보며각 단어의 좌우 문맥을 모두 고려하여 단어의 의미를 학습한다.

 

BERT는 대규모 텍스트 코퍼스를 사용하여 사전 학습되어 다양한 NLP 작업에서 성능이 우수하다는 것이 입증되었다. BERT를 기반으로 한 다양한 변형 모델들도 개발되었고, 전이 학습(transfer learning)을 통해 작은 데이터셋에서도 좋은 성능을 발휘할 수 있다.

 

다음은 BERT를 기반으로 한 몇 가지 주요 모델이다.

 

  1. RoBERTa(Robustly Optimized BERT Pretraining Approach):
    RoBERTa는 BERT의 개선된 버전으로, 더 큰 데이터셋과 더 오래 학습시킨 모델이다. BERT와 비교했을 때 미세 조정(fine-tuning) 단계에서 성능이 향상되었고, 다양한 자연어 처리 작업에서 우수한 성능을 보인다.

  2. DistilBERT:
    DistilBERT는 BERT의 경량화 버전이다. 작은 모델 크기와 빠른 추론 속도를 제공하면서도, 원본 BERT와 비슷한 성능을 유지한다. 주로 자원이 제한된 환경에서 사용된다.
  3. ELECTRA (Efficiently Learning an Encoder that Classifies Token Replacements Accurately):
    ELECTRA는 BERT 기반이지만 다른 방식으로 작동한다. 생성자와 판별자라는 두 개의 신경망을 사용하여 생성자는 무작위로 단어를 마스킹하고, 판별자는 이를 식별하도록 사전 학습되었다. 이 모델은 BERT와 유사한 성능을 발휘하면서도 훨씬 더 효율적인 학습을 가능하게 한다.
  4. ALBERT(A Lite BERT):
    ALBERT는 BERT의 파라미터 공유와 규모를 줄여 모델의 효율성을 향상시킨 모델이다. 더 작은 모델 크기와 빠른 학습을 제공하면서도 성능 손실을 최소화한다.

이외에도 BERT를 기반으로 한 다양한 변형 모델들이 개발되었으며, 이들은 각자의 특징과 장점을 가지고 있다.

 

from transformers import AutoModel, AutoTokenizer, BertTokenizer

MODEL_NAME = "bert-base-multilingual-cased"
model = AutoModel.from_pretrained(MODEL_NAME)
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)

sen_1 = "오늘 점심에 배가 너무 고파서 밥을 너무 많이 먹었다."
sen_2 = "오늘 점심에 배가 고파서 밥을 많이 먹었다."
sen_3 = "오늘 배가 너무 고파서 점심에 밥을 너무 많이 먹었다."
sen_4 = "오늘 점심에 배가 고파서 비행기를 많이 먹었다."
sen_5 = "어제 저녁에 밥을 너무 많이 먹었더니 배가 부르다."
sen_6 = "이따가 오후 7시에 출발하는 비행기가 3시간 연착 되었다고 하네요."

bert_sen_1 = tokenizer(sen_1, return_tensors="pt")
bert_sen_2 = tokenizer(sen_2, return_tensors="pt")
bert_sen_3 = tokenizer(sen_3, return_tensors="pt")
bert_sen_4 = tokenizer(sen_4, return_tensors="pt")
bert_sen_5 = tokenizer(sen_5, return_tensors="pt")
bert_sen_6 = tokenizer(sen_6, return_tensors="pt")

sen_1_outputs = model(**bert_sen_1)
sen_1_pooler_output = sen_1_outputs.pooler_output

sen_2_outputs = model(**bert_sen_2)
sen_2_pooler_output = sen_2_outputs.pooler_output

sen_3_outputs = model(**bert_sen_3)
sen_3_pooler_output = sen_3_outputs.pooler_output

sen_4_outputs = model(**bert_sen_4)
sen_4_pooler_output = sen_4_outputs.pooler_output

sen_5_outputs = model(**bert_sen_5)
sen_5_pooler_output = sen_5_outputs.pooler_output

sen_6_outputs = model(**bert_sen_6)
sen_6_pooler_output = sen_6_outputs.pooler_output

from torch import nn

cos_sim = nn.CosineSimilarity(dim=1, eps=1e-6)

print(f"의미가 유사한 문장 간 유사도 계산 (조사 생략): (sen_1, sen_2) = {cos_sim(sen_1_pooler_output, sen_2_pooler_output)}")
print(f"의미가 유사한 문장 간 유사도 계산 (순서 변경): (sen_1, sen_3) = {cos_sim(sen_1_pooler_output, sen_3_pooler_output)}")
print(f"문장 내 단어를 임의의 단어로 치환한 문장과 원본 문장 간 유사도 계산: (sen_2, sen_4) = {cos_sim(sen_2_pooler_output, sen_4_pooler_output)}")
print(f"의미는 다르지만 비슷한 주제를 가지는 문장 간 유사도 계산: (sen_1, sen_5) = {cos_sim(sen_1_pooler_output, sen_5_pooler_output)}")
print(f"의미가 서로 다른 문장 간 유사도 계산: (sen_1, sen_6) = {cos_sim(sen_1_pooler_output, sen_6_pooler_output)}")

"""
의미가 유사한 문장 간 유사도 계산 (조사 생략): (sen_1, sen_2) = tensor([0.9901], grad_fn=<SumBackward1>)
의미가 유사한 문장 간 유사도 계산 (순서 변경): (sen_1, sen_3) = tensor([0.9972], grad_fn=<SumBackward1>)
문장 내 단어를 임의의 단어로 치환한 문장과 원본 문장 간 유사도 계산: (sen_2, sen_4) = tensor([0.9916], grad_fn=<SumBackward1>)
의미는 다르지만 비슷한 주제를 가지는 문장 간 유사도 계산: (sen_1, sen_5) = tensor([0.9744], grad_fn=<SumBackward1>)
의미가 서로 다른 문장 간 유사도 계산: (sen_1, sen_6) = tensor([0.9533], grad_fn=<SumBackward1>)
"""

 

 

 

728x90

+ Recent posts