Fine-Tuning
Fine-Tuning이란 무엇일까?
Fine-Tuning을 한국어로 직역하면 "미세 조정"이다.
Fine-Tuning은 "미세 조정"이라는 뜻과 같게 이미 학습된 모델을 주어진 요구사항에 맞춰 추가 학습을 시키는 것이다.
왜 Fine-Tuning을 사용하는가?
나와 같은 학생들은 거대한 모델을 만들 수 있는 컴퓨팅 파워(GPU 서버)가 없다.
하지만 Fine-Tuning을 사용한다면 이미 만들어진 거대 모델(YOLO, ResNet 등)들을 자신의 필요에 맞춰 사용할 수 있는 것이다.
이 외의 Fine-Tuning의 장점을 설명하자면
- 데이터 부족 문제 해결
데이터가 적어도 기존 모델의 지식을 활용할 수 있음 - 학습 시간과 비용 절감
처음부터 학습하는 것보다 훨씬 적은 시간과 비용이 듦 - 더 나은 성능
기존의 지식을 활용해서 더 나은 성능을 보여줌
이렇게나 좋은 Fine-Tuning은 딥러닝 산업에서 빠질 수 없는 기술이 되었다.
Fine-Tuning 사용 코드
ResNet-18을 Fine-Tuning하여 개와 고양이를 분류하는 모델을 만들었다.
dataloader.py
import kagglehub
from torch.utils.data import DataLoader
import torch
import pandas as pd
import os
from torchvision import datasets, transforms
def get_transform():
transform = transforms.Compose([
transforms.Resize((224, 224)), # ResNet은 224x224 입력 사용
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) # ImageNet 정규화
])
return transform
def get_dataset(transform):
base_path = r"C:\Users\user\.cache\kagglehub\datasets\tongpython\cat-and-dog\versions\1"
train_dir = os.path.join(base_path, "training_set", "training_set")
test_dir = os.path.join(base_path, "test_set", "test_set")
train_dataset = datasets.ImageFolder(root=train_dir, transform=transform)
test_dataset = datasets.ImageFolder(root=test_dir, transform=transform)
return train_dataset, test_dataset
def get_dataloader(train_dataset, test_dataset):
train_dataloader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_dataset, batch_size=64, shuffle=False)
return train_dataloader, test_dataloader
main.py
import torch.optim as optim
import torch.nn as nn
import torchvision.models as models
from dataloader import get_dataloader, get_dataset, get_transform
import torch
transform = get_transform()
train_dataset, test_dataset = get_dataset(transform)
train_loader, test_loader = get_dataloader(train_dataset, test_dataset)
model = models.resnet18(weights=models.ResNet18_Weights.IMAGENET1K_V1)
model.fc = nn.Linear(model.fc.in_features, 2)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.01)
best_accuracy = 0.0 # best accuracy 초기화
best_model_weights = None # best model weights 초기화
model.train() # batch_norm, drop_out 활성화
epochs = 3
for epoch in range(epochs):
running_loss = 0.0 # loss 초기화
for images, labels in train_loader:
outputs = model(images) # images feedforward
loss = criterion(outputs, labels) # loss 계산
optimizer.zero_grad() # gradient 초기화
loss.backward() # backpropagation
optimizer.step() # step
running_loss += loss.item() # sum of loss
avg_train_loss = running_loss / len(train_loader) # loss avg
model.eval() # batch_norm, drop_out 비활성화
correct, total = 0, 0 # correct, total 초기화
with torch.no_grad(): # 역전파와 gradient 계산 비활성화
for images, labels in test_loader:
outputs = model(images) # images feedforward
_, predicted = torch.max(outputs, 1) # 확률 값이 가장 큰 index 값 저장
total += labels.size(0) # 데이터의 개수 저장
correct += (predicted == labels).sum().item() # 맞은 데이터 개수 저장
accuracy = 100 * correct / total # 정확도 계산
if accuracy > best_accuracy: # best accuracy 보다 현 epoch의 accuracy가 높다면
best_accuracy = accuracy # best accuracy로 저장
best_model_weights = model.state_dict().copy() # best accuracy의 model weights 저장
print(f"Epoch [{epoch+1}/{epochs}], Loss: {avg_train_loss:.4f}, Validation Accuracy: {accuracy:.2f}%")
model.train()
if best_model_weights:
model.load_state_dict(best_model_weights) # model에 best accuracy의 weight를 가져옴
torch.save(best_model_weights, 'best_model.pth') # model 저장
print(f"Best model weights saved with accuracy: {best_accuracy:.2f}")
결과는 아쉽게도 Fine-Tuning한 것보다 그냥 학습시킨 모델이 더 잘나왔다...
내 생각에는 너무 간단한 테스크를 수행하는 것이여서 거대한 모델의 기존 지식이 노이즈화 되어 오히려 학습에 악영향을 끼친거 같다.
하지만 3% 정도 차이면 개와 고양이만 구별할 수 있는 그냥 학습 모델보다 1000개의 클래스를 분류할 수 있는 Fine-Tuning 모델이 더 좋지 않을까 생각한다.
전이 학습과 Fine-Tuning의 차이
과정)
- 사전 학습되어 있는 모델을 가져오고 최종 출력층 레이어를 보유 중인 데이터에 맞춰 설정한 뒤 결합한다.
- 결합한 최종 출력층을 보유 중인 데이터로 학습시킨다.
전이 학습
이 과정에서 기존 모델의 파라미터는 바뀌지 않고 최종 출력층 파라미터만 바뀌게 된다.
Fine-Tuning
이 과정에서 기존 모델의 파라미터까지 바뀐다.
마무리
나와 같이 컴퓨팅 파워가 약한 사람들에게는 정말 희망적인 기술이다. 그리고 적은 비용으로 엄청난 모델을 만들 수 있는 기술이기 떄문에 딥러닝 산업에 필수적인 기술이 되었다. 그렇기 때문에 모두 한 번은 Fine-Tuning으로 모델을 만들고 프로젝트 경험이 있었으면 좋겠다.