This commit is contained in:
Filip Gralinski 2022-05-07 11:56:42 +02:00
parent 0a9dc121ef
commit 09ccde4ea7
2 changed files with 12 additions and 11 deletions

File diff suppressed because one or more lines are too long

View File

@ -4,13 +4,13 @@
Na poprzednim wykładzie rozpatrywaliśmy różne funkcje
$A(w_1,\dots,w_{i-1})$, dzięki którym możliwe było „skompresowanie” ciągu słów
(a właściwie ich zanurzeń) dowolnej długości w wektor o stałej długości.
(a właściwie ich zanurzeń) o dowolnej długości w wektor o stałej długości.
Funkcję $A$ moglibyśmy zdefiniować w inny sposób, w sposób **rekurencyjny**.
Otóż moglibyśmy zdekomponować funkcję $A$ do
- pewnego stanu początkowego $\vec{s^0} \in \mathcal{R}^p$,
- pewnego stanu początkowego $\vec{s_0} \in \mathcal{R}^p$,
- pewnej funkcji rekurencyjnej $R : \mathcal{R}^p \times \mathcal{R}^m \rightarrow \mathcal{R}^p$.
Wówczas funkcję $A$ można będzie zdefiniować rekurencyjnie jako:
@ -19,7 +19,7 @@ $$A(w_1,\dots,w_t) = R(A(w_1,\dots,w_{t-1}), E(w_t)),$$
przy czym dla ciągu pustego:
$$A(\epsilon) = \vec{s^0}$$
$$A(\epsilon) = \vec{s_0}$$
Przypomnijmy, że $m$ to rozmiar zanurzenia (embeddingu). Z kolei $p$ to rozmiar wektora stanu
(często $p=m$, ale nie jest to konieczne).
@ -39,12 +39,12 @@ gdzie $C$ jest wyuczalną macierzą o rozmiarze $|V| \times p$.
Nietrudno zdefiniować model „worka słów” w taki rekurencyjny sposób:
- $p=m$,
- $\vec{s^0} = [0,\dots,0]$,
- $\vec{s_0} = [0,\dots,0]$,
- $R(\vec{s}, \vec{x}) = \vec{s} + \vec{x}.$
Dodawanie (również wektorowe) jest operacją przemienną i łączną, więc
to rekurencyjne spojrzenie niewiele tu wnosi. Można jednak zastosować
funkcję $R$, która nie jest przemienna — w ten sposób wyjdziemy poza
inną funkcję $R$, która nie jest przemienna — w ten sposób wyjdziemy poza
nieuporządkowany worek słów.
** Związek z programowaniem funkcyjnym
@ -57,7 +57,7 @@ w językach funkcyjnych:
W Pythonie odpowiednik ~fold~ jest funkcja ~reduce~ z pakietu ~functools~:
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
from functools import reduce
def product(ns):
@ -83,10 +83,10 @@ przez macierz) i jakąś prostą funkcję aktywacji (na przykład sigmoidę):
$$R(\vec{s}, \vec{e}) = \sigma(W[\vec{s},\vec{e}] + \vec{b}).$$
Dodatkowo jeszcze wprowadziliśmy wektor obciążeń $\vec{b}, a zatem wyuczalne wagi to:
Dodatkowo jeszcze wprowadziliśmy wektor obciążeń $\vec{b}$, a zatem wyuczalne wagi obejmują:
- macierz $W \in \mathcal{R}^p \times \mathcal{R}^{p+m}$,
- wektor obciążń $b \in \mathcal{R}^p$.
- wektor obciążeń $b \in \mathcal{R}^p$.
Olbrzymią zaletą sieci rekurencyjnych jest fakt, że liczba wag nie zależy od rozmiaru wejścia!
@ -124,11 +124,11 @@ Tak więc w skrajnym przypadku:
- jeśli $\Gamma_\gamma = [0,\dots,0]$, sieć całkowicie zapomina
informację płynącą z poprzednich wyrazów,
- jeśli $\Gamma_\update = [0,\dots,0]$, sieć nie bierze pod uwagę
- jeśli $\Gamma_u = [0,\dots,0]$, sieć nie bierze pod uwagę
bieżącego wyrazu.
Zauważmy, że bramki mogą selektywnie, na każdej pozycji wektora stanu,
sterować przepływem informacji. Na przykład $Gamma_\gamma =
sterować przepływem informacji. Na przykład $\Gamma_\gamma =
[0,1,\dots,1]$ oznacza, że pierwsza pozycja wektora stanu jest
zapominana, a pozostałe — wnoszą wkład w całości.
@ -142,7 +142,7 @@ gdzie $\bullet$ oznacza iloczyn Hadamarda (nie iloczyn skalarny!) dwóch wektor
$$[x_1,\dots,x_n] \bullet [y_1,\dots,y_n] = [x_1 y_1,\dots,x_n y_n].$$
Obliczanie $$\vec{\xi_t}$$ bardzo przypomina zwykłą sieć rekurencyjną,
Obliczanie $\vec{\xi_t}$ bardzo przypomina zwykłą sieć rekurencyjną,
jedyna różnica polega na tym, że za pomocą bramki $\Gamma_\gamma$
modulujemy wpływ poprzedniego stanu.