Pytorch Learning Rate Scheduler 정리 및 시각화
Learning Rate Scheduler
모델을 학습할 때 사용되는 learning rate에 따라 모델의 학습 정도가 크게 달라질 수 있다.
learning rate를 사용하는 기법은 계속 같은 learning rate를 사용해도 되지만
처음엔 learning rate를 큰 값을 사용했다가 최적값에 가까워질수록 값을 줄여 미세조정을 하거나
learning rate를 줄였다 늘렸다 하는 것도 성능향상에 크게 도움이 된다.
이때 학습에 사용되는 learning rate를 optimizer에 접근하여 수정이 가능하다.
- optimizer.param_groups[0][‘lr’]
import torch
import matplotlib.pyplot as plt
model = torch.nn.Linear(1, 1)
optimizer = torch.optim.SGD(model.parameters(), lr=100)
LambdaLR
LambdaLR은 가장 유연한 learning rate scheduler
Lambda 표현식으로 작성한 함수를 통해 learning rate를 조절한다.
- lr = 초기lr * lambda(epoch)
optimizer = torch.optim.SGD(model.parameters(), lr=100)
scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer=optimizer,
lr_lambda=lambda epoch: 0.95 ** epoch)
lrs = []
for i in range(100):
optimizer.step()
lrs.append(optimizer.param_groups[0]["lr"])
scheduler.step()
plt.plot(range(100),lrs)
plt.show()
optimizer = torch.optim.SGD(model.parameters(), lr=100)
def func(epoch):
if epoch < 40:
return 0.5
elif epoch < 70:
return 0.5 ** 2
elif epoch < 90:
return 0.5 ** 3
else:
return 0.5 ** 4
scheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda = func)
lrs = []
for i in range(100):
optimizer.step()
lrs.append(optimizer.param_groups[0]["lr"])
scheduler.step()
plt.plot(range(100),lrs)
plt.show()
MultiplicativeLR
초기 learning rate에 lambda함수에서 나온 값을 누적곱해서 learning rate를 계산한다.
- lr = 이전lr * lambda(epoch)
optimizer = torch.optim.SGD(model.parameters(), lr=100)
scheduler = torch.optim.lr_scheduler.MultiplicativeLR(optimizer=optimizer,
lr_lambda=lambda epoch: 0.95 ** epoch)
lrs = []
for i in range(100):
optimizer.step()
lrs.append(optimizer.param_groups[0]["lr"])
scheduler.step()
plt.plot(range(100),lrs)
plt.show()
Step LR
특정 Step에 따라 lr 를 감소시키는 Scheduler
- StepLR(optimizer, step_size=20, gamma=0.5)
step_size 마다 gamma를 곱한다.
optimizer = torch.optim.SGD(model.parameters(), lr=100)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=20, gamma=0.5)
lrs = []
for i in range(100):
optimizer.step()
lrs.append(optimizer.param_groups[0]["lr"])
scheduler.step()
plt.plot(range(100),lrs)
plt.show()
MultiStepLR
step이 아닌 지정한 epoch마다 lr 감소
optimizer = torch.optim.SGD(model.parameters(), lr=100)
scheduler = torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones=[20,50,80], gamma=0.5)
lrs = []
for i in range(100):
optimizer.step()
lrs.append(optimizer.param_groups[0]["lr"])
scheduler.step()
plt.plot(range(100),lrs)
plt.show()
ExponentialLR
지수적(exponential)으로 learning rate가 감소
lr = 이전lr * gamma
optimizer = torch.optim.SGD(model.parameters(), lr=100)
scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.8)
lrs = []
for i in range(100):
optimizer.step()
lrs.append(optimizer.param_groups[0]["lr"])
scheduler.step()
plt.plot(range(100),lrs)
plt.show()
ReduceLROnPlateau
성능이 향상이 없을 때 learning rate를 감소
validation loss나 metric(평가지표)을 learning rate step함수의 input으로 넣어주어야 한다. 그래서 metric이 향상되지 않을 때, patience횟수(epoch)만큼 참고 그 이후에는 learning rate를 줄인다. optimizer에 momentum을 설정해야 사용할 수 있다.
- ReduceLROnPlateau(optimizer, ‘min’, factor=0.1, patience=5, min_lr=0.0001)
CosineAnnealingLR
cosine 그래프를 그리면서 learning rate가 진동하는 방식
- CosineAnnealingLR(optimizer, T_max=50, eta_min=0)
T_max: 최대 iteration 횟수
learing rate가 cos함수를 따라서 eta_min까지 떨어졌다 다시 초기 learning rate까지 올라온다.
optimizer = torch.optim.SGD(model.parameters(), lr=0.001)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=10, eta_min=0)
lrs = []
for i in range(100):
optimizer.step()
lrs.append(optimizer.param_groups[0]["lr"])
scheduler.step()
plt.plot(range(100),lrs)
plt.show()
# T_max = 10 -> 50
optimizer = torch.optim.SGD(model.parameters(), lr=0.001)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=50, eta_min=0)
lrs = []
for i in range(100):
optimizer.step()
lrs.append(optimizer.param_groups[0]["lr"])
scheduler.step()
plt.plot(range(100),lrs)
plt.show()
CyclicLR
CosineAnnealingLR은 단순한 cosine 곡선인 반면에 CyclicLR은 3가지 모드를 지원하면서 변화된 형태로 주기적인 learning rate 증감을 지원
-
triangular1
-
triangular2
-
exp_range
CyclicLR(optimizer, base_lr=0.001, max_lr=0.1, step_size_up=50, step_size_down=100, mode=’triangular’)
base_lr은 가장 작은 lr, max_lr은 가장 큰 lr,
step_size_up은 base_lr → max_lr로 증가하는 epoch 수가 되고 step_size_down은 반대로 max_lr → base_lr로 감소하는 epoch 수가 된다.
triangular1
optimizer = torch.optim.SGD(model.parameters(), lr=0.001)
scheduler = torch.optim.lr_scheduler.CyclicLR(optimizer, base_lr=0.001, max_lr=0.1, step_size_up=10, step_size_down=20, mode='triangular')
lrs = []
for i in range(100):
optimizer.step()
lrs.append(optimizer.param_groups[0]["lr"])
scheduler.step()
plt.plot(range(100),lrs)
plt.show()
triangular2
optimizer = torch.optim.SGD(model.parameters(), lr=0.001)
scheduler = torch.optim.lr_scheduler.CyclicLR(optimizer, base_lr=0.001, max_lr=0.1, step_size_up=10, step_size_down=20, mode='triangular2')
lrs = []
for i in range(100):
optimizer.step()
lrs.append(optimizer.param_groups[0]["lr"])
scheduler.step()
plt.plot(range(100),lrs)
plt.show()
exp_range
optimizer = torch.optim.SGD(model.parameters(), lr=0.001)
scheduler = torch.optim.lr_scheduler.CyclicLR(optimizer, base_lr=0.001, max_lr=0.1, step_size_up=10, mode='exp_range', gamma=0.85)
lrs = []
for i in range(100):
optimizer.step()
lrs.append(optimizer.param_groups[0]["lr"])
scheduler.step()
plt.plot(range(100),lrs)
plt.show()
OneCycleLR
초기 lr에서 1cycle annealing하는 scheduler
초기 lr에서 최대 lr까지 올라간 후 초기 lr보다 훨씬 낮은 lr로 annealing한다.
2가지 모드 지원
-
cos(default)
-
linear
OneCycleLR(optimizer, max_lr=0.1, steps_per_epoch=10, epochs=10,anneal_strategy=’linear’)
optimizer = torch.optim.SGD(model.parameters(), lr=0.001)
scheduler = torch.optim.lr_scheduler.OneCycleLR(optimizer, max_lr=0.1, steps_per_epoch=10, epochs=10)
lrs = []
for i in range(100):
optimizer.step()
lrs.append(optimizer.param_groups[0]["lr"])
scheduler.step()
plt.plot(range(100),lrs)
plt.show()
optimizer = torch.optim.SGD(model.parameters(), lr=0.001)
scheduler = torch.optim.lr_scheduler.OneCycleLR(optimizer, max_lr=0.1, steps_per_epoch=10, epochs=10,anneal_strategy='linear')
lrs = []
for i in range(100):
optimizer.step()
lrs.append(optimizer.param_groups[0]["lr"])
scheduler.step()
plt.plot(range(100),lrs)
plt.show()
CosineAnnealingWarmRestarts
cosine annealing 함수를 따르면서 Ti epoch마다 다시 시작한다.
T_0는 최초 주기값, T_mult는 주기가 반복되면서 최초 주기값에 비해 얼만큼 주기를 늘려나갈 것인가
optimizer = torch.optim.SGD(model.parameters(), lr=0.001)
scheduler = torch.optim.lr_scheduler.CosineAnnealingWarmRestarts(optimizer, T_0=10,
T_mult=2, eta_min=0.00001)
lrs = []
for i in range(100):
optimizer.step()
lrs.append(optimizer.param_groups[0]["lr"])
scheduler.step()
plt.plot(range(100),lrs)
plt.show()
댓글남기기