timm documentation

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

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

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

На этой странице приведена справочная документация по API планировщиков скорости обучения, входящих в timm, а также обзор того, как они создаются и обновляются.

Использование

Планировщики создаются по имени с помощью create_scheduler_v2, который возвращает планировщик и общее количество эпох для обучения (включая любую префиксную фазу разгона, циклы и охлаждение, см. ниже). В отличие от torch.optim.lr_scheduler, планировщики timm не подсчитывают шаги самостоятельно. Они спроектированы как бессостоятельные: lr является функцией конфигурации расписания и явного номера эпохи или количества обновлений, поэтому для возобновления запуска требуется только номер эпохи, а состояние планировщика не сохраняется в контрольных точках. Цикл обучения явно передает номер эпохи или количество обновлений:

  • scheduler.step(epoch) в конце каждой эпохи, с индексом следующей эпохи (epoch + 1)
  • scheduler.step_update(num_updates) после каждого обновления оптимизатора, с количеством выполненных обновлений

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

import timm
from timm.optim import create_optimizer_v2
from timm.scheduler import create_scheduler_v2

model = timm.create_model('resnet50')
optimizer = create_optimizer_v2(model, opt='adamw', lr=1e-3, weight_decay=0.05)
updates_per_epoch = len(loader)  # optimizer updates per epoch

# Cosine decay w/ 5 epochs of linear warmup, stepped per update for a smooth schedule.
scheduler, num_epochs = create_scheduler_v2(
    optimizer,
    sched='cosine',
    num_epochs=100,
    warmup_epochs=5,
    min_lr=1e-6,
    step_on_epochs=False,
    updates_per_epoch=updates_per_epoch,
)

num_updates = 0
for epoch in range(num_epochs):
    for batch in loader:
        ...  # forward, backward, optimizer.step()
        num_updates += 1
        scheduler.step_update(num_updates=num_updates)
    scheduler.step(epoch + 1)  # pass the eval metric too for 'plateau', scheduler.step(epoch + 1, metric)

Длительности (num_epochs, warmup_epochs, decay_epochs, …) всегда задаются в эпохах; фабрика преобразует их в обновления, когда step_on_epochs=False. Планировщики также можно создавать напрямую из их классов, при этом длительности указываются в единицах, в которых выполняется шаг (t_in_epochs).

Скрипт обучения (train.py) предоставляет аргументы фабрики через эти флаги:

  • --sched выбирает расписание.
  • --epochs задаёт длину расписания.
  • Шагов на обновление вместо шагов на эпоху для --sched-on-updates.
  • --warmup-epochs задаёт длительность прогрева.
  • --warmup-lr задает начальную скорость обучения для warmup.
  • --warmup-prefix добавляет разгон перед расписанием, а не перекрывает его начало.
  • --min-lr задает минимальную скорость обучения.
  • --decay-epochs задаёт интервал ступенчатого снижения или длительность финального снижения для WSD / rsqrt.
  • --decay-milestones задаёт эпохи затухания для многошагового расписания.
  • --decay-rate задаёт коэффициент затухания, то есть степень для полиномиального расписания.
  • --cooldown-epochs добавляет эпохи с минимальной скоростью обучения после завершения расписания.
  • --patience-epochs задаёт терпеливость планировщика plateau.
  • --lr-noise выбирает часть расписания с шумом скорости обучения.
  • --lr-noise-pct ограничивает величину шума.
  • --lr-noise-std задает стандартное отклонение шума.
  • --lr-cycle-mul задает множитель длины цикла.
  • --lr-cycle-decay задает множитель пиковой скорости обучения между циклами.
  • --lr-cycle-limit задает количество циклов.
  • --lr-k-decay задаёт k-decay для косинусных и полиномиальных расписаний.
  • --lr-decay-fn выбирает итоговую функцию затухания для WSD / rsqrt.
  • --lr-stable-timescale задаёт масштаб времени фазы rsqrt stable.

Расписания

schedКлассРасписание
cosineCosineLRSchedulerКосинусная аннелинг от базовой lr до min_lr (SGDR), необязательные перезапуски (циклы) и k-затухание
tanhTanhLRSchedulerЗатухание гиперболического тангенса (статья), необязательные перезапуски
polyPolyLRSchedulerПолиномиальное затухание до min_lr, степень задается параметром decay_rate, необязательные перезапуски и k-затухание
stepStepLRSchedulerlr умножается на decay_rate каждые decay_epochs
multistepMultiStepLRSchedulerlr умножается на decay_rate на каждом из эпох decay_milestones
plateauPlateauLRSchedulerУстарело. lr умножается на decay_rate, если метрика eval не улучшалась в течение patience_epochs, только при пошаговом изменении по эпохам
wsdWSDLRSchedulerWarmup-stable-decay (MiniCPM), постоянная lr, затем спад до min_lr в течение последних decay_epochs, по умолчанию спад 1-sqrt (статья)
rsqrtWSDLRSchedulerЗатухание обратной квадратной корени с линейным охлаждением в течение последних decay_epochs (Big Vision)

Часто используемые параметры

  • Warmup. warmup_epochs линейного прогрева с warmup_lr до базовой lr, поддерживается всеми расписаниями.
    • warmup_prefix: по умолчанию warmup перекрывает начало расписания (расписание вычисляется с эпохи 0, warmup заменяет его первые эпохи), поэтому num_epochs — это общая длина. При warmup_prefix=True расписание начинается после warmup, и warmup добавляется к общей длине.
    • Для wsd и rsqrt стабильная фаза всегда начинается после прогрева; без warmup_prefix фазы стабильности и затухания укладываются в num_epochs - warmup_epochs, поэтому num_epochs остаётся общим количеством эпох.
  • min_lr: значение lr, которого достигают затухающие расписания (cosine, tanh, poly, wsd, rsqrt) в конце, и нижняя граница для plateau.

Расписание plateau устарело и будет удалено в одном из будущих релизов. Оно никогда не вписывалось в описанный выше stateless-дизайн: его lr зависит от истории метрики оценки, а не от эпохи, и эта история (лучшая метрика, счётчики patience и cooldown) не сохраняется в контрольных точках, поэтому при возобновлении запуска логика plateau начинается заново. Поддержка контрольных точек не будет добавлена. Кроме того, плато на валидации — слабый сигнал для определения момента аннелинга; фиксированное расписание, такое как cosine или wsd, воспроизводимо и возобновляется точно, а WSD-свип (см. Hyperparameter Sweeps) сравнивает cooldown при нескольких бюджетах на основе одного стабильного запуска.

  • cooldown_epochs: эпохи, в течение которых обучение продолжается с min_lr после завершения расписания (cosine, tanh, poly, wsd, rsqrt), добавляются к возвращаемому num_epochs. Поскольку расписание достигает min_lr на один шаг позже своего последнего шага, эпоха cooldown также позволяет обучаться с min_lr при выполнении шагов по эпохам.
  • Циклы (cosine, tanh, poly): cycle_limit > 1 перезапускает расписание, при этом каждый цикл длится в cycle_mul раз дольше, а его пиковое значение lr умножается на cycle_decay по сравнению с предыдущим. Возвращаемое num_epochs охватывает все циклы.
  • k_decay (cosine, poly): k-decay изменяет форму затухания (t ** k), k > 1 поддерживает высокий lr дольше.
  • Шум: noise добавляет случайный мультипликативный шум к lr на участке расписания, заданном в долях от num_epochs (начало, или начало и конец), ограниченный noise_pct.

WSD и rsqrt

У WSDLRScheduler есть три фазы: линейное разогревание, стабильная фаза и спад до min_lr.

  • decay_epochs задаёт длительность финального затухания. Значение в диапазоне (0, 1) — это доля от общей длины стабильной фазы и фазы затухания, по умолчанию 20%.
  • decay_fn (--lr-decay-fn) выбирает 1-sqrt (по умолчанию для wsd), linear (по умолчанию для rsqrt), cosine, power или exp.
  • stable_timescale (--lr-stable-timescale, в эпохах) управляет стабильной фазой rsqrt, которая затухает по закону (1 + t / timescale) ** -0.5 после окончания warmup. По умолчанию значение равно длине warmup и должно быть задано явно, если warmup отсутствует.

Класс также поддерживает обобщённую power стабильную фазу и пользовательские функции затухания.

Именно на финальном отжиге расписания WSD получают наибольшую выгоду, поэтому используйте шаг на обновление (--sched-on-updates) или добавьте эпоху охлаждения, если фаза затухания длится всего несколько эпох. При шаге на эпоху последняя эпоха короткого затухания заметно выше min_lr (около 10% от базовой lr для последней из 5 эпох затухания с 1-sqrt).

# 300 epochs, 5 epoch warmup, constant lr, then a 1-sqrt decay over the final 20%
scheduler, num_epochs = create_scheduler_v2(
    optimizer, sched='wsd', num_epochs=300, warmup_epochs=5, decay_epochs=0.2,
    step_on_epochs=False, updates_per_epoch=updates_per_epoch,
)

Масштабирование групп параметров lr

Группы параметров с полем lr_scale (например, группы для послойного затухания lr из param_groups_layer_decay) получают запланированное lr, умноженное на их масштаб. Базовое lr каждой группы записывается как initial_lr в группе при создании планировщика.

Возобновление

По мере передачи количества шагов планировщик для возобновлённого запуска настраивается путём его создания так же, как для исходного запуска, и приведения к точке возобновления: scheduler.step(start_epoch) или scheduler.step_update(start_epoch * updates_per_epoch). state_dict() / load_state_dict() сохраняют и восстанавливают атрибуты планировщика.

API

Фабричные функции

timm.scheduler.create_scheduler

< >

( argsoptimizer: Optimizerupdates_per_epoch: int = 0 )

timm.scheduler.create_scheduler_v2

< >

( optimizer: Optimizersched: str = 'cosine'num_epochs: int = 300decay_epochs: typing.Optional[float] = Nonedecay_milestones: typing.List[int] = (90, 180, 270)cooldown_epochs: int = 0patience_epochs: int = 10decay_rate: float = 0.1min_lr: float = 0.0warmup_lr: float = 1e-05warmup_epochs: int = 0warmup_prefix: bool = Falsenoise: typing.Union[float, typing.List[float]] = Nonenoise_pct: float = 0.67noise_std: float = 1.0noise_seed: int = 42cycle_mul: float = 1.0cycle_decay: float = 0.1cycle_limit: int = 1k_decay: float = 1.0decay_fn: typing.Optional[str] = Nonestable_timescale: typing.Optional[float] = Noneplateau_mode: str = 'max'step_on_epochs: bool = Trueupdates_per_epoch: int = 0 )

Параметры

  • optimizer — оптимизатор для планирования
  • sched — имя планировщика, одно из ‘cosine’, ‘tanh’, ‘step’, ‘multistep’, ‘poly’, ‘wsd’, ‘rsqrt’, ‘constant’, ‘plateau’ (устаревшее) или ‘none’ для отключения планировщика (возвращает None, lr оптимизатора не изменяется). ‘constant’ удерживает lr после warmup с применением param group lr_scale (послойное затухание lr).
  • num_epochs — количество эпох в расписании (без учёта warmup, если warmup_prefix, и без учёта cooldown)
  • decay_epochs — интервал затухания lr (шаг) или длина фазы затухания (wsd / rsqrt) в эпохах; значение в диапазоне (0, 1) означает долю от общей длины расписания. None = 90 (шаг), 0.2 (wsd / rsqrt)
  • decay_milestones — эпохи, на которых нужно снижать lr (multistep)
  • cooldown_epochs — количество эпох, в течение которых lr удерживается на уровне min_lr после завершения расписания
  • patience_epochs — количество эпох без улучшения перед снижением lr (plateau, устарело)
  • decay_rate — коэффициент затухания lr (step, multistep, plateau), степень полинома (poly)
  • min_lr — нижняя граница lr для планировщиков, которые затухают до этого значения
  • warmup_lr — lr в начале warmup
  • warmup_epochs — эпохи линейного прогрева
  • warmup_prefix — исключает период прогрева из num_epochs (добавляется к общему количеству); wsd / rsqrt всегда имеют префикс прогрева, при warmup_prefix=False их стабильная и фаза затухания укладываются в num_epochs
  • noise — точки включения/выключения шума lr как доли длины расписания
  • noise_pct — процент ограничения шума для lr
  • noise_std — стандартное отклонение шума lr
  • noise_seed — seed шума для lr
  • cycle_mul — множитель длины цикла (cosine, tanh, poly)
  • cycle_decay — затухание lr в каждом цикле (cosine, tanh, poly)
  • cycle_limit — количество циклов (cosine, tanh, poly)
  • k_decay — k-затухание (cosine, poly)
  • decay_fn — функция фазы затухания (wsd / rsqrt), None = ‘1-sqrt’ для wsd, ‘linear’ для rsqrt
  • stable_timescale — масштаб времени rsqrt в эпохах (rsqrt), None = warmup_epochs
  • plateau_mode — ‘max’ или ‘min’, направление метрики (плато)
  • step_on_epochs — обновлять расписание по эпохам, иначе — по каждому обновлению (требуется updates_per_epoch)
  • updates_per_epoch — количество обновлений оптимизатора на эпоху (step_on_epochs=False)

Создайте планировщик скорости обучения по имени.

Классы планировщиков

класс timm.scheduler.CosineLRScheduler

< >

( optimizer: Optimizert_initial: intlr_min: float = 0.0cycle_mul: float = 1.0cycle_decay: float = 1.0cycle_limit: int = 1warmup_t: int = 0warmup_lr_init: float = 0.0warmup_prefix: bool = Falset_in_epochs: bool = Truenoise_range_t: typing.Union[typing.List[int], typing.Tuple[int, int], int, NoneType] = Nonenoise_pct: float = 0.67noise_std: float = 1.0noise_seed: int = 42k_decay: float = 1.0initialize: bool = True )

Косинусное затухание с перезапусками. Это описано в статье https://arxiv.org/abs/1608.03983.

Вдохновлено https://github.com/allenai/allennlp/blob/master/allennlp/training/learning_rate_schedulers/cosine.py

Опция k-decay, основанная на k-decay: A New Method For Learning Rate Schedule - https://arxiv.org/abs/2004.05909

класс timm.scheduler.MultiStepLRScheduler

< >

( optimizer: Optimizerdecay_t: typing.List[int]decay_rate: float = 1.0warmup_t: int = 0warmup_lr_init: float = 0.0warmup_prefix: bool = Truet_in_epochs: bool = Truenoise_range_t: typing.Union[typing.List[int], typing.Tuple[int, int], int, NoneType] = Nonenoise_pct: float = 0.67noise_std: float = 1.0noise_seed: int = 42initialize: bool = True )

Многошаговое расписание скорости обучения с разминкой и шумом.

Вне warmup контрольные точки затухания сравниваются с t + 1, где t исключает warmup, если warmup_prefix=True. Например, без warmup контрольная точка 10 применяется на индексе расписания 9.

Эта устоявшаяся конвенция отличается от MultiStepLR в PyTorch и сохраняется для совместимости с существующими графиками обучения.

класс timm.scheduler.PlateauLRScheduler

< >

( optimizer: Optimizerdecay_rate: float = 0.1patience_t: int = 10threshold: float = 0.0001cooldown_t: int = 0warmup_t: int = 0warmup_lr_init: float = 0.0lr_min: float = 0.0mode: str = 'max'noise_range_t: typing.Union[typing.List[int], typing.Tuple[int, int], int, NoneType] = Nonenoise_type: str = 'normal'noise_pct: float = 0.67noise_std: float = 1.0noise_seed: typing.Optional[int] = Noneinitialize: bool = True )

Уменьшайте LR в несколько раз каждый раз, когда валидационная потеря выходит на плато.

Устарело: этот планировщик будет удалён в будущей версии. Планировщики timm спроектированы как безсостоятельные функции от номера эпохи или количества обновлений, чем этот метрико-управляемый расписание никогда не было. Его состояние (лучшая метрика, счётчики терпения и охлаждения) не сохраняется в контрольных точках обучения, поэтому при возобновлении запуска логика плато перезапускается, и поддержка контрольных точек не будет добавлена. Рекомендуется использовать фиксированное расписание, такое как cosine или wsd; ветвление WSD cooldown в sweep.py сравнивает отжиг при нескольких бюджетах с воспроизводимыми расписаниями.

класс timm.scheduler.PolyLRScheduler

< >

( optimizer: Optimizert_initial: intpower: float = 0.5lr_min: float = 0.0cycle_mul: float = 1.0cycle_decay: float = 1.0cycle_limit: int = 1warmup_t: int = 0warmup_lr_init: float = 0.0warmup_prefix: bool = Falset_in_epochs: bool = Truenoise_range_t: typing.Union[typing.List[int], typing.Tuple[int, int], int, NoneType] = Nonenoise_pct: float = 0.67noise_std: float = 1.0noise_seed: int = 42k_decay: float = 1.0initialize: bool = True )

Полиномиальный планировщик LR с warmup, шумом и k-затуханием

Опция k-decay, основанная на k-decay: A New Method For Learning Rate Schedule - https://arxiv.org/abs/2004.05909

класс timm.scheduler.StepLRScheduler

< >

( optimizer: Optimizerdecay_t: floatdecay_rate: float = 1.0warmup_t: int = 0warmup_lr_init: float = 0.0warmup_prefix: bool = Truet_in_epochs: bool = Truenoise_range_t: typing.Union[typing.List[int], typing.Tuple[int, int], int, NoneType] = Nonenoise_pct: float = 0.67noise_std: float = 1.0noise_seed: int = 42initialize: bool = True )

класс timm.scheduler.TanhLRScheduler

< >

( optimizer: Optimizert_initial: intlb: float = -7.0ub: float = 3.0lr_min: float = 0.0cycle_mul: float = 1.0cycle_decay: float = 1.0cycle_limit: int = 1warmup_t: int = 0warmup_lr_init: float = 0.0warmup_prefix: bool = Falset_in_epochs: bool = Truenoise_range_t: typing.Union[typing.List[int], typing.Tuple[int, int], int, NoneType] = Nonenoise_pct: float = 0.67noise_std: float = 1.0noise_seed: int = 42initialize: bool = True )

Затухание гиперболического тангенса с перезапусками. Это описано в статье https://arxiv.org/abs/1806.01593

класс timm.scheduler.WSDLRScheduler

< >

( optimizer: Optimizert_initial: intdecay_t: intlr_min: float = 0.0stable_fn: str = 'constant'stable_timescale: typing.Optional[float] = Nonestable_power: float = 0.5decay_fn: typing.Union[str, typing.Callable[[float], float]] = '1-sqrt'decay_power: float = 0.5decay_ratio: float = 0.1warmup_t: int = 0warmup_lr_init: float = 0.0t_in_epochs: bool = Truenoise_range_t: typing.Union[typing.List[int], typing.Tuple[int, int], int, NoneType] = Nonenoise_pct: float = 0.67noise_std: float = 1.0noise_seed: int = 42initialize: bool = True )

Параметры

  • optimizer — оптимизатор для планирования
  • t_initial — длина фаз стабильности и затухания (эпохи или обновления, см. t_in_epochs)
  • decay_t — длина фазы затухания, последние decay_t шагов из t_initial
  • lr_min — lr в конце фазы затухания
  • stable_fn — функция стабильной фазы, одно из значений: ‘constant’, ‘rsqrt’, ‘power’
  • stable_timescale — временная шкала для стабильных функций ‘rsqrt’ / ‘power’, по умолчанию warmup_t
  • stable_power — показатель степени функции «power»
  • decay_fn — функция фазы затухания, одно из значений ‘linear’, ‘1-sqrt’, ‘cosine’, ‘power’, ‘exp’ или вызываемый объект
  • decay_power — показатель степени функции затухания «power»
  • decay_ratio — конечная доля (до нормализации) функции затухания ‘exp’
  • warmup_t — длина разгона, префикс к t_initial
  • warmup_lr_init — lr в начале warmup
  • t_in_epochs — t измеряется в эпохах (step()), иначе — в обновлениях (step_update())
  • noise_range_t — диапазон шума lr, см. Scheduler
  • noise_pct — процент ограничения шума для lr
  • noise_std — стандартное отклонение шума lr
  • noise_seed — seed шума для lr
  • initialize — инициализирует поле initial_lr группы параметров из текущего значения lr

График изменения скорости обучения Warmup-Stable-Decay (WSD) с возможностью выбора функций для стабильной фазы и фазы затухания.

Три фазы: линейное повышение в течение warmup_t шагов, стабильная фаза и снижение до lr_min в последние decay_t шагов. t_initial — это длина фаз стабильности и снижения; фаза повышения всегда является префиксом, поэтому общая длина расписания составляет warmup_t + t_initial (см. get_cycle_length()), после чего поддерживается значение lr_min.

NOTE: как и в случае с другими планировщиками, lr_min достигается при t = warmup_t + t_initial, то есть на один шаг позже последнего запланированного шага, поэтому последний запланированный шаг на один шаг затухания короче. При короткой фазе затухания, выполняемой по эпохам, это существенно (например, последняя из 5 эпох затухания с ‘1-sqrt’ находится примерно на 10% от стабильного lr). Финальное отжигание важно для WSD, поэтому выполняйте шаги по обновлениям (t_in_epochs=False, --sched-on-updates в train.py) или добавьте эпоху охлаждения (удерживаемую на lr_min, --cooldown-epochs).

Стабильная функция вычисляется по времени с момента окончания warmup (t_s) и равна 1 при t_s = 0, поэтому warmup всегда передаёт управление на базовом lr. Функция затухания отображает прогресс затухания frac в диапазоне [0, 1] в коэффициент от 1 до 0 и умножает на стабильное значение, так что затухающая стабильная функция продолжает затухать на протяжении фазы decay (как в расписании Big Vision rsqrt + linear cooldown).

lr(t) = lr_min + (base_lr stable(t_s) - lr_min) decay(frac)

Стабильные функции:

  • constant: 1, расписание WSD
  • rsqrt: (1 + t_s / timescale) ** -0.5, расписание обратного квадратного корня Big Vision, когда stable_timescale == warmup_t (по умолчанию)
  • power: (1 + t_s / timescale) ** -stable_power, обобщённый rsqrt (планировщик Power)

Функции затухания:

  • 1-sqrt: 1 - sqrt(frac), наиболее эффективный cooldown в https://arxiv.org/abs/2405.18392 (по умолчанию)
  • linear: 1 - frac, расписание «трапеция» и Big Vision cooldown
  • cosine: 0.5 (1 + cos(pi frac))
  • power: 1 - frac ** decay_power, 0.5 == ‘1-sqrt’, 1.0 == ‘linear’, 2.0 is a ‘square’ decay
  • exp: экспоненциальное затухание до доли decay_ratio от стабильного значения, нормированное для достижения lr_min
  • вызываемая функция fn(frac) -> factor для всех остальных случаев
Update on GitHub