\documentclass[a4paper,reqno,12pt]{amsart}
%\usepackage{t1enc}
\usepackage[margin=1in]{geometry}
\usepackage{ifthen}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usepackage{hyperref}

%\addtolength{\textwidth}{+30mm}
%\addtolength{\hoffset}{-15mm}
%\addtolength{\marginparwidth}{-30pt}
%\addtolength{\voffset}{-15mm}
\addtolength{\textheight}{+3mm}

\newcommand{\A}{\mathcal{A}}
\newcommand{\C}{\mathbf{C}}
\newcommand{\R}{\mathbf{R}}
\newcommand{\Z}{\mathbf{Z}}
\newcommand{\pr}{\mathbf{P}}
\newcommand{\ex}{\mathbf{E}}
\newcommand{\N}{\mathbb{N}}
\newcommand{\ind}{\mathbf{1}}

\DeclareMathOperator{\dist}{dist}
\DeclareMathOperator{\diam}{diam}
\DeclareMathOperator{\id}{Id}
\DeclareMathOperator{\sign}{sign}
\DeclareMathOperator{\supp}{supp}
\DeclareMathOperator{\res}{Res}
\DeclareMathOperator{\dom}{dom}
\DeclareMathOperator{\loss}{\mathbf{L}}


\sloppy
\numberwithin{equation}{section}

\begin{document}
\pagenumbering{gobble}
\pagestyle{empty}

Rozważamy sieć neuronową, która ma $L$ gęstych warstw, po $n^{[l]}$ neuronów w~warstwie $l=1,\ldots L$,
i~która przyjmuje wektor z $\R^{n^{[0]}}$. Dla uproszczenia notacji zakładamy, że we wszyskich
warstwach używamy takiej samej funkcji aktywacji $\varphi:\R\to\R$.


Niech $W^{[l]}$ będzie macierzą wag w~warstwie $l$, tj.
\[
W^{[l]} = [ w^{[l]}_{k,j}]_{k=1,\ldots,n^{[l]}; j=0,\ldots,n^{[l-1]}}, \quad l=1,2,\ldots, L.
\]
Powiedzmy, że argumentem sieci jest wektor
\[
a^{[0]} = \left[ \begin{matrix}
    a^{[0]}_1 \\
    a^{[0]}_2 \\
    \ldots \\
    a^{[0]}_{n^{[0]}}
    \end{matrix} \right] \in \R^{n^{[0]}}.
\]

\paragraph{\bf Propagacja w przód (obliczanie wartości), krok indukcyjny}

Powiedzmy, że $l\in\{0,1,\ldots,L-1\}$ oraz że mamy dany wektor
\[
a^{[l]} = \left[ \begin{matrix}
    a^{[l]}_1 \\
    a^{[l]}_2 \\
    \ldots \\
    a^{[l]}_{n^{[l]}}
    \end{matrix} \right].
\]
z~$\R^{n^{[l]}}$. Kładziemy $x^{[l]}_0 = 1$ oraz $x^{[l]}_j = a^{[l]}_j$ dla $j\geq 1$, czyli
\[
x^{[l]} = \left[ \begin{matrix}
    x^{[l]}_0 \\
    x^{[l]}_1 \\
    x^{[l]}_2 \\
    \ldots \\
    x^{[l]}_{n^{[l]}}
  \end{matrix} \right]
=
\left[ \begin{matrix}
    1 \\
    a^{[l]}_1 \\
    a^{[l]}_2 \\
    \ldots \\
    a^{[l]}_{n^{[l]}}
  \end{matrix} \right].
\]
Wektor $x^{[l]}$ jest więc wektorem $a^{[l]}$  z~dołączoną jedynką na początku.
Obliczamy
\[
 net^{[l+1]} = W^{[l+1]} x^{[l]},
 \]
 oraz
\[
a^{[l+1]} = \varphi(net^{[l+1]}) :=
\left[
    \varphi( \sum_{j=0}^{n^{[l]}} w^{[l+1]}_{k,j} x^{[l]}_j)
    \right]_{k=1,\ldots,n^{[l+1]}}.
\]

\paragraph{\bf Propagacja w przód (obliczanie wartości), wyjście sieci}
Mając dany wektor $a^{[0]}$, możemy stosować $L$-krotnie powyższy krok indukcyjny, aby obliczyć
kolejno $a^{[1]}, a^{[2]}, \ldots, a^{[L]}$. Wyjściem sieci jest ostatni wektor $a^{[L]}$.
Innymi słowy, rozważana sieć neuronowa jest funkcją następującej postaci
\[
\R^{n^{[0]}} \ni a^{[0]} \mapsto a^{[L]} \in \R^{n^{[L]}}.
\]

\paragraph{\bf Funkcja kosztu}
Powiedzmy, że dla $x^{[0]}$  obliczyliśmy $a^{[L]}$ jak wyżej, jednak spodziewaliśmy się otrzymać
inny wektor, $y \in \R^{n^{[L]}}$. Zmodyfikujemy wagi za pomocą algorytmu \emph{gradient descent},
licząc gradient funkcji kosztu względem wag.

Przyjmijmy, że nasza funkcja kosztu ma postać
\[
\loss(y, a^{[L]}) = \frac{1}{2} \sum_{k=1}^{n^{[L]}} (y_k - a^{[L]}_k)^2.
\]

Najpierw obliczymy
\[
 \frac{\partial \loss}{\partial a^{[L]}_k} = a^{[L]}_k - y_k, \qquad k=1,\ldots,n^{[L]}.
\]
Powyższe równości będziemy zapisywać w skrócie tak:
\begin{equation}\label{eq:LaL}
 \frac{\partial \loss}{\partial a^{[L]}} = \left[ a^{[L]}_k - y_k \right]_{k=1,\ldots,n^{[L]}},
\end{equation}
po obu stronach mamy wektor kolumnowy.

\paragraph{\bf Propagacja wstecz, krok indukcyjny}

Powiedzmy, że $l\in\{1,\ldots,L\}$ oraz że mamy dany wektor
\[
\frac{\partial \loss}{\partial a^{[l]}}.
\]
Przypomnijmy, że zachodzi wzór
\[
a^{[l]} = 
\left[
    \varphi( \sum_{j=0}^{n^{[l-1]}} w^{[l]}_{k,j} x^{[l-1]}_j)
    \right]_{k=1,\ldots,n^{[l]}}
 = 
\left[
    \varphi( net^{[l]}_k)  \right]_{k=1,\ldots,n^{[l]}}.
\]
Możemy więc obliczyć $\frac{\partial \loss}{\partial w^{[l]}_{k_0,j_0}}$ używając reguły łańcucha
\begin{align*}
  \frac{\partial \loss}{\partial w^{[l]}_{k_0,j_0}}
  &=
  \sum_{k=1,\ldots,n^{[l]}}  \frac{\partial \loss}{\partial a^{[l]}_k} \cdot \frac{\partial a^{[l]}_k}{\partial w^{[l]}_{k_0,j_0}} \\
  &=   \frac{\partial \loss}{\partial a^{[l]}_{k_0}} \;
  \varphi'\left( \sum_{j=0}^{n^{[l-1]}} w^{[l]}_{k_0,j} x^{[l-1]}_j\right) \; x^{[l-1]}_{j_0} =: \delta^{[l]}_{k_0}x^{[l-1]}_{j_0}, 
\end{align*}
gdzie wektor kolumnowy $\delta^{[l]}$ jest określony następująco
\[
\delta^{[l]} = \left[\frac{\partial \loss}{\partial a^{[l]}_{k_0}} \; \varphi'\left( \sum_{j=0}^{n^{[l-1]}} w^{[l]}_{k_0,j} x^{[l-1]}_j\right)
  \right]_{k=1,\ldots,n^{[l]}}
 = \left[\frac{\partial \loss}{\partial a^{[l]}_{k_0}} \; \varphi'\left( net^{[l]}_{k_0}\right)
  \right]_{k=1,\ldots,n^{[l]}}.
\]
Taka notacja pozwala zapisać w~skrócie otrzymane wyżej wzory na pochodne,
\[
\frac{\partial \loss}{\partial w^{[l]}} = \delta^{[l]} \cdot (x^{[l-1]})^T,
\]
gdzie po obu stronach mamy macierze o~$n^{[l]}$ wierszach i~$(n^{[l-1]}+1)$ kolumnach.

Podobnie możemy też obliczyć $\frac{\partial \loss}{\partial x^{[l-1]}_{j_0}}$ używając reguły łańcucha
\begin{align*}
  \frac{\partial \loss}{\partial x^{[l-1]}_{j_0}}
  &=
  \sum_{k=1}^{n^{[l]}}  \frac{\partial \loss}{\partial a^{[l]}_k} \cdot \frac{\partial a^{[l]}_k}{\partial x^{[l-1]}_{j_0}} \\
  &=   \sum_{k=1}^{n^{[l]}}  \frac{\partial \loss}{\partial a^{[l]}_k}
  \varphi'\left( \sum_{j=0}^{n^{[l-1]}} w^{[l]}_{k,j} x^{[l-1]}_j\right) \; w^{[l]}_{k,j_0}
  = \sum_{k=1}^{n^{[l]}} w^{[l]}_{k,j_0}  \delta^{[l]}_{k}.
\end{align*}
W notacji macierzowej:
\[
\frac{\partial \loss}{\partial x^{[l-1]}} = (W^{[l]})^T \cdot \delta^{[l]}.
\]
Przypomnijmy, że $x^{[l-1]}_j = a^{[l-1]}_j$ dla $j\geq 1$, a~więc pomijając pierwszy element powyższego
wektora otrzymujemy
\[
\frac{\partial \loss}{\partial a^{[l-1]}}.
\]

\paragraph{\bf Propagacja wstecz, podsumowanie}
Korzystając ze wzoru \eqref{eq:LaL}, możemy zastosować krok indukcyjny dla $l=L$, otrzymamy pochodne funkcji kosztu po wagach z~ostatniej warstwy oraz $\frac{\partial \loss}{\partial a^{[L-1]}}$.
To pozwala zastosować krok indukcyjny dalej, kolejno  dla $l=L-1,\ldots,1$.
W ten sposób otrzymamy pochodne $\loss$ po wszystkich wagach, co pozwala zastosować algorytm \emph{gradient descent}.

\medskip

\hfill\hrule\hfill

\medskip
\vspace{3mm}

\paragraph{\bf Funkcja softmax i ,,categorical cross entropy''}

W problemach kategotyzacji często używa się w~\emph{ostatniej} warstwie funkcji aktywującej \emph{softmax}.
Ma ona taką zaletę, że wówczas wyjście sieci ma współrzędne nieujemne sumujące się do~$1$, można więc je interpretować jako rozkład prawdopodobieństwa.
Niestety, funkcja softmax  nie wpisuje się w~ogólny schemat pokazany do tej pory, ponieważ zależy ona od całego wektora $net^{[L]}$, konkretnie
\[
a^{[L]} = \psi(net^{[L]}) :=
\left[
  \frac{ \exp(net^{[L]}_k)}
  { \sum_{j=1}^{n^{[L]}} \exp(net^{[L]}_j)}
    \right]_{k=1,\ldots,n^{[L]}}.
\]
W związku z tym propagacja wsteczna dla ostatniej warstwy będzie miała inną postać, którą teraz znajdziemy. Założymy tutaj, że używamy funkcji kosztu \emph{categorical cross entropy}, określonej następująco
\[
\loss(y, a^{[L]}) = - \sum_{k=1}^{n^{[L]}} y_k \log(a^{[L]}_k)
 = - \sum_{k=1}^{n^{[L]}} y_k \left(net^{[L]}_k - \log(\sum_{j=1}^{n^{[L]}} \exp(net^{[L]}_j)) \right).
\]
Zwróćmy uwagę, że $a^{[L]}_k >0$, a~więc funkcja ta jest dobrze określona. Przypomnijmy, że
\[
net^{[L]}_k =
 \sum_{j=0}^{n^{[L-1]}} w^{[L]}_{k,j} x^{[L-1]}_j ,\qquad k=1,\ldots,n^{[L]}.
\]
Obliczamy
\begin{align*}
  \frac{\partial \loss}{\partial w^{[L]}_{k_0,j_0}}
  &=
  -y_{k_0} x^{[L-1]}_{j_0}
  + \sum_{k=1}^{n^{[L]}} y_k
  \frac{1}{\sum_{j=1}^{n^{[L]}} \exp(net^{[L]}_j)} \cdot \left(
  \frac{\partial}{\partial  w^{[L]}_{k_0,j_0}} 
  \exp(net^{[L]}_{k_0})\right) \\
  &=
  -y_{k_0} x^{[L-1]}_{j_0}
  + \sum_{k=1}^{n^{[L]}} y_k
  \frac{\exp(net^{[L]}_{k_0})}{\sum_{j=1}^{n^{[L]}} \exp(net^{[L]}_j)} x^{[L-1]}_{j_0} \\
  &=
\left(  \bigg(\sum_{k=1}^{n^{[L]}} y_k\bigg)\cdot a^{[L]}_{k_0} - y_{k_0} \right) x^{[L-1]}_{j_0}.
\end{align*}
Kładąc
\begin{equation}\label{eq:deltasoftmax}
  \delta^{[L]} = \left[ \bigg(\sum_{j=1}^{n^{[L]}} y_j\bigg)\cdot a^{[L]}_{k} - y_{k}
  \right]_{k=1,\ldots,n^{[l]}},
\end{equation}
otrzymujemy taki sam wzór, jak poprzednio:
\[
\frac{\partial \loss}{\partial w^{[L]}} = \delta^{[L]} \cdot (x^{[L-1]})^T.
\]
Obliczmy jeszcze podobnie
\begin{align*}
  \frac{\partial \loss}{\partial x^{[L-1]}_{j_0}}
  &= -\sum_{k=1}^{n^{[L]}} y_k w^{[L]}_{k,j_0}
  + \sum_{k=1}^{n^{[L]}} y_k
  \frac{1}{\sum_{j=1}^{n^{[L]}} \exp(net^{[L]}_j)} \cdot \left(
  \frac{\partial}{\partial x^{[L-1]}_{j_0}}
  \sum_{j=1}^{n^{[L]}}\exp(net^{[L]}_j)\right) \\
  &=-\sum_{k=1}^{n^{[L]}} y_k w^{[L]}_{k,j_0}
  + \sum_{k=1}^{n^{[L]}} y_k
\sum_{p=1}^{n^{[L]}}  \frac{\exp(net^{[L]}_p) w^{[L]}_{p,j_0}}{\sum_{j=1}^{n^{[L]}} \exp(net^{[L]}_j)}  \\
  &=-\sum_{p=1}^{n^{[L]}} y_p w^{[L]}_{p,j_0}
  + \sum_{k=1}^{n^{[L]}} y_k
\sum_{p=1}^{n^{[L]}}  a^{[L]}_p w^{[L]}_{p,j_0} \\
&=
\sum_{p=1}^{n^{[L]}}
\left( \Big (\sum_{k=1}^{n^{[L]}} y_k\Big) a^{[L]}_p - y_p \right)
w^{[L]}_{p,j_0} \\
&=
\sum_{p=1}^{n^{[L]}}
\delta^{[L]}_p
w^{[L]}_{p,j_0}.
\end{align*}
Otrzymaliśmy znowu taki sam wzór jak poprzednio, w notacji macierzowej:
\[
\frac{\partial \loss}{\partial x^{[L-1]}} = (W^{[L]})^T \cdot \delta^{[L]}.
\]
Podsumowując, zachodzą takie same wzory jak poprzednio, jeśli tylko zmodyfikujemy
definicję $\delta^{[L]}$ (tylko dla ostatniej warstwy), przyjmując \eqref{eq:deltasoftmax}.

Zobaczmy jeszcze, że wzór na  $\delta^{[L]}$ upraszcza się, jeśli założymy,
że $\sum_{k=1}^{n^{[L]}} y_k = 1$ (tak typowo jest w~zagadnieniach
klasyfikacyjnych). Wówczas
\[
\delta^{[L]} = \left[ a^{[L]}_{k} - y_{k}
  \right]_{k=1,\ldots,n^{[l]}}.
\]
 
\hfill\tiny{przygotował Bartek Dyda, \href{https://creativecommons.org/licenses/by-nc-sa/4.0/deed.pl}{CC BY-NC-SA 4.0}}
\end{document}
