PyTorch: планировщик скорости обучения

Скорость обучения (Learning Rate) — один из самых важных гиперпараметров при обучении нейронных сетей. Если скорость обучения слишком велика, обучение колеблется или даже расходится; если слишком мала, сходимость крайне медленная, и легко попасть в локальные оптимумы.

Планировщик скорости обученияДинамически регулируя скорость обучения во время обучения, он обеспечивает баланс между быстрой сходимостью на раннем этапе и тонкой настройкой на позднем этапе.


1. Основные понятия и шаблоны использования

Стандартная схема использования

)

import torch
import torch.nn as nn
import torch.optim as optim

model     = nn.Linear(10, 1)
optimizer = optim.SGD(model.parameters(), lr=0.1)

# 1. Создайте планировщик, передав в него оптимизатор
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=30, гамма=0.1)

for epoch in range(100):
    # 2. Обучение
    train(model, optimizer)

    # 3. После каждой эпохи вызовите scheduler.step()
    scheduler.step()

    # 4. Просмотр текущей скорости обучения
    current_lr = scheduler.get_last_lr()[0]
    print(f"Epoch {epoch+1}, LR: {current_lr:.6f}")

Когда вызывать step()

Пример

# Правильно: сначала optimizer.step(), затем scheduler.step()
optimizer.step()
scheduler.step()

# Неправильно: scheduler.step() до optimizer.step()
# После PyTorch 1.1.0 будет сгенерировано предупреждение, и некоторые планировщики будут работать некорректно
scheduler.step()
optimizer.step()

Примечание:optimizer.step()Должно бытьscheduler.step()вызван раньше.

Просмотр и сохранение состояния скорости обучения

Пример

# Получить текущую скорость обучения
current_lr = optimizer.param_groups[0]['lr']
current_lr = scheduler.get_last_lr()[0]   # LR после предыдущего step()

# Сохранить чекпоинт (также нужно сохранить состояние планировщика)
torch.save({
    'epoch': epoch,
    'model': model.state_dict(),
    'optimizer': optimizer.state_dict(),
    'scheduler': scheduler.state_dict(),   # Не пропустите это
}, 'checkpoint.pth')

# Восстановить контрольную точку
ckpt = torch.load('checkpoint.pth')
model.load_state_dict(ckpt['model'])
optimizer.load_state_dict(ckpt['optimizer'])
scheduler.load_state_dict(ckpt['scheduler'])

2. Планировщики с фиксированным затуханием

2.1 StepLR: ступенчатое затухание

Каждое фиксированноеstep_sizeчисло эпох, умножьте скорость обучения наgamma. Это один из самых простых и наиболее часто используемых планировщиков.

Формула: lr = lr_base * gamma^(floor(step / step_size))

Пример

optimizer = optim.SGD(model.parameters(), lr=0.1)
scheduler = optim.lr_scheduler.StepLR(
    optimizer,
    step_size=30,   # Уменьшать каждые 30 эпох
    gamma=0.1       # Умножать на 0.1 каждый раз (т.е. уменьшать до 1/10 от исходного)
)

# Изменения LR:
# Эпоха 0-29: 0.1
# Эпоха 30-59: 0.01
# Эпоха 60-89: 0.001
# Эпоха 90+: 0.0001

Применимые сценарии:Задачи с фиксированным ритмом обучения и чёткими этапами, например обучение ResNet на ImageNet (90 эпох, с уменьшением на 30-й и 60-й эпохах).


2.2 MultiStepLR Многоэтапное снижение

Уменьшайте скорость обучения в нескольких указанных эпохах (контрольных точках), что более гибко, чем StepLR.

Пример

optimizer = optim.SGD(model.parameters(), lr=0.1)
scheduler = optim.lr_scheduler.MultiStepLR(
    optimizer,
    milestones=[30, 60, 80],   # Уменьшение на 30-й, 60-й и 80-й эпохах
    гамма=0.1
)

# Изменения LR:
# Эпоха 0-29: 0.1
# Эпоха 30-59: 0.01
# Эпоха 60-79: 0.001
# Эпоха 80+: 0.0001

Применимые сценарии:Когда заранее известно, на каких эпохах модели требуется тонкая настройка, например на этапе точной сходимости в средней и поздней фазах моделей классификации.


2.3 ExponentialLR Экспоненциальное затухание

Скорость обучения снижается на каждой эпохе и продолжает экспоненциально уменьшаться, обеспечивая более плавное снижение.

Формула: lr = lr_base * gamma^epoch

Пример

optimizer = optim.Adam(model.parameters(), lr=0.01)
scheduler = optim.lr_scheduler.ExponentialLR(
    optimizer,
    gamma=0.95   # Умножить на 0.95 каждую эпоху
)

# Изменения LR (первые 5 эпох):
# Эпоха 1: 0.0100
# Эпоха 2: 0.0095
# Эпоха 3: 0.0090
# Эпоха 4: 0.0086
# Эпоха 5: 0.0081

gammaЕсли задать слишком маленьким (например, 0.5), скорость обучения быстро приблизится к нулю; обычно её задают в диапазоне от 0.9 до 0.99.


3. Адаптивные планировщики

3.1 ReduceLROnPlateau: затухание на основе метрики

Один из самых интеллектуальных планировщиков: отслеживайте определённую метрику (например, потери на валидации) и автоматически снижайте скорость обучения, когда метрика перестаёт улучшаться. Нет необходимости заранее знать, на какой эпохе уменьшать.

Пример

optimizer = optim.Adam(model.parameters(), lr=0.01)
scheduler = optim.lr_scheduler.ReduceLROnPlateau(
    optimizer,
    mode='min',       # 'min': чем меньше отслеживаемое значение, тем лучше (потери); 'max': чем больше, тем лучше (точность)
    factor=0.1,       # При срабатывании lr = lr × factor
    patience=10,      # Количество эпох, в течение которых метрике разрешено оставаться на плато; при превышении — снижение
    threshold=1e-4,   # Улучшение меньше этого значения считается отсутствием улучшения
    min_lr=1e-6,      # Нижняя граница скорости обучения; она не будет ниже этого значения
    verbose=True      # Выводить информацию о снижении
)

for epoch in range(100):
    train_loss = train(model, optimizer)
    val_loss   = evaluate(model)

    # В отличие от других планировщиков, сюда передайте отслеживаемую метрику
    scheduler.step(val_loss)

Стиль записи для мониторинга точности:

Пример

scheduler = optim.lr_scheduler.ReduceLROnPlateau(
    optimizer,
    mode='max',       # Чем выше точность, тем лучше
    factor=0.5,
    patience=5,
)

scheduler.step(val_accuracy)

Применимые сценарии:Выбор по умолчанию для почти всех задач, особенно когда вы не уверены, сколько эпох обучать, или когда обучение нестабильно.


3.2 CosineAnnealingLR Косинусное затухание

Скорость обучения изменяется покосинусной кривойот начального значения, плавно снижаясь до минимального значения (eta_min), избегая резких изменений ступенчатого затухания.

Формула: lr_t = eta_min + 0.5 * (eta_max - eta_min) * (1 + cos(t * pi / T_max)

Пример

optimizer = optim.SGD(model.parameters(), lr=0.1)
scheduler = optim.lr_scheduler.CosineAnnealingLR(
    optimizer,
    T_max=100,     # Длина половины цикла (обычно устанавливается равной общему числу эпох)
    eta_min=1e-6   # Минимальная скорость обучения (по умолчанию 0)
)

# Траектория изменения LR (схематично при T_max=10):
# 0.1 -> 0.095 -> 0.079 -> 0.055 -> 0.026 -> 0.001
# (плавное снижение по косинусоидальной кривой)

Применимые сценарии:Сценарии с фиксированным числом эпох обучения, широко используемые в таких работах, как Vision Transformer и ResNet, с хорошим качеством сходимости.


3.3 CosineAnnealingWarmRestarts

Улучшенная версия косинусного отжига поддерживаетпериодические тёплые перезапуски(Warm Restarts): после завершения каждого цикла скорость обучения сбрасывается к начальному значению и начинается новый цикл косинусного затухания. Это позволяет модели выходить из локальных оптимумов.

Пример

optimizer = optim.SGD(model.parameters(), lr=0.1)
scheduler = optim.lr_scheduler.CosineAnnealingWarmRestarts(
    optimizer,
    T_0=10,       # Длина первого цикла (число эпох)
    T_mult=2,     # Множитель длины цикла после каждого перезапуска (1=равная длина, 2=постепенно увеличивающаяся)
    eta_min=1e-6
)

# Длины циклов при T_mult=2: 10 -> 20 -> 40 -> 80 ...
# Изменения LR (T_0=10, T_mult=1):
# 0.1 -> ... -> 0 -> 0.1 -> ... -> 0 -> 0.1 (перезапуск каждые 10 эпох)

Применимые сценарии:При обучении больших моделей или когда вы хотите, чтобы модель выбрала лучшую среди нескольких точек сходимости, это эффективно работает со Snapshot Ensemble.


4. Планировщики разогрева

Разогревозначает постепенное увеличение скорости обучения с очень малого значения до целевого в течение первых нескольких шагов обучения. При обучении с большим размером батча и в Transformer-подобных моделях почти всегда требуется разогрев; иначе начальные обновления градиента слишком агрессивны, и модель трудно стабилизировать.

4.1 LinearLR Линейное планирование

Линейно изменять скорость обучения в течение заданного числа эпох (можно использовать для линейного разогрева или линейного затухания).

Пример

optimizer = optim.Adam(model.parameters(), lr=0.01)

# Линейный разогрев: в течение первых 5 эпох lr линейно увеличивается с 0.01×0.1=0.001 до 0.01
warmup_scheduler = optim.lr_scheduler.LinearLR(
    optimizer,
    start_factor=0.1,   # начальный lr = base_lr × start_factor
    end_factor=1.0,     # конечный lr = base_lr × end_factor
    total_iters=5       # Завершается после 5 эпох
)

# Изменения LR: 0.001 -> 0.003 -> 0.005 -> 0.007 -> 0.009 -> 0.01

4.2 ConstantLR Постоянная фаза

В течение заданного числа эпох зафиксируйте скорость обучения наbase_lr × factor, а затем восстановите исходное значение.

Пример

# Используйте base_lr × 0.5 для первых 5 эпох, затем восстановите нормальное значение
scheduler = optim.lr_scheduler.ConstantLR(
    optimizer,
    factor=0.5,
    total_iters=5
)

4.3 SequentialLR Комбинированное планирование

Объедините несколько планировщиковпоследовательно, что является стандартным подходом для реализации комбинированной стратегии "разогрев + затухание".

Пример

optimizer = optim.Adam(model.parameters(), lr=0.01)

# Фаза 1: разогрев (первые 5 эпох, LR линейно увеличивается с 0.001 до 0.01)
warmup = optim.lr_scheduler.LinearLR(
    optimizer, start_factor=0.1, end_factor=1.0, total_iters=5
)

# Фаза 2: косинусное затухание (оставшиеся 95 эпох)
cosine = optim.lr_scheduler.CosineAnnealingLR(
    optimizer, T_max=95, eta_min=1e-6
)

# Комбинированный: сначала выполнить warmup, затем переключиться на cosine после 5-й эпохи
scheduler = optim.lr_scheduler.SequentialLR(
    optimizer,
    schedulers=[warmup, cosine],
    milestones=[5]          # Переключение на 5-й эпохе
)

# Использование точно такое же, как у обычного планировщика
for epoch in range(100):
    train(...)
    scheduler.step()

Применимые сценарии:Стандартная конфигурация для обучения Transformer (warmup + cosine annealing); предобучение BERT, GPT и ViT — все используют эту стратегию.


5. Циклические планировщики

5.1 CyclicLR Циклическая скорость обучения

Скорость обученияbase_lrиmax_lrмеждуциклами периодически, что помогает модели исследовать более широкое пространство параметров и выходить из седловых точек.

Пример

optimizer = optim.SGD(model.parameters(), lr=0.01)
scheduler = optim.lr_scheduler.CyclicLR(
    optimizer,
    base_lr=0.001,          # Нижняя граница скорости обучения
    max_lr=0.01,            # Верхняя граница скорости обучения
    step_size_up=2000,      # Число итераций для роста от base_lr до max_lr
    step_size_down=2000,    # Число итераций для спада от max_lr до base_lr (по умолчанию равно step_size_up)
    mode='triangular',      # Треугольный цикл (постоянная амплитуда)
    # mode='triangular2' # амплитуда уменьшается вдвое каждый цикл
    # mode='exp_range' # экспоненциальное затухание амплитуды
)

# CyclicLR вызывается на каждом шаге (батче), а не на каждой эпохе
for epoch in range(num_epochs):
    for inputs, labels in train_loader:
        optimizer.zero_grad()
        loss = criterion(model(inputs), labels)
        loss.backward()
        optimizer.step()
        scheduler.step()    # Вызывать после каждого батча

Сравнение трёх режимов:

modeИзменение амплитудыХарактеристика
triangularКонстантаСтабильное исследование, подходит для ранних этапов
triangular2Уменьшается вдвое каждый циклСначала исследование, затем сходимость
exp_rangeЭкспоненциальное затуханиеВ итоге плавно сходится

5.2 OneCycleLR: стратегия одного цикла

Один из лучших по эффективности планировщиков, предложенный fastai как 1-Cycle Policy. Всё обучение имеет только один цикл: скорость обучения сначала возрастает, затем убывает, а моментум меняется в противоположном направлении.

Обучение быстрее, обычно требует лишь1/5~1/10число эпох традиционного обучения.

Пример

optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

steps_per_epoch = len(train_loader)

scheduler = optim.lr_scheduler.OneCycleLR(
    optimizer,
    max_lr=0.1,                              # Максимальная скорость обучения
    steps_per_epoch=steps_per_epoch,         # Количество шагов за эпоху
    epochs=10,                               # Общее количество эпох
    pct_start=0.3,                           # Первые 30% используются для роста на этапе warmup
    anneal_strategy='cos',                   # Стратегия затухания ('cos' или 'linear')
    div_factor=25,                           # Начальный lr = max_lr / div_factor
    final_div_factor=1e4                     # Конечный lr = max_lr / final_div_factor
)

# Начальный lr = 0.1 / 25 = 0.004
# Пиковый lr = 0.1 (на 30%)
# Конечный lr = 0.1 / 10000 = 0.00001

# Также называется per batch
for epoch in range(10):
    for inputs, labels in train_loader:
        optimizer.zero_grad()
        loss = criterion(model(inputs), labels)
        loss.backward()
        optimizer.step()
        scheduler.step()    # Вызывать после каждого батча

Сценарии применения:Первый выбор, когда вычислительные ресурсы ограничены и нужно быстро проверить идеи;max_lrРекомендуется использовать инструмент LR Finder для определения оптимального значения.


6. Пользовательские планировщики

6.1 Функциональная настройка LambdaLR

Полностью настройте стратегию планирования, передав Lambda-функцию (которая принимает номер эпохи и возвращает множитель скорости обучения).

Пример

optimizer = optim.Adam(model.parameters(), lr=0.01)

# Пример 1: классическая стратегия разогрева Transformer
# lr ∝ min(step^-0.5, step × warmup_steps^-1.5)
def transformer_lr(epoch, warmup_epochs=10, d_model=512):
    if epoch == 0:
        return 1e-7 / 0.01          # Избегаем деления на ноль
    step = epoch + 1
    warmup = warmup_epochs
    return (d_model ** -0.5) * min(step ** -0.5, step * warmup ** -1.5) / 0.01

scheduler = optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=transformer_lr)


# Пример 2: полиномиальное затухание (lr линейно/полиномиально уменьшается от начального значения до 0)
def polynomial_decay(epoch, total_epochs=100, power=1.0):
    return max((1 - epoch / total_epochs) ** power, 0.0)

scheduler = optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=polynomial_decay)


# Пример 3: сгруппированные скорости обучения (разные стратегии для разных групп параметров)
optimizer = optim.Adam([
    {'params': model.backbone.parameters(), 'lr': 1e-4},
    {'params': model.head.parameters(),     'lr': 1e-3},
])

# Одна лямбда-функция на группу параметров
scheduler = optim.lr_scheduler.LambdaLR(
    optimizer,
    lr_lambda=[
        lambda epoch: 0.95 ** epoch,    # backbone: медленное затухание
        lambda epoch: 0.85 ** epoch,    # head: быстрое затухание
    ]
)

6.2 Наследование LRScheduler

Когда нужна более сложная логика, наследуйтеLRScheduler(PyTorch >= 2.0, в старых версиях_LRScheduler) для реализации полной настройки:

Пример

from torch.optim.lr_scheduler import LRScheduler
import math

class WarmupCosineScheduler(LRScheduler):
    """
Комбинированный планировщик разогрева + косинусного отжига (версия с ручной реализацией)
- Линейный разогрев в течение первых warmup_epochs эпох
- Затем косинусный отжиг до min_lr
    """

    def __init__(self, optimizer, warmup_epochs, total_epochs,
                 min_lr=1e-6, last_epoch=-1):
        self.warmup_epochs = warmup_epochs
        self.total_epochs  = total_epochs
        self.min_lr        = min_lr
        super().__init__(optimizer, last_epoch)

    def get_lr(self):
        epoch = self.last_epoch

        # Фаза разогрева: линейное увеличение
        if epoch < self.warmup_epochs:
            warmup_factor = (epoch + 1) / self.warmup_epochs
            return [base_lr * warmup_factor for base_lr in self.base_lrs]

        # Фаза косинусного отжига
        progress = (epoch - self.warmup_epochs) / (
            self.total_epochs - self.warmup_epochs
        )
        cosine_factor = 0.5 * (1 + math.cos(math.pi * progress))
        return [
            self.min_lr + (base_lr - self.min_lr) * cosine_factor
            for base_lr in self.base_lrs
        ]


optimizer = optim.Adam(model.parameters(), lr=0.01)
scheduler = WarmupCosineScheduler(
    optimizer,
    warmup_epochs=10,
    total_epochs=100,
    min_lr=1e-6
)

7. Сравнение визуализации планировщиков

Следующий код может построить кривые изменения LR каждого планировщика для наглядного сравнения:

Пример

import torch
import torch.optim as optim
import matplotlib.pyplot as plt

def simulate_lr(scheduler_fn, epochs=100, steps_per_epoch=None):
    """Симулировать и записывать изменения скорости обучения планировщика"""
    model     = torch.nn.Linear(1, 1)
    optimizer = optim.SGD(model.parameters(), lr=0.1)
    scheduler = scheduler_fn(optimizer)
    lrs = []

    if steps_per_epoch:
        # Планировщик вызывается на каждом шаге
        for _ in range(epochs):
            for _ in range(steps_per_epoch):
                optimizer.step()
                scheduler.step()
                lrs.append(optimizer.param_groups[0]['lr'])
    else:
        # Планировщик вызывается каждую эпоху
        for _ in range(epochs):
            optimizer.step()
            scheduler.step()
            lrs.append(optimizer.param_groups[0]['lr'])
    return lrs

schedulers = {
    'StepLR(step=30, gamma=0.1)':
        lambda opt: optim.lr_scheduler.StepLR(opt, 30, 0.1),
    'CosineAnnealingLR':
        lambda opt: optim.lr_scheduler.CosineAnnealingLR(opt, T_max=100),
    'ExponentialLR(gamma=0.95)':
        lambda opt: optim.lr_scheduler.ExponentialLR(opt, 0.95),
    'CosineWarmRestarts(T0=25)':
        lambda opt: optim.lr_scheduler.CosineAnnealingWarmRestarts(opt, T_0=25),
}

plt.figure(figsize=(12, 5))
for name, fn in schedulers.items():
    plt.plot(simulate_lr(fn), label=name)

plt.xlabel('Эпоха')
plt.ylabel('Скорость обучения')
plt.title('Сравнение планировщиков LR в PyTorch')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('lr_schedulers.png', dpi=150)
plt.show()

8. Полный шаблон обучения

Шаблон обучения промышленного уровня, объединяющий разогрев + косинусный отжиг, сохранение и восстановление модели:

Пример

import torch
import torch.nn as nn
import torch.optim as optim
from torch.optim.lr_scheduler import SequentialLR, LinearLR, CosineAnnealingLR

# Гиперпараметры
EPOCHS       = 100
WARMUP_EPOCHS = 5
BASE_LR      = 1e-3
MIN_LR       = 1e-6
SAVE_PATH    = 'best_model.pth'

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

# Модель / Оптимизатор / Планировщик
model     = MyModel().to(device)
optimizer = optim.AdamW(model.parameters(), lr=BASE_LR, weight_decay=1e-4)
criterion = nn.CrossEntropyLoss(label_smoothing=0.1)

# Разогрев 5 эпох + косинусное затухание 95 эпох
warmup_sched = LinearLR(optimizer, start_factor=0.1, total_iters=WARMUP_EPOCHS)
cosine_sched = CosineAnnealingLR(optimizer, T_max=EPOCHS - WARMUP_EPOCHS, eta_min=MIN_LR)
scheduler    = SequentialLR(optimizer, [warmup_sched, cosine_sched], milestones=[WARMUP_EPOCHS])

# Восстановить контрольную точку
start_epoch = 0
best_acc    = 0.0

try:
    ckpt = torch.load(SAVE_PATH, map_location=device)
    model.load_state_dict(ckpt['model'])
    optimizer.load_state_dict(ckpt['optimizer'])
    scheduler.load_state_dict(ckpt['scheduler'])
    start_epoch = ckpt['epoch'] + 1
    best_acc    = ckpt['best_acc']
    print(f"Возобновлено с эпохи {start_epoch}, лучшая точность {best_acc:.4f}")
except FileNotFoundError:
    print("Обучение с нуля")

# Цикл обучения
history = {'train_loss': [], 'val_acc': [], 'lr': []}

for epoch in range(start_epoch, EPOCHS):
    # Обучить
    model.train()
    total_loss = 0.0
    for inputs, labels in train_loader:
        inputs, labels = inputs.to(device), labels.to(device)
        optimizer.zero_grad()
        loss = criterion(model(inputs), labels)
        loss.backward()
        torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)  # Отсечение градиентов
        optimizer.step()
        total_loss += loss.item()

    # Валидация
    model.eval()
    correct = 0
    with torch.no_grad():
        for inputs, labels in val_loader:
            inputs, labels = inputs.to(device), labels.to(device)
            correct += (model(inputs).argmax(1) == labels).sum().item()

    avg_loss = total_loss / len(train_loader)
    val_acc  = correct / len(val_loader.dataset)
    cur_lr   = scheduler.get_last_lr()[0]

    # Запись и вывод
    history['train_loss'].append(avg_loss)
    history['val_acc'].append(val_acc)
    history['lr'].append(cur_lr)
    print(f"Эпоха {epoch+1:3d}/{EPOCHS} | "
          f"Потери: {avg_loss:.4f} | Точность: {val_acc:.4f} | LR: {cur_lr:.2e}")

    # Обновление планировщика
    scheduler.step()

    # Сохранить лучшую модель
    if val_acc > best_acc:
        best_acc = val_acc
        torch.save({
            'epoch': epoch,
            'model': model.state_dict(),
            'optimizer': optimizer.state_dict(),
            'scheduler': scheduler.state_dict(),
            'best_acc': best_acc,
        }, SAVE_PATH)
        print(f" Сохранение лучшей модели, Acc: {best_acc:.4f}")

print(f"\n"Обучение завершено, лучшая точность валидации: {best_acc:.4f}")

9. Руководство по выбору планировщика

Рекомендации по типу задачи

СценарийРекомендуемый планировщикПричина
Быстрые эксперименты / проверка прототипаReduceLROnPlateauНе требуется настройка гиперпараметров, адаптивное затухание
Классификация изображений (фиксированное число эпох)CosineAnnealingLRПлавное затухание, хорошее качество сходимости
Transformer / BERTLinearLR + CosineAnnealingLRРазогрев обязателен
Ограниченные ресурсы, быстрое обучениеOneCycleLRДостичь той же точности за 1/5 времени
Дообучение больших моделей (fine-tune)LinearLR(разогрев) +ConstantLRНизкая скорость обучения для стабильного дообучения
Неопределённое количество эпохReduceLROnPlateauАвтоматически реагирует, не зависит от фиксированного расписания
Обнаружение объектов (YOLO/Faster-RCNN)MultiStepLR / OneCycleLRИмеет чёткие точки снижения или нацелен на скорость
Хотите выйти из локальных оптимумовCosineAnnealingWarmRestartsПериодический перезапуск для исследования пространства параметров

Типичные комбинации конфигураций

Пример

# Комбинация 1: Разогрев + косинусное отжигание (стандарт для Transformer)
SequentialLR([LinearLR(5 epochs), CosineAnnealingLR(95 epochs)])

# Комбинация 2: мониторинг валидационного набора + автоматическое снижение (универсально предпочтительно)
ReduceLROnPlateau(mode='min', patience=5, factor=0.5)

# Комбинация 3: OneCycleLR (предпочтительно для быстрого обучения)
OneCycleLR(max_lr=0.1, total_steps=total_steps, pct_start=0.3)

# Комбинация 4: традиционное ступенчатое снижение (классика CV)
MultiStepLR(milestones=[30, 60, 90], gamma=0.1)

Краткий справочник по заметкам

ПроблемаРешение
Планировщик не срабатываетПроверитьscheduler.step()является лиoptimizer.step() послевызова
CyclicLR / OneCycleLR не меняетсяЭти два основаны наbatchвызовах, а не по эпохам
ReduceLROnPlateau не срабатываетПроверитьmodeправильно ли он задан (используйте loss для'min', используйте accuracy для'max')
LR некорректен после возобновления обученияПроверьте, было ли это сохранено и загруженоscheduler.state_dict()
Настройки LR для нескольких групп параметровИспользуйтеLambdaLRПередайте список, по одной lambda на каждую группу параметров
Другие расширения