HardSkills/ML,DL

파인튜닝(Fine tuning)이란 무엇인가?

공유는 즐거워 2024. 3. 13. 16:39

파인튜닝은 사전 훈련된 모델을 특정 작업이나 데이터셋에 최적화하기 위해 추가 훈련을 수행하는 과정입니다. 이는 전이 학습(Transfer Learning)의 한 예로, 이미 대량의 데이터로 훈련된 모델의 지식을 활용하여 새로운, 비교적 작은 데이터셋에 대해 높은 성능을 달성할 수 있게 해줍니다. 파인튜닝을 하는 이유는 다음과 같습니다

  1. 시간 및 자원 절약: 대규모 데이터셋을 처음부터 훈련시키는 것은 많은 시간과 계산 자원을 필요로 합니다. 사전 훈련된 모델을 사용하면 이러한 비용을 크게 줄일 수 있습니다.
  2. 데이터 부족 문제 해결: 특정 작업에 대한 대량의 레이블이 지정된 데이터를 확보하기 어려울 수 있습니다. 사전 훈련된 모델은 일반적인 지식을 이미 학습했기 때문에, 작은 데이터셋으로도 효과적인 학습이 가능합니다.
  3. 성능 향상: 사전 훈련된 모델은 다양한 언어 패턴, 문맥, 일반적인 지식을 이미 이해하고 있습니다. 이를 기반으로 특정 작업에 맞게 조정함으로써, 더 높은 정확도와 성능을 달성할 수 있습니다.

이제, 예시 데이터셋을 100개의 샘플을 가진 데이터셋으로 확장하는 방법을 보여드리겠습니다. 여기서는 간단한 긍정/부정 텍스트 분류 작업을 위한 데이터셋을 생성하는 코드 예시를 제공하겠습니다.

  • 모델 선택
    BERT (Bidirectional Encoder Representations from Transformers)는 다양한 NLP 작업에 널리 사용되는 모델입니다. 우리는 Hugging Face의 transformers 라이브러리를 통해 사전 훈련된 BERT 모델을 가져와서 파인튜닝할 것입니다.

  • 파인튜닝 스크립트 작성
    다음은 텍스트 분류를 위한 파인튜닝 스크립트의 기본 구조입니다. 이 예시에서는 간단한 데이터셋을 사용하며, 실제 데이터셋으로 작업할 때는 데이터 로딩 및 전처리 부분을 자신의 데이터에 맞게 수정해야 합니다.

import pandas as pd
from sklearn.model_selection import train_test_split
from datasets import Dataset
import random

# 예시 데이터 생성
texts = ["This product has been an amazing addition to my kitchen."]*50 + \
        ["I'm very disappointed with the purchase. Would not recommend."]*50
labels = [1]*50 + [0]*50  # 1: 긍정, 0: 부정

# 데이터 섞기
data = list(zip(texts, labels))
random.shuffle(data)
texts, labels = zip(*data)

# 데이터프레임 생성
df = pd.DataFrame({'text': texts, 'label': labels})

# 데이터셋 분할
train_df, test_df = train_test_split(df, test_size=0.2)

# Hugging Face의 datasets 라이브러리 형식으로 변환
train_dataset = Dataset.from_pandas(train_df)
test_dataset = Dataset.from_pandas(test_df)

# 토크나이저와 모델 로딩
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertForSequenceClassification.from_pretrained('bert-base-uncased')

# 토큰화 함수
def tokenize_function(examples):
    return tokenizer(examples['text'], padding="max_length", truncation=True)

# 데이터셋에 토큰화 적용
tokenized_train_dataset = train_dataset.map(tokenize_function, batched=True)
tokenized_test_dataset = test_dataset.map(tokenize_function, batched=True)

# 훈련 설정
training_args = TrainingArguments(
    output_dir='./results',          # 모델과 체크포인트 저장 디렉토리
    num_train_epochs=3,              # 총 훈련 에포크
    per_device_train_batch_size=8,   # 훈련 배치 크기
    per_device_eval_batch_size=8,    # 평가 배치 크기
    warmup_steps=500,                # 러닝레이트 웜업에 사용할 스텝 수
    weight_decay=0.01,               # 가중치 감소율
    logging_dir='./logs',            # 로그 저장 디렉토리
    evaluation_strategy="epoch",     # 에폭마다 평가
)

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_train_dataset,
    eval_dataset=tokenized_test_dataset,
)

# 모델 훈련
trainer.train()