Jak sprawić, żeby sieć uczyła się i generalizowała
Sześciowarstwowa sieć z loss nieruchomym na ln 2, naprawiana pomiar po pomiarze. Potem double descent: 5 000 parametrów na 40 punktach.
Na tej stronie
Sieć z rozdziału 5 działa. Ma dziewięć parametrów, uczy się XOR, a jej gradienty zgadzają się z PyTorch do szesnastego miejsca po przecinku.
Zrób ją sześciowarstwową, a całkowicie przestanie się uczyć. Nie powoli — całkowicie. Oto sześciowarstwowa sieć na problemie klasyfikacji dwóch spiral, trenowana przez 5000 kroków:
step 1: loss 0.693147
step 5000: loss 0.693147
accuracy: 50.0 %Ta liczba nie jest przypadkowa. to binary cross-entropy modelu, który dla wszystkiego zwraca prawdopodobieństwo , a 50 % to rzut monetą na zbalansowanym zbiorze danych. Po pięciu tysiącach kroków sieć nie przesunęła się nawet o jedną cyfrę. Nic się nie wysypało, nic nie ostrzegło, a gradienty nadal są dokładnie poprawne.
Ten rozdział jest o luce między siecią, która się uruchamia, a siecią, która działa. Ma dwie połowy, które wyglądają jak różne tematy, ale są tym samym zadaniem: sprawić, żeby loss szedł w dół, i sprawić, żeby szedł w dół na danych, których model nigdy nie widział.
Dlaczego sześciowarstwowa sieć jest martwa
Link do sekcji: Dlaczego sześciowarstwowa sieć jest martwaZacznij od patrzenia, nie od zgadywania. Przepuść batch wejść przez sieć i wypisz odchylenie standardowe aktywacji w każdej warstwie, a potem odchylenie standardowe gradientów wag:
def profile(model, x):
h = x
for layer in model:
h = layer(h)
if isinstance(layer, (nn.Tanh, nn.ReLU)):
print(f"activation std: {h.std().item():.4f}")
model(x).sum().backward()
for p in model.parameters():
if p.dim() == 2:
print(f"gradient std: {p.grad.std().item():.2e}")Trzy inicjalizacje, ta sama architektura, sześć warstw :
| inicjalizacja | std aktywacji, warstwy 1→6 |
|---|---|
| normalna, std | 0.0145 · 0.0016 · 0.0002 · 0.0000 · 0.0000 · 0.0000 |
| normalna, std | 0.6573 · 0.9296 · 0.9585 · 0.9634 · 0.9637 · 0.9625 |
| Xavier | 0.1579 · 0.1493 · 0.1353 · 0.1333 · 0.1325 · 0.1403 |
| inicjalizacja | std gradientu, pierwsza warstwa → ostatnia |
|---|---|
| normalna, std | 3.20e-06 · 4.97e-07 · … · 6.40e-06 |
| normalna, std | 1.94e+03 · 2.28e+02 · 1.22e+02 · 4.43e+01 · 1.85e+01 · 7.30e+00 |
| Xavier | 2.31e+00 · 4.50e-01 · 4.26e-01 · 3.89e-01 · 4.39e-01 · 4.73e-01 |
Pierwszy wiersz to sieć powyżej, i ona nie uczy się powoli — nie ma już żadnego sygnału. Do czwartej warstwy odchylenie standardowe aktywacji spadło do zera przy czterech miejscach po przecinku. Każde wejście daje to samo wyjście, wyjście jest stałą, a gradient stałej jest niczym. Wagi zainicjalizowano małe „dla bezpieczeństwa”, a małe okazało się śmiertelne.
Drugi wiersz to przeciwna awaria i warto ją zrozumieć, bo jest nieintuicyjna. Aktywacje wyglądają zdrowo — około 0.96 — ale to nasycone, przybite blisko swojej granicy, dokładnie ten reżim, który rozdział 5 zmierzył jako tracący prawie dziesięć tysięcy razy na gradiencie. A jednak gradienty są ogromne: 1940 w pierwszej warstwie. Obie rzeczy są prawdziwe naraz. Każdy krok wstecz mnoży przez , a przy 128 wejściach o wariancji jednostkowej ten czynnik ma wzmocnienie około , które przytłacza kurczenie wynikające z nasyconego . Gradienty rosną geometrycznie w drodze powrotnej. To exploding gradient i w każdym prawdziwym treningu w kilka kroków produkuje wartości loss równe nan.
Trzeci wiersz jest tym, czego chcesz: aktywacje mają mniej więcej stałą skalę przez głębokość, gradienty mają mniej więcej stałą skalę przez głębokość. Nic nie umiera, nic nie eksploduje.
Normalizacja i ta, która przetrwała
Link do sekcji: Normalizacja i ta, która przetrwałaDobra inicjalizacja naprawia skalę w kroku zero. Nie utrzymuje jej na stałe: wagi się ruszają i w kroku pięć tysięcy ostrożny argument o wariancji już nie obowiązuje.
Warstwy normalizacji wymuszają skalę ciągle. Mając wektor aktywacji, odejmij średnią, podziel przez odchylenie standardowe, a potem zastosuj uczoną skalę i przesunięcie , żeby warstwa mogła cofnąć normalizację, jeśli okaże się, że właśnie tego chce:
Jedyne prawdziwe pytanie brzmi: po czym uśredniasz. Batch normalisation3 liczy i wzdłuż wymiaru batch, jedną statystykę na cechę. Layer normalisation4 liczy je po cechach, jedną statystykę na przykład.
Ten wybór wygląda drobno, a decyduje o prawie wszystkim dalej:
BatchNorm sprawia, że wyjście każdego przykładu zależy od innych przykładów, które akurat trafiły do jego batch. W czasie treningu to łagodny regularizator. W czasie inference nie ma batch, więc musi utrzymywać średnią kroczącą statystyk zebranych podczas treningu — co oznacza, że warstwa zachowuje się inaczej w trybie treningu i ewaluacji, a zapomnienie o przełączeniu trybów jest jednym z najczęstszych błędów w tej dziedzinie. Pogarsza się też przy małych batch i jest niewygodny przy sekwencjach zmiennej długości, bo „średnia po batch na pozycji 40” jest liczona z tylu sekwencji, ile akurat jest tak długich.
LayerNorm normalizuje każdy przykład osobno. Brak zależności od batch, brak statystyk kroczących, identyczne zachowanie w treningu i inference, obojętność na rozmiar batch, obojętność na długość sekwencji. Każda z tych właściwości staje się wymaganiem, a nie miłym dodatkiem, gdy generujesz jeden token naraz dla jednego użytkownika — czyli tam, gdzie kończy się rozdział 13.
Właśnie dlatego LayerNorm spotkasz ponownie w rozdziale 9 bez zmian: blok transformer go używa i używa go z powodów z prawej kolumny, a nie dlatego, że abstrakcyjnie działa lepiej.
Naprawianie po jednej rzeczy naraz, czyli prawdziwy skill
Link do sekcji: Naprawianie po jednej rzeczy naraz, czyli prawdziwy skillCztery potencjalne poprawki dla martwej sieci: inicjalizacja Xavier, LayerNorm, połączenia resztkowe i Adam zamiast SGD. Pokusa polega na tym, żeby zastosować wszystkie cztery i iść dalej. Zrób tak, a nigdy nie dowiesz się, która miała znaczenie; następnym razem nie będziesz mieć metody — tylko rytuał.
Zastosuj je więc pojedynczo. Ten sam seed, te same dane, ta sama architektura, 800 kroków:
| co dodano | końcowy loss | accuracy |
|---|---|---|
| nic | 0.6931 | 50.0 % |
| inicjalizacja Xavier | 0.5692 | 60.4 % |
| LayerNorm | 0.6230 | 61.5 % |
| połączenia resztkowe | 0.6651 | 56.6 % |
| Adam | 0.6787 | 58.7 % |
| wszystkie cztery | 0.0000 | 100.0 % |
Przeczytaj tę tabelę tak, jak czytałbyś ją o 2 w nocy, a wniosek brzmi: nic nie działa samo, wszystko działa razem, więc deep learning to alchemia. Ten wniosek jest błędny, a odkrycie dlaczego jest najcenniejszą rzeczą w tym rozdziale.
Daj każdemu przebiegowi sześć razy większy budżet — 5000 kroków zamiast 800 — a obraz zmienia się całkowicie:
| co dodano | końcowy loss @ 5000 | accuracy |
|---|---|---|
| nic | 0.6931 | 50.0 % |
| inicjalizacja Xavier | 0.0007 | 100.0 % |
| LayerNorm | 0.0002 | 100.0 % |
| połączenia resztkowe | 0.6653 | 56.7 % |
| Adam | 0.6908 | 53.4 % |
| Xavier + Adam | 0.0000 | 100.0 % |
| Xavier + LayerNorm | 0.0001 | 100.0 % |
Teraz obraz jest ostry i jest diagnozą, nie rytuałem.
Sama inicjalizacja to naprawia. Sama normalizacja to naprawia. Każda adresuje prawdziwą chorobę — sygnał w przód zapadający się do zera — i każda wystarcza. Przy 800 krokach wyglądały tylko jak częściowe punkty, bo rozwiązały problem, ale wciąż wychodziły z dołka.
Połączenia resztkowe i Adam tego nie naprawiają, przy żadnym budżecie. Nie dlatego, że są złe, tylko dlatego, że leczą inną chorobę. Połączenie resztkowe daje gradientowi ścieżkę wokół blokującej warstwy; to jest bardzo cenne, gdy problemem jest gradient, i nic niewarte, gdy sygnał w przód jest już zerowy, bo skrót wokół martwej warstwy nadal niesie martwą wartość. Adam przeskalowuje krok każdego parametru według jego własnej historii gradientu; pomaga, gdy gradienty mają skrajnie różne wielkości, ale nie potrafi wskrzesić sieci, której wyjście nie zależy od wejścia.
A „nic” po pięciu tysiącach kroków nadal jest dokładnie 0.6931. Nie 0.6929. To nie jest wolne; to jest martwe, a ta różnica jest widoczna jak nigdy wcześniej, bo masz do porównania wiersz mówiący, że poprawka działa.
Zasłużyć na PyTorch
Link do sekcji: Zasłużyć na PyTorchOd tego miejsca kurs używa PyTorch. To powinno być zasłużone, nie ogłoszone, więc oto dokładnie, co robi — a ty już umiesz to zrobić.
Optimizer to reguła zamiany gradientów na aktualizacje parametrów. Zwykły gradient descent używa gradientu. Momentum używa jego średniej kroczącej, co wygładza szum i buduje prędkość w kierunkach, które pozostają spójne:
v = beta * v + p.grad
p -= lr * v Adam5 utrzymuje dwie średnie kroczące — gradientu i gradientu podniesionego do kwadratu — i dzieli jedną przez pierwiastek z drugiej, dzięki czemu każdy parametr dostaje krok przeskalowany do własnej niedawnej wielkości gradientu:
m = b1 * m + (1 - b1) * g # mean of the gradient
v = b2 * v + (1 - b2) * g * g # mean of the squared gradient
m_hat = m / (1 - b1 ** t) # bias correction: both averages start at zero
v_hat = v / (1 - b2 ** t)
p -= lr * m_hat / (v_hat.sqrt() + eps) Dziesięć linii. Uruchom oba przeciwko torch.optim na tym samym problemie przez 50 kroków:
SGD+momentum by hand [2.7781870365142822, -1.0304985046386719]
torch [2.7781870365142822, -1.0304983854293823] max |diff| = 1.19e-07
Adam by hand [0.4893140196800232, -0.46317872405052185]
torch [0.48931416869163513, -0.46317875385284424] max |diff| = 1.49e-07Identyczne do precyzji float32. torch.optim.Adam to te pięć linii plus dekady troski o przypadki brzegowe i kernel C++. To jest wymiana, którą od teraz robisz: nie magia zamiast zrozumienia, tylko szybkość za linie, które już napisałeś.
Dlaczego Adam istnieje: krzywizna
Link do sekcji: Dlaczego Adam istnieje: krzywiznaTypowe wyjaśnienie Adama brzmi „adaptacyjne learning rates per parametr”, co jest opisem, a nie powodem. Powodem jest geometria i da się ją zmierzyć.
Weź loss, którego krzywizna różni się między kierunkami: stroma w jednym, płytka w drugim. SGD ma jeden globalny learning rate, więc musi wybrać wartość na tyle małą, żeby była stabilna w najbardziej stromym kierunku — a ta wartość jest potem o wiele za mała dla płytkiego kierunku, gdzie postęp pełznie. To powoduje klasyczny obraz gradient descent zygzakującego w dół wąskiej doliny.
Dwa stosunki krzywizny, trzy optimizery, 300 kroków, a każdy optimizer dostaje najlepszy learning rate z przeszukiwania, żeby nikt nie był poszkodowany:
| stosunek krzywizny | SGD | SGD + momentum | Adam |
|---|---|---|---|
| 10 : 1 | błąd 0.000002 | błąd 0.000000 | błąd 0.000000 |
| 1000 : 1 | błąd 1.925485 | błąd 0.001432 | błąd 0.000000 |
| rozbieżność przy (1000:1) | 4 z 8 stawek | 4 z 8 stawek | 0 z 6 stawek |
Przy stosunku dziesięć wszystko działa i nie ma o czym dyskutować. Przy tysiącu zwykły SGD nie potrafi dojść do odpowiedzi przy żadnym z próbowanych learning rates — jego najlepszy wynik nadal ma błąd 1.93 — i wprost się rozbiega przy połowie stawek. Adam trafia dokładnie w cel i nie rozbiega się przy żadnej.
Ta ostatnia kolumna jest praktycznym powodem, dla którego Adam jest domyślny. Nie chodzi o to, że Adam znajduje lepsze rozwiązania; na dobrze uwarunkowanych problemach dostrojony SGD często mu dorównuje albo go przebija. Chodzi o to, że Adam jest dużo mniej wrażliwy na wybrany learning rate, a prawdziwe sieci mają stosunki krzywizny znacznie gorsze niż tysiąc w swoich milionach parametrów.
Tu należą jeszcze dwie rzeczy i obie mieszczą się w jednej linii. Gradient clipping przeskalowuje wektor gradientu, gdy jego norma przekracza próg, co zamienia wiersz „loss nagle skacze do ogromnej wartości” z tabeli diagnostycznej w niezdarzenie. Oraz learning rate schedules: krótki warmup od prawie zera przez pierwszych kilkaset kroków, bo estymacje wariancji Adama są śmieciowe, dopóki nie zobaczą kilku gradientów, a pełnowymiarowy krok zrobiony na śmieciach może zniszczyć inicjalizację; potem cosine decay w kierunku zera, bo kończenie przebiegu z takim samym rozmiarem kroku jak na początku oznacza drganie wokół minimum zamiast osiadania w nim.
Druga połowa: model, który dopasowuje idealnie i niczego nie przewiduje
Link do sekcji: Druga połowa: model, który dopasowuje idealnie i niczego nie przewidujeWszystko do tej pory dotyczyło sprowadzenia loss w dół. Teraz trudniejsza połowa, bo spadający loss nie jest celem — jest proxy celu, a to proxy zawodzi w konkretny i słynny sposób.
Dwanaście punktów z gładkiej funkcji z odrobiną szumu. Dopasuj wielomiany rosnącego stopnia:
| stopień | train RMSE | test RMSE |
|---|---|---|
| 1 | 0.764499 | 0.6985 |
| 3 | 0.252605 | 0.3031 |
| 5 | 0.164437 | 0.1568 |
| 9 | 0.088960 | 0.2347 |
| 11 | 0.000000 | 1.2094 |
Stopień 11 przez 12 punktów przechodzi dokładnie przez każdy z nich — błąd train zero do sześciu miejsc po przecinku — i jest osiem razy gorszy niż stopień 5 na danych, których nie widział. Poproś stopień 3 i stopień 11 o predykcję w , tuż poza zakresem treningowym:
degree 3: predicts -1.053 (truth -0.012)
degree 11: predicts +61.224 (truth -0.012)Sześćdziesiąt jeden, gdy odpowiedź wynosi w przybliżeniu zero. Model nie nauczył się funkcji; nauczył się dwunastu punktów, a między nimi robi to, czego wymaga arytmetyka.
To jest overfitting, a jego przeciwieństwo — stopień 1, który w ogóle nie potrafi reprezentować krzywej i jest zły wszędzie — to underfitting. Klasyczne ujęcie dzieli oczekiwany błąd modelu na trzy części: bias, błąd wynikający z tego, że model jest zbyt sztywny, by reprezentować prawdę; variance, błąd wynikający z tego, że model jest tak elastyczny, iż goni za szumem w tej konkretnej próbce; oraz szum nieredukowalny, którego nic nie naprawi. Proste modele są biasowe, elastyczne modele mają wysoką variance, a klasyczna recepta to znalezienie złotego środka — stopnia 5 w tabeli powyżej.
Standardowe narzędzia atakują składnik variance:
- Regularizacja L2 (weight decay) dodaje do loss, przyciągając wagi do zera i wygładzając funkcję. W tabeli powyżej największy współczynnik stopnia 11 robi szkodę; karanie wielkości ją rozbraja.
- L1 dodaje zamiast tego . Różnica nie jest kosmetyczna: gradient L2 jest proporcjonalny do wagi, więc maleje wraz z wagą, zbliżając się do zera, ale nigdy do niego nie docierając, podczas gdy gradient L1 jest stałą , która pcha aż do końca. L1 produkuje więc wagi dokładnie równe zero — wybiera cechy. L2 produkuje małe wagi. Używaj L2, gdy chcesz gładkości, L1, gdy chcesz rzadkości.
- Dropout7 zeruje losowy podzbiór aktywacji w każdym kroku treningu, więc żadna jednostka nie może polegać na tym, że konkretna inna jednostka będzie obecna.
- Early stopping obserwuje validation loss i zatrzymuje trening, gdy zaczyna rosnąć.
- Data augmentation wytwarza więcej przykładów treningowych z tych, które masz, atakując problem u źródła: overfitting jest niedoborem danych równie mocno, co nadmiarem parametrów.
- Cross-validation dzieli dane na części i trenuje razy, co kupuje wiarygodną estymację błędu testowego, gdy masz za mało danych, by odłożyć osobny zbiór held-out.
Double descent, czyli dlaczego poprzednia sekcja to nie cała historia
Link do sekcji: Double descent, czyli dlaczego poprzednia sekcja to nie cała historiaTeraz fakt, który łamie ten obraz.
Historia bias-variance mówi, że za złotym środkiem więcej parametrów oznacza gorszą generalizację. Współczesne modele językowe mają znacznie więcej parametrów, niż klasyczne reguły pozwalałyby dla danych, które widzą, i generalizują świetnie. Oba zdania są prawdziwe, a pogodzenie ich jest najcenniejszą rzeczą w tym rozdziale.
Czterdzieści punktów treningowych, dwudziestowymiarowe wejścia, losowe cechy ReLU, a liczba cech przeszukana od 2 do 5000 — z wyborem rozwiązania o minimalnej normie, gdy istnieje wiele rozwiązań dopasowujących dane:
| train RMSE | test RMSE | |||
|---|---|---|---|---|
| 10 | 0.25 | 0.8822 | 1.2520 | 1.89 |
| 20 | 0.50 | 0.5962 | 1.1634 | 2.59 |
| 30 | 0.75 | 0.3896 | 1.5323 | 4.15 |
| 38 | 0.95 | 0.1769 | 3.7163 | 10.25 |
| 40 | 1.00 | 0.0000 | 5.8140 | 14.83 |
| 42 | 1.05 | 0.0000 | 3.1623 | 9.35 |
| 60 | 1.50 | 0.0000 | 1.1058 | 2.78 |
| 200 | 5.00 | 0.0000 | 0.6638 | 0.98 |
| 1500 | 37.50 | 0.0000 | 0.5859 | 0.33 |
| 5000 | 125.00 | 0.0000 | 0.5664 | 0.18 |
Czytaj to w trzech częściach. Do klasyczna historia działa dokładnie: błąd spada, potem zaczyna rosnąć. Przy — progu interpolacji, gdzie model ma dokładnie tyle parametrów, by przejść przez każdy punkt treningowy — błąd testowy osiąga szczyt, 5.81, pięć razy gorzej niż mały model. Ten szczyt jest klasycznym ostrzeżeniem i jest realny.
Potem znowu opada. I opada dalej, za , za , aż do , gdzie błąd testowy 0.5664 jest lepszy niż najlepszy wynik, jaki kiedykolwiek osiągnął model niedoparametryzowany. Model z 5000 parametrów dopasowany do 40 punktów jest najlepszym modelem w tabeli.
To jest double descent,89 a mechanizm widać w ostatniej kolumnie. Gdy , istnieje nieskończenie wiele ustawień parametrów, które dokładnie dopasowują dane treningowe, a to, które dostaniesz, zależy od tego, jak wybierasz. Rozwiązanie o minimalnej normie wybiera najmniejsze, a pokazuje, co to znaczy: osiąga szczyt 14.83 dokładnie na progu — gdzie istnieje dokładnie jedno rozwiązanie interpolujące i jesteś na nie skazany, jakkolwiek ekstremalne — a potem maleje monotonicznie, gdy rośnie, bo więcej parametrów oznacza więcej rozwiązań interpolujących do wyboru, czyli najmniejsze dostępne staje się mniejsze. Przy norma wynosi 0.18, osiemdziesiąt razy mniej niż na progu.
Dodatkowe parametry nie dodają więc złożoności. Dodają wybór, a reguła wyboru wydaje ten wybór na prostotę. Regularizacja nie jest w funkcji loss; jest w algorytmie. Gradient descent z małej inicjalizacji ma udokumentowany bias w stronę rozwiązań o małej normie, dlatego to zachowanie pojawia się w prawdziwych sieciach trenowanych zwykłym sposobem, a nie tylko w algebrze liniowej powyżej.
Praktyczna konsekwencja, od której zależy rozdział 10: „model ma więcej parametrów niż danych, więc będzie overfitował” nie jest poprawnym argumentem. To była dobra reguła, gdy modele żyły po lewej stronie progu. Wszystko, co teraz ciekawe, żyje daleko po jego prawej stronie, gdzie reguła się odwraca.
Dokąd to prowadzi dalej
Link do sekcji: Dokąd to prowadzi dalejNarzędzia z tego rozdziału wystarczają, żeby wytrenować sieć działającą na danych, które da się włożyć do tabeli: wiersze liczb, kolumna etykiet.
Język taki nie jest. Zanim model będzie mógł przewidzieć następne słowo, coś musi zdecydować, czym w ogóle jest „słowo” — a odpowiedzią nie są ani litery, ani słowa, tylko słownik, którego model uczy się z surowych bajtów danych treningowych. Ta decyzja, podjęta raz przed startem treningu, określa, ile rzeczy model może powiedzieć, ile kosztuje zapytanie i dlaczego modele, które potrafią zdać egzamin prawniczy, nie potrafią niezawodnie policzyć liter w strawberry.
Rozdział 7 buduje tokenizer.
Źródła i metoda
Link do sekcji: Źródła i metodaDla połączeń resztkowych użytych powyżej: He et al., Deep Residual Learning for Image Recognition (arXiv:1512.03385). Building makemore Part 3: Activations & Gradients, BatchNorm Andreja Karpathy’ego przeprowadza przez diagnostykę histogramów aktywacji na prawdziwym modelu i jest najlepszym praktycznym omówieniem pierwszej połowy tego rozdziału. Wykłady 8 oraz 11–13 Yasera Abu-Mostafy z Learning From Data porządnie przedstawiają klasyczną teorię generalizacji, włącznie z częściami, które ten rozdział ścisnął do jednego akapitu.
Przypisy
Link do sekcji: Przypisy-
Glorot, X. and Bengio, Y. Understanding the difficulty of training deep feedforward neural networks. AISTATS (2010). Argument zachowania wariancji odtworzony w ramce powyżej. ↩
-
He, K., Zhang, X., Ren, S. and Sun, J. Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification. arXiv:1502.01852 (2015). ↩
-
Ioffe, S. and Szegedy, C. Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift. arXiv:1502.03167 (2015). Zauważ, że wyjaśnienie „internal covariate shift” z tytułu zostało od tego czasu mocno zakwestionowane; warstwa działa, ale pierwotne wyjaśnienie dlaczego jest sporne. ↩
-
Ba, J. L., Kiros, J. R. and Hinton, G. E. Layer Normalization. arXiv:1607.06450 (2016). ↩
-
Kingma, D. P. and Ba, J. Adam: A Method for Stochastic Optimization. arXiv:1412.6980 (2014). ↩
-
Loshchilov, I. and Hutter, F. Decoupled Weight Decay Regularization. arXiv:1711.05101 (2017). ↩
-
Srivastava, N., Hinton, G., Krizhevsky, A., Sutskever, I. and Salakhutdinov, R. Dropout: A Simple Way to Prevent Neural Networks from Overfitting. JMLR 15, pp. 1929–1958 (2014). ↩
-
Belkin, M., Hsu, D., Ma, S. and Mandal, S. Reconciling modern machine-learning practice and the classical bias–variance trade-off. PNAS 116(32), pp. 15849–15854 (2019). Artykuł, który nazwał to zjawisko. ↩
-
Nakkiran, P., Kaplun, G., Bansal, Y., Yang, T., Barak, B. and Sutskever, I. Deep Double Descent: Where Bigger Models and More Data Hurt. arXiv:1912.02292 (2019). Pokazuje efekt w prawdziwych głębokich sieciach, a także wzdłuż osi czasu treningu, nie tylko osi rozmiaru modelu. ↩