딥러닝과 자연어 처리(NLP)가 발전하면서 다양한 모델들이 등장하였고, 그중 BERT(Bidirectional Encoder Representations from Transformers)는 오늘날 NLP에서 가장 영향력 있는 모델 중 하나로 자리 잡았습니다. 이번 강좌에서는 허깅페이스의 트랜스포머 라이브러리를 활용하여 BERT를 앙상블 모델로 구현하기 위해 데이터세트를 준비하는 방법에 대해 다루겠습니다.
1. 앙상블 학습의 개념
앙상블 학습이란 여러 개의 모델을 결합하여 성능을 개선하는 기법입니다. 여러 모델의 예측 결과를 조합함으로써 각각의 모델이 가지는 단점을 보완할 수 있습니다. 앙상블 학습은 일반적으로 두 가지 방식으로 이루어집니다:
- 배깅(Bagging): 반복적인 샘플링을 통해 여러 모델을 훈련시키고, 각 모델의 예측 결과를 평균내거나 다수결 투표를 통해 최종 예측을 생성합니다.
- 부스팅(Boosting): 이전 모델의 오차를 학습하는 방식으로 새로운 모델을 순차적으로 훈련시킵니다. 대표적인 방법으로는 XGBoost와 AdaBoost가 있습니다.
이번 강좌에서는 BERT 모델을 사용하여 다수의 모델을 조합해 앙상블 학습을 구현하는 데 중점을 두겠습니다.
2. 허깅페이스 트랜스포머 라이브러리 소개
허깅페이스의 트랜스포머 라이브러리는 다양한 사전 훈련된 언어 모델을 손쉽게 사용할 수 있도록 도와주는 파이썬 라이브러리입니다. BERT 모델뿐 아니라 GPT, T5 등의 다양한 모델들이 포함되어 있어 NLP 태스크를 수행하는 데 유용합니다. 이 라이브러리의 주요 기능은 다음과 같습니다:
- 사전 훈련된 모델의 손쉬운 다운로드 및 활용
- 모델과 tokenizer의 통합 사용
- 간단한 API로 다양한 NLP 태스크(분류, 생성 등) 수행 가능
이제 BERT 모델을 활용하기 위해 필요한 데이터셋을 준비해보겠습니다.
3. 데이터셋 준비
우선, 앙상블 모델을 훈련하기 위해 사용할 데이터셋을 준비해야 합니다. BERT 모델을 학습하기 위해 일반적으로는 텍스트와 라벨이 필요한 데이터셋이 필요합니다. 예를 들어, 감정 분석 모델을 훈련한다고 가정할 때 다음과 같은 형식의 데이터가 필요합니다:
| 텍스트 | 라벨 |
|------------------|------|
| "좋아요!" | 1 |
| "실망했어요" | 0 |
| "최고의 경험!" | 1 |
| "다시는 안 할래요" | 0 |
데이터를 준비한 후 CSV 파일로 저장해보겠습니다. 이 예시에서는 파이썬의 pandas 라이브러리를 활용하여 데이터를 CSV 형식으로 저장합니다.
import pandas as pd
# 예시 데이터 생성
data = {
'text': [
'좋아요!',
'실망했어요',
'최고의 경험!',
'다시는 안 할래요'
],
'label': [1, 0, 1, 0]
}
# 데이터프레임으로 변환
df = pd.DataFrame(data)
# CSV 파일로 저장
df.to_csv('sentiment_data.csv', index=False, encoding='utf-8-sig')
4. 데이터셋 로딩 및 전처리
CSV 파일로 저장된 데이터셋을 로딩하고, BERT 모델에 맞게 전처리해야 합니다. 여기서는 허깅페이스의 ‘transformers’ 라이브러리에서 제공하는 tokenizer를 사용하여 데이터를 전처리합니다. 먼저 필요한 라이브러리를 설치하고 로딩하겠습니다.
!pip install transformers
!pip install torch
이제 파이썬 코드로 데이터셋을 로딩하고 전처리할 수 있습니다.
from transformers import BertTokenizer
# 토크나이저 로드
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
# 데이터셋 로딩
df = pd.read_csv('sentiment_data.csv')
# 텍스트 전처리
encodings = tokenizer(df['text'].tolist(), truncation=True, padding=True, max_length=128)
# 텍스트와 라벨 확인
print(encodings['input_ids'])
print(df['label'].tolist())
위 코드에서 ‘input_ids’는 각 단어가 BERT 모델에 입력되기 위해 매핑된 인덱스 값이며, 라벨은 예측하고자 하는 목표입니다. 모델을 훈련하기 위해 데이터셋의 형태로 변환해야 합니다.
5. 데이터 로더 생성
데이터를 모델에 전달하기 위해 PyTorch의 DataLoader를 사용하여 배치 단위로 데이터를 리턴하는 클래스를 만들어야 합니다.
import torch
from torch.utils.data import Dataset, DataLoader
class SentimentDataset(Dataset):
def __init__(self, encodings, labels):
self.encodings = encodings
self.labels = labels
def __getitem__(self, idx):
item = {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}
item['labels'] = torch.tensor(self.labels[idx])
return item
def __len__(self):
return len(self.labels)
# 데이터셋 객체 만들기
dataset = SentimentDataset(encodings, df['label'].tolist())
# DataLoader 생성
train_loader = DataLoader(dataset, batch_size=2, shuffle=True)
6. 모델 훈련
모델을 훈련시키기 위해 BERT 모델을 로드하고, 옵티마이저와 손실 함수를 설정합니다. 훈련 및 평가 과정에서 BERT 모델을 사용하게 됩니다.
from transformers import BertForSequenceClassification, AdamW
# 모델 로드
model = BertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)
# 옵티마이저 설정
optimizer = AdamW(model.parameters(), lr=5e-5)
# GPU 사용 시, 모델을 GPU로 이동
if torch.cuda.is_available():
model = model.cuda()
# 모델 훈련
model.train()
for epoch in range(3): # 에폭 수
for batch in train_loader:
optimizer.zero_grad()
# GPU 사용 시, 배치를 GPU로 이동
if torch.cuda.is_available():
batch = {k: v.cuda() for k, v in batch.items()}
outputs = model(**batch)
loss = outputs.loss
loss.backward()
optimizer.step()
print(f'Epoch {epoch}, Loss: {loss.item()}')
모델 훈련 시 출력된 손실 값은 모델이 얼마나 잘 학습하고 있는지를 나타내는 지표입니다. 손실 값이 낮아질수록 모델의 예측 성능이 좋아진다고 볼 수 있습니다.
7. 앙상블 모델 구축
여러 BERT 모델을 훈련시킨 후 앙상블하는 방법에는 여러 가지가 있습니다. 여기서는 간단한 방법으로 모델의 예측 결과를 평균내는 방식을 사용해보겠습니다.
predictions = []
# 앙상블할 모델 수 설정
model_count = 3
for i in range(model_count):
model = BertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)
# 모델 훈련은 생략(위에서 설명한 훈련 코드 사용)
# ...
# 테스트 데이터에 대한 예측
model.eval()
with torch.no_grad():
outputs = model(**batch)
logits = outputs.logits
predictions.append(logits.softmax(dim=-1))
# 예측 평균
final_predictions = torch.mean(torch.stack(predictions), dim=0)
predicted_labels = final_predictions.argmax(dim=-1).tolist()
8. 결과 검증
모델의 예측력을 평가하기 위해, 실제 라벨과의 비교를 통해 정확도를 계산할 수 있습니다. 다음은 정확도를 계산하고 출력하는 방법입니다.
from sklearn.metrics import accuracy_score
# 실제 라벨
true_labels = df['label'].tolist()
# 정확도 계산
accuracy = accuracy_score(true_labels, predicted_labels)
print(f'Accuracy: {accuracy * 100:.2f}%')
9. 최종 정리
이번 강좌에서는 허깅페이스의 트랜스포머 라이브러리를 활용하여 BERT 모델을 앙상블로 구성하는 방법에 대해 알아보았습니다. 데이터세트를 준비하고, 전처리 및 DataLoader 생성을 통해 BERT 모델을 훈련시켰습니다. 마지막으로 여러 모델의 예측 결과를 앙상블하여 최종 결과를 도출하였습니다.
딥러닝 모델의 성능 향상을 위해 앙상블 기법을 적용하는 것은 매우 효과적인 방법입니다. 이 강좌에서 배운 내용을 바탕으로 다양한 모델과 데이터셋에 실험해 보길 권장합니다.