06 · Sieci · 4 min czytania · Interaktywne · aktualizacja
Co to jest forward pass w sieci neuronowej i jak sieć liczy wynik?
W skrócie
Przejście w przód to obliczenie wyniku sieci: dane płyną warstwa po warstwie przez mnożenie przez wagi i funkcje aktywacji, aż do predykcji i straty.
Co to jest
Przejście w przód (ang. forward pass, też forward propagation) to obliczenie wyjścia sieci neuronowej dla danego wejścia: dane przechodzą kolejno przez wszystkie warstwy, a każda mnoży je przez swoje wagi, dodaje wyraz wolny i stosuje funkcję aktywacji. Na końcu powstaje predykcja, a w czasie treningu także wartość funkcji straty. To jedyna operacja potrzebna do używania gotowego modelu.
Można to porównać do linii produkcyjnej. Surowiec (piksele, słowa, liczby z tabeli) trafia na pierwsze stanowisko, które przetwarza go na półprodukt, i tak dalej. Żadne stanowisko nie widzi całości, każde dostaje tylko wynik poprzedniego. Ostatnie wydaje gotowy produkt: np. dziesięć prawdopodobieństw, po jednym dla każdej cyfry.
Podczas treningu przejście w przód jest pierwszą połową kroku uczenia. Drugą jest propagacja wsteczna, która idzie tą samą drogą w odwrotnym kierunku i liczy, jak zmienić każdą wagę. Dlatego w trakcie treningu przejście w przód zapamiętuje wyniki pośrednie: będą potrzebne do obliczenia gradientów.
Mechanizm — dlaczego tak działa
Dla jednej warstwy w pełni połączonej obliczenie ma dwa kroki: najpierw z = W·a + b (każdy neuron liczy sumę ważoną wyjść poprzedniej warstwy a), potem a' = f(z), gdzie f to aktywacja, np. ReLU, sigmoida albo tanh. Sieć to złożenie takich funkcji: wynik = f₃(W₃·f₂(W₂·f₁(W₁·x + b₁) + b₂) + b₃). Cały „model” to po prostu konkretne wartości macierzy W i wektorów b.
Ostatnia warstwa zależy od zadania. W regresji zwykle nie ma aktywacji i sieć zwraca liczbę. W klasyfikacji binarnej sigmoida σ(z) = 1 / (1 + e^(−z)) zamienia wynik na prawdopodobieństwo. W klasyfikacji wieloklasowej softmax zamienia wektor surowych wyników (logitów) na rozkład prawdopodobieństwa sumujący się do 1.
W praktyce nie przetwarza się przykładów pojedynczo. Cały mini-batch układa się w macierz X (wiersze to przykłady), a warstwa liczy Z = X·W + b dla wszystkich naraz. Mnożenie macierzy jest bardzo dobrze zoptymalizowane na procesorach i kartach graficznych, dlatego czas przejścia w przód rośnie z liczbą przykładów mniej niż liniowo, dopóki sprzęt nie jest w pełni wykorzystany.
Koszt obliczeń jest łatwy do policzenia: warstwa z n wejściami i m neuronami wykonuje n·m mnożeń z dodawaniem. Przejście w przód jest więc tanie w porównaniu z treningiem. Krok treningu (przejście w przód plus propagacja wsteczna) kosztuje typowo około trzy razy tyle, co samo przejście w przód, a trening powtarza go tysiące razy.
Dwie warstwy zachowują się inaczej w treningu i w predykcji. Dropout w trybie treningowym losowo zeruje neurony, w trybie predykcji nie. Normalizacja wsadowa w treningu używa statystyk bieżącego batcha, a w predykcji średnich zapamiętanych w trakcie treningu. Zapomnienie o przełączeniu trybu daje wyniki, które zmieniają się przy każdym wywołaniu albo zależą od tego, jakie inne przykłady są w batchu.
Na przykładzie
Mała sieć 2-2-1 z sigmoidą w obu warstwach. Wejście x = (1; 0,5), wagi pierwszego neuronu ukrytego (0,5; −0,3), drugiego (0,2; 0,8), wyrazy wolne zerowe, wagi wyjścia (1; −1). Neuron pierwszy: z₁ = 0,5·1 − 0,3·0,5 = 0,35, więc h₁ = σ(0,35) ≈ 0,587. Neuron drugi: z₂ = 0,2·1 + 0,8·0,5 = 0,60, więc h₂ = σ(0,60) ≈ 0,646. Wyjście: z = 0,587 − 0,646 ≈ −0,059, a y = σ(−0,059) ≈ 0,485. Jeśli prawidłowa odpowiedź to 1, entropia krzyżowa wynosi −ln(0,485) ≈ 0,723. Ten sam przykład kontynuuje hasło o propagacji wstecznej.
Na zbiorze Digits 8×8 (piksele podzielone przez 16, sieć 64-64-10 z ReLU, MLPClassifier, random_state=0) jedno przejście w przód to 64·64 + 64·10 = 4736 mnożeń z dodawaniem. Ręczne obliczenie Z = X·W + b na wagach z coefs_ daje prawdopodobieństwa identyczne z predict_proba. Dla pierwszego obrazka testowego (cyfra 2) aktywnych jest 45 z 64 neuronów ukrytych, a softmax daje 70,9% dla „2” i 28,3% dla „3”: logity 4,60 i 3,69 różnią się niecałą jednostką, a to wystarczy na wyraźną przewagę.
Dane: Digits (ręcznie pisane cyfry 8×8)
W praktyce
- PyTorch: wywołanie
model(x)uruchamia metodęforward. Do predykcji używajmodel.eval()itorch.no_grad()(albotorch.inference_mode()), żeby wyłączyć dropout, zamrozić statystyki normalizacji i nie zapisywać grafu obliczeń. - scikit-learn:
predict_probaipredictwMLPClassifierto przejście w przód; wagi są wcoefs_iintercepts_, co pozwala policzyć je ręcznie dla zrozumienia. - Kształty tensorów to najczęstsze źródło błędów:
nn.Linear(64, 10)oczekuje wejścia o ostatnim wymiarze 64; wypisujx.shapepo każdej warstwie przy debugowaniu. - Nie stosuj softmaxu przed
nn.CrossEntropyLoss, bo ta funkcja sama go stosuje (w stabilnej numerycznie formie log-softmax); podwójny softmax spłaszcza gradienty. - Pamięć w treningu rośnie z rozmiarem batcha, bo przejście w przód przechowuje aktywacje każdej warstwy do propagacji wstecznej.
Najczęstsze pytania
- Czym różni się przejście w przód od inferencji?
- Inferencja to używanie wytrenowanego modelu do predykcji i składa się wyłącznie z przejść w przód. Przejście w przód występuje też w treningu, ale wtedy zapisuje wyniki pośrednie i jest poprzedzeniem propagacji wstecznej.
- Dlaczego sieć daje różne wyniki dla tego samego wejścia?
- Najczęściej model jest w trybie treningowym, więc dropout losowo wyłącza neurony, a normalizacja wsadowa używa statystyk bieżącego batcha. Po `model.eval()` wynik powinien być deterministyczny (z dokładnością do drobnych różnic numerycznych na GPU).
- Co to są logity?
- To surowe wyniki ostatniej warstwy, zanim zamieni je softmax lub sigmoida. Liczą się różnice między nimi: gdy logit jednej klasy rośnie o 1, stosunek jej prawdopodobieństwa do prawdopodobieństwa każdej innej klasy rośnie e ≈ 2,7 raza.
Źródła
- Goodfellow I., Bengio Y., Courville A., „Deep Learning”, MIT Press, 2016, rozdz. 6, zwłaszcza podrozdz. 6.5.
- Zhang A., Lipton Z. C., Li M., Smola A. J., „Dive into Deep Learning”, d2l.ai, rozdział „Forward Propagation, Backward Propagation, and Computational Graphs”.
- Bishop C. M., „Pattern Recognition and Machine Learning”, Springer, 2006, podrozdz. 5.1 „Feed-forward Network Functions”.
- Dokumentacja PyTorch,
torch.nn.Module: https://pytorch.org/docs/stable/generated/torch.nn.Module.html