본문 바로가기
C.W.K.
Stream
Lesson 05 of 12 · published

비전 전이학습

~18 min · transfer-learning, fine-tuning, vision

Level 0호기심
0 XP0/73 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

왜 전이학습이 기본값일까

사전학습된 백본은 수백만 개의 예시를 보며 '이미지가 어떻게 작동하는지' 이미 배웠어. 반면 직접 풀어야 할 후속 과제는 라벨이 붙은 예시 5000개로 새 7종을 분류하는 정도지. 이미지 5000개만으로 CNN을 처음부터 학습하면 심하게 과적합돼. 전이학습을 쓰면 백본이 이미 익힌 내용을 재사용하고, 과제에 맞는 작은 헤드만 학습할 수 있어.

방법은 3가지야. 동결된 백본은 헤드만 학습하므로 가장 저렴하면서도 의외로 자주 경쟁력 있는 성능을 내. 전체 미세 조정은 모든 층을 학습해 가장 높은 정확도를 노리지만 연산량이 더 많아. 부분 동결 해제는 헤드와 마지막 몇 개 층만 학습하는 중간 방식이야.

팁: 첫 실행에서는 동결된 백본을 기본값으로 삼아. 빠르게 기준선을 얻을 수 있고, 그것만으로 충분할 수도 있어. 정확도가 부족하면 마지막 블록의 동결을 해제하고, 그래도 부족하면 아주 작은 학습률인 1e-4 또는 1e-5로 전체 미세 조정을 해.

미세 조정 학습률 요령

전체 미세 조정에는 처음부터 학습할 때보다 훨씬 작은 학습률을 써. 1e-3 대신 1e-4 또는 1e-5가 적절해. 새 헤드에는 사전학습된 백본보다 높은 학습률을 따로 적용할 수도 있어. 헤드는 무작위 상태에서 시작해 더 많은 갱신이 필요하지만, 백본은 이미 잘 학습되어 있어서 큰 갱신을 가하면 성능이 손상될 수 있거든.

데이터 전처리를 맞춰라

백본을 학습할 때 사용한 전처리 방식에 맞춰야 해. ImageNet 사전학습 모델은 정해진 정규화 값인 mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]와 정해진 입력 크기인 보통 224×224를 기대해. torchvision은 weights.transforms()를 통해 올바른 변환을 제공해. 그걸 쓰고 직접 다시 만들지 마.

원칙: 전이학습은 비전 과제에서 선택할 수 있는 가장 영향력 높은 모델링 결정이야. 동결된 ResNet50과 선형 헤드를 조합하면 보통 이미지 10K개로 처음부터 학습한 어떤 모델보다도 좋은 성능을 내.

Code

백본을 동결한 전이학습·python
import torch
import torch.nn as nn
import torchvision.models as tvm
from torchvision.models import ResNet50_Weights

weights = ResNet50_Weights.IMAGENET1K_V2
backbone = tvm.resnet50(weights=weights)

# Freeze all backbone parameters
for p in backbone.parameters():
    p.requires_grad = False

# Replace head with task-specific layer (only trainable)
backbone.fc = nn.Linear(backbone.fc.in_features, n_classes)

# Optimizer over only the trainable params
opt = torch.optim.AdamW([p for p in backbone.parameters() if p.requires_grad], lr=1e-3)

# Use the backbone's preprocessing
preprocess = weights.transforms()
차등 학습률을 적용한 전체 미세 조정·python
# Unfreeze everything but train head faster than backbone
for p in backbone.parameters():
    p.requires_grad = True

backbone_params = [p for n, p in backbone.named_parameters() if not n.startswith("fc.")]
head_params     = [p for n, p in backbone.named_parameters() if n.startswith("fc.")]

opt = torch.optim.AdamW([
    {"params": backbone_params, "lr": 1e-5},
    {"params": head_params,     "lr": 1e-3},
])

External links

Exercise

같은 작은 데이터셋으로 모델 3개를 학습해. (1) ResNet50을 처음부터 학습하고, (2) ResNet50의 백본을 동결한 뒤 새 헤드만 학습하고, (3) ResNet50 전체를 작은 학습률로 미세 조정해. 세 모델의 최종 검증 정확도를 비교해. 보통 처음부터 학습한 모델이 크게 뒤처질 거야.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.