Почему методом обучения torch.optim.SGD изменяется скорость обучения? - PullRequest
0 голосов
/ 04 мая 2020

С SGD скорость обучения не должна изменяться в течение эпох, но это так. Помогите мне понять, почему это происходит, и как предотвратить это изменение LR?

import torch
params = [torch.nn.Parameter(torch.randn(1, 1))]
optimizer = torch.optim.SGD(params, lr=0.9)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, 1, gamma=0.9)
for epoch in range(5):
    print(scheduler.get_lr())
    scheduler.step()

Вывод:

[0.9]
[0.7290000000000001]
[0.6561000000000001]
[0.5904900000000002]
[0.5314410000000002]

Моя версия горелки - 1.4.0

Ответы [ 3 ]

1 голос
/ 04 мая 2020

Это именно то, что torch.optim.lr_scheduler.StepLR должен делать. Это меняет скорость обучения. Из документации к pytorch:

Затухает скорость обучения каждой группы параметров по гамме каждые эпохи step_size. Обратите внимание, что такое затухание может происходить одновременно с другими изменениями скорости обучения извне этого планировщика. Когда last_epoch = -1, устанавливает начальный lr как lr

Если вы пытаетесь оптимизировать params, ваш код должен выглядеть примерно так (просто игрушечный пример, точная форма loss будет зависеть от вашей заявки)

for epoch in range(5):
  optimizer.zero_grad()
  loss = (params[0]**2).sum()
  loss.backward()
  optimizer.step()
1 голос
/ 04 мая 2020

Чтобы развернуть ответ xiawi о "странном" поведении (отсутствует 0.81): это стандарт PyTorch с момента выпуска 1.1.0, проверьте документацию , а именно эту часть :

[...] Если вы используете планировщик скорости обучения (вызов scheduler.step()) перед обновлением оптимизатора (вызов optimizer.step()), при этом будет пропущено первое значение расписания скорости обучения. .

Кроме того, вы должны получить UserWarning, выдаваемый этой функцией после первого вызова get_lr(), поскольку вы вообще не вызываете optimizer.step().

1 голос
/ 04 мая 2020

Поскольку вы используете команду torch.optim.lr_scheduler.StepLR(optimizer, 1, gamma=0.9) (то есть фактически torch.optim.lr_scheduler.StepLR(optimizer, step_size=1, gamma=0.9)), таким образом, вы умножаете скорость обучения на gamma=0.9 каждый step_size=1 шаг:

  • 0,9 = 0,9
  • 0,729 = 0,9 * 0,9 * 0,9
  • 0,6561 = 0,9 * 0,9 * 0,9 * 0,9
  • 0,59049 = 0,9 * 0,9 * 0,9 * 0,9 * 0,9

Единственный «странный» момент - отсутствие второго 0,81 = 0,9 * 0,9 (ОБНОВЛЕНИЕ: см. ответ Szymon Maszke для объяснения)

Чтобы предотвратить раннее снижение, если у вас есть N выборок в вашем наборе данных, и размер пакета равен D, затем установите torch.optim.lr_scheduler.StepLR(optimizer, step_size=N/D, gamma=0.9) для уменьшения в каждую эпоху. Чтобы уменьшить каждую эпоху, установите torch.optim.lr_scheduler.StepLR(optimizer, step_size=E*N/D, gamma=0.9)

...