Дивна поведінка з оптимізатором Адама, коли занадто довго тренувалися


11

Я намагаюся навчити один перцептрон (1000 вхідних одиниць, 1 вихід, без прихованих шарів) на 64 випадково генерованих точках даних. Я використовую Pytorch за допомогою оптимізатора Адама:

import torch
from torch.autograd import Variable

torch.manual_seed(545345)
N, D_in, D_out = 64, 1000, 1

x = Variable(torch.randn(N, D_in))
y = Variable(torch.randn(N, D_out))

model = torch.nn.Linear(D_in, D_out)
loss_fn = torch.nn.MSELoss(size_average=False)

optimizer = torch.optim.Adam(model.parameters())
for t in xrange(5000):
  y_pred = model(x)
  loss = loss_fn(y_pred, y)

  print(t, loss.data[0])

  optimizer.zero_grad()
  loss.backward()
  optimizer.step()

Спочатку збитки швидко зменшуються, як очікувалося:

(0, 91.74887084960938)
(1, 76.85824584960938)
(2, 63.434078216552734)
(3, 51.46927261352539)
(4, 40.942893981933594)
(5, 31.819372177124023)

Близько 300 ітерацій помилка доходить до нуля:

(300, 2.1734419819452455e-12)
(301, 1.90354676465887e-12)
(302, 2.3347573874232808e-12)

Це триває кілька тисяч ітерацій. Однак після занадто довгої тренування помилка знову починає зростати:

(4997, 0.002102422062307596)
(4998, 0.0020302983466535807)
(4999, 0.0017039275262504816)

Чому це відбувається?


Я не думаю, що перевиконання пояснює це - втрата тренінгу зростає, а не втрата валідації. Наприклад, цього не відбувається при використанні SGD, лише з Адамом.
Бай Лі

Модель має 1000 параметрів і є лише 1 точка даних, тому модель повинна точно відповідати даним, а втрата повинна дорівнювати нулю.
Бай Лі

Пробач, ти маєш рацію. Є 64 точки даних.
Бай Лі

Є 64 точки даних (тобто обмеження) та 1000 параметрів, тому можна знайти вибір параметрів, щоб помилка дорівнювала нулю (а це легко зробити аналітично). Моє запитання, чому Адам не знаходить цього.
Бай Лі

Відповіді:


19

Ця невелика нестабільність наприкінці конвергенції є особливістю Адама (і RMSProp) завдяки тому, як він оцінює середні величини градієнта за останні кроки та поділи на них.

Одне, що робить Адам, це підтримувати котяче середнє геометричне значення останніх градієнтів та квадратів градієнтів. Квадрати градієнтів використовуються для поділу поточного градієнта (іншого середнього кочення) для вирішення поточного кроку. Однак, коли ваш градієнт стає і залишається дуже близьким до нуля, це зробить квадрати градієнта настільки низькими, що або мають великі помилки округлення, або фактично нульові, що може внести нестабільність (наприклад, довготривалий стабільний градієнт у один вимір робить порівняно невеликий крок від до через зміни в інших парамах), і розмір кроку почне стрибати навколо, перш ніж знову поселитися.10-1010-5

Це насправді робить Адама менш стійким і гіршим для вашої проблеми, ніж більш базовий градієнтний спуск, припускаючи, що ви хочете отримати максимально близький до нульових втрат, оскільки обчислення дозволяють вирішити вашу проблему.

На практиці щодо проблем глибокого навчання ви не наближаєтесь до такої конвергенції (а для деяких методів регуляризації, таких як рання зупинка, все одно не хочеться), тому, як правило, це не стосується тих проблем, які Адам був розроблений для.

Ви дійсно можете побачити це, що трапляється для RMSProp, порівнявши різні оптимізатори (RMSProp - чорна лінія - спостерігайте за останніми кроками, як тільки вона досягне мети):

введіть тут опис зображення

Ви можете зробити Адама більш стійким і здатним наблизитися до справжньої конвергенції, зменшивши рівень навчання. Напр

optimizer = torch.optim.Adam(model.parameters(), lr=1e-5)

Оптимізація займе більше часу. Використання lr=1e-5вам необхідно навчити для ітерацій , перш ніж 20000 ви бачите нестабільність і нестійкість менш драматична, значення парити близько .10-7


Це ефектна візуалізація, Ніл. Які фактичні розміри? Що представляє х і у? Чи є кадри дельта т або n епох на кадр? Я здогадуюсь, що зірка - це глобальний оптимум у топографічному поданні розбіжності (помилки) стосовно двох обраних параметрів. Моя здогадка правильна?
Дуглас Дазеєко

Це не моя візуалізація, ви її знайдете в багатьох місцях. Розміри - це довільні одиниці вхідних параметрів для тестової функції, і на графіку показані контурні лінії для цієї функції (знову ж таки в довільних одиницях, імовірно масштабованих, щоб NN працював нормально). Кожен кадр є ваговим кроком оновлення. Це, мабуть, еквівалентно міні-пакетному оновленню, і, завдяки поведінці SGD, я думаю, що він насправді вирішується саме за допомогою справжнього градієнта тестової функції - тобто немає набору даних або вибірки.
Ніл Слейтер

1

Причина саме в тому, що згадується в іншій відповіді, із великою пропозицією використовувати менший рівень навчання, щоб уникнути цієї проблеми навколо невеликих градієнтів.

Я можу придумати кілька підходів:

  1. Ви можете обрізати градієнти верхньою / нижньою межею, але це не гарантує конвергенції і може призвести до тренування замерзання, потрапивши в пастку в якихось локальних мінімумах і ніколи не виходьте з нього.

  2. Тренуйтеся з більшим розміром партії, більшою мірою епох і зі зниженою швидкістю навчання. Зараз я не маю жодних практичних доказів того, що збільшення розміру партії призводить до кращих градієнтів, але від того, що я спостерігав, стикаючись з проблемами, подібними до ваших, це майже завжди допомагало.

Я впевнений, що існують інші методи (наприклад, циклічна швидкість навчання тощо), які намагаються знайти оптимальну швидкість навчання на основі статистики.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.