Podstawy uczenia maszynowego — spadek gradientu, propagacja wsteczna i sieci neuronowe od podstaw

Każda sieć neuronowa to po prostu kompozycja mnożeń macierzy i nieliniowości trenowana spadkiem gradientu. Ten wpis rozkłada matematykę — SGD, momentum, Adam, regułę łańcuchową propagacji wstecznej, entropię krzyżową softmax — i wiąże każde pojęcie z interaktywną symulacją.

1. Spadek gradientu

Uczenie maszynowe sprowadza się do jednego uniwersalnego problemu: znaleźć wektor parametrów θ, który minimalizuje skalarną funkcję straty L(θ). Spadek gradientu robi to, wielokrotnie krocząc w kierunku najszybszego spadku:

SGD i warianty

Zwykły SGD: θ ← θ − η · ∇L(θ)

Momentum (heavy-ball):
  v ← β v − η · ∇L(θ)
  θ ← θ + v

Adam (momenty adaptacyjne):
  m ← β₁ m + (1−β₁) g   (moment 1. rzędu)
  v ← β₂ v + (1−β₂) g²  (moment 2. rzędu)
  θ ← θ − η · m̂ / (√v̂ + ε)

Powierzchnia straty dla małych sieci to powierzchnia w przestrzeni wielowymiarowej. Punkty siodłowe są znacznie częstsze niż minima lokalne — nowoczesne optymalizatory omijają je dzięki szumowi i adaptacyjnym krokom.

2. Propagacja wsteczna — reguła łańcuchowa w praktyce

Backprop to nic innego jak reguła łańcuchowa rachunku różniczkowego zastosowana systematycznie do grafu obliczeniowego. Dla straty L = f(g(x)):

Reguła łańcuchowa — przejście w przód i wstecz

W przód: z¹ = W¹x + b¹, a¹ = σ(z¹), z² = W²a¹ + b², ŷ = softmax(z²)
Strata: L = −Σ yᵢ log ŷᵢ (entropia krzyżowa)

Wstecz: ∂L/∂W² = (∂L/∂ŷ)(∂ŷ/∂z²)(∂z²/∂W²) = (ŷ − y)ᵀ · a¹
∂L/∂W¹ = (W²ᵀ δ²) ⊙ σ′(z¹) · xᵀ  (gdzie δ² = ŷ − y)

Kluczowa obserwacja: gradienty płyną wstecz przez każdą warstwę, mnożone za każdym razem przez lokalny jakobian. Przy aktywacjach ReLU (σ′ = 0 lub 1) gradient albo przechodzi bez zmian, albo jest zerowy — co jest zarówno źródłem wydajności, jak i patologii "umierającego ReLU".

// Minimalny backprop dla sieci 2-warstwowej (pseudokod JavaScript)
function backward(x, y, W1, W2, b1, b2) {
  // Przejście w przód
  const z1 = matMul(W1, x).add(b1);
  const a1 = relu(z1);
  const z2 = matMul(W2, a1).add(b2);
  const yHat = softmax(z2);

  // Gradient warstwy wyjściowej (softmax + entropia krzyżowa upraszczają się ładnie)
  const dz2 = yHat.sub(y);                    // (C × 1)
  const dW2 = matMul(dz2, a1.T);             // (C × H)

  // Gradient warstwy ukrytej
  const da1 = matMul(W2.T, dz2);             // (H × 1)
  const dz1 = da1.mul(reluGrad(z1));         // element-wise ReLU′
  const dW1 = matMul(dz1, x.T);             // (H × D)

  return { dW1, dW2, db1: dz1, db2: dz2 };
}

3. Intuicja konwolucyjna

Warstwa konwolucyjna przesuwa mały jądro (np. 3×3) po wejściu. Każda pozycja daje jedną skalarną wartość przez obliczenie iloczynu skalarnego między wagami jądra a lokalnym polem recepcyjnym. To współdzielenie parametrów — ponowne użycie tego samego jądra w każdej lokalizacji — daje CNN niezmienniczość translacyjną i drastycznie zmniejsza liczbę parametrów w porównaniu z alternatywą w pełni połączoną.

4. Uczenie ze wzmocnieniem i ewolucja

Algorytmy w skrócie

Stochastyczny spadek gradientu Optymalizator Adam Propagacja wsteczna Reguła łańcuchowa Entropia krzyżowa softmax ReLU / Tanh Warstwy konwolucyjne Q-learning Policy gradient Algorytm genetyczny Mapa Kohonena Nieczystość Giniego CART

Dlaczego ReLU działa lepiej niż sigmoida? Sigmoida nasyca się przy 0 i 1 — gradienty zanikają przy dużych aktywacjach (problem "zanikającego gradientu"). ReLU jest liniowa dla dodatnich wejść, więc gradienty przepływają bez zmniejszania. Warianty takie jak Leaky ReLU (nachylenie 0,01 dla x < 0) i GELU (jednostka liniowa błędu Gaussa, używana w transformerach) rozwiązują problem "umierającego ReLU", gdzie neurony na stałe zwracają zero.