[딥러닝] 전이 학습과 파인 튜닝: 기존 모델 재사용, 파인 튜닝 기법
전이 학습 소개
전이 학습의 정의
전이 학습(Transfer Learning)이란 이미 한 분야 또는 한 문제에 대해 학습된 모델의 지식을, 다른 분야 또는 다른 문제 해결에 활용하는 기법입니다. 이 접근 방식은 인간이 과거의 경험으로부터 얻은 지식을 새로운 상황에 적용하는 방식에 영감을 받았습니다. 인공 지능 분야에서 이 기법은 데이터가 부족하거나, 학습에 많은 시간과 자원이 필요한 상황에서 특히 중요하게 사용됩니다.
전이 학습의 원리
전이 학습의 핵심 원리는 이미 학습된 모델이 가지고 있는 지식(특히, 특징 추출 능력)을 새로운, 비슷한 문제에 재사용하는 것입니다. 예를 들어, 강아지와 고양이를 구분하는 모델이 있을 때, 이 모델에서 학습된 특징 추출기(feature extractor)는 다른 종류의 동물을 분류하는 데에도 유용할 수 있습니다. 이렇게 하면 새로운 문제에 대한 모델을 처음부터 학습시키지 않아도 되므로, 학습 시간을 단축시키고, 필요한 데이터의 양을 줄일 수 있습니다.
전이 학습의 장점
전이 학습을 사용함으로써 기대할 수 있는 주요 장점은 다음과 같습니다.
- 데이터 절약: 이미 학습된 모델을 사용하기 때문에, 새로운 작업을 위한 레이블이 지정된 데이터의 양을 크게 줄일 수 있습니다.
- 학습 시간 단축: 사전 학습된 모델을 활용함으로써, 새로운 작업에 대한 학습 시간을 상당히 줄일 수 있습니다.
- 성능 개선: 대규모 데이터셋으로 미리 학습된 모델은 보통 고수준의 패턴을 이미 잘 파악하고 있기 때문에, 새로운 과제에 적용할 때 더 뛰어난 성능을 낼 가능성이 높습니다.
- 일반화 능력 강화: 다양한 작업을 위해 전이 학습을 적용하면 모델의 일반화 능력이 강화되어, 보지 못한 데이터에 대한 예측력도 개선될 수 있습니다.
예시 코드 (PyTorch)
이제 PyTorch를 사용하여 전이 학습의 한 예시를 살펴보겠습니다. 널리 알려진 ResNet
모델을 사용하여, 이미 학습된 파라미터를 활용하여 새로운 분류 작업에 적용하는 간단한 예시입니다.
import torch
import torchvision.models as models
from torch import nn
# 사전 학습된 ResNet 모델 로드
resnet = models.resnet18(pretrained=True)
# 모든 파라미터를 고정(학습되지 않도록)
for param in resnet.parameters():
param.requires_grad = False
# ResNet의 마지막 Fully Connected Layer를 새로운 작업에 맞게 교체
num_features = resnet.fc.in_features
resnet.fc = nn.Linear(num_features, 100) # 예를 들어, 100개의 클래스가 있는 새 작업을 가정
# 새로운 작업에 대해 모델 학습
# 이 예시에서는 학습 과정 코드는 생략하고, 모델 구조 변경 부분만을 강조합니다.
위 코드에서는 PyTorch의 torchvision.models
를 사용하여 사전 학습된 ResNet18
모델을 로드하고, 마지막 분류 층을 새 작업에 맞게 교체하였습니다. 이렇게 하여 ResNet18
의 강력한 특징 추출 능력을 새로운 작업에 적용할 수 있습니다.
전이 학습은 많은 딥러닝 분야에서 효과적이며, 특히 데이터가 부족할 때 그 가치가 더욱 빛나는 방법입니다. 여기에는 이미지 분류, 자연어 처리(NLP), 음성 인식 등 다양한 분야가 있습니다. 다음은 각 분야에서 전이 학습을 활용하는 구체적인 사례들입니다.
이미지 분류
이미지 분류에서 전이 학습을 활용하는 가장 대표적인 방법은 사전 학습된 네트워크를 사용하는 것입니다. 이는 이미 대규모 데이터셋(예를 들어 ImageNet)으로 학습되었으며, 이와 관련된 고수준의 특징을 추출할 수 있는 능력을 갖고 있습니다. 파이토치(PyTorch)를 사용하면 사전 학습된 모델을 쉽게 불러와 사용할 수 있습니다.
import torch
from torchvision import models, transforms
from torch import nn
# 사전 학습된 ResNet 모델 불러오기
model = models.resnet18(pretrained=True)
# 새 데이터셋에 맞춰 마지막 레이어 수정
num_ftrs = model.fc.in_features
model.fc = nn.Linear(num_ftrs, 100) # 예를 들어 새로운 데이터셋이 100개 클래를 가지고 있다고 가정
# 모델을 필요한 환경(cpu 또는 gpu)으로 이동
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model = model.to(device)
이 예제에서는 ResNet18 모델을 사용했습니다. 마지막 fully connected layer를 새로운 데이터셋에 적합하도록 수정했습니다. 사전 학습된 네트워크의 대부분의 층은 동결시킨 채 마지막 몇 층만을 학습하여 새로운 작업에 맞게 조정합니다.
자연어 처리(NLP)
NLP에서도 전이 학습은 큰 변화를 가져왔습니다. 예를 들어 BERT와 같은 사전 학습 모델은 다양한 NLP 태스크에서 사용될 수 있는 풍부한 언어적 특징들을 이미 학습하고 있습니다.
from transformers import BertModel, BertTokenizer
# BERT 모델 및 토크나이저 로드
model = BertModel.from_pretrained('bert-base-uncased')
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
# 텍스트를 BERT가 이해할 수 있는 형태로 변환
input_text = "Hello, world!"
input_ids = tokenizer.encode(input_text, add_special_tokens=True)
# 모델에 입력
with torch.no_grad():
outputs = model(torch.tensor([input_ids]))
last_hidden_states = outputs.last_hidden_state
# 여기서 last_hidden_states를 사용하여 필요한 작업 수행
BERT와 같은 사전 학습된 모델을 사용할 때, 모델의 마지막 몇 층을 수정하여 특정 NLP 태스크에 맞게 조정하는 방식으로 전이 학습을 수행할 수 있습니다.
음성 인식
음성 인식 또한 전이 학습의 혜택을 받는 분야입니다. 이 분야에서는 대규모 음성 데이터에 대해 사전 학습된 모델을 사용하고, 해당 모델을 특정 음성 인식 작업에 맞게 조정하여 사용할 수 있습니다.
PyTorch를 사용하는 예시는 다음과 같습니다.
# 음성 인식을 위한 사전 학습된 모델 로드 예시 코드는 공개된 자료에 기반한 사용 가능한 모델이 필요하므로
# 직접적인 예시는 생략하나, 아이디어는 이미지 분류나 NLP에서 사용하는 것과 유사합니다.
# 예를 들어, 음성 인식 모델의 특정 부분을 새로운 음성 데이터셋에 맞게 Fine-tuning합니다.
음성 인식의 경우 특정 언어, 발화자의 특성, 또는 억양 등을 잘 처리하기 위해 사전 학습된 모델을 세밀하게 조정할 필요가 있습니다. 이때 적은 양의 특화된 데이터로도 좋은 성능을 달성할 수 있게 해주는 것이 전이 학습의 장점입니다.
각 분야에서 전이 학습을 활용함으로써, 상대적으로 적은 데이터와 계산 자원으로도 뛰어난 성능의 모델을 효율적으로 개발할 수 있는 가능성을 열어줍니다.
파인 튜닝(Fine-tuning) 소개
파인 튜닝의 정의
파인 튜닝은 이미 대량의 데이터로 훈련된 모델(보통은 심층 신경망)을 가져와서, 그 모델을 새로운, 비교적 작은 데이터셋을 대상으로 추가적인 학습을 시키는 과정을 말합니다. 전이 학습의 한 형태인 파인 튜닝에서는 기존 모델의 구조와 많은 학습된 특성(파라미터)들을 재활용하지만, 모델의 마지막 몇 층을 새로운 작업에 맞게 변경하고 다시 학습시키는 것이 일반적입니다. 따라서 전이 학습에 비해 모델의 더 많은 부분을 수정하고, 특정 작업에 더욱 특화시키는 것이 파인 튜닝의 특징이라 할 수 있습니다.
파인 튜닝의 과정
파인 튜닝은 대체로 다음과 같은 단계를 포함합니다:
-
사전학습된 모델 선택: 우선, 특정 작업에 맞게 사전에 학습된 모델을 선택합니다. 이 모델은 일반적으로 방대한 데이터셋(예: ImageNet)에서 학습되어 복잡한 특성을 인식할 수 있는 능력을 가지고 있습니다.
-
모델의 마지막 층을 새로운 작업에 맞게 변경: 기존 모델의 마지막 층(보통은 분류를 위한 층)을 새로운 작업의 출력 사이즈에 맞게 변경합니다. 예를 들어, 강아지와 고양이를 분류하는 1000개 클래스의 모델을 가져와 20개의 다양한 물체를 분류하는 작업에 맞게 마지막 층을 변경할 수 있습니다.
-
모델의 초기 가중치 고정: 선택적인 단계로, 모델의 일부 또는 대부분의 가중치를 고정시켜 그 부분을 학습에서 제외시킬 수 있습니다. 이를 통해 학습 시간을 단축시키고, 작은 데이터셋에서 과적합(overfitting)의 위험을 줄일 수 있습니다.
-
새로운 데이터셋으로 학습: 새로운 작업에 맞게 변경된 모델을 사용해 새로운 데이터셋으로 학습을 진행합니다. 이때 수정된 층 또는 추가된 층에 대해서만 가중치가 업데이트 됩니다.
-
모든 층을 대상으로 미세 조정: 필요에 따라 모델의 모든 층(혹은 더 많은 층)에 대하여 학습률을 매우 낮게 설정하여 전체 모델을 미세조정할 수 있습니다.
파이토치(PyTorch)를 이용한 파인 튜닝 예제 코드
import torch
import torchvision.models as models
import torch.nn as nn
import torch.optim as optim
# 사전학습된 모델 로드
model = models.resnet18(pretrained=True)
# 모델의 마지막 층 변경
num_ftrs = model.fc.in_features
model.fc = nn.Linear(num_ftrs, 20) # 20개의 클래스로 변경
# 필요한 경우에만 특정 층의 가중치를 고정
for param in model.parameters():
param.requires_grad = False
# 마지막 층의 가중치는 학습할 수 있도록 설정
for param in model.fc.parameters():
param.requires_grad = True
# 옵티마이저와 손실 함수 정의
optimizer = optim.Adam(model.fc.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()
# 이후에는 일반적인 학습 과정을 따릅니다. (데이터 로딩, 학습 반복 등)
이 코드는 사전학습된 ResNet-18 모델을 가져와서 분류 층을 수정하고, 마지막 분류 층만을 대상으로 학습을 진행하는 예시를 보여줍니다. 전체 모델을 미세조정하기 위해서는 optimizer
에 모델의 모든 파라미터를 포함시키고 아주 작은 학습률을 사용해야 합니다.
파인 튜닝 활용 기법
파인 튜닝은 사전에 학습된 모델을 새로운, 보통 작고 특정한 데이터셋에 대해 추가적으로 학습시켜서 성능을 개선하는 기법입니다. 이 과정에서 몇 가지 중요한 단계가 있습니다.
모델 선택
파인 튜닝에 적합한 모델 선택은 해당 태스크에 대해 이미 좋은 성능을 보여준 모델을 고르는 데 기반합니다. 일반적으로, 큰 데이터셋에서 사전 학습된 모델이 좋은 출발점이 됩니다. 예를 들어, 이미지 처리에서는 ResNet, Inception, VGG 등이 널리 사용됩니다. 자연어 처리에서는 BERT, GPT, Transformer 등이 좋은 선택이 될 수 있습니다. 주요 판단 기준은 사전 학습된 모델이 타겟 데이터셋과 얼마나 유사한지, 그리고 계산 리소스의 제약이 어떠한지입니다.
데이터 준비
파인 튜닝을 위한 데이터는 사전 학습 단계에서 사용된 것보다 훨씬 작을 수 있으며, 타겟 태스크에 매우 특화되어 있습니다. 데이터는 크게 훈련 세트와 검증 세트로 나뉘며, 때로는 테스트 세트도 준비할 수 있습니다. 데이터의 퀄리티가 높을수록 파인 튜닝의 결과도 좋아집니다. 데이터 증강(Data Augmentation)과 같은 기법을 사용해 훈련 데이터의 다양성을 높이는 것은 파인 튜닝에서 큰 도움이 될 수 있습니다.
학습률 조정
파인 튜닝 시 가장 중요한 하이퍼파라미터 중 하나는 학습률입니다. 파인 튜닝 과정에서 너무 높은 학습률은 사전 학습된 모델의 가중치를 너무 많이 변형시킬 수 있으며, 너무 낮은 학습률은 새로운 데이터에 모델이 잘 적응하지 못하게 할 수 있습니다. 이를 조절하기 위해 학습률 스케줄러를 사용할 수 있으며, 초기에는 높은 학습률에서 시작해 점차 낮춰가는 방법이 일반적입니다.
import torch
from torch import nn
from torch.optim import Adam
from torch.optim.lr_scheduler import StepLR
model = ... # 사전 학습된 모델 로드
optimizer = Adam(model.parameters(), lr=0.001) # 초깃값으로 설정
scheduler = StepLR(optimizer, step_size=30, gamma=0.1) # 30 에폭마다 lr를 10% 감소
과적합 방지
파인 튜닝은 종종 데이터의 양이 제한적이기 때문에 과적합이 발생하기 쉽습니다. 과적합을 방지하기 위한 몇 가지 방법은 다음과 같습니다.
- 데이터 증강: 이미지 회전, 뒤집기, 자르기 등 데이터의 다양성을 증가시킵니다.
- 드롭아웃(Dropout): 학습 과정에서 무작위로 뉴런의 일부를 생략해 과적합을 방지합니다.
- 조기 종료(Early Stopping): 검증 데이터셋의 성능이 더 이상 개선되지 않을 때 학습을 중단합니다.
from torch.nn import functional as F
class MyModel(nn.Module):
def __init__(self):
super(MyModel, self).__init__()
# 모델 구조 정의
self.dropout = nn.Dropout(0.5) # 드롭아웃 적용
def forward(self, x):
x = ... # 일부 계산
x = self.dropout(x) # 드롭아웃 적용 부분
return x
파인 튜닝은 사전 학습된 모델을 최대한 활용하여 적은 노력으로 좋은 성능을 얻는 기법입니다. 위에서 언급된 기법들을 적절히 조합하고 실험하여 최적의 결과를 도출하시기 바랍니다.