🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

전이학습과 Fine-tuning 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 12. 9. · 14 Views

전이학습과 Fine-tuning 완벽 가이드

전이학습의 개념부터 실전 Fine-tuning 전략까지, 적은 데이터로도 고성능 딥러닝 모델을 만드는 방법을 실무 사례와 함께 쉽게 풀어낸 가이드입니다.


목차

  1. 전이학습이 필요한 이유
  2. Feature Extraction 방식
  3. Fine-tuning 방식
  4. Learning Rate 스케줄링
  5. Layer Freezing 전략
  6. 적은 데이터로 학습하기

1. 전이학습이 필요한 이유

최지은 씨는 스타트업에서 이미지 분류 모델을 만들어야 하는 임무를 받았습니다. 하지만 수집한 학습 데이터는 겨우 500장.

"이걸로 어떻게 모델을 만들죠?" 답답한 마음에 선배 김시니어 씨를 찾아갔습니다.

전이학습은 이미 다른 작업으로 학습된 모델의 지식을 새로운 작업에 전달하는 기법입니다. 마치 영어를 잘하는 사람이 프랑스어를 더 빠르게 배우는 것처럼, 모델도 기존 지식을 활용하면 적은 데이터로도 좋은 성능을 낼 수 있습니다.

데이터가 부족하거나 학습 시간이 제한적일 때 필수적인 접근법입니다.

다음 코드를 살펴봅시다.

import torch
import torchvision.models as models

# ImageNet으로 사전 학습된 ResNet50 불러오기
pretrained_model = models.resnet50(pretrained=True)

# 모델 구조 확인
print(f"전체 레이어 수: {len(list(pretrained_model.children()))}")

# 마지막 레이어(분류기) 교체
num_classes = 10  # 우리가 분류할 클래스 개수
pretrained_model.fc = torch.nn.Linear(2048, num_classes)

# 이제 새로운 작업에 맞춰 학습 준비 완료
print("전이학습 준비 완료!")

최지은 씨는 걱정스러운 얼굴로 선배의 자리에 앉았습니다. "선배님, 이미지 분류 모델을 만들어야 하는데 데이터가 500장밖에 없어요.

이걸로 제대로 된 모델이 나올까요?" 김시니어 씨는 미소를 지으며 고개를 끄덕였습니다. "걱정하지 마세요.

전이학습을 사용하면 됩니다." 전이학습이란 정확히 무엇일까요? 쉽게 비유하자면, 전이학습은 마치 외국어를 배우는 과정과 같습니다.

영어를 이미 잘하는 사람이 프랑스어를 배울 때, 문법 구조나 단어의 개념을 완전히 처음부터 배우지 않습니다. 영어에서 익힌 언어적 감각을 활용해 훨씬 빠르게 학습합니다.

딥러닝 모델도 마찬가지입니다. 왜 전이학습이 필요한 걸까요?

처음부터 모델을 학습시키려면 엄청난 양의 데이터가 필요합니다. 예를 들어 ImageNet 데이터셋은 1,400만 장이 넘는 이미지로 구성되어 있습니다.

일반적인 기업이나 연구실에서 이런 규모의 데이터를 수집하는 것은 거의 불가능합니다. 더 큰 문제는 학습 시간입니다.

강력한 GPU를 여러 대 사용해도 모델을 처음부터 학습시키는 데는 며칠에서 몇 주가 걸립니다. 전기료만 해도 수백만 원이 들어갈 수 있습니다.

바로 이런 문제를 해결하기 위해 전이학습이 등장했습니다. 전이학습을 사용하면 사전 학습된 모델의 지식을 그대로 가져올 수 있습니다.

ImageNet으로 학습된 ResNet이나 VGG 같은 모델은 이미 이미지의 기본적인 특징을 파악하는 능력을 갖추고 있습니다. 선, 곡선, 질감, 패턴 같은 저수준 특징부터 눈, 귀, 바퀴 같은 고수준 특징까지 모두 학습되어 있습니다.

위의 코드를 한 줄씩 살펴보겠습니다. 먼저 models.resnet50(pretrained=True) 부분을 보면 ImageNet으로 사전 학습된 ResNet50 모델을 불러옵니다.

pretrained=True 옵션이 핵심입니다. 이 옵션을 켜면 이미 학습된 가중치를 함께 다운로드합니다.

다음으로 마지막 레이어를 교체합니다. pretrained_model.fc는 ResNet의 마지막 완전 연결 레이어입니다.

원래는 ImageNet의 1,000개 클래스를 분류하도록 설계되었지만, 우리는 10개 클래스만 분류하면 되므로 새로운 레이어로 교체합니다. 실제 현업에서는 어떻게 활용할까요?

의료 영상 분석을 예로 들어보겠습니다. 병원에서 수집한 X-ray 이미지가 1,000장 정도 있다고 가정해봅시다.

이 데이터만으로는 처음부터 모델을 학습시키기 어렵습니다. 하지만 ImageNet으로 학습된 모델을 가져와 전이학습을 적용하면, 모델은 이미 이미지의 일반적인 특징을 이해하고 있으므로 X-ray의 특수한 패턴만 추가로 학습하면 됩니다.

구글, 페이스북, 마이크로소프트 같은 대기업들은 자체 데이터로 학습한 모델을 공개하고 있습니다. 우리는 이런 모델을 활용해 비용과 시간을 크게 절약할 수 있습니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 무조건 큰 모델을 선택하는 것입니다.

ResNet152처럼 매우 깊은 모델은 성능이 좋지만, 데이터가 너무 적으면 오히려 과적합이 발생할 수 있습니다. 데이터 규모에 맞는 적절한 모델을 선택해야 합니다.

또 다른 실수는 사전 학습된 모델과 완전히 다른 도메인에 적용하는 것입니다. 예를 들어 ImageNet은 자연 이미지로 학습되었으므로, 의료 영상이나 위성 사진에는 효과가 떨어질 수 있습니다.

이럴 때는 도메인에 맞는 사전 학습 모델을 찾거나, 추가 학습을 충분히 진행해야 합니다. 다시 최지은 씨의 이야기로 돌아가 봅시다.

김시니어 씨의 설명을 들은 최지은 씨는 안도의 한숨을 내쉬었습니다. "아, 처음부터 만들 필요가 없었네요!" 전이학습을 제대로 이해하면 적은 데이터와 제한된 자원으로도 실용적인 딥러닝 모델을 만들 수 있습니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 항상 사전 학습된 모델부터 시작하세요. 처음부터 학습은 최후의 선택지입니다.

  • 데이터가 1,000장 미만이라면 전이학습이 거의 필수입니다.
  • PyTorch Hub나 TensorFlow Hub에서 다양한 사전 학습 모델을 찾을 수 있습니다.

2. Feature Extraction 방식

전이학습을 처음 접한 최지은 씨는 궁금한 점이 생겼습니다. "선배님, 그럼 사전 학습된 모델을 어떻게 사용하는 건가요?

전체를 다시 학습시켜야 하나요?" 김시니어 씨는 칠판에 그림을 그리며 설명을 시작했습니다.

Feature Extraction은 사전 학습된 모델의 하위 레이어들을 고정시키고, 마지막 분류기만 새로운 데이터로 학습시키는 방식입니다. 마치 카메라는 그대로 두고 렌즈만 교체하는 것과 같습니다.

모델의 특징 추출 능력은 그대로 활용하면서, 특정 작업에 맞는 분류기만 새롭게 학습합니다.

다음 코드를 살펴봅시다.

import torch
import torchvision.models as models

# 사전 학습된 ResNet50 불러오기
model = models.resnet50(pretrained=True)

# 모든 파라미터 고정 (학습 안 되도록)
for param in model.parameters():
    param.requires_grad = False

# 마지막 분류기만 교체 (이 레이어만 학습됨)
num_features = model.fc.in_features
model.fc = torch.nn.Linear(num_features, 5)  # 5개 클래스 분류

# 학습 가능한 파라미터 수 확인
trainable_params = sum(p.numel() for p in model.parameters() if p.requires_grad)
print(f"학습 가능한 파라미터: {trainable_params:,}개")

김시니어 씨가 칠판에 모델의 구조를 그렸습니다. 긴 막대 모양의 박스 여러 개가 연결되어 있고, 마지막에 작은 박스 하나가 붙어 있습니다.

"이게 바로 딥러닝 모델의 기본 구조예요." 선배는 긴 박스들을 가리키며 설명했습니다. "이 부분들은 특징 추출기입니다.

이미지에서 유용한 특징을 뽑아내는 역할을 하죠. 그리고 마지막 작은 박스가 분류기입니다.

추출된 특징을 보고 최종 판단을 내립니다." Feature Extraction이란 무엇일까요? 쉽게 비유하자면, Feature Extraction은 마치 전문 카메라맨이 사진을 찍는 것과 같습니다.

카메라맨은 이미 좋은 카메라를 가지고 있습니다. 이 카메라로 풍경, 인물, 음식 등 다양한 사진을 찍어왔습니다.

이제 새로운 주제인 꽃을 촬영해야 한다면, 카메라는 그대로 두고 렌즈만 꽃 촬영에 적합한 것으로 교체하면 됩니다. 딥러닝에서도 마찬가지로 특징 추출 부분은 그대로 두고, 분류기만 교체합니다.

왜 이런 방식이 효과적일까요? 사전 학습된 모델의 하위 레이어들은 이미 범용적인 특징을 잘 학습했습니다.

첫 번째 레이어는 선이나 모서리 같은 기본 요소를 감지합니다. 중간 레이어들은 질감이나 패턴을 인식합니다.

상위 레이어들은 더 복잡한 형태를 파악합니다. 이런 특징들은 대부분의 이미지 작업에 공통적으로 필요합니다.

고양이를 분류하든, 자동차를 분류하든, X-ray를 분석하든 기본적인 시각 특징은 비슷합니다. 따라서 이 부분을 다시 학습할 필요가 없습니다.

Feature Extraction 방식의 가장 큰 장점은 학습 속도입니다. 위의 코드를 보면 param.requires_grad = False로 설정하는 부분이 있습니다.

이 코드가 핵심입니다. requires_grad가 False이면 해당 파라미터는 역전파 과정에서 업데이트되지 않습니다.

즉, 학습 대상에서 제외됩니다. 결과적으로 수천만 개의 파라미터 중에서 마지막 분류기의 몇천 개만 학습하면 됩니다.

학습 시간이 10배에서 100배까지 단축됩니다. GPU 메모리도 훨씬 적게 사용합니다.

또 다른 장점은 안정성입니다. 학습할 파라미터가 적으면 과적합 위험이 줄어듭니다.

데이터가 100장밖에 없어도 안정적으로 학습할 수 있습니다. 학습률 같은 하이퍼파라미터 설정도 까다롭지 않습니다.

실제 현업에서는 어떻게 활용할까요? 패션 쇼핑몰에서 상품 이미지를 자동으로 분류하는 시스템을 만든다고 가정해봅시다.

상의, 하의, 신발, 가방, 액세서리 5개 카테고리로 나눠야 합니다. 각 카테고리당 500장씩 총 2,500장의 이미지가 있습니다.

ImageNet으로 학습된 ResNet을 가져와 Feature Extraction 방식을 적용하면, 단 몇 분 만에 학습이 완료됩니다. 정확도도 95% 이상 나옵니다.

처음부터 학습시켰다면 며칠이 걸렸을 작업이 금방 끝납니다. 하지만 주의할 점도 있습니다.

Feature Extraction은 새로운 데이터가 사전 학습 데이터와 비슷할 때 가장 효과적입니다. 만약 완전히 다른 도메인이라면 효과가 떨어질 수 있습니다.

예를 들어 ImageNet으로 학습한 모델을 의료 영상에 적용할 때는 특징 추출기도 어느 정도 조정이 필요할 수 있습니다. 또 다른 제약은 표현력입니다.

특징 추출기를 고정하면 새로운 작업에 최적화된 특징을 학습할 수 없습니다. 성능의 상한선이 정해져 있는 셈입니다.

최고 성능이 필요하다면 다음에 배울 Fine-tuning을 고려해야 합니다. 다시 최지은 씨의 이야기로 돌아가 봅시다.

"아, 그러니까 엔진은 그대로 쓰고 바퀴만 바꾸는 거네요!" 최지은 씨가 이해한 듯 말했습니다. 김시니어 씨가 웃으며 고개를 끄덕였습니다.

Feature Extraction을 제대로 이해하면 빠르고 안정적으로 전이학습을 시작할 수 있습니다. 데이터가 부족하거나 빠른 프로토타이핑이 필요할 때 첫 번째로 시도해볼 만한 방법입니다.

실전 팁

💡 - 데이터가 5,000장 미만이라면 Feature Extraction부터 시작하세요.

  • 학습 시간이 너무 오래 걸린다면 배치 크기를 늘려보세요. 특징 추출기가 고정되어 있어 메모리 여유가 있습니다.
  • 성능이 만족스럽지 않다면, 마지막 분류기를 더 복잡하게 만들어보세요. 예를 들어 은닉층을 추가할 수 있습니다.

3. Fine-tuning 방식

Feature Extraction으로 모델을 학습시킨 최지은 씨는 90%의 정확도를 얻었습니다. 하지만 프로젝트 요구사항은 95% 이상입니다.

"선배님, 더 높은 성능을 내려면 어떻게 해야 하나요?" 김시니어 씨는 이번에는 Fine-tuning이라는 더 강력한 방법을 알려주기로 했습니다.

Fine-tuning은 사전 학습된 모델의 일부 레이어를 함께 학습시키는 방식입니다. 마치 중고차를 사서 엔진과 서스펜션을 내 취향에 맞게 튜닝하는 것과 같습니다.

특징 추출기의 상위 레이어들을 새로운 데이터에 맞게 조정하여, Feature Extraction보다 높은 성능을 달성할 수 있습니다.

다음 코드를 살펴봅시다.

import torch
import torchvision.models as models
import torch.optim as optim

# 사전 학습된 모델 불러오기
model = models.resnet50(pretrained=True)

# 마지막 분류기 교체
model.fc = torch.nn.Linear(2048, 5)

# Fine-tuning: 마지막 2개 블록만 학습 가능하게
for name, param in model.named_parameters():
    # layer4와 fc만 학습
    if "layer4" in name or "fc" in name:
        param.requires_grad = True
    else:
        param.requires_grad = False

# 학습 가능한 레이어는 작은 학습률, 새로운 레이어는 큰 학습률
optimizer = optim.Adam([
    {'params': model.layer4.parameters(), 'lr': 1e-4},
    {'params': model.fc.parameters(), 'lr': 1e-3}
])

print("Fine-tuning 준비 완료!")

김시니어 씨가 화이트보드에 다시 그림을 그렸습니다. 이번에는 긴 막대 박스 중 뒤쪽 몇 개에 색을 칠했습니다.

"Feature Extraction에서는 이 부분들을 모두 고정했죠. 하지만 Fine-tuning에서는 뒤쪽 레이어들을 함께 학습시킵니다." 최지은 씨가 고개를 갸우뚱했습니다.

"그럼 모든 레이어를 다시 학습시키면 더 좋지 않나요?" 선배가 미소를 지으며 답했습니다. "좋은 질문이에요.

하지만 그렇게 하면 과적합이 발생할 수 있습니다." Fine-tuning이란 정확히 무엇일까요? 쉽게 비유하자면, Fine-tuning은 마치 중고차를 구입해서 튜닝하는 것과 같습니다.

기본 성능은 이미 좋지만, 내 운전 스타일에 맞게 엔진 세팅을 조정하고 서스펜션을 바꿉니다. 차체는 그대로 두지만 핵심 부품들을 미세하게 조정하는 것입니다.

딥러닝 모델도 마찬가지입니다. 하위 레이어는 범용적인 특징을 학습했으므로 그대로 둡니다.

하지만 상위 레이어는 더 추상적이고 작업별로 특화된 특징을 다루므로, 이 부분을 새로운 데이터에 맞게 조정합니다. 왜 Fine-tuning이 필요한 걸까요?

Feature Extraction만으로는 한계가 있습니다. 특징 추출기가 고정되어 있으면 새로운 작업에 최적화된 특징을 학습할 수 없습니다.

예를 들어 의료 영상을 분석한다면, 일반 이미지와는 다른 특수한 패턴을 감지해야 합니다. Fine-tuning을 사용하면 모델이 새로운 도메인에 적응할 수 있습니다.

상위 레이어들이 작업별로 중요한 특징을 찾아내도록 조정됩니다. 결과적으로 Feature Extraction보다 5-10% 높은 성능을 얻을 수 있습니다.

위의 코드를 한 줄씩 살펴보겠습니다. 먼저 named_parameters()로 모든 파라미터를 순회합니다.

이름에 "layer4"나 "fc"가 포함된 파라미터만 requires_grad = True로 설정합니다. ResNet의 layer4는 마지막 블록으로, 가장 추상적인 특징을 다룹니다.

핵심은 옵티마이저 설정입니다. 사전 학습된 layer4에는 작은 학습률 1e-4를, 새로운 분류기에는 큰 학습률 1e-3을 적용합니다.

이를 차등 학습률이라고 합니다. 왜 학습률을 다르게 설정할까요?

사전 학습된 레이어는 이미 좋은 가중치를 가지고 있습니다. 큰 학습률을 사용하면 이 좋은 가중치가 망가질 수 있습니다.

반면 새로운 분류기는 무작위로 초기화되었으므로 빠르게 학습해야 합니다. 실제 현업에서는 어떻게 활용할까요?

자율주행 자동차에서 보행자를 감지하는 모델을 만든다고 가정해봅시다. ImageNet으로 학습된 모델은 사람을 어느 정도 인식할 수 있지만, 도로 위의 다양한 각도와 거리에서 촬영된 보행자는 다릅니다.

Fine-tuning을 적용하면 모델이 도로 환경에 특화된 특징을 학습합니다. 예를 들어 횡단보도 위의 사람, 차 사이로 보이는 사람, 밤에 촬영된 사람 등을 더 잘 감지합니다.

실제로 테슬라나 웨이모 같은 기업들이 이런 방식을 사용합니다. 하지만 주의할 점도 있습니다.

가장 흔한 실수는 너무 많은 레이어를 학습시키는 것입니다. 데이터가 충분하지 않은 상태에서 전체 모델을 Fine-tuning하면 과적합이 발생합니다.

일반적으로 마지막 1-2개 블록만 학습시키는 것이 안전합니다. 또 다른 주의사항은 학습률 설정입니다.

사전 학습된 레이어에 너무 큰 학습률을 사용하면 치명적 망각이 발생합니다. 모델이 기존에 학습한 유용한 특징들을 잊어버리는 현상입니다.

학습률은 일반적으로 처음부터 학습할 때보다 10-100배 작게 설정합니다. 배치 정규화 레이어도 주의해야 합니다.

Fine-tuning 중에는 배치 정규화의 통계량을 업데이트할지 말지 결정해야 합니다. 일반적으로 작은 배치 크기를 사용한다면 통계량을 고정하는 것이 좋습니다.

다시 최지은 씨의 이야기로 돌아가 봅시다. Fine-tuning을 적용한 후 최지은 씨의 모델은 96%의 정확도를 달성했습니다.

"와, 정말 효과가 있네요!" 최지은 씨가 감탄했습니다. Fine-tuning을 제대로 이해하면 전이학습의 진정한 힘을 발휘할 수 있습니다.

데이터가 어느 정도 있고, 최고 성능이 필요할 때 반드시 시도해볼 만한 방법입니다.

실전 팁

💡 - 데이터가 5,000장 이상이라면 Fine-tuning을 고려하세요.

  • 처음에는 마지막 블록만 학습시키고, 필요하면 점진적으로 더 많은 레이어를 학습시키세요.
  • 사전 학습된 레이어의 학습률은 새로운 레이어의 1/10 정도로 설정하세요.

4. Learning Rate 스케줄링

Fine-tuning을 시작한 최지은 씨는 초반에는 손실이 빠르게 줄어들었지만, 나중에는 거의 변화가 없다는 것을 발견했습니다. "선배님, 학습이 멈춘 것 같아요.

뭔가 잘못된 건가요?" 김시니어 씨는 학습률 그래프를 보여주며 학습률 스케줄링의 중요성을 설명했습니다.

Learning Rate 스케줄링은 학습 과정에서 학습률을 동적으로 조정하는 기법입니다. 마치 자동차를 운전할 때 속도를 조절하는 것과 같습니다.

처음에는 빠르게 학습하다가 점차 속도를 줄여 최적점에 안착할 수 있도록 합니다. Fine-tuning에서 성능을 극대화하는 핵심 기법입니다.

다음 코드를 살펴봅시다.

import torch
import torch.optim as optim
from torch.optim.lr_scheduler import CosineAnnealingLR, ReduceLROnPlateau

# 옵티마이저 설정
optimizer = optim.Adam([
    {'params': model.layer4.parameters(), 'lr': 1e-4},
    {'params': model.fc.parameters(), 'lr': 1e-3}
])

# Cosine Annealing: 학습률을 부드럽게 감소
scheduler = CosineAnnealingLR(optimizer, T_max=50, eta_min=1e-6)

# 또는 ReduceLROnPlateau: 성능이 개선되지 않으면 학습률 감소
# scheduler = ReduceLROnPlateau(optimizer, mode='min', factor=0.5, patience=5)

# 학습 루프
for epoch in range(50):
    train_loss = train_one_epoch(model, train_loader, optimizer)

    # 스케줄러 업데이트
    scheduler.step()

    print(f"Epoch {epoch}: LR={optimizer.param_groups[0]['lr']:.6f}")

김시니어 씨가 모니터에 학습 곡선을 띄웠습니다. 손실이 처음에는 가파르게 줄어들다가 어느 순간부터 거의 평평해졌습니다.

"이게 바로 전형적인 패턴이에요. 학습이 멈춘 게 아니라, 학습률이 너무 크거나 작아서 그런 겁니다." 최지은 씨가 궁금한 표정을 지었습니다.

"학습률을 고정하면 안 되나요?" 선배가 고개를 저었습니다. "고정된 학습률은 최적이 아닙니다.

상황에 맞게 조절해야 해요." Learning Rate 스케줄링이란 무엇일까요? 쉽게 비유하자면, 학습률 스케줄링은 마치 목적지를 찾아가는 자동차 운전과 같습니다.

처음에는 고속도로에서 빠르게 달립니다. 목적지 근처에 도착하면 속도를 줄입니다.

주차장에 들어서면 아주 천천히 움직여 정확한 위치에 주차합니다. 딥러닝 학습도 마찬가지입니다.

초반에는 큰 학습률로 빠르게 좋은 영역을 찾아갑니다. 중반에는 학습률을 줄여 더 정교하게 조정합니다.

후반에는 매우 작은 학습률로 최적점에 정착합니다. 왜 학습률 스케줄링이 중요할까요?

고정된 학습률에는 두 가지 문제가 있습니다. 첫째, 너무 크면 최적점 주변에서 진동하며 수렴하지 못합니다.

마치 주차할 때 너무 빠르게 움직여 계속 오버슈팅하는 것과 같습니다. 둘째, 너무 작으면 학습 속도가 매우 느립니다.

좋은 영역을 찾는 데 너무 오래 걸리거나, 나쁜 지역 최솟값에 갇힐 수 있습니다. 학습률 스케줄링을 사용하면 두 가지 장점을 모두 얻을 수 있습니다.

빠른 초기 수렴과 정교한 최종 조정이 가능합니다. 위의 코드를 자세히 살펴보겠습니다.

Cosine Annealing은 가장 인기 있는 스케줄링 방법입니다. 학습률이 코사인 곡선을 따라 부드럽게 감소합니다.

T_max는 한 주기의 길이이고, eta_min은 최소 학습률입니다. 이 방법의 장점은 예측 가능하고 안정적이라는 것입니다.

학습 초반에는 빠르게 감소하고, 중후반에는 천천히 감소합니다. 많은 최신 논문에서 사용하는 표준 기법입니다.

ReduceLROnPlateau는 다른 접근법입니다. 검증 손실이 개선되지 않으면 자동으로 학습률을 줄입니다.

patience=5는 5 에폭 동안 개선이 없으면 학습률을 감소시킨다는 의미입니다. factor=0.5는 학습률을 절반으로 줄인다는 뜻입니다.

이 방법의 장점은 적응적이라는 것입니다. 모델이 학습 중간에 막히면 자동으로 학습률을 조정해 빠져나갑니다.

실제 현업에서는 어떻게 활용할까요? 대형 이커머스 회사에서 상품 추천 모델을 Fine-tuning한다고 가정해봅시다.

수백만 개의 상품과 사용자 데이터를 다루므로 학습에 시간이 오래 걸립니다. Cosine Annealing을 사용하면 학습률을 사람이 수동으로 조절할 필요가 없습니다.

학습 초반에는 빠르게 좋은 영역을 찾고, 후반에는 미세하게 조정하여 최고 성능을 달성합니다. 구글, 페이스북 같은 기업들이 이런 방식을 적극 활용합니다.

하지만 주의할 점도 있습니다. 스케줄링 설정이 데이터나 작업에 맞지 않으면 오히려 성능이 나빠질 수 있습니다.

예를 들어 T_max를 너무 짧게 설정하면 학습률이 너무 빨리 감소해 충분히 학습하지 못합니다. 또 다른 실수는 Warm-up을 빼먹는 것입니다.

Fine-tuning 초기에는 새로운 분류기가 무작위로 초기화되어 있어 그래디언트가 불안정합니다. 처음 몇 에폭 동안 학습률을 점진적으로 증가시키는 Warm-up을 적용하면 더 안정적으로 학습할 수 있습니다.

ReduceLROnPlateau를 사용할 때는 patience 값이 중요합니다. 너무 짧으면 학습률이 너무 자주 감소해 충분히 탐색하지 못합니다.

너무 길면 나쁜 영역에서 오래 머뭅니다. 일반적으로 5-10 에폭이 적당합니다.

다시 최지은 씨의 이야기로 돌아가 봅시다. Cosine Annealing을 적용한 후 최지은 씨의 모델은 97%의 정확도를 달성했습니다.

"학습률 하나로 이렇게 차이가 나다니!" 최지은 씨가 놀라워했습니다. Learning Rate 스케줄링을 제대로 이해하면 Fine-tuning의 성능을 한 단계 더 끌어올릴 수 있습니다.

복잡한 하이퍼파라미터 튜닝 없이도 안정적이고 높은 성능을 달성할 수 있습니다.

실전 팁

💡 - 대부분의 경우 Cosine Annealing을 먼저 시도하세요. 간단하고 효과적입니다.

  • Fine-tuning할 때는 사전 학습 시보다 10-100배 작은 최대 학습률로 시작하세요.
  • Warm-up을 사용하면 초기 학습이 더 안정적입니다. 처음 5-10 에폭 동안 학습률을 0에서 목표 값까지 점진적으로 증가시키세요.

5. Layer Freezing 전략

모델 성능이 97%에 도달한 최지은 씨는 만족스러웠지만, 학습 시간이 너무 오래 걸린다는 문제가 있었습니다. "선배님, 학습에 2시간이나 걸려요.

더 빠르게 할 방법은 없나요?" 김시니어 씨는 Layer Freezing 전략을 단계별로 적용하는 방법을 알려주었습니다.

Layer Freezing은 모델의 레이어를 선택적으로 고정하거나 해제하는 전략입니다. 마치 건물을 리모델링할 때 기초는 그대로 두고 필요한 층만 공사하는 것과 같습니다.

학습 초기에는 많은 레이어를 고정해 빠르게 학습하고, 후반에는 점진적으로 더 많은 레이어를 학습시켜 성능을 최적화합니다.

다음 코드를 살펴봅시다.

import torch

def freeze_layers(model, freeze_until):
    """특정 레이어까지 고정"""
    freeze = True
    for name, param in model.named_parameters():
        if freeze_until in name:
            freeze = False
        param.requires_grad = not freeze

def unfreeze_gradually(model, epoch, strategy='gradual'):
    """에폭에 따라 점진적으로 레이어 해제"""
    if strategy == 'gradual':
        if epoch < 10:
            freeze_layers(model, 'layer4')  # layer4만 학습
        elif epoch < 20:
            freeze_layers(model, 'layer3')  # layer3, layer4 학습
        else:
            # 전체 모델 학습 (매우 작은 학습률)
            for param in model.parameters():
                param.requires_grad = True

# 학습 루프에서 사용
for epoch in range(30):
    unfreeze_gradually(model, epoch)
    train_one_epoch(model, train_loader, optimizer)
    print(f"Epoch {epoch}: 학습 중인 레이어 수 업데이트됨")

김시니어 씨가 화이트보드에 시간표를 그렸습니다. "Fine-tuning을 한 번에 하면 오래 걸립니다.

대신 단계별로 나눠서 하면 훨씬 효율적이에요." 선배는 세 개의 박스를 그렸습니다. "1단계: 분류기만 학습.

2단계: 상위 블록 추가. 3단계: 전체 미세 조정.

이렇게 하면 시간도 절약되고 성능도 더 좋아집니다." Layer Freezing 전략이란 무엇일까요? 쉽게 비유하자면, Layer Freezing은 마치 건물을 단계별로 리모델링하는 것과 같습니다.

처음에는 내부 인테리어만 바꿉니다. 그다음에는 상층부 구조를 조정합니다.

마지막으로 전체적인 마무리를 합니다. 처음부터 전체를 동시에 공사하는 것보다 효율적이고 안전합니다.

딥러닝에서도 마찬가지입니다. 처음에는 마지막 분류기만 학습시킵니다.

이 단계에서 모델은 새로운 작업에 대한 기본적인 이해를 얻습니다. 그다음 상위 레이어들을 점진적으로 해제하면서 더 세밀하게 조정합니다.

왜 이런 단계적 접근이 효과적일까요? 첫째, 학습 안정성이 크게 향상됩니다.

새로운 분류기가 무작위로 초기화된 상태에서 전체 모델을 학습시키면, 큰 그래디언트가 하위 레이어까지 전파되어 기존에 학습된 좋은 특징들이 망가질 수 있습니다. 단계적으로 접근하면 먼저 분류기가 안정화됩니다.

분류기가 어느 정도 학습된 후에 상위 레이어를 해제하면, 그래디언트가 더 안정적으로 전파됩니다. 둘째, 학습 속도가 빨라집니다.

초기 단계에서는 학습할 파라미터가 적으므로 에폭당 시간이 짧습니다. 빠르게 여러 번 반복하면서 좋은 초기 상태를 만들 수 있습니다.

위의 코드를 자세히 살펴보겠습니다. freeze_layers 함수는 특정 레이어 이름을 기준으로 그 앞의 모든 레이어를 고정합니다.

예를 들어 freeze_until='layer4'로 설정하면 layer1, layer2, layer3은 고정되고 layer4와 fc만 학습됩니다. unfreeze_gradually 함수가 핵심입니다.

에폭 번호에 따라 학습할 레이어 범위를 자동으로 조정합니다. 처음 10 에폭은 layer4만, 다음 10 에폭은 layer3와 layer4를, 마지막에는 전체 모델을 학습시킵니다.

이 접근법의 장점은 자동화입니다. 사람이 중간에 개입해서 설정을 바꿀 필요가 없습니다.

학습 스크립트를 시작하면 알아서 단계적으로 진행됩니다. 실제 현업에서는 어떻게 활용할까요?

의료 영상 AI 스타트업에서 X-ray 이상 탐지 모델을 개발한다고 가정해봅시다. 데이터는 10,000장 정도로 충분하지만, 학습에 GPU를 며칠씩 돌려야 합니다.

Layer Freezing 전략을 적용하면 첫 단계에서 빠르게 좋은 분류기를 얻습니다. 이 단계만 해도 90% 정도의 성능이 나옵니다.

그다음 상위 블록을 해제하면서 95%까지 올립니다. 마지막 전체 미세 조정으로 97%에 도달합니다.

전체 과정이 처음부터 Fine-tuning하는 것보다 30-50% 빠르고, 최종 성능은 더 높습니다. 하지만 주의할 점도 있습니다.

가장 흔한 실수는 단계 전환 시점을 잘못 정하는 것입니다. 분류기가 충분히 학습되기 전에 상위 레이어를 해제하면, 불안정한 그래디언트가 전파되어 오히려 성능이 나빠질 수 있습니다.

일반적으로 검증 손실이 안정화되는 시점을 기준으로 삼습니다. 예를 들어 분류기만 학습시킬 때 검증 손실이 3-5 에폭 동안 개선되지 않으면, 다음 단계로 넘어갑니다.

또 다른 주의사항은 배치 정규화입니다. 레이어를 해제할 때 배치 정규화의 running_meanrunning_var도 업데이트할지 결정해야 합니다.

일반적으로 데이터 분포가 많이 다르다면 업데이트하는 것이 좋습니다. 학습률 조정도 중요합니다.

새로운 레이어를 해제할 때마다 해당 레이어의 학습률을 다르게 설정해야 합니다. 하위 레이어일수록 더 작은 학습률을 사용합니다.

다시 최지은 씨의 이야기로 돌아가 봅시다. Layer Freezing 전략을 적용한 후 학습 시간이 2시간에서 1시간으로 줄었고, 정확도는 98%로 향상되었습니다.

"이렇게 효율적인 방법이 있었다니!" 최지은 씨가 감탄했습니다. Layer Freezing 전략을 제대로 이해하면 학습 시간과 성능을 동시에 개선할 수 있습니다.

특히 제한된 GPU 자원으로 큰 모델을 Fine-tuning할 때 매우 유용한 기법입니다.

실전 팁

💡 - 첫 단계(분류기만 학습)는 빠르게 수렴하므로 10-20 에폭이면 충분합니다.

  • 각 단계에서 학습률을 점진적으로 감소시키세요. 새로운 레이어를 해제할 때 학습률을 1/10로 줄이는 것이 안전합니다.
  • 검증 손실을 모니터링하면서 단계 전환 시점을 동적으로 결정하면 더 좋은 결과를 얻을 수 있습니다.

6. 적은 데이터로 학습하기

프로젝트가 거의 마무리될 무렵, 최지은 씨는 새로운 프로젝트 의뢰를 받았습니다. 하지만 이번에는 데이터가 단 200장뿐입니다.

"선배님, 이번에는 정말 데이터가 너무 적은데... 이것도 가능한가요?" 김시니어 씨는 웃으며 데이터 증강정규화 기법을 알려주었습니다.

적은 데이터 학습은 데이터 증강, 강력한 정규화, 그리고 신중한 학습 전략을 결합한 접근법입니다. 마치 적은 재료로 풍성한 요리를 만드는 것과 같습니다.

원본 데이터를 다양하게 변형하고, 과적합을 막는 여러 기법을 적용하여, 수백 장의 이미지만으로도 실용적인 모델을 만들 수 있습니다.

다음 코드를 살펴봅시다.

import torch
import torchvision.transforms as transforms
from torch.utils.data import DataLoader

# 강력한 데이터 증강
train_transforms = transforms.Compose([
    transforms.RandomResizedCrop(224, scale=(0.6, 1.0)),
    transforms.RandomHorizontalFlip(),
    transforms.RandomRotation(15),
    transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2),
    transforms.RandomAffine(degrees=0, translate=(0.1, 0.1)),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])

# 모델에 Dropout 추가
model = models.resnet50(pretrained=True)
model.fc = torch.nn.Sequential(
    torch.nn.Dropout(0.5),  # 강한 정규화
    torch.nn.Linear(2048, 256),
    torch.nn.ReLU(),
    torch.nn.Dropout(0.3),
    torch.nn.Linear(256, 5)
)

# L2 정규화(Weight Decay) 적용
optimizer = torch.optim.Adam(model.fc.parameters(), lr=1e-3, weight_decay=1e-4)

김시니어 씨가 고개를 끄덕였습니다. "200장이면 확실히 적긴 하지만, 불가능하지 않아요.

몇 가지 비법이 있습니다." 선배는 첫 번째 비법으로 데이터 증강을 꺼냈습니다. "원본 이미지 하나에서 수십 가지 변형을 만들어낼 수 있어요.

회전, 확대, 색상 조정 등을 적용하면 모델이 더 다양한 상황을 학습합니다." 적은 데이터로 학습한다는 것은 무슨 의미일까요? 쉽게 비유하자면, 적은 데이터로 학습하는 것은 마치 몇 가지 재료로 다양한 요리를 만드는 것과 같습니다.

토마토, 양파, 마늘만 있어도 조리 방법을 달리하면 수프, 소스, 샐러드 등 여러 요리를 만들 수 있습니다. 딥러닝에서도 원본 데이터를 다양하게 변형하면 더 많은 학습 샘플을 확보할 수 있습니다.

왜 적은 데이터 학습이 어려운 걸까요? 딥러닝 모델은 수백만 개의 파라미터를 가지고 있습니다.

이 많은 파라미터를 제대로 학습시키려면 엄청난 양의 데이터가 필요합니다. 데이터가 부족하면 모델이 과적합됩니다.

학습 데이터는 완벽하게 외우지만, 새로운 데이터에는 전혀 대응하지 못합니다. 예를 들어 고양이 사진 100장만으로 모델을 학습시켰다고 가정해봅시다.

모델은 이 100장의 고양이를 완벽하게 인식하지만, 101번째 고양이는 인식하지 못할 수 있습니다. 일반화 능력이 부족한 것입니다.

이 문제를 해결하는 첫 번째 방법은 데이터 증강입니다. 위의 코드를 보면 다양한 변형이 적용되어 있습니다.

RandomResizedCrop은 이미지를 무작위로 잘라내고 크기를 조정합니다. 이렇게 하면 모델이 객체의 부분만 보고도 인식할 수 있게 됩니다.

RandomHorizontalFlip은 좌우 반전입니다. 대부분의 객체는 좌우가 바뀌어도 동일하므로 이 변형이 효과적입니다.

RandomRotation은 회전을 적용해 다양한 각도에서 본 모습을 학습시킵니다. ColorJitter는 밝기, 대비, 채도를 조정합니다.

같은 객체라도 조명 조건에 따라 색상이 달라지므로, 이런 변형을 통해 모델이 조명에 강인해집니다. 두 번째 방법은 정규화 기법입니다.

코드를 보면 분류기에 Dropout이 추가되어 있습니다. Dropout은 학습 중에 무작위로 뉴런을 꺼서 모델이 특정 뉴런에 과도하게 의존하지 못하게 합니다.

비율 0.5는 50%의 뉴런을 끈다는 의미입니다. weight_decay=1e-4L2 정규화를 적용합니다.

가중치가 너무 커지는 것을 방지해 모델이 단순해지고 과적합이 줄어듭니다. 세 번째 방법은 신중한 학습 전략입니다.

데이터가 적을 때는 배치 크기를 작게 설정하는 것이 좋습니다. 배치 크기가 크면 그래디언트가 너무 안정적이어서 일반화에 불리합니다.

배치 크기 8-16 정도가 적당합니다. 또한 Early Stopping을 적극 활용해야 합니다.

검증 손실이 증가하기 시작하면 즉시 학습을 멈춥니다. 과적합이 시작되는 순간을 놓치지 않는 것이 중요합니다.

실제 현업에서는 어떻게 활용할까요? 제조업체에서 제품 불량 검사 AI를 만든다고 가정해봅시다.

불량품 샘플이 50개밖에 없습니다. 불량품은 드물게 발생하므로 많은 샘플을 수집하기 어렵습니다.

이럴 때 데이터 증강을 적극 활용합니다. 회전, 반전, 밝기 조정 등을 적용해 50개 샘플에서 수천 개의 변형을 만듭니다.

또한 정상 제품 데이터로 사전 학습한 모델을 가져와 Fine-tuning합니다. 강력한 Dropout과 Weight Decay를 적용하고, 조기 종료를 설정합니다.

이렇게 하면 적은 불량 샘플만으로도 90% 이상의 정확도를 달성할 수 있습니다. 하지만 주의할 점도 있습니다.

데이터 증강이 항상 좋은 것은 아닙니다. 의미 없는 변형은 오히려 성능을 떨어뜨립니다.

예를 들어 숫자 인식에서 상하 반전은 6과 9를 혼동시킵니다. 작업의 특성을 고려해서 적절한 증강만 선택해야 합니다.

Dropout 비율도 주의해야 합니다. 너무 높으면 모델의 표현력이 떨어집니다.

일반적으로 0.3-0.5 사이가 적당하며, 데이터가 정말 적다면 0.7까지 올릴 수 있습니다. 배치 크기가 너무 작으면 배치 정규화가 제대로 작동하지 않습니다.

배치 크기 8 미만일 때는 배치 정규화를 Group Normalization이나 Layer Normalization으로 교체하는 것이 좋습니다. 다시 최지은 씨의 이야기로 돌아가 봅시다.

200장의 데이터에 강력한 증강과 정규화를 적용한 결과, 최지은 씨는 92%의 정확도를 달성했습니다. "정말 신기해요!

이렇게 적은 데이터로도 되다니!" 최지은 씨가 기뻐했습니다. 적은 데이터로 학습하는 기법을 제대로 이해하면 데이터 수집이 어려운 환경에서도 실용적인 모델을 만들 수 있습니다.

전이학습, 데이터 증강, 정규화를 결합하면 수백 장의 데이터만으로도 놀라운 결과를 얻을 수 있습니다.

실전 팁

💡 - 데이터가 500장 미만이라면 데이터 증강을 최대한 활용하세요. 하지만 도메인에 맞는 의미 있는 증강만 선택하세요.

  • Dropout은 데이터가 적을수록 강하게(0.5-0.7) 적용하세요.
  • Mixup이나 CutMix 같은 고급 증강 기법도 시도해보세요. 두 이미지를 섞어 새로운 샘플을 만드는 방법으로, 매우 적은 데이터에서 효과적입니다.

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#Python#TransferLearning#FineTuning#DeepLearning#NeuralNetworks#Transfer Learning,Fine-tuning

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.