| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
- SVM
- CNN
- 생물정보학
- 블록체인
- 파이썬
- 자바
- Java
- 시그모이드
- BLaST
- 바이오인포매틱스
- COVID
- 서열정렬
- 이항분포
- 생명정보학
- 오류역전파
- 바이오파이썬
- Kaggle
- AP
- MERS
- 인공신경망
- RNN
- 캐글
- 인공지능
- AP Computer Science A
- bioinformatics
- ncbi
- 딥러닝
- 결정트리
- HMM
- 인공지능 수학
- Today
- Total
데이터 과학
BERT 개요 본문
BERT 원논문에는 사전학습과제 (MLM, NSP)와 파인튜닝 절차가 모두 정리되어 있습니다.
아래 링크를 참조하면 됩니다.
https://arxiv.org/pdf/1810.04805
논문 내용을 요약하면 다음과 같습니다.
BERT는 자연어를 이해하기 위해 고안된 딥러닝 모델로, Google AI Language 팀이 개발하였습니다. 기존의 언어 모델들은 문장을 왼쪽에서 오른쪽으로 읽거나, 오른쪽에서 왼쪽으로 읽는 식으로 한 방향만 고려하여 학습되었습니다. 그러나 자연어는 단어가 문장 속에서 어떤 의미를 가지는지 양쪽 문맥(all directions) 을 모두 보아야 정확하게 이해할 수 있습니다. BERT는 이러한 문제점을 해결하기 위해 Bidirectional Transformer(양방향 트랜스포머) 구조를 기반으로 학습하여, 단어의 의미를 양쪽 문맥에서 동시에 이해하도록 설계되었습니다
BERT는 두 가지 독특한 사전학습 방법을 사용합니다. 첫 번째는 Masked Language Model(MLM) 이며, 문장에서 임의로 단어를 가려(mask) 놓고 주변 문맥을 보고 가려진 단어를 맞히는 방식입니다. 이를 통해 모델은 문장의 앞뒤 정보를 모두 고려하여 단어의 의미를 이해하게 됩니다. 두 번째는 Next Sentence Prediction(NSP) 입니다. 이는 문장 A 다음에 문장 B가 실제로 이어지는 문장인지 판단하도록 학습하는 방식입니다. 이 학습은 문장 간의 관계를 이해하는 능력을 길러 주어, 질문 답변과 같은 두 문장 간 추론 작업에 매우 효과적입니다
BERT는 이렇게 사전학습을 거친 후, 다양한 작업에 맞게 미세조정(fine-tuning) 하는 방식으로 활용됩니다. 기존 모델들은 작업에 따라 구조를 바꾸는 복잡한 과정이 필요했지만, BERT는 사전학습된 모델 위에 출력층 하나만 추가하면 다양한 자연어 처리 문제에 적용할 수 있습니다. 예를 들어 문장 분류, 감정 분석, 질문에 대한 답 찾기, 문장 간 관계 판단 등이 있습니다. 이 방식은 모델 구조 변경 없이도 다양한 문제에 높은 성능을 보여 주는 장점이 있습니다
실험 결과, BERT는 GLUE, SQuAD, SWAG 등 여러 자연어 처리 벤치마크에서 기존 최고 성능을 크게 뛰어넘었습니다. 특히 질문에 대한 답을 텍스트에서 찾아내는 SQuAD 데이터셋에서는 기존 최고 모델보다 높은 정확도를 기록하였습니다. 이러한 결과는 BERT가 단어와 문장을 깊이 있게 이해하는 능력을 가지고 있으며, 다양한 자연어 처리 분야에서 강력하게 활용될 수 있다는 것을 보여줍니다.
결론적으로 BERT는 단방향이 아닌 양방향 문맥 이해를 통해 자연어 의미를 정확하게 파악하고, 단순한 구조 추가만으로 다양한 문제에 적용될 수 있는 범용성과 확장성을 가진 모델입니다. 이러한 특징을 통해 BERT는 이후 등장한 많은 자연어 처리 모델의 기반이 되었으며, 자연어 이해 분야에서 중요한 전환점을 만든 모델입니다.
그리고, BERT와 GPT, Gemini에 대한 간단한 설명입니다.
위에 설명한바와 같이 BERT는 Google에서 개발한 자연어 처리 모델로, 문장을 왼쪽에서 오른쪽으로만 읽거나 오른쪽에서 왼쪽으로만 읽는 이전 방식과 달리, 문장을 양쪽 방향에서 동시에 읽으며 의미를 이해하는 모델입니다.
이 방식 덕분에 단어 하나가 문장에서 어떤 역할을 하는지를 주변 문맥 전체를 보고 판단할 수 있습니다.
이를 위해 BERT는 두 가지 학습을 수행하는데,
첫 번째는 마스크드 언어 모델(MLM) 입니다. 문장의 일부 단어를 가리고, 그 가려진 단어를 문맥을 보고 추론하는 방식입니다. 두 번째는 다음 문장 예측(NSP) 입니다. 문장 A 다음에 문장 B가 실제로 이어지는지 맞추면서 문장 간 관계를 학습합니다. 이러한 사전학습을 거친 BERT는 단어·문장 이해 능력이 높아져 이후 질문 답변, 문장 분류 등 다양한 문제에 별도의 복잡한 설계 없이도 높은 성능을 냅니다
GPT는 BERT보다 이전에 나온 모델로, 문장을 왼쪽에서 오른쪽으로만 읽는 단방향 언어 모델입니다. 그래서 다음에 어떤 단어가 올지를 예측하는 데 뛰어나며, 글을 생성하는 작업에서 좋은 성능을 보입니다. 하지만 GPT는 한 방향에서만 문장을 읽기 때문에 문장을 이해하는 능력보다는 생성하는 능력이 강한 모델입니다.
Gemini는 Google이 2023년 이후 개발한 최신 모델로, 텍스트뿐 아니라 이미지, 음성, 영상까지 동시에 이해할 수 있는 멀티모달 모델입니다.
Gemini는 단순히 문장을 이해하는 수준을 넘어, 다양한 형태의 데이터를 결합하여 상황을 추론하고 새로운 결과를 만들어냅니다.
예를 들어, 문제 사진을 주고 설명하면 방법을 설명하는 것이 가능합니다.
정리하면, BERT는 문장을 깊게 이해하는 데 최적화된 모델, GPT는 문장 생성에 최적화된 모델, Gemini는 여러 데이터를 동시에 이해하고 종합하는 모델입니다. BERT는 이해 중심, GPT는 생성 중심, Gemini는 이해 + 생성 + 다양한 데이터 처리라는 확장된 개념입니다. 이 때문에 실제 연구나 산업에서 세 모델은 서로 경쟁하기보다는 목적에 맞게 선택되어 사용됩니다.
모델 방향성 특징 잘하는 일
| BERT | 양방향 이해 | 문맥을 가장 깊게 파악함 | 문장 분류, 정답 찾기, 의미 분석 |
| GPT | 한 방향 생성 | 다음 단어 생성에 강함 | 글쓰기, 답변 생성 |
| Gemini | 멀티모달 | 텍스트 + 이미지 + 영상 이해 | 다양한 데이터를 결합한 문제 해결 |
Bert 예제
text = "스토리가 시간이 아깝네요."
간단하게 Bert로 작성한 자연어처리 관련 예제입니다.
영화 감상평을 읽고 내용이 긍정인지 부정인지 알아보는 예제입니다.
예시)
아래는 Gemini / GPT / BERT를 같은 데이터로 비교하는 초간단 실험 스크립트입니다.
작업은 이진 감성 분류(긍정/부정)이며, 각 모델은 다음 방식으로 사용합니다.
- BERT: 허깅페이스의 한국어 포함 멀티링궐 사전학습 모델 기반 사전학습된 감성모델 사용입니다.
- GPT: OpenAI Chat Completions API로 제로샷 프롬프트 분류입니다.
- Gemini: Google Generative AI API로 제로샷 프롬프트 분류입니다.
!pip install transformers datasets torch openai google-generativeai
# compare_gemini_gpt_bert.py
# pip install transformers datasets torch openai google-generativeai
import os
import time
import re
from typing import List, Tuple
# --- 1) 데이터: 한국어 문장 + 정답 레이블(1=긍정, 0=부정) 입니다.
DATA = [
("이 영화 정말 재미있었어요", 1),
("배우 연기는 좋았지만 너무 지루했어요", 0),
("감동적이고 음악도 훌륭했어요", 1),
("스토리가 엉성하고 시간 낭비였어요", 0),
("생각보다 훨씬 몰입됐어요", 1),
("완전 별로였고 다시 보고 싶지 않아요", 0),
]
# --- 2) 평가 유틸리티 입니다.
def accuracy(golds: List[int], preds: List[int]) -> float:
return sum(int(g == p) for g, p in zip(golds, preds)) / len(golds)
def normalize_label(text: str) -> int:
"""모델 출력에서 긍/부정 레이블을 1/0으로 정규화합니다."""
t = text.strip().upper()
if re.search(r"POS|긍정|POSITIVE|좋|훌륭|감동|재미|추천", t):
return 1
if re.search(r"NEG|부정|NEGATIVE|별로|지루|최악|다시는", t):
return 0
# 모호하면 기본적으로 부정으로 처리합니다.
return 0
# --- 3) BERT: 허깅페이스 파이프라인으로 간단 감성분류 입니다.
# 한국어 포함 멀티링궐 감성 모델(별점 1~5)을 사용하고 4~5=긍정, 1~2=부정으로 매핑합니다.
from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
def run_bert(texts: List[str]) -> List[int]:
model_id = "nlptown/bert-base-multilingual-uncased-sentiment"
tok = AutoTokenizer.from_pretrained(model_id)
mdl = AutoModelForSequenceClassification.from_pretrained(model_id)
clf = pipeline("sentiment-analysis", model=mdl, tokenizer=tok)
preds = []
for t in texts:
out = clf(t, truncation=True, max_length=256)[0]["label"] # e.g., "4 stars"
stars = int(out.split()[0])
preds.append(1 if stars >= 4 else 0)
return preds
# --- 4) GPT: OpenAI Chat Completions 제로샷 분류 입니다.
# 환경변수 OPENAI_API_KEY 가 필요합니다.
from openai import OpenAI
def run_gpt(texts: List[str]) -> List[int]:
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
system = "You are a strict sentiment classifier. Answer with only one token: POSITIVE or NEGATIVE."
preds = []
for t in texts:
prompt = f"Classify the sentiment of this Korean sentence as POSITIVE or NEGATIVE only:\n\"{t}\""
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role":"system","content":system},
{"role":"user","content":prompt}],
temperature=0
)
choice = resp.choices[0].message.content
preds.append(normalize_label(choice))
return preds
# --- 5) Gemini: Google Generative AI 제로샷 분류 입니다.
# 환경변수 GOOGLE_API_KEY 가 필요합니다.
import google.generativeai as genai
def run_gemini(texts: List[str]) -> List[int]:
genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))
model = genai.GenerativeModel("gemini-1.5-flash")
system = "You are a strict sentiment classifier. Reply only POSITIVE or NEGATIVE."
preds = []
for t in texts:
prompt = f"{system}\nClassify the sentiment of this Korean sentence as POSITIVE or NEGATIVE only:\n\"{t}\""
resp = model.generate_content(prompt)
out = resp.text or ""
preds.append(normalize_label(out))
return preds
# --- 6) 실행 및 비교 입니다.
if __name__ == "__main__":
texts = [x[0] for x in DATA]
golds = [x[1] for x in DATA]
# BERT
t0 = time.time()
bert_preds = run_bert(texts)
t1 = time.time()
# GPT
t2 = time.time()
try:
gpt_preds = run_gpt(texts)
except Exception as e:
print("[GPT] 실행 오류:", e)
gpt_preds = [0]*len(texts)
t3 = time.time()
# Gemini
t4 = time.time()
try:
gem_preds = run_gemini(texts)
except Exception as e:
print("[Gemini] 실행 오류:", e)
gem_preds = [0]*len(texts)
t5 = time.time()
print("\n=== 결과 요약 ===")
print(f"BERT acc={accuracy(golds, bert_preds):.2f}, 시간={t1 - t0:.2f}s")
print(f"GPT acc={accuracy(golds, gpt_preds):.2f}, 시간={t3 - t2:.2f}s")
print(f"Gemini acc={accuracy(golds, gem_preds):.2f}, 시간={t5 - t4:.2f}s")
print("\n정답:", golds)
print("BERT :", bert_preds)
print("GPT :", gpt_preds)
print("Gem :", gem_preds)
-------------------------------
BERT acc=0.67, 시간=10.41s
GPT acc=0.50, 시간=0.00s
Gemini acc=0.50, 시간=0.00s
정답: [1, 0, 1, 0, 1, 0]
BERT : [1, 0, 1, 0, 0, 1]
GPT : [0, 0, 0, 0, 0, 0]
Gem : [0, 0, 0, 0, 0, 0]
BERT는 이미 감성에 맞춰 사전학습된 모델을 사용하므로, 소량 데이터에서도 안정적으로 동작하는 경향이 있습니다.
GPT / Gemini는 제로샷 프롬프트로 분류하므로, 프롬프트 지시를 명확히 해야 하며 “POSITIVE / NEGATIVE만 출력” 같은 엄격한 출력 제약을 걸어주는 것이 중요합니다.
동일 데이터에서 정확도와 처리 시간을 함께 출력하므로, 모델별 정확도–속도–비용의 감각을 얻는 데 도움이 됩니다.