Spec-Zone.ru › PyTorch 1

torch.optim

torch.optim — пакет, реализующий различные алгоритмы оптимизации. Наиболее часто используемые методы уже поддерживаются, а интерфейс достаточно общий, чтобы в будущем легко интегрировать и более сложные алгоритмы.

Как использовать оптимизатор

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

Создание оптимизатора

Для создания объекта Optimizer нужно передать итерируемый объект, содержащий параметры (все должны быть Variable), которые необходимо оптимизировать. Затем можно указать опции, специфичные для оптимизатора, такие как скорость обучения, регуляризация по весам и т. д.

Пример:

optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
optimizer = optim.Adam([var1, var2], lr=0.0001)

Опции для каждого параметра

Объекты Optimizer также поддерживают указание опций для каждого параметра. Для этого вместо передачи итерируемого объекта Variable передайте итерируемый объект dict с параметрами. Каждый из них определит отдельную группу параметров и должен содержать ключ params, содержащий список параметров, относящихся к этой группе. Другие ключи должны соответствовать ключевым аргументам, принимаемым оптимизаторами, и будут использоваться в качестве параметров оптимизации для этой группы.

Примечание

Вы по-прежнему можете передавать параметры в виде ключевых аргументов. Они будут использоваться как значения по умолчанию в группах, которые их не переопределили. Это полезно, когда вы хотите изменить только один параметр, сохраняя все остальные параметры согласованными в различных группах параметров.

Например, это очень полезно, когда необходимо указать скорость обучения для каждого слоя:

optim.SGD([
                {'params': model.base.parameters()},
                {'params': model.classifier.parameters(), 'lr': 1e-3}
            ], lr=1e-2, momentum=0.9)

Это означает, что параметры model.base будут использовать скорость обучения по умолчанию 1e-2, параметры model.classifier будут использовать скорость обучения 1e-3, а для всех параметров будет использоваться импульс 0.9.

Выполнение шага оптимизации

Все оптимизаторы реализуют метод step(), который обновляет параметры. Он может использоваться двумя способами:

optimizer.step()

Это упрощенная версия, поддерживаемая большинством оптимизаторов. Функция может быть вызвана после вычисления градиентов, например, с помощью backward().

Пример:

for input, target in dataset:
    optimizer.zero_grad()
    output = model(input)
    loss = loss_fn(output, target)
    loss.backward()
    optimizer.step()

optimizer.step(closure)

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

Пример:

for input, target in dataset:
    def closure():
        optimizer.zero_grad()
        output = model(input)
        loss = loss_fn(output, target)
        loss.backward()
        return loss
    optimizer.step(closure)

Базовый класс

class torch.optim.Optimizer(params, defaults) [source]

Базовый класс для всех оптимизаторов.

Предупреждение

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

Параметры:
  • params (iterable) – итерируемый объект, содержащий torch.Tensor или dict. Указывает, какие тензоры должны быть оптимизированы.
  • defaults – (dict): словарь, содержащий значения параметров оптимизации по умолчанию (используется, когда группа параметров не указывает их).

Optimizer.add_param_group

Добавляет группу параметров в Optimizer param_groups.

Optimizer.load_state_dict

Загружает состояние оптимизатора.

Optimizer.state_dict

Возвращает состояние оптимизатора в виде dict.

Optimizer.step

Выполняет один шаг оптимизации (обновление параметров).

Optimizer.zero_grad

Устанавливает градиенты всех оптимизируемых torch.Tensor в ноль.

Алгоритмы

Adadelta

Реализует алгоритм Adadelta.

Adagrad

Реализует алгоритм Adagrad.

Adam

Реализует алгоритм Adam.

AdamW

Реализует алгоритм AdamW.

SparseAdam

Реализует ленивую версию алгоритма Adam, подходящую для разреженных тензоров.

Adamax

Реализует алгоритм Adamax (вариант Adam, основанный на бесконечной норме).

ASGD

Реализует усреднённый стохастический градиентный спуск.

LBFGS

Реализует алгоритм L-BFGS, сильно вдохновлённый minFunc.

NAdam

Реализует алгоритм NAdam.

RAdam

Реализует алгоритм RAdam.

RMSprop

Реализует алгоритм RMSprop.

Rprop

Реализует алгоритм результирующего обратного распространения.

SGD

Реализует стохастический градиентный спуск (по желанию с импульсом).

Как настроить скорость обучения

torch.optim.lr_scheduler предоставляет несколько методов настройки скорости обучения на основе количества эпох. torch.optim.lr_scheduler.ReduceLROnPlateau позволяет динамически уменьшать скорость обучения на основе некоторых показателей валидации.

График изменения скорости обучения следует применять после обновления оптимизатора; например, ваш код должен быть написан следующим образом:

Пример:

model = [Parameter(torch.randn(2, 2, requires_grad=True))]
optimizer = SGD(model, 0.1)
scheduler = ExponentialLR(optimizer, gamma=0.9)

for epoch in range(20):
    for input, target in dataset:
        optimizer.zero_grad()
        output = model(input)
        loss = loss_fn(output, target)
        loss.backward()
        optimizer.step()
    scheduler.step()

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

Пример:

model = [Parameter(torch.randn(2, 2, requires_grad=True))]
optimizer = SGD(model, 0.1)
scheduler1 = ExponentialLR(optimizer, gamma=0.9)
scheduler2 = MultiStepLR(optimizer, milestones=[30,80], gamma=0.1)

for epoch in range(20):
    for input, target in dataset:
        optimizer.zero_grad()
        output = model(input)
        loss = loss_fn(output, target)
        loss.backward()
        optimizer.step()
    scheduler1.step()
    scheduler2.step()

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

>>> scheduler = ...
>>> for epoch in range(100):
>>>     train(...)
>>>     validate(...)
>>>     scheduler.step()

Предупреждение

До PyTorch 1.1.0 планировщик скорости обучения должен был вызываться до обновления оптимизатора; 1.1.0 изменил это поведение, что повлекло за собой разрыв обратной совместимости. Если вы используете планировщик скорости обучения (вызывая scheduler.step()) перед обновлением оптимизатора (вызывая optimizer.step()) , это пропустит первое значение графика скорости обучения. Если вы не можете воспроизвести результаты после обновления до PyTorch 1.1.0, проверьте, вызываете ли вы scheduler.step() в неправильное время.

lr_scheduler.LambdaLR

Устанавливает скорость обучения каждого параметра группы в начальную lr, умноженную на заданную функцию.

lr_scheduler.MultiplicativeLR

Умножает скорость обучения каждой параметрической группы на множитель, указанный в заданной функции.

lr_scheduler.StepLR

Уменьшает скорость обучения каждой параметрической группы на множитель gamma через каждые step_size эпох.

lr_scheduler.MultiStepLR

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

lr_scheduler.ConstantLR

Уменьшает скорость обучения каждой параметрической группы на небольшой постоянный множитель до тех пор, пока количество эпох не достигнет предварительно определенной вехи: total_iters.

lr_scheduler.LinearLR

Уменьшает скорость обучения каждой параметрической группы путём линейного изменения небольшого множителя до тех пор, пока количество эпох не достигнет предварительно определённой вехи: total_iters.

lr_scheduler.ExponentialLR

Уменьшает скорость обучения каждой параметрической группы на множитель gamma через каждую эпоху.

lr_scheduler.PolynomialLR

Уменьшает скорость обучения каждой параметрической группы с использованием полиномиальной функции в заданном total_iters.

lr_scheduler.CosineAnnealingLR

Устанавливает скорость обучения каждой параметрической группы с помощью расписания косинусного отжига, где ηmax\eta_{max} устанавливается на начальную lr, а TcurT_{cur} — количество эпох с момента последнего перезапуска в SGDR:

lr_scheduler.ChainedScheduler

Цепочкой список планировщиков скорости обучения.

lr_scheduler.SequentialLR

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

lr_scheduler.ReduceLROnPlateau

Уменьшить скорость обучения, когда метрика перестала улучшаться.

lr_scheduler.CyclicLR

Устанавливает скорость обучения каждой параметрической группы в соответствии с циклической политикой скорости обучения (CLR).

lr_scheduler.OneCycleLR

Устанавливает скорость обучения каждой параметрической группы в соответствии с политикой скорости обучения 1cycle.

lr_scheduler.CosineAnnealingWarmRestarts

Устанавливает скорость обучения каждой параметрической группы с помощью расписания косинусного отжига, где ηmax\eta_{max} устанавливается на начальную lr, TcurT_{cur} — количество эпох с момента последнего перезапуска, а TiT_{i} — количество эпох между двумя перезапусками в SGDR:

Среднее арифметическое стохастических весов

torch.optim.swa_utils реализует метод усреднения стохастических весов (SWA). В частности, torch.optim.swa_utils.AveragedModel класс реализует модели SWA, torch.optim.swa_utils.SWALR реализует планировщик скорости обучения SWA, а torch.optim.swa_utils.update_bn() — вспомогательная функция, используемая для обновления статистических данных пакетной нормализации SWA в конце обучения.

Метод SWA был предложен в статье Averaging Weights Leads to Wider Optima and Better Generalization.

Создание усредненных моделей

Класс AveragedModel служит для вычисления весов модели SWA. Вы можете создать усредненную модель, выполнив следующие действия:

>>> swa_model = AveragedModel(model)

Здесь модель model может быть любым объектом torch.nn.Module. swa_model будет отслеживать текущие средние значения параметров model. Чтобы обновить эти средние значения, вы можете использовать функцию update_parameters():

>>> swa_model.update_parameters(model)

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

Обычно в SWA скорость обучения устанавливается в высокое постоянное значение. SWALR — это планировщик скорости обучения, который уменьшает скорость обучения до фиксированного значения, а затем держит её постоянной. Например, следующий код создаёт планировщик, линейно уменьшающий скорость обучения от её начального значения до 0,05 за 5 эпох в каждой группе параметров:

>>> swa_scheduler = torch.optim.swa_utils.SWALR(optimizer, \
>>>         anneal_strategy="linear", anneal_epochs=5, swa_lr=0.05)

Вы также можете использовать косинусное уменьшение до фиксированного значения вместо линейного, установив anneal_strategy="cos".

Обработка пакетной нормализации

update_bn() — это вспомогательная функция, которая позволяет вычислять статистику пакетной нормализации для модели SWA на заданном наборе данных loader в конце обучения:

>>> torch.optim.swa_utils.update_bn(loader, swa_model)

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

Предупреждение

update_bn() предполагает, что каждый пакет в наборе данных loader представляет собой тензор или список тензоров, где первый элемент — тензор, к которому должна применяться сеть swa_model. Если ваш набор данных имеет другую структуру, вы можете обновить статистику пакетной нормализации swa_model путём выполнения прохода вперёд с swa_model для каждого элемента набора данных.

Настройка стратегий усреднения

По умолчанию, torch.optim.swa_utils.AveragedModel вычисляет среднее значение параметров, которые вы предоставляете, но вы также можете использовать пользовательские функции усреднения с параметром avg_fn. В следующем примере ema_model вычисляет экспоненциально скользящее среднее.

Пример:

>>> ema_avg = lambda averaged_model_parameter, model_parameter, num_averaged:\
>>>         0.1 * averaged_model_parameter + 0.9 * model_parameter
>>> ema_model = torch.optim.swa_utils.AveragedModel(model, avg_fn=ema_avg)

Объединение всего в одно целое

В примере ниже, swa_model — это модель SWA, которая накапливает средние значения весов. Мы обучаем модель в течение 300 эпох, переключаемся на планировщик скорости обучения SWA и начинаем собирать средние значения SWA параметров на 160 эпохе:

>>> loader, optimizer, model, loss_fn = ...
>>> swa_model = torch.optim.swa_utils.AveragedModel(model)
>>> scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=300)
>>> swa_start = 160
>>> swa_scheduler = SWALR(optimizer, swa_lr=0.05)
>>>
>>> for epoch in range(300):
>>>       for input, target in loader:
>>>           optimizer.zero_grad()
>>>           loss_fn(model(input), target).backward()
>>>           optimizer.step()
>>>       if epoch > swa_start:
>>>           swa_model.update_parameters(model)
>>>           swa_scheduler.step()
>>>       else:
>>>           scheduler.step()
>>>
>>> # Update bn statistics for the swa_model at the end
>>> torch.optim.swa_utils.update_bn(loader, swa_model)
>>> # Use swa_model to make predictions on test data
>>> preds = swa_model(test_input)

© 2024, PyTorch Contributors
PyTorch has a BSD-style license, as found in the LICENSE file.
https://pytorch.org/docs/1.13/optim.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API