3 분 소요

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()

image.png

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()

image.png

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()

image.png

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()

image.png

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()

image.png

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()

image.png

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까지 올라온다.

1.png

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()

image.png

# 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()

image.png

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()

image.png

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()

image.png

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()

image.png

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()

image.png

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()

image.png

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()

image.png

태그:

카테고리:

업데이트:

댓글남기기