Kurs uczenia maszynowego od zera · Lekcja 3.6 · 19 z 33 gotowych lekcji · 12 min
Wczesne zatrzymanie
W skrócie
Sieć uczona za długo zapamiętuje błędne etykiety. Przy 20% losowych etykiet 100 epok zamiast zatrzymania obniża trafność testową z 86,1% do 76,3%.
Rozgrzewka Dwa pytania z wcześniejszych lekcji. Minuta, a lekcji nie blokuje.
Sieć neuronowa uczy się w epokach: jedna epoka to jedno przejście przez wszystkie przykłady treningowe. Po każdej epoce strata treningowa zwykle spada. Pytanie z lekcji 3.1 wraca w nowej postaci: ile epok to za dużo? Wczesne zatrzymanie odpowiada na nie zbiorem walidacyjnym: trening staje, gdy strata walidacyjna przestaje spadać, a model wraca do najlepszej epoki.
Wybierz odpowiedź i pewność.
Odpowiedz, żeby odblokować lab.
Eksperyment
Ten interaktywny eksperyment działa w przeglądarce z włączonym JavaScriptem. Tekst wokół opisuje, co w nim widać.
Pokaż odpowiedź
Poprawna odpowiedź: Spada z 86,1% do 76,3%, bo sieć zapamiętuje też błędne etykiety
Wagi z epoki 28 mają na 997 obrazkach testowych 86,1%, a po 100 epokach 76,3%: o 9,7 pkt proc. mniej. Strata walidacyjna rośnie w tym czasie z 0,48 do 0,84, a z 51 błędnych etykiet sieć powtarza na koniec wszystkie.
Spróbuj
- Lab startuje od etykiet czystych. Przełącz na losowe etykiety i zostaw cierpliwość 5. W której epoce trening staje, które wagi zostają i czy to najlepsza epoka całego przebiegu?
- Zwiększ cierpliwość do 10. Co zmienia się w zachowanej epoce i w trafności na teście?
- Wróć do etykiet czystych. Ile teraz kosztuje trening do końca?
Gdy już sprawdzisz to w labie, nazwijmy, co widzisz.
Pomysł w prostych słowach
Na początku treningu sieć uczy się tego, co wspólne dla wielu obrazków: kształtu zera, ósemki, siódemki. Strata treningowa i walidacyjna spadają razem. Potem sieć zaczyna dopasowywać pojedyncze przykłady, także te z błędną etykietą. Strata treningowa dalej spada, a walidacyjna zaczyna rosnąć. To przeuczenie z lekcji 3.1, tylko w osi epok zamiast liczby parametrów.
Wczesne zatrzymanie pilnuje straty walidacyjnej. Zapamiętuje epokę z najniższą stratą i liczy epoki bez poprawy. Gdy jest ich tyle, ile wynosi cierpliwość, trening staje, a sieć wraca do wag z najlepszej epoki. W labie przy cierpliwości 10 trening staje w epoce 38, a zostają wagi z epoki 28: 86,1% na teście zamiast 76,3% po 100 epokach.
Za mała cierpliwość też szkodzi. Krzywa walidacyjna drga od epoki do epoki. Przy cierpliwości 5 trening staje już w epoce 23 i zostają wagi z epoki 18 (85,0% na teście), choć najlepsza była epoka 28.
Jak to policzono
- Cyfry: Optical Recognition of Handwritten Digits, UCI, licencja CC BY 4.0. 1797 obrazków 8×8 pikseli.
- Podział warstwowy: 299 obrazków do nauki, 501 do walidacji, 997 do testu. W wersji z szumem każda etykieta treningowa z prawdopodobieństwem 20% zamieniona na losową cyfrę: zmieniło się 51 etykiet (losowa cyfra czasem trafia w prawdziwą).
- Sieć 64 → 32 → 10, ReLU, entropia krzyżowa, SGD z momentum 0,9, krok 0,05, paczki po 32 obrazki, 100 epok. Strata walidacyjna liczona po każdej epoce.
- Walidacja i test mają prawdziwe etykiety. Szum jest tylko w danych treningowych.
Dlaczego to działa
Przykład z błędną etykietą jest dla sieci trudny: obrazek wygląda jak trójka, a etykieta mówi „siedem”. Żeby zmniejszyć stratę na takim przykładzie, sieć musi nauczyć się reguły, która pasuje tylko do niego. Zwykle robi to późno, gdy łatwe, wspólne wzorce są już opanowane. W labie w epoce 28 sieć powtarza 10 z 51 błędnych etykiet, a po 100 epokach wszystkie 51. Na własnych danych treningowych ma wtedy 99,7% trafności, czyli zgadza się nawet z etykietami, które są nieprawdziwe.
Reguły dopasowane do błędnych etykiet psują odpowiedzi na nowych obrazkach. Zbiór walidacyjny ma prawdziwe etykiety, więc jego strata rośnie dokładnie wtedy, gdy sieć zaczyna uczyć się szumu. Dlatego to ona, a nie strata treningowa, mówi, kiedy przestać.
To nie jest przypadek jednego przebiegu. W kodzie niżej ten sam eksperyment idzie na 10 innych podziałach i losowaniach szumu w scikit-learn: najlepsza epoka wypada między 13 a 23, a trening do 100 epok obniża trafność testową w każdym z 10 przebiegów, średnio z 87,2% do 76,4%. Najlepsza epoka labu (28) leży poza tym zakresem, bo zależy też od wag startowych i kolejności paczek: ta sama sieć z labu z 9 innymi ziarnami losowymi wypada najlepiej między epoką 12 a 25, a trening do 100 epok za każdym razem obniża trafność testową.
Częsty błąd
Prawda czy fałsz: „dłuższy trening zawsze daje lepszy model”. Fałsz. Dłuższy trening zawsze lepiej dopasowuje dane treningowe, ale nie nowe dane. Przy losowych etykietach 100 epok daje 99,7% trafności na treningu i 76,3% na teście, podczas gdy zatrzymanie w epoce 28 daje 86,1% na teście.
Uwaga w drugą stronę: przy czystych etykietach trening do końca prawie nic nie psuje. Najlepsza strata walidacyjna przypada na epokę 30 (93,9% na teście), a po 100 epokach trafność wynosi 94,5%. Wczesne zatrzymanie nie zawsze ratuje trafność, ale zawsze oszczędza czas i chroni przed sytuacją, w której dane są gorsze, niż myślisz.
Quiz
Trzy pytania na sprawdzenie się. Wybierz odpowiedź albo rozwiń odpowiedź pod pytaniem. Z klawiatury: strzałki wybierają, Enter albo spacja zatwierdza.
Najważniejsze wnioski
- Epoka to jedno przejście przez dane treningowe; strata treningowa spada prawie zawsze, walidacyjna nie.
- Wczesne zatrzymanie przerywa trening, gdy strata walidacyjna przez kilka epok (cierpliwość) się nie poprawia, i wraca do najlepszych wag.
- Za długi trening przy błędnych etykietach uczy sieć szumu: test spada z 86,1% do 76,3%.
- Za mała cierpliwość zatrzymuje trening na przypadkowym drganiu krzywej.
Głębiej: wzór, kod, praktyka
Matematyka
Strata walidacyjna po epoce e: L_val(e) = −(1/m) · Σᵢ log p_e(yᵢ | xᵢ) na m obrazkach walidacyjnych (entropia krzyżowa).
Reguła z cierpliwością P: e = argmin_{e ≤ t} L_val(e); trening staje w pierwszej epoce t, dla której t − e ≥ P, i zwraca wagi w(e). Gdy taka epoka nie nadejdzie, zwraca w(e) z całego przebiegu.
Wczesne zatrzymanie działa podobnie jak kara z lekcji 3.4. Przy spadku gradientu z małym krokiem wagi startują blisko zera i oddalają się od niego z każdą epoką. Mniej epok to mniejsze wagi: dla modelu liniowego z kwadratową stratą zatrzymanie po t krokach daje w przybliżeniu ten sam efekt co ridge z α rzędu 1 / (krok · t).
W kodzie (Python)
Ten sam eksperyment w scikit-learn: 10 różnych podziałów i losowań szumu, sieć 64 → 32 → 10 uczona epoka po epoce, z zapamiętaniem wag z epoki o najniższej stracie walidacyjnej.
import copy
import numpy as np
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
from sklearn.metrics import log_loss
X, y = load_digits(return_X_y=True)
X = X / 16
def run(seed): # 300 cyfr do nauki, 500 do walidacji, pozostałe 997 do testu
used, te = train_test_split(np.arange(len(y)), train_size=800, stratify=y, random_state=seed)
tr, va = train_test_split(used, test_size=500, stratify=y[used], random_state=seed)
rng = np.random.default_rng(seed)
noisy = y[tr].copy()
flip = rng.random(len(tr)) < 0.2 # 20% etykiet treningowych zamienionych na losową cyfrę
noisy[flip] = rng.integers(0, 10, flip.sum())
net = MLPClassifier(hidden_layer_sizes=(32,), solver="sgd", learning_rate_init=0.05, momentum=0.9, batch_size=32, alpha=0, random_state=seed)
best, best_loss = None, np.inf
for epoch in range(1, 101):
net.partial_fit(X[tr], noisy, classes=np.arange(10))
loss = log_loss(y[va], net.predict_proba(X[va]), labels=np.arange(10))
if loss < best_loss:
best, best_loss, best_epoch = copy.deepcopy(net), loss, epoch # wczesne zatrzymanie zachowuje wagi z najlepszej epoki
return best_epoch, best.score(X[te], y[te]), net.score(X[te], y[te])
r = np.array([run(s) for s in range(10)])
print(f"10 splits and noise draws: lowest validation loss at epoch {r[:, 0].min():.0f} to {r[:, 0].max():.0f}; test at that epoch {r[:, 1].mean():.1%}, after 100 epochs {r[:, 2].mean():.1%}; lower after 100 in {(r[:, 2] < r[:, 1]).sum()} of 10")
Wynik
10 splits and noise draws: lowest validation loss at epoch 13 to 23; test at that epoch 87.2%, after 100 epochs 76.4%; lower after 100 in 10 of 10
Podziały, wagi startowe i szum są inne niż w labie, więc liczby też są inne. Obraz jest ten sam: najlepsza epoka wypada wcześnie (między 13 a 23), a trening do 100 epok obniża trafność testową we wszystkich 10 przebiegach, średnio z 87,2% do 76,4%.
Pobierz notebook (.ipynb). Otwórz go w Jupyterze albo wgraj do Google Colab; brakujące dane pobierze sam.
Dla praktyka
- W Kerasie:
EarlyStopping(monitor="val_loss", patience=10, restore_best_weights=True). Bezrestore_best_weights=Truezostają wagi z ostatniej epoki, nie z najlepszej. - W PyTorchu pętlę piszesz sam: po każdej epoce licz stratę walidacyjną i zapisuj kopię wag, gdy jest najniższa.
- W scikit-learn:
MLPClassifier(early_stopping=True, n_iter_no_change=...)odkłada część danych treningowych na walidację; patrzy na trafność walidacyjną, nie na stratę. W gradient boostingu ten sam pomysł nazywa sięn_iter_no_changealboearly_stopping_rounds. - Liczba epok wybrana na walidacji to też hiperparametr: wynik walidacji w najlepszej epoce jest trochę zawyżony (lekcja 3.5), więc ostateczną ocenę rób na odłożonym teście.
Czy to było pomocne?
Dzięki! To pomaga nam poprawiać Atlas.
Więcej w Atlasie
Hasła encyklopedii o pojęciach z tej lekcji: