오늘은 ResNet 모델에 대해서 배웠다. 분명 전에 다뤄본 모델이었는데 이름만 익숙했지 사용법은 전혀 달라서 놀랐다.
| 모델명 | 상세 내용 |
|---|---|
| ResNet | • 매우 깊은 신경망에서도 학습이 가능하도록 잔차 연결(skip connection)을 사용 • ImageNet 사전 학습 모델로 가장 널리 사용 • 전이학습 실습에서 사실상 표준 선택지 |
| VGGNet | • 단순하고 직관적인 구조를 가진 합성곱 신경망 모델 • 구조 이해는 좋지만 파라미터 수가 많아 최근 실무에서의 적용이 줄어들었음 |
| DenseNet | • 모든 층을 촘촘하게 연결하여 특징 재사용을 극대화한 구조 • 메모리 효율은 좋지만 구조 설명이 복잡함 |
| EfficientNet | • 모델의 깊이, 너비, 입력 해상도를 균형 있게 확장해 적은 파라미터로 높은 성능을 보임 • 정확도 대비 연산 효율이 좋아 경량 모델이나 실무 환경에서 자주 사용 |
| 구분 | 특징 추출 (Feature Extraction) | 미세 조정 (Fine-tuning) |
|---|---|---|
| 가중치 활용 | 사전 학습 모델의 가중치를 그대로 유지(동결) | 사전 학습 모델의 일부 또는 전체 가중치를 함께 학습 |
| 학습 범위 | 분류기(마지막 층)만 새로 구성하여 학습 | 새로운 데이터의 특성에 맞춰 모델을 조금씩 다시 학습시켜 적응 |
| 적합한 상황 | 데이터가 적거나 빠른 적용이 필요한 경우에 적합 | 데이터가 충분하거나 더 높은 성능이 필요한 경우에 사용 |
from torchvision import models
import torch.nn as nn
weights = models.ResNet18_Weights.DEFAULT
model = models.resnet18(weights=weights)

model.layer4[-1].conv2
# Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
sum(p.numel() for p in model.parameters() if p.requires_grad)
# 11689512
for p in model.parameters():
p.requires_grad = False
sum(p.numel() for p in model.parameters() if p.requires_grad)
# 0
model.fc = nn.Linear(in_features=model.fc.in_features, out_features=10, bias=True)
model.fc.parameters() 지정criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(params=model.fc.parameters(), lr=0.001)
trainer = Trainer(
model=model,
criterion=criterion,
optimizer=optimizer,
train_loader=train_loader,
test_loader=test_loader,
flatten=False,
device=device
)
history = trainer.fit(10)
for p in model.layer4.parameters():
p.requires_grad = True
params_fine_tuning = filter(lambda p: p.requires_grad, model.parameters())
optimizer = torch.optim.Adam(params=params_fine_tuning, lr=0.0001)
trainer.optimizer = optimizer
history = trainer.fit(5)
file_path = 'CIFAR10_ResNet18.pth'
torch.save(obj=model.state_dict(), f=file_path)
내일은 학원이 쉬는 날이지만 주말까지 일정이 있어서 공부를 많이 할 수는 없을 것 같다. 그래도 시간을 내서 개인 프로젝트를 조금이나마 진행해보면 좋을 것 같다.