책 리뷰/101가지 문제로 배우는 딥러닝 허깅페이스 트랜스포머
02장. DistilBERT 파인튜닝 및 평가 (문제12~13)
조조링
2024. 11. 26. 01:33
728x90
반응형
문제12. Trainer 클래스 사전학습
문제4부터 11까지의 과정에 기반한 Trainer클래스를 인스턴스화하고 파인튜닝하세요. 키워드 인수로 model, args, train_dataset, eval_dataset을 명확하게 전달하세요. 그리고 파인튜닝 전후에 다음 세 문장 각각의 극성 판별 결과를 비교하세요.
1. "I feel fantastic"
2. "My life is going something wrong"
3. "I have not figured out what the chosen title has to do with the movie"
먼저 파인튜닝 전에 세 문장의 극성 판별 결과는 다음과 같다.
여기서 파인튜닝을 하지 않은 모델이 두,세 번째 입력 문장 극성을 잘못 판정하고 있음에 유의하자.
# 파인튜닝 이전에 세 입력 문장 극성 판별
# 이는 한국어판을 취해 추가된 코드임
input_tokens = tokenizer(["I feel fantastic", "My life is going something wrong", "I have not figured out what the chosen title has to do with the movie."], truncation=True, padding=True)
# 입력 문장 토크나이징 결과(input_tokens)에 담긴 input_ids를 모델에 투입
# 그리고 모델 출력 결과를 GPU로 전송하며 값은 변수 outputs에 저장
outputs = model(torch.tensor(input_tokens['input_ids']).to(device))
# 레이블 딕셔너리 생성
label_dict = {1:'positive', 0:'negative'}
# outputs 변수에 담긴 logits 값을 행 단위, 즉 입력 문장 단위로 가장 큰 값 위치(인덱스) 추출
# 그 결과값(인덱스)을 cpu로 넘기고 넘파이 타입으로 변경 후, 인덱스에 매칭되는 레이블 출력
print([label_dict[i] for i in torch.argmax(outputs['logits'], axis=1).cpu().numpy()])
# ['positive', 'positive', 'positive']
파인튜닝 절차는 Trainer.train()을 사용하면 쉽게 할 수 있다.
매번 임의로 주어지는 가중치를 가지고 실행되는 딥러닝 모델의 특성상, Training Loss는 실행 시마다 결과가 약간 달라질 수 있다.
# 런타임 약 4 혹은 5분 소요
# 딥러닝 모델의 특성상 결과가 매번 약간 다르게 나올 수 있슴
from transformers import Trainer
trainer = Trainer(
model=model, # 사전학습 모델 인스턴스화
args=training_args, # TrainingArguments에 정의한 하이퍼 파라미터값 가져오기
train_dataset=train_dataset, # 학습 데이터세트
eval_dataset=val_dataset # evaluation 데이터세트
)
trainer.train()
8회의 에포크 동안의 학습을 수행 전후로, 원래 [긍정, 긍정, 긍정]으로 잘못 판정되었던 것이 [긍정, 부정, 부정]으로 올바르게 판별됐다. 여기서, Epoch는 전체 데이터세트를 모델에 반복해서 투입하는 횟수를 의미한다.
# Trainer.train()에 의한 파인튜팅 이후 세 입력 문장 극성 판별
input_tokens = tokenizer(["I feel fantastic", "My life is going something wrong", "I have not figured out what the chosen title has to do with the movie."], truncation=True, padding=True)
outputs = model(torch.tensor(input_tokens['input_ids']).to(device))
# 영어 원문의 1과 0값과 달리 일반적인 용례에 따라 변경
label_dict = {1:'positive', 0:'negative'}
print([label_dict[i] for i in torch.argmax(outputs['logits'], axis=1).cpu().numpy()])
# ['positive', 'negative', 'negative']
문제13. 파이토치 사전학습
문제4부터 11까지에 기반한 모델을 파인튜닝하기 위해서 파이토치를 사용하세요. 문제12에서는 Trainer클래스를 사용했지만, 여기서는 파이토치를 사용해 보세요. 이후 파인튜닝 전후에 다음 세 문장 각각의 극성 판별 결과를 비교하세요.
파이토치에 의한 파인튜닝 과정은 다음과 같이 10단계로 이루어진다.
- 사전학습 모델 및 토크나이저 불러오기
- DataLoader 인스턴스화
- 최적화 함수 정의
- 모델을 학습(training) 모드로 전환
- 에포크 횟수만큼 루프 반복
- 최적화 함수의 그래디언트 초기화
- 모델을 사용한 추론(inference)
- 손실 계산
- 오차역전파
- 가중치 업데이트
# 런타임 5분 30초 소요
from torch.utils.data import DataLoader
from transformers import DistilBertForSequenceClassification, AdamW
from transformers import DistilBertTokenizerFast
#1) 사전학습 모델과 토크나이저 불러오기
# 그리고 모델 실행결과에 to(devic) 코드 추가(가능한 경우 결과를 GPU에 전달)
tokenizer = DistilBertTokenizerFast.from_pretrained('distilbert-base-uncased')
model = DistilBertForSequenceClassification.from_pretrained('distilbert-base-uncased')
model.to(device)
# 파인튜닝 이전 모델을 사용하여 test_inference 함수 실행
print(test_inference(model, tokenizer))
#2)DataLoader 인스턴스화
train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True)
#3)최적화 함수 정의
optim = AdamW(model.parameters(), lr=5e-5)
#4)모델을 학습(train) 모드로 전환
# 이는 드롭아웃 및 배치 정규화에 영향을 미침
model.train()
losses = []
#5)에포크 횟수(epochs)만큼 루프 반복
for epoch in range(8):
print(f'epoch:{epoch}')
for batch in train_loader:
#6)최적화 함수의 기울기(그래디언트) 초기화
optim.zero_grad()
input_ids = batch['input_ids'].to(device)
attention_mask = batch['attention_mask'].to(device)
labels = batch['labels'].to(device)
#7) 모델을 사용한 추론
outputs = model(input_ids, attention_mask=attention_mask, labels=labels)
#8) 손실 계산
loss = outputs[0]
losses.append(loss)
#9) 오차역전파
loss.backward()
#10) 가중치(weight) 업데이트
optim.step()
# 모델을 eval 모드로 전환
model.eval()
# eval 모드를 사용하여 test_inference 함수 실행
print(test_inference(model, tokenizer))
# ['negative', 'negative', 'negative'] 파인튜닝 전
# epoch:0
# epoch:1
# epoch:2
# epoch:3
# epoch:4
# epoch:5
# epoch:6
# epoch:7
# ['positive', 'negative', 'positive'] 파인튜닝 후
728x90
반응형