Dziwne zachowanie z optymalizatorem Adama podczas treningu zbyt długo

11

Próbuję wytrenować pojedynczy perceptron (1000 jednostek wejściowych, 1 wyjście, brak ukrytych warstw) na 64 losowo generowanych punktach danych. Używam Pytorch za pomocą optymalizatora Adama:

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()

Początkowo strata szybko maleje, zgodnie z oczekiwaniami:

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

Około 300 iteracji błąd sięga prawie zera:

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

Trwa to przez kilka tysięcy iteracji. Jednak po zbyt długim treningu błąd zaczyna się ponownie zwiększać:

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

Dlaczego to się dzieje?

Bai Li
źródło
Nie sądzę, że nadmierne dopasowanie to wyjaśnia - utrata treningów rośnie, a nie utrata walidacji. Na przykład tak się nie dzieje podczas korzystania z SGD, tylko z Adamem.
Bai Li
Model ma 1000 parametrów i jest tylko 1 punkt danych, więc model powinien dokładnie pasować do danych, a strata powinna wynosić zero.
Bai Li
Och przepraszam, masz rację. Istnieje 64 punktów danych.
Bai Li
Istnieją 64 punkty danych (tj. Ograniczenia) i 1000 parametrów, więc można znaleźć opcje dla parametrów, aby błąd wynosił zero (i łatwo to zrobić analitycznie). Moje pytanie brzmi: dlaczego Adam tego nie znajduje.
Bai Li

Odpowiedzi:

19

Ta niewielka niestabilność na końcu zbieżności jest cechą Adama (i RMSProp) ze względu na to, jak szacuje średnie wielkości gradientu w ostatnich krokach i dzieli je.

Jedną rzeczą, którą Adam robi, jest utrzymanie ruchomej średniej geometrycznej ostatnich gradientów i kwadratów gradientów. Kwadraty gradientów służą do dzielenia (kolejnej średniej kroczącej) bieżącego gradientu w celu podjęcia decyzji o bieżącym kroku. Jednak gdy gradient staje się i pozostaje bardzo bliski zeru, spowoduje to, że kwadraty gradientu staną się tak niskie, że albo będą miały duże błędy zaokrąglania, albo będą faktycznie zerowe, co może wprowadzić niestabilność (na przykład długoterminowy stabilny gradient w jeden wymiar robi względnie mały krok od do powodu zmian w innych parametrach ), a rozmiar kroku zacznie skakać, zanim ponownie się uspokoi.10-1010-5

To faktycznie sprawia, że ​​Adam jest mniej stabilny i gorzej dla twojego problemu niż bardziej podstawowe zejście gradientu, zakładając, że chcesz zbliżyć się do liczbowo bliskiego zerowej straty, jak pozwalają na to obliczenia.

W praktyce w przypadku problemów z głębokim uczeniem się, nie zbliżasz się tak bardzo do konwergencji (a w przypadku niektórych technik regularyzacji, takich jak wczesne zatrzymanie, i tak nie chcesz), więc zazwyczaj nie jest to praktyczne zmartwienie dotyczące rodzajów problemów, które Adam został zaprojektowany dla.

Możesz faktycznie zobaczyć, jak to się dzieje w przypadku RMSProp w porównaniu różnych optymalizatorów (RMSProp to czarna linia - obserwuj ostatnie kroki, gdy tylko osiągnie cel):

wprowadź opis zdjęcia tutaj

Możesz sprawić, by Adam był bardziej stabilny i mógł zbliżyć się do prawdziwej konwergencji poprzez zmniejszenie wskaźnika uczenia się. Na przykład

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

Optymalizacja potrwa dłużej. Używając lr=1e-5musisz trenować przez ponad 20 000 iteracji, zanim zobaczysz niestabilność, a niestabilność jest mniej dramatyczna, wartości krążą wokół10-7.

Neil Slater
źródło
To spektakularna wizualizacja, Neil. Jakie są rzeczywiste wymiary? Co oznacza xiy? Czy ramki mają jakieś delty lub n epoki na ramkę? Domyślam się, że gwiazda jest globalnym optimum w topograficznej reprezentacji rozbieżności (błędu) w stosunku do dwóch wybranych parametrów. Czy moje przypuszczenie jest prawidłowe?
Douglas Daseeco
To nie jest moja wizualizacja, znajdziesz ją w wielu miejscach. Wymiary są dowolnymi jednostkami parametrów wejściowych funkcji testowej, a wykres pokazuje linie konturowe dla tej funkcji (ponownie w dowolnych jednostkach, prawdopodobnie skalowane tak, aby NN działało OK). Każda ramka to krok aktualizacji wagi. Prawdopodobnie jest to odpowiednik aktualizacji mini-wsadowej, a ze względu na zachowanie SGD oczekuję, że w rzeczywistości jest on rozwiązany dokładnie przy użyciu prawdziwego gradientu funkcji testowej - tj. Nie ma zestawu danych ani próbkowania.
Neil Slater,
1

Powód jest dokładnie taki, jak wspomniany w drugiej odpowiedzi, ze świetną sugestią, aby użyć mniejszego współczynnika uczenia się, aby uniknąć tego problemu przy małych gradientach.

Mogę wymyślić kilka podejść:

  1. Możesz przyciąć gradienty górną / dolną granicą, ale nie gwarantuje to zbieżności i może spowodować zamrożenie treningu przez uwięzienie w lokalnych minimach i nigdy się z niego nie wydostanie.

  2. Trenuj z większą wielkością partii, większą liczbą epok i ze zmniejszoną szybkością uczenia się. Teraz nie mam żadnego praktycznego dowodu, że zwiększenie wielkości partii skutkuje lepszymi gradientami, ale z tego, co zaobserwowałem w obliczu problemów podobnych do twojego, prawie zawsze pomogło.

Jestem pewien, że istnieją inne metody (takie jak cykliczny współczynnik uczenia się itp.), Które próbują znaleźć optymalny współczynnik uczenia się na podstawie statystyk.

Sanjay Krishna
źródło