Класс OneCycleLR
Класс OneCycleLR реализует однопериодную политику изменения скорости обучения (learning rate schedule) в PyTorch. Этот метод был предложен Лесли Смитом и позволяет значительно ускорить сходимость нейронных сетей за счёт использования высоких скоростей обучения в середине цикла. Планировщик изменяет скорость обучения по следующему закону: от начального значения она возрастает до максимального, а затем убывает до очень малого значения к концу обучения.
Основное преимущество OneCycleLR заключается в том, что он позволяет достичь высокой точности модели за меньшее количество эпох. Этот метод особенно эффективен для задач компьютерного зрения и при работе с глубокими сетями.
Синтаксис
torch.optim.lr_scheduler.OneCycleLR(
optimizer,
max_lr,
steps_per_epoch=None,
epochs=None,
pct_start=0.3,
anneal_strategy='cos',
cycle_momentum=True,
base_momentum=0.85,
max_momentum=0.95,
div_factor=25.0,
final_div_factor=10000.0,
three_phase=False,
last_epoch=-1,
verbose=False
)
Параметры
Класс принимает следующие параметры для настройки цикла изменения скорости обучения:
optimizer - оптимизатор, для которого будет применяться планировщик;
max_lr - максимальное значение скорости обучения в цикле. Может быть задано числом или списком значений для разных групп параметров;
steps_per_epoch - количество шагов оптимизации (батчей) в одной эпохе. Обязателен, если не указан epochs;
epochs - общее количество эпох обучения. Обязателен, если не указан steps_per_epoch;
pct_start - доля от общего числа шагов, в течение которых скорость обучения возрастает от начальной до максимальной (по умолчанию 0.3);
anneal_strategy - стратегия уменьшения скорости обучения на второй половине цикла. Доступны значения 'cos' (косинусоидальная) и 'linear' (линейная). По умолчанию 'cos';
cycle_momentum - если True, то моментум изменяется синхронно со скоростью обучения (по умолчанию True);
base_momentum - минимальное значение моментума в начале и конце цикла (по умолчанию 0.85);
max_momentum - максимальное значение моментума в середине цикла (по умолчанию 0.95);
div_factor - коэффициент, определяющий начальную скорость обучения: initial_lr = max_lr / div_factor (по умолчанию 25.0);
final_div_factor - коэффициент, определяющий конечную скорость обучения: final_lr = initial_lr / final_div_factor (по умолчанию 10000.0);
three_phase - при True добавляется третья фаза, в которой скорость обучения снова возрастает от минимальной к максимальной (по умолчанию False);
last_epoch - индекс последней эпохи. При значении -1 планировщик начинает отсчёт с нуля (по умолчанию -1);
verbose - если True, планировщик выводит сообщения при обновлении скорости обучения (по умолчанию False).
Пример
Создадим простую нейронную сеть и применим к ней планировщик OneCycleLR:
import torch
import torch.nn as nn
from torch.optim import SGD
from torch.optim.lr_scheduler import OneCycleLR
# Создаем модель и оптимизатор
model = nn.Linear(20, 10)
optimizer = SGD(model.parameters(), lr=0.01, momentum=0.9)
# Инициализируем планировщик OneCycleLR
scheduler = OneCycleLR(
optimizer,
max_lr=0.1,
steps_per_epoch=20,
epochs=5,
pct_start=0.25
)
# Цикл обучения
for epoch in range(5):
for step in range(20):
# Имитация обучения
loss = torch.rand(1)
optimizer.zero_grad()
loss.backward()
optimizer.step()
scheduler.step()
# Отображаем текущую скорость обучения
current_lr = scheduler.get_last_lr()[0]
print(f"Epoch {epoch}, Step {step}: {current_lr:.6f}")
Результат выполнения кода:
Epoch 0, Step 0: 0.001000
Epoch 0, Step 1: 0.001900
Epoch 0, Step 2: 0.002800
Epoch 0, Step 3: 0.003700
Epoch 0, Step 4: 0.004600
Epoch 0, Step 5: 0.005500
Пример
Используем трёхфазный режим планировщика OneCycleLR для более гибкого управления скоростью обучения:
import torch
import torch.nn as nn
from torch.optim import Adam
from torch.optim.lr_scheduler import OneCycleLR
torch.manual_seed(0)
# Создаем модель и оптимизатор
model = nn.Sequential(
nn.Linear(10, 20),
nn.ReLU(),
nn.Linear(20, 1)
)
optimizer = Adam(model.parameters(), lr=0.001)
# Настраиваем OneCycleLR с тремя фазами
scheduler = OneCycleLR(
optimizer,
max_lr=0.01,
steps_per_epoch=10,
epochs=4,
three_phase=True,
pct_start=0.2,
div_factor=10.0,
final_div_factor=1000.0
)
# Симуляция обучения
for epoch in range(4):
for step in range(10):
loss = torch.rand(1)
optimizer.zero_grad()
loss.backward()
optimizer.step()
scheduler.step()
current_lr = scheduler.get_last_lr()[0]
print(f"Epoch {epoch}, Step {step}: LR = {current_lr:.6f}")
Результат выполнения кода:
Epoch 0, Step 0: LR = 0.001000
Epoch 0, Step 1: LR = 0.002700
Epoch 0, Step 2: LR = 0.005800
Epoch 0, Step 3: LR = 0.009100
Epoch 0, Step 4: LR = 0.009900
Epoch 0, Step 5: LR = 0.007500
Пример
Используем планировщик OneCycleLR с косинусоидальной стратегией уменьшения скорости обучения и синхронным изменением моментума:
import torch
import torch.nn as nn
from torch.optim import SGD
from torch.optim.lr_scheduler import OneCycleLR
torch.manual_seed(42)
# Создаем модель с двумя параметрами
model = nn.Linear(5, 5)
optimizer = SGD(model.parameters(), lr=0.001, momentum=0.9)
# Настраиваем OneCycleLR с изменением моментума
scheduler = OneCycleLR(
optimizer,
max_lr=0.05,
steps_per_epoch=8,
epochs=3,
pct_start=0.4,
anneal_strategy='cos',
cycle_momentum=True,
base_momentum=0.8,
max_momentum=0.95,
div_factor=20.0,
final_div_factor=5000.0
)
# Симуляция обучения
for epoch in range(3):
for step in range(8):
loss = torch.rand(1)
optimizer.zero_grad()
loss.backward()
optimizer.step()
scheduler.step()
current_lr = scheduler.get_last_lr()[0]
print(f"Epoch {epoch}, Step {step}: LR = {current_lr:.6f}")
Результат выполнения кода:
Epoch 0, Step 0: LR = 0.001500
Epoch 0, Step 1: LR = 0.007875
Epoch 0, Step 2: LR = 0.017875
Epoch 0, Step 3: LR = 0.031750
Epoch 0, Step 4: LR = 0.048000
Epoch 0, Step 5: LR = 0.047500
Смотрите также
-
класс
CyclicLR,
который реализует циклическое изменение скорости обучения -
класс
CosineAnnealingLR,
который использует косинусоидальное затухание скорости обучения -
класс
StepLR,
который уменьшает скорость обучения через заданные интервалы -
класс
ReduceLROnPlateau,
который уменьшает скорость обучения при остановке улучшения метрики