01 · Podstawy · 4 min czytania · Interaktywne · aktualizacja
Czym jest pochodna i dlaczego uczenie maszynowe jej potrzebuje?
W skrócie
Pochodna mówi, jak szybko zmienia się wynik funkcji przy małej zmianie wejścia. W ML wskazuje, w którą stronę i jak mocno poprawić parametr modelu.
Co to jest
Pochodna funkcji f w punkcie x to tempo, w jakim zmienia się f(x), gdy x zmienia się o nieskończenie mało: f′(x) = lim (f(x + h) − f(x)) / h przy h → 0. Geometrycznie to nachylenie stycznej do wykresu w danym punkcie. Dodatnia pochodna oznacza, że funkcja rośnie, ujemna — że maleje, a zero — że w tym miejscu jest płasko.
W uczeniu maszynowym funkcją jest zwykle strata: liczba mówiąca, jak bardzo model się myli, zależna od jego parametrów. Pochodna straty względem parametru odpowiada na najważniejsze pytanie treningu: „jeśli trochę zwiększę ten parametr, to błąd wzrośnie czy spadnie, i o ile?”.
Gdy parametrów jest wiele, liczy się pochodną względem każdego z osobna, trzymając pozostałe w miejscu. Te pochodne cząstkowe zebrane w wektor tworzą gradient — strzałkę wskazującą kierunek najszybszego wzrostu straty. Spadek gradientu idzie w przeciwną stronę.
Mechanizm — dlaczego tak działa
Kluczowa idea: z bliska każda gładka funkcja wygląda jak prosta. Jeśli przybliżyć wykres wystarczająco mocno, krzywizna znika i zostaje odcinek o nachyleniu f′(x). Stąd przybliżenie f(x + h) ≈ f(x) + f′(x) · h, prawdziwe dla małych h. Cały trening sieci neuronowych opiera się na tym jednym zdaniu: lokalnie wiemy, jak zmiana parametru przełoży się na błąd, więc wiemy, w którą stronę iść.
To „lokalnie” jest ważnym zastrzeżeniem. Pochodna nic nie mówi o tym, co dzieje się daleko od punktu. Dlatego kroki muszą być małe — stąd współczynnik uczenia. Za duży krok przeskakuje dolinę, bo przybliżenie liniowe przestaje obowiązywać. Za mały krok marnuje czas.
W minimum funkcji pochodna wynosi zero: nie da się już zejść niżej żadnym małym ruchem. Odwrotna implikacja nie zachodzi — zero oznacza też maksimum albo punkt siodłowy, a w sieciach z milionami parametrów punkty siodłowe i płaskie obszary są częstsze niż „złe” minima lokalne. Dla funkcji wypukłych (np. błędu średniokwadratowego w regresji liniowej) zero pochodnej gwarantuje minimum globalne.
Pochodną można policzyć na trzy sposoby. Symbolicznie — wzorami z podręcznika (pochodna x² to 2x, pochodna eˣ to eˣ). Numerycznie — podstawiając małe h do ilorazu różnicowego; to proste, ale niedokładne i bardzo wolne przy milionach parametrów. Automatycznie — tak robią PyTorch i JAX: program zapamiętuje każdą elementarną operację i składa ich pochodne regułą łańcuchową. Różniczkowanie numeryczne służy dziś głównie do sprawdzania, czy automatyczne działa poprawnie.
Ograniczenie: pochodna istnieje tylko tam, gdzie funkcja jest gładka. ReLU ma „kolano” w zerze, a funkcja wartości bezwzględnej szpic. Biblioteki przyjmują tam umowną wartość (np. 0) i w praktyce to wystarcza, ale funkcje schodkowe — jak dokładność klasyfikacji — mają pochodną zero prawie wszędzie i nie da się ich bezpośrednio optymalizować gradientem. Dlatego trenuje się na gładkiej stracie, a dokładność tylko raportuje.
Na przykładzie
Zbiór Diabetes (442 pacjentów) zawiera wskaźnik postępu choroby po roku i BMI. Przewidujemy postęp prostą: odchylenie postępu od średniej ≈ w · (odchylenie BMI od średniej). Błąd średniokwadratowy jako funkcja nachylenia w wynosi 5930 dla w = 0, 4424 dla w = 5 i 3892 dla w = 10. Pochodna błędu w punkcie w = 0, policzona wzorem, to −398,6; ten sam wynik daje iloraz różnicowy z h = 0,001. Znak ujemny mówi: zwiększaj w, błąd spadnie — o około 4 jednostki na każde 0,01 kroku.
Pochodna maleje co do wartości, gdy zbliżamy się do dna: przy w = 5 wynosi −203,8, a przy w = 15 już +185,7 (minęliśmy dno, trzeba wracać). Zero osiąga przy w ≈ 10,23 — każdy dodatkowy punkt BMI to średnio około 10 punktów postępu choroby — a błąd spada wtedy do 3890,5, co odpowiada R² = 0,34. Trzy kroki spadku gradientu z krokiem 0,01, startując od zera, dają kolejno w = 3,99, 6,42 i 7,91: każdy krok jest krótszy, bo pochodna sama maleje w pobliżu minimum.
Dane: Diabetes (progresja cukrzycy)
W praktyce
- W PyTorch:
loss.backward()liczy pochodne straty względem wszystkich parametrów zrequires_grad=True, a wynik ląduje wparam.grad. - Pochodną zapisanej funkcji sprawdzisz numerycznie przez
torch.autograd.gradcheck(w podwójnej precyzji) albo ręcznie ilorazem centralnym (f(x + h) − f(x − h)) / 2h z h rzędu 1e-5. SymPy(sympy.diff) liczy pochodne symbolicznie — przydatne do nauki i sprawdzania wzorów.- Gradient bliski zeru od początku treningu często oznacza nasycone aktywacje albo martwe neurony, a nie znalezione minimum.
- Pamiętaj o zerowaniu gradientów (
optimizer.zero_grad()): PyTorch domyślnie je sumuje między wywołaniamibackward.
Najczęstsze pytania
- Czym różni się pochodna od gradientu?
- Pochodna dotyczy funkcji jednej zmiennej i jest liczbą. Gradient to wektor wszystkich pochodnych cząstkowych funkcji wielu zmiennych; wskazuje kierunek najszybszego wzrostu. W treningu modeli prawie zawsze chodzi o gradient.
- Czy zerowa pochodna oznacza, że model jest wytrenowany?
- Niekoniecznie. Może to być minimum lokalne, punkt siodłowy, płaskowyż albo efekt nasycenia aktywacji. Dlatego ocenia się model na danych walidacyjnych, a nie po wartości gradientu.
- Po co uczyć się pochodnych, skoro PyTorch liczy je sam?
- Żeby rozumieć, co idzie źle: dlaczego gradient zanika, czemu współczynnik uczenia jest za duży, dlaczego jakiejś metryki nie da się optymalizować wprost. Ręcznego liczenia potrzeba rzadko, intuicji — codziennie.
Źródła
- Goodfellow, Bengio, Courville „Deep Learning”, MIT Press, 2016, rozdz. 4.3 (Gradient-Based Optimization).
- Deisenroth, Faisal, Ong „Mathematics for Machine Learning”, Cambridge University Press, 2020, rozdz. 5 (Vector Calculus).
- Zhang i in. „Dive into Deep Learning”, d2l.ai, rozdz. 2.4 (Calculus).
- Efron, Hastie, Johnstone, Tibshirani, 2004, „Least Angle Regression”, Annals of Statistics 32(2), 407–499 (źródło zbioru Diabetes).
- Dokumentacja PyTorch: Automatic differentiation package, https://pytorch.org/docs/stable/autograd.html