
딥러닝 모델 개발, 특히 현대 AI의 핵심인 전이 학습(Transfer Learning) 환경에서 모든 파라미터를 처음부터 학습시키는 것은 시간과 자원의 낭비입니다. 이미 거대한 데이터셋으로 학습된 모델(Pre-trained Model)의 지식을 보존하면서, 내가 원하는 특정 레이어만 학습시키는 기술인 가중치 고정(Weight Freezing)은 주니어와 시니어 엔지니어를 가르는 중요한 척도가 됩니다. 단순히 requires_grad를 끄는 것만으로는 부족합니다. 배치 정규화(Batch Normalization)의 통계치 고정이나 옵티마이저와의 상호작용까지 고려해야 완벽한 모델 통제가 가능합니다. 본 포스팅에서는 파이토치(PyTorch)의 계산 그래프 원리를 이용해 가중치를 고정하는 독창적인 메커니즘을 분석하고, 실무에서 즉시 활용 가능한 7가지 고급 해결 예제를 제시합니다.
1. 가중치 고정(Freezing)의 내부 메커니즘과 차이점
파이토치에서 가중치를 고정한다는 것은 해당 텐서를 연산 그래프의 Leaf Node에서 제외하거나, 기울기 계산 대상에서 누락시키는 것을 의미합니다. 가장 흔히 사용되는 requires_grad 설정과 model.eval() 모드의 차이점을 명확히 이해해야 합니다.
| 항목 | requires_grad = False | model.eval() 모드 |
|---|---|---|
| 기울기 계산 | 수행하지 않음 (Backprop 차단) | 계산은 수행함 (설정에 따라) |
| 메모리 최적화 | 그래프를 생성하지 않아 메모리 절약 | 메모리 절약 효과는 미비함 |
| 배치 정규화(BN) | 학습된 통계치(Mean/Var) 업데이트 가능 | 고정된 이동 평균 통계치 사용 |
| 드롭아웃(Dropout) | 여전히 활성화됨 | 완전히 비활성화(Identity)됨 |
| 주요 목적 | 파라미터 업데이트 자체를 방지 | 추론 시 모델의 거동 고정 |
2. 가중치를 고정해야 하는 결정적 이유 (독창적 가치)
- 지식 보존(Catastrophic Forgetting 방지): 사전 학습된 모델의 하위 레이어는 일반적인 특징(Edge, Texture)을 추출합니다. 이를 고정하면 소량의 데이터로도 상위 레이어의 Task-Specific한 학습이 가능합니다.
- 연산 효율성: 고정된 레이어에 대해서는 기울기를 계산하지 않으므로 학습 속도가 향상되고 GPU VRAM 점유율이 낮아집니다.
- 학습 안정성: 초기에 무작위로 초기화된 Fully Connected 레이어의 큰 오차가 잘 학습된 Backbone의 가중치를 파괴하는 것을 방지합니다.
3. 실무자를 위한 가중치 고정 해결 예제 7가지 (Sample Examples)
실제 프로젝트 현장에서 Backbone 모델을 가져와 커스터마이징할 때 즉시 복사하여 사용할 수 있는 실전 코드입니다.
Example 1: 모델 전체 파라미터 고정 방법
import torch
import torchvision.models as models
model = models.resnet50(pretrained=True)
# 모든 파라미터의 기울기 계산 비활성화
for param in model.parameters():
param.requires_grad = False
Example 2: 이름(Name)을 기반으로 특정 레이어만 선택적 고정
# layer1과 layer2만 고정하고 나머지는 학습
for name, param in model.named_parameters():
if "layer1" in name or "layer2" in name:
param.requires_grad = False
print(f"Frozen: {name}")
Example 3: 마지막 분류기(FC Layer)만 새로 학습하기 (해결책)
model = models.vgg16(pretrained=True)
for param in model.features.parameters():
param.requires_grad = False
# 새로운 헤드는 기본적으로 requires_grad=True
model.classifier[6] = torch.nn.Linear(4096, 10)
Example 4: 배치 정규화(BN) 레이어의 통계값까지 완벽 고정
BN 레이어는 requires_grad가 False여도 train() 모드라면 통계값이 변합니다. 이를 막는 해결 방법입니다.
def freeze_bn(m):
if isinstance(m, torch.nn.modules.batchnorm._BatchNorm):
m.eval()
model.apply(freeze_bn) # 모델 전체의 BN만 eval 모드로 고정
Example 5: 옵티마이저에 학습 대상 파라미터만 전달 (메모리 최적화)
# requires_grad가 True인 파라미터만 필터링하여 전달하는 것이 효율적입니다.
optimizer = torch.optim.Adam(
filter(lambda p: p.requires_grad, model.parameters()),
lr=1e-4
)
Example 6: 특정 레이어 그룹(Child) 단위로 고정 해결
# 자식 모듈 단위로 접근하여 한 번에 제어
for child in model.children():
if isinstance(child, torch.nn.Sequential): # 특정 모듈 타입만 타겟팅
for param in child.parameters():
param.requires_grad = False
Example 7: 학습 도중 동적으로 가중치 해제(Unfreezing)
# 10 에포크 이후에 모든 가중치를 풀어주는 전략 (Fine-tuning)
if current_epoch == 10:
for param in model.parameters():
param.requires_grad = True
# 옵티마이저를 갱신해줘야 함에 주의하십시오.
4. 시니어 엔지니어의 핵심 인사이트: 웜업(Warm-up) 전략
실무에서 가장 효과적인 방법은 처음 3~5 에포크 동안은 Backbone을 완전히 고정하고 새로 추가한 Head만 학습시킨 뒤, 이후 아주 작은 학습률(Learning Rate)로 전체 모델의 고정을 풀고 미세 조정(Fine-tuning)하는 것입니다. 이렇게 하면 모델이 수렴 초기 단계에서 겪는 급격한 기울기 변동으로부터 사전 학습된 가중치를 보호할 수 있습니다.
5. 결론 및 요약
파이토치에서 특정 레이어의 가중치를 고정하는 것은 전이 학습의 성패를 결정짓는 핵심 기법입니다.
requires_grad = False는 기울기 계산을 멈추고 메모리를 아낍니다.- 특정 레이어만 고정하고 싶다면
named_parameters()를 활용한 조건문 처리가 가장 깔끔합니다. - 옵티마이저에는 반드시
filter를 거친 파라미터만 전달하여 불필요한 연산을 방지하십시오.
참조 및 출처 (Sources)
- PyTorch Official Docs: Autograd mechanics - Excluding subgraphs from backward
- Deep Learning with PyTorch: Transfer Learning and Weight Freezing Patterns
- Stanford CS231n: Optimization and Transfer Learning Notes
'Artificial Intelligence > 21. PyTorch' 카테고리의 다른 글
| [PYTORCH] retain_graph=True 옵션이 필요한 3가지 시나리오와 연산 그래프 에러 해결 방법 7가지 (0) | 2026.03.23 |
|---|---|
| [PYTORCH] 커스텀 Autograd 함수 구현 방법 2가지와 미분 비연속성 해결 방법 7가지 (0) | 2026.03.23 |
| [PYTORCH] 중간 텐서 그래디언트 확인 방법 2가지와 register_hook 활용 해결책 7가지 (0) | 2026.03.23 |
| [PYTORCH] backward() 두 번 호출 시 에러 발생하는 이유 1가지와 해결 방법 7가지 (0) | 2026.03.23 |
| [PYTORCH] 야코비안(Jacobian) 행렬의 3가지 핵심 원리와 벡터 미분 해결 방법 7가지 (0) | 2026.03.23 |