728x90
BERT?
어떤 단어를 가리고(Mask), 그것을 예측하기 위해 양방향으로 전체 문장을 분석하는 학습 모델
BERT는 "Bidirectional Encoder Representations from Transformers"의 약자로, 이름에서 알 수 있듯이 트랜스포머 아키텍처를 사용하여 사전 학습된 언어 모델이다.
BERT의 가장 큰 특징은 양방향(bidirectional) 언어 모델이라는 점이다. 이전의 모델들은 문맥을 좌측에서 우측으로 순차적으로 처리하는 단방향 언어 모델이었다. 반면 BERT는 입력 문장의 모든 단어를 동시에 보며, 각 단어의 좌우 문맥을 모두 고려하여 단어의 의미를 학습한다.
BERT는 대규모 텍스트 코퍼스를 사용하여 사전 학습되어 다양한 NLP 작업에서 성능이 우수하다는 것이 입증되었다. BERT를 기반으로 한 다양한 변형 모델들도 개발되었고, 전이 학습(transfer learning)을 통해 작은 데이터셋에서도 좋은 성능을 발휘할 수 있다.
다음은 BERT를 기반으로 한 몇 가지 주요 모델이다.
- RoBERTa(Robustly Optimized BERT Pretraining Approach):
RoBERTa는 BERT의 개선된 버전으로, 더 큰 데이터셋과 더 오래 학습시킨 모델이다. BERT와 비교했을 때 미세 조정(fine-tuning) 단계에서 성능이 향상되었고, 다양한 자연어 처리 작업에서 우수한 성능을 보인다. - DistilBERT:
DistilBERT는 BERT의 경량화 버전이다. 작은 모델 크기와 빠른 추론 속도를 제공하면서도, 원본 BERT와 비슷한 성능을 유지한다. 주로 자원이 제한된 환경에서 사용된다. - ELECTRA (Efficiently Learning an Encoder that Classifies Token Replacements Accurately):
ELECTRA는 BERT 기반이지만 다른 방식으로 작동한다. 생성자와 판별자라는 두 개의 신경망을 사용하여 생성자는 무작위로 단어를 마스킹하고, 판별자는 이를 식별하도록 사전 학습되었다. 이 모델은 BERT와 유사한 성능을 발휘하면서도 훨씬 더 효율적인 학습을 가능하게 한다. - 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
'자연어 처리(NLP) 공부' 카테고리의 다른 글
자연어 처리 진행 순서 (0) | 2023.06.02 |
---|---|
여러 가지 자연어 처리 Task를 알아보자! (0) | 2023.06.02 |
[NLP 스터디] Transformer의 구조를 알아보자 (0) | 2023.05.29 |
NLP, NLU, NLG (0) | 2023.05.26 |
[NLP 스터디] Scaled Dot-Product Attention (0) | 2023.05.22 |