딥러닝 모델을 학습할 때, 학습률(Learning Rate)은 학습 성능에 큰 영향을 미칩니다. 학습률을 잘못 설정하면 학습이 너무 느리거나, 최적화 과정에서 손실함수가 발산할 수 있습니다. 이를 해결하기 위해 학습 중에 학습률 스케줄링 기법을 사용하여 학습률을 점진적으로 조절하는 방법이 있습니다.
이번 포스팅에서는 8가지 대표적인 학습률 스케줄링 기법에 대해 설명합니다.
각 기법의 개념과 PyTorch에서 사용하는 방법을 함께 소개할게요.
1. StepLR
개념
StepLR은 일정한 주기마다 학습률을 일정 비율로 감소시키는 방식입니다. 예를 들어, 매 10 에폭마다 학습률을 50%씩 줄이도록 설정할 수 있습니다. 학습 초기에는 큰 학습률로 빠르게 최적화하고, 후반부로 갈수록 더 작은 학습률로 세밀한 조정을 합니다.
import torch.optim as optim
# 학습 데이터 로더에서 한 에폭당 스텝 수를 계산
steps_per_epoch = len(train_loader)
# 학습률을 현재의 50%로 감소시키기 위한 gamma 값 설정
scheduler_gamma = 0.5
# 10 에폭마다 학습률을 감소시키기 위한 설정
epochs_per_lr_decay = 10
scheduler_step_size = steps_per_epoch * epochs_per_lr_decay
# StepLR 스케줄러 선언
scheduler = optim.lr_scheduler.StepLR(
optimizer,
step_size=scheduler_step_size, # 몇 스텝마다 학습률을 감소시킬지 결정
gamma=scheduler_gamma # 학습률 감소 비율
)
여기서 step_size는 몇 에폭마다 학습률을 감소시킬지, gamma는 감소 비율을 의미합니다. 위 예시에서는 10 에폭마다 학습률을 절반으로 감소시킵니다.
2. ExponentialLR
개념
ExponentialLR은 학습률을 매 스텝마다 일정 비율로 감소시키는 방식입니다. 이를 통해 학습률이 점진적으로 줄어들며, 수렴을 더 안정적으로 만들어 줍니다.
scheduler = optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.9)
여기서 gamma는 매 스텝마다 학습률을 곱할 값입니다. 위 설정은 매 스텝마다 학습률이 90%로 감소됩니다.
- Epoch 1: lr = 0.01 * 0.9 = 0.009
- Epoch 2: lr = 0.009 * 0.9 = 0.0081
- Epoch 3: lr = 0.0081 * 0.9 = 0.007293
Step: optimizer.step() 호출 후 매번 학습률이 변경됩니다.
Epoch: 에폭이 끝난 후 scheduler.step()을 호출하면, 1 에폭이 끝날 때마다 학습률이 업데이트됩니다.
import torch
import torch.optim as optim
import torch.nn as nn
# 간단한 모델 정의
model = nn.Linear(10, 2)
# 옵티마이저 정의
optimizer = optim.SGD(model.parameters(), lr=0.01)
# ExponentialLR 스케줄러 정의 (gamma=0.9)
scheduler = optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.9)
# 손실 함수 정의
criterion = nn.CrossEntropyLoss()
# 예시 학습 루프
num_epochs = 10
for epoch in range(num_epochs):
model.train()
# 여기에 데이터 로딩 및 배치 처리 코드가 들어가야 합니다.
# 예시:
inputs = torch.randn(64, 10) # 입력 데이터
labels = torch.randint(0, 2, (64,)) # 라벨 데이터
# 순전파
outputs = model(inputs)
loss = criterion(outputs, labels)
# 역전파 및 옵티마이저 업데이트
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 에폭이 끝날 때마다 스케줄러로 학습률 조정
scheduler.step()
# 학습률 출력 (옵션)
print(f'Epoch {epoch+1}/{num_epochs}, Learning Rate: {scheduler.get_last_lr()[0]:.6f}, Loss: {loss.item():.4f}')
3. CosineAnnealingLR
개념
CosineAnnealingLR은 학습률을 Cosine 함수에 기반해 감소시키는 방식입니다. 학습률이 감소하다가 일정 주기 이후에 다시 원래 값으로 복원됩니다. 이 방식은 학습 중에도 다양한 학습률을 탐색할 수 있어, 더 나은 수렴을 도와줍니다.
scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=50)
- T_max: 학습률이 최솟값에 도달하는 에폭 수를 의미합니다. 예를 들어, T_max=50으로 설정하면 학습률은 50 에폭 동안 점진적으로 감소한 후 다시 원래 값으로 돌아갑니다.
이 스케줄러는 학습률이 주기적으로 줄어들다가 다시 증가하는 방식으로 작동하여, 여러 학습률을 탐색할 수 있습니다.
4. ReduceLROnPlateau
개념
ReduceLROnPlateau는 학습 성능이 더 이상 향상되지 않을 때, 자동으로 학습률을 줄이는 방식입니다. 모델이 특정 기준 이상으로 성능이 개선되지 않으면 학습률을 감소시켜 더 세밀하게 학습할 수 있게 돕습니다.
scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', patience=10, factor=0.1)
- mode: 성능 지표의 향상 여부를 결정하는 기준입니다. min은 손실 함수가 감소하지 않으면 학습률을 줄이겠다는 의미입니다.
- patience: 성능 향상이 없을 때, 몇 에폭을 기다린 후 학습률을 줄일지 결정합니다. patience=10은 10 에폭 동안 개선이 없으면 학습률을 줄이게 됩니다.
- factor: 학습률을 얼마나 줄일지 결정하는 비율입니다. factor=0.1은 학습률을 10%로 감소시킵니다.
5. CyclicLR
개념
CyclicLR은 학습률을 주기적으로 증가 및 감소시키는 방식입니다. 학습률을 낮은 값에서 시작해 높은 값으로 증가시킨 후 다시 감소시키는 사이클을 반복합니다. 이를 통해 모델이 학습률 탐색을 더 효과적으로 수행할 수 있습니다.
scheduler = optim.lr_scheduler.CyclicLR(optimizer, base_lr=0.001, max_lr=0.01, step_size_up=10)
- base_lr: 학습률의 최솟값입니다. base_lr=0.001은 학습률이 가장 낮을 때 0.001이 된다는 의미입니다.
- max_lr: 학습률의 최댓값입니다. max_lr=0.01은 학습률이 가장 높을 때 0.01이 됩니다.
- step_size_up: 학습률이 최댓값에 도달할 때까지 걸리는 스텝 수입니다. step_size_up=10은 10 스텝 동안 학습률이 증가한다는 의미입니다.
이 스케줄러는 학습률을 반복적으로 증가시키고 감소시키는 사이클을 만들어, 다양한 학습률을 탐색합니다.
6. OneCycleLR
개념
OneCycleLR은 한 사이클 동안 학습률을 점진적으로 증가시키고, 이후 감소시키는 방식입니다. 학습 초기에는 큰 학습률로 빠르게 수렴하고, 후반부로 갈수록 학습률을 줄여 더 안정적인 학습을 진행합니다.
scheduler = optim.lr_scheduler.OneCycleLR(optimizer, max_lr=0.01, total_steps=100)
- max_lr: 사이클 중 학습률이 가장 높아질 때의 값을 나타냅니다.
- total_steps: 한 사이클 동안의 총 스텝 수를 의미합니다. total_steps=100이면, 100 스텝 동안 학습이 진행됩니다.
이 스케줄러는 학습 초기에 학습률을 빠르게 증가시켜 빠르게 최적화한 후, 이후에는 감소시켜 세밀한 학습을 수행할 수 있게 합니다.
7. PolynomialLR (PolyLR)
PolynomialLR은 학습률을 다항식(polynomial) 함수에 따라 감소시키는 방식입니다. 이 기법은 학습률을 처음에는 높게 설정하고, 학습이 진행될수록 점차 감소시킵니다. 이 방식은 학습률이 감소하는 속도를 다항식의 차수(파워)를 이용해 조절할 수 있습니다.
개념 설명
- max_iter: 학습이 끝나는 시점에서의 총 반복 수를 의미합니다. 이 값은 학습률이 다항식에 의해 감소될 전체 스텝 수를 나타냅니다.
- power: 다항식의 차수를 의미합니다. power=2는 2차 함수에 의해 학습률이 감소하고, power=1은 선형적으로 감소하는 형태를 의미합니다. 값이 클수록 학습률이 더 빠르게 감소합니다.
import torch.optim as optim
# 옵티마이저 선언
optimizer = optim.SGD(model.parameters(), lr=0.01)
# PolynomialLR 스케줄러 선언
scheduler = optim.lr_scheduler.PolynomialLR(optimizer, max_iter=100, power=2)
- max_iter: 학습이 끝나는 시점에서의 총 반복 수를 의미합니다.
- power: 학습률 감소를 조절하는 다항식의 차수입니다. power=2는 2차 함수로 학습률을 감소시키겠다는 의미입니다.
학습률 변화 예시
- 학습 초반: 높은 학습률로 빠르게 최적화.
- 학습 중반: 학습률이 서서히 줄어듭니다.
- 학습 후반: 학습률이 매우 작아져 세밀하게 최적화됩니다.
그래프 설명
학습률이 다항식 함수에 따라 점차 줄어들며, 학습 후반부로 갈수록 학습률이 급격히 줄어듭니다. 이를 통해 학습 초반에는 빠른 수렴을 돕고, 후반에는 안정적인 학습을 유도합니다.
8. LambdaLR
LambdaLR은 학습률을 사용자가 정의한 람다 함수에 따라 조정하는 방식입니다. 이 기법은 매우 유연하며, 특정한 방식으로 학습률을 변경하고자 할 때 유용합니다. 사용자가 직접 정의한 함수를 사용해 학습률을 변화시키기 때문에, 학습률 변화를 세밀하게 조절할 수 있습니다.
개념 설명
- lr_lambda: 학습률 변화를 제어하는 사용자 정의 함수입니다. 이 함수를 통해 학습률이 특정 조건에 따라 변하도록 만들 수 있습니다.
- **에폭(epoch)**을 인자로 받아, 학습률이 에폭에 따라 어떻게 변할지 결정합니다.
import torch.optim as optim
# 옵티마이저 선언
optimizer = optim.SGD(model.parameters(), lr=0.01)
# LambdaLR 스케줄러 선언
lambda1 = lambda epoch: 0.95 ** epoch # 에폭마다 학습률이 95%로 감소
scheduler = optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=lambda1)
- lambda1 = lambda epoch: 0.95 ** epoch: 에폭이 진행될수록 학습률을 95%로 줄입니다. 첫 에폭에서는 학습률이 0.01이었다면, 두 번째 에폭에서는 0.01 * 0.95, 세 번째 에폭에서는 0.01 * 0.95^2가 됩니다.
학습률 변화 예시:
- 첫 번째 에폭: 학습률이 0.01.
- 두 번째 에폭: 학습률이 0.01 * 0.95 = 0.0095.
- 세 번째 에폭: 학습률이 0.01 * (0.95^2) = 0.009025.
그래프 설명:
LambdaLR을 사용하면 학습률이 사용자가 정의한 함수에 따라 자유롭게 변화합니다. 위 예시에서는 학습률이 매 에폭마다 95%로 감소하지만, 이 함수는 사용자가 원하는 대로 정의할 수 있습니다.
'AI > 딥러닝' 카테고리의 다른 글
SVM(Support Vector Machine) 이란? [R-CNN] (0) | 2024.09.03 |
---|---|
Bottom-up Region Proposals 이란? [R-CNN] (4) | 2024.09.03 |
[Ch.02] 01 - CNN 모델 만들기 part 1 (0) | 2023.01.04 |
[Ch.01] 04 - 다중 분류 Mnist (0) | 2023.01.03 |
[Ch.01] 03 - Pytorch 를 활용한 간단한 회귀분석 (0) | 2023.01.02 |
댓글