Kurs: sieci neuronowe od środka · Lekcja 3 z 12 · 12 min
Funkcje aktywacji: po co zginać
W skrócie
Bez funkcji aktywacji dziesięć warstw liczy to samo co jedna. Lekcja pokazuje, jak aktywacja zgina granicę i czemu przy tym samym kroku ReLU wyprzedza sigmoidę.
Rozgrzewka Dwa pytania z kursu ML, na których ta lekcja się opiera. Minuta, a lekcji nie blokuje.
Jeden neuron rysuje jedną prostą. Sieć ma ich wiele, ułożonych w warstwy, więc powinna umieć więcej. Umie, ale pod jednym warunkiem: każdy neuron musi przepuścić swoją sumę przez funkcję aktywacji. Która funkcja, ma znaczenie, i to nie tylko dla kształtu granicy, ale też dla tempa nauki.
Wybierz odpowiedź i pewność.
Odpowiedz, żeby odblokować lab.
Pokaż odpowiedź
Poprawna odpowiedź: ReLU, wyraźnie niżej
ReLU kończy ze stratą 0,052, a sigmoida z 0,269, ponad pięć razy wyższą. Na nowych punktach ReLU trafia 97%, sigmoida 86,5%.
Spróbuj
- Ustaw „Epoki treningu” na 1000 i przełączaj aktywacje. Znajdź taką, z którą strata spada poniżej 0,1. To cel labu.
- Przełącz „Co rysować” na pochodną i porównaj szczyty: sigmoida ma 0,25, tanh 1.
- Wybierz ReLU i przeczytaj pod wykresami, ile neuronów jest martwych po 1000 epokach.
- Cofnij suwak epok do 10: wszystkie pięć aktywacji mają jeszcze stratę powyżej 0,3. Różnice rosną dopiero z czasem.
Pomysł w prostych słowach
Funkcja aktywacji to krzywa, przez którą neuron przepuszcza swoją ważoną sumę. Sigmoida ściska ją do przedziału od 0 do 1, tanh do przedziału od −1 do 1. ReLU przepuszcza dodatnie bez zmian i zeruje ujemne. GELU to gładka wersja ReLU, używana w transformerach.
Po co ta krzywa? Warstwa bez aktywacji liczy przekształcenie liniowe: mnoży przez macierz wag i dodaje bias. Druga taka warstwa na wyjściu pierwszej to znowu jedno przekształcenie liniowe. Dziesięć warstw bez aktywacji daje więc to samo co jedna, a granica zostaje prostą. Aktywacja zgina wynik każdego neuronu. Dopiero wtedy warstwa ukryta składa kilka prostych w jedną zakrzywioną granicę, taką jak między dwoma księżycami.
Dlaczego to działa
Sieć uczy się spadkiem gradientu, tym samym co w kursie ML. Gradient płynie od straty wstecz przez każdy neuron i po drodze mnoży się przez pochodną jego aktywacji. Pochodna sigmoidy nigdy nie przekracza 0,25, a przy dużych wejściach prawie znika. Pochodna ReLU dla dodatnich wejść wynosi 1. Ten sam krok przy sigmoidzie przesuwa więc wagi słabiej: w labie już w pierwszym kroku gradient wag warstwy ukrytej ma normę 0,213 przy sigmoidzie, a 0,725 przy tanh.
W głębokiej sieci ten efekt się mnoży. Przez 10 warstw sigmoidy same pochodne aktywacji dają razem czynnik najwyżej 0,25 do potęgi 10, czyli około 9,5·10⁻⁷. Gradient mnoży się jednak także przez wagi. W łańcuchu pojedynczych neuronów z wagami nie większymi niż 1 cały gradient traci co najmniej tyle. Duże wagi mogą spadek odwrócić: 10 sigmoid z wagą 6 i biasem −3 mnoży gradient przez 57,7. To nie lekarstwo, bo duże wagi grożą wybuchającym gradientem albo wpychają sigmoidę w płaskie końce, gdzie pochodna prawie znika. Do obu zjawisk, zanikającego i wybuchającego gradientu, wrócimy w lekcji 7.
ReLU ma swoją cenę. Neuron, który dla każdego przykładu dostaje ujemne wejście, zawsze daje 0, a jego pochodna też jest zerem. Taki martwy neuron przestaje się uczyć. W labie po 1000 epokach martwy jest 1 z 8 neuronów ReLU. Leaky ReLU zamiast zera mnoży ujemne wejścia przez 0,01, więc gradient słabnie, ale nie znika.
Częsty błąd
Prawda czy fałsz: „Bez funkcji aktywacji głębsza sieć i tak wygnie granicę.” Fałsz. Złożenie przekształceń liniowych jest liniowe, więc 10 warstw bez aktywacji to wciąż jedna prosta. W kodzie niżej dziesięć losowych macierzy mnożonych po kolei daje dokładnie to samo co ich iloczyn. Ta sama sieć z ReLU rozwiązuje XOR, a bez ReLU daje zwykłą funkcję liniową. Drugie częste przekonanie: „aktywacja to szczegół”. Przy tym samym kroku 0,5 sigmoida uczy się dużo wolniej: kończy ze stratą 0,269, a ReLU z 0,052, bo pochodna sigmoidy (najwyżej 0,25) skraca jej kroki. Krok można jednak dobrać każdej osobno. Najlepszy z kroków 0,5, 1, 2, 4, 8 i 16 daje sigmoidzie stratę 0,036 (krok 8), a ReLU 0,035 (krok 2). Na pięciu innych próbkach księżyców przy najlepszym kroku raz wygrywa jedna, raz druga, a sigmoida nigdy nie potrzebuje mniejszego kroku niż ReLU. W tej płytkiej sieci aktywacja decyduje więc głównie o tym, jaki krok zadziała. W głębokiej sieci większy krok tego nie nadrobi: krok jest jeden dla wszystkich warstw, a w 20 warstwach sigmoidy gradient pierwszej warstwy jest biliony razy słabszy niż ostatniej (lekcja 7).
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
- Bez funkcji aktywacji dowolnie głęboka sieć liczy jedno przekształcenie liniowe i rysuje prostą.
- Aktywacja zgina wynik każdego neuronu, więc warstwa ukryta może złożyć proste w zakrzywioną granicę.
- Pochodna sigmoidy nie przekracza 0,25, więc gradient przez nią słabnie; ReLU dla dodatnich wejść go nie osłabia.
- Porównując aktywacje, daj każdej jej najlepszy krok: w płytkiej sieci z labu sigmoida z większym krokiem prawie dogania ReLU.
- ReLU może mieć martwe neurony; Leaky ReLU zostawia im słaby gradient.
Głębiej: wzór, kod, praktyka
Matematyka
Warstwa bez aktywacji liczy W·x + b. Dwie takie warstwy: W₂(W₁·x + b₁) + b₂ = (W₂W₁)·x + (W₂b₁ + b₂), czyli znowu jedna warstwa liniowa z macierzą W₂W₁.
- Sigmoida:
σ(x) = 1 / (1 + e^(−x)), pochodnaσ′(x) = σ(x)·(1 − σ(x)). Iloczynp·(1 − p)jest największy przyp = 0,5, więcσ′(x) ≤ 0,25. - Tanh: pochodna
1 − tanh²(x) ≤ 1. ReLU:max(0, x), pochodna 1 dlax > 0i 0 dlax < 0. - GELU:
x·Φ(x), gdzieΦto dystrybuanta rozkładu normalnego. - Reguła łańcuchowa: gradient warstwy niżej to gradient warstwy wyżej razy pochodna aktywacji razy wagi. Pochodne sigmoidy dają po
nwarstwach najwyżej0,25ⁿ; wagi mogą ten iloczyn dalej zmniejszyć albo zwiększyć.
W kodzie (Python)
Trzy krótkie sprawdzenia w numpy: XOR z ReLU i bez, dziesięć warstw liniowych jako jedna macierz, szczyt pochodnej sigmoidy:
import numpy as np
relu = lambda x: np.maximum(0, x)
sigmoid = lambda x: 1 / (1 + np.exp(-x))
# XOR: cztery punkty, dwa neurony ukryte z wagami ustawionymi ręcznie
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
W1, b1 = np.array([[1, 1], [1, 1]]), np.array([0, -1])
w2 = np.array([1, -2])
print("with ReLU: ", relu(X @ W1 + b1) @ w2) # XOR: 0 1 1 0
print("without ReLU:", (X @ W1 + b1) @ w2) # prosta: nie da XOR
# dziesięć warstw liniowych to jedna macierz
rng = np.random.default_rng(0)
Ws = [rng.normal(size=(2, 2)) for _ in range(10)]
x = rng.normal(size=2)
h = x
for W in Ws:
h = W @ h
M = np.linalg.multi_dot(Ws[::-1])
print("10 layers = one matrix:", np.allclose(h, M @ x))
# pochodna sigmoidy nigdy nie przekracza 0,25
z = np.linspace(-10, 10, 2001)
d = sigmoid(z) * (1 - sigmoid(z))
print(f"max sigmoid'(z) = {d.max():.2f} at z = {z[d.argmax()]:.1f}; 0.25 ** 10 = {0.25 ** 10:.1e}")
Wynik
with ReLU: [0 1 1 0]
without ReLU: [2 1 1 0]
10 layers = one matrix: True
max sigmoid'(z) = 0.25 at z = 0.0; 0.25 ** 10 = 9.5e-07
Bez ReLU wynik to −(x₁ + x₂) + 2, funkcja liniowa, która punktów (0, 0) i (1, 1) nie da do jednej klasy. Uruchomione w numpy 2.1.3.
Pobierz notebook (.ipynb). Otwórz go w Jupyterze albo wgraj do Google Colab; brakujące dane pobierze sam.
Dla praktyka
- W warstwach ukrytych zacznij od ReLU; w transformerach standardem jest GELU. Sigmoidę zostaw na wyjście, gdy potrzebujesz prawdopodobieństwa jednej klasy.
- Z ReLU inicjalizuj wagi metodą He, a z tanh i sigmoidą metodą Xaviera: obie dobierają skalę wag do pochodnej aktywacji.
- Sprawdzaj, ile neuronów ReLU nigdy się nie włącza. Dużo martwych neuronów to zwykle za duży krok uczenia; pomaga mniejszy krok albo Leaky ReLU.
- Porównując aktywacje, trzymaj ten sam start wag, a krok dobierz każdej osobno na walidacji, jak optymalizatorom w lekcji 6. Przy jednym wspólnym kroku mierzysz także to, czy ten krok pasuje do aktywacji.
Więcej w Atlasie
Hasła encyklopedii o pojęciach z tej lekcji: