Fix 11
This commit is contained in:
parent
6909b422a4
commit
eedb3f7741
@ -185,222 +185,3 @@ Zauważmy, że względem $n$ oznacza to bardzo korzystną złożoność
|
||||
$O(n)$! Oznacza to, że nasz model może działać dla dużo większych
|
||||
wartości $n$ niż tradycyjny, statystyczny n-gramowy model języka (dla którego
|
||||
wartości $n > 5$ zazwyczaj nie mają sensu).
|
||||
|
||||
** Model worka słów
|
||||
|
||||
Jak stwierdziliśmy przed chwilą, dwuwarstwowy n-gramowy model języka
|
||||
może działać dla stosunkowo dużego $n$. Zauważmy jednak, że istnieje
|
||||
pewna słabość tego modelu. Otóż o ile intuicyjnie ma sens odróżniać
|
||||
słowo poprzedzające, słowo występujące dwie pozycje wstecz i zapewne
|
||||
trzy pozycje wstecz, a zatem uczyć się osobnych macierzy $C_{-1}$,
|
||||
$C_{-2}$, $C_{-3}$ to różnica między wpływem słowa
|
||||
występującego cztery pozycje wstecz i pięć pozycji wstecz jest już
|
||||
raczej nieistotna; innymi słowy różnica między macierzami $C_{-4}$ i
|
||||
$C_{-5}$ będzie raczej niewielka i sieć niepotrzebnie będzie uczyła
|
||||
się dwukrotnie podobnych wag. Im dalej wstecz, tym różnica wpływu
|
||||
będzie jeszcze mniej istotna, można np. przypuszczać, że różnica
|
||||
między $C_{-10}$ i $C_{-13}$ nie powinna być duża.
|
||||
|
||||
Spróbujmy najpierw zaproponować radykalne podejście, w którym nie
|
||||
będziemy w ogóle uwzględniać pozycji słów (lub będziemy je uwzględniać
|
||||
w niewielkim stopniu), później połączymy to z omówionym wcześniej
|
||||
modelem $n$-gramowym.
|
||||
|
||||
*** Agregacja wektorów
|
||||
|
||||
Zamiast patrzeć na kilka poprzedzających słów, można przewidywać na
|
||||
podstawie *całego* ciągu słów poprzedzających odgadywane słowo. Zauważmy jednak, że
|
||||
sieć neuronowa musi mieć ustaloną strukturę, nie możemy zmieniać jej
|
||||
rozmiaru. Musimy zatem najpierw zagregować cały ciąg do wektora o
|
||||
*stałej* długości. Potrzebujemy zatem pewnej funkcji agregującej $A$, takiej by
|
||||
$A(w_1,\dots,w_{i-1})$ było wektorem o stałej długości, niezależnie od $i$.
|
||||
|
||||
*** Worek słów
|
||||
|
||||
Najprostszą funkcją agregującą jest po prostu… suma. Dodajemy po
|
||||
prostu zanurzenia słów:
|
||||
|
||||
$$A(w_1,\dots,w_{i-1}) = E(w_1) + \dots + E(w_{i-1}) = \sum_{j=1}^{i-1} E(w_j).$$
|
||||
|
||||
*Uwaga*: zanurzenia słów nie zależą od pozycji słowa (podobnie było w wypadku n-gramowego modelu!).
|
||||
|
||||
Jeśli rozmiar zanurzenia (embeddingu) wynosi $m$, wówczas rozmiar
|
||||
wektora uzyskanego dla całego poprzedzającego tekstu wynosi również $m$.
|
||||
|
||||
Proste dodawanie wydaje się bardzo „prostacką” metodą, a jednak
|
||||
suma wektorów słów jest *zaskakująco skuteczną metodą zanurzenia
|
||||
(embedowania) całych tekstów (doc2vec)*. Prostym wariantem dodawania jest obliczanie *średniej wektorów*:
|
||||
|
||||
$$A(w_1,\dots,w_{i-1}) = \frac{E(w_1) + \dots + E(w_{i-1})}{i-1} = \frac{\sum_{j=1}^{i-1} E(w_j)}{i-1}.$$
|
||||
|
||||
Tak czy siak uzyskany wektor *nie zależy od kolejności słów*
|
||||
(dodawanie jest przemienne i łączne!). Mówimy więc o *worku słów*
|
||||
(/bag of words/, /BoW/) — co ma symbolizować fakt, że słowa są
|
||||
przemieszane, niczym produkty w torbie na zakupy.
|
||||
|
||||
**** Schemat graficzny modelu typu worek słów
|
||||
|
||||
Po zanurzeniu całego poprzedzającego tekstu postępujemy podobnie jak w
|
||||
modelu bigramowym — rzutujemy embedding na długi wektor wartości, na
|
||||
którym stosujemy funkcję softmax:
|
||||
|
||||
#+CAPTION: Model typu worek słów
|
||||
[[./08_Neuronowy_ngramowy_model/bow1.drawio.png]]
|
||||
|
||||
Odpowiada to wzorowi:
|
||||
|
||||
$$y = \operatorname{softmax}(C\sum_{j=1}^{i-1} E(w_j)).$$
|
||||
|
||||
*** Jak traktować powtarzające się słowa?
|
||||
|
||||
Według wzoru podanego wyżej, jeśli słowo w poprzedzającym tekście
|
||||
pojawia się więcej niż raz, jego embedding zostanie zsumowany odpowiednią liczbę razy.
|
||||
Na przykład embedding tekstu /to be or not to be/ będzie wynosił:
|
||||
|
||||
$$E(\mathrm{to}) + E(\mathrm{be}) + E(\mathrm{or}) + E(\mathrm{not}) + E(\mathrm{to}) + E(\mathrm{be}) = 2E(\mathrm{to}) + 2E(\mathrm{be}) + E(\mathrm{or}) + E(\mathrm{not}).$$
|
||||
|
||||
Innymi słowy, choć w worku słów nie uwzględniamy kolejności słów, to
|
||||
*liczba wystąpień* ma dla nas ciągle znaczenie. Można powiedzieć, że
|
||||
traktujemy poprzedzający tekst jako *multizbiór* (struktura
|
||||
matematyczna, w której nie uwzględnia się kolejności, choć zachowana
|
||||
jest informacja o liczbie wystąpień).
|
||||
|
||||
**** Zbiór słów
|
||||
|
||||
Oczywiście moglibyśmy przy agregowaniu zanurzeń pomijać powtarzające
|
||||
się słowa, a zatem zamiast multizbioru słów rozpatrywać po prostu ich zbiór:
|
||||
|
||||
$$A(w_1,\dots,w_{i-1}) = \sum_{w \in \{w_1,\dots,w_{i-1}\}} E(w).$$
|
||||
|
||||
Jest kwestią dyskusyjną, czy to lepsze czy gorsze podejście — w końcu
|
||||
liczba wystąpień np. słów /Ukraina/ czy /Polska/ może wpływać w jakimś
|
||||
stopniu na prawdopodobieństwo kolejnego słowa (/Kijów/ czy
|
||||
/Warszawa/?).
|
||||
|
||||
*** Worek słów a wektoryzacja tf
|
||||
|
||||
Wzór na sumę zanurzeń słów można przekształcić w taki sposób, by
|
||||
sumować po wszystkich słowach ze słownika, zamiast po słowach rzeczywiście występujących w tekście:
|
||||
|
||||
$$A(w_1,\dots,w_{i-1}) = \sum_{j=1}^{i-1} E(w_j) = \sum_{w \in V} \#wE(w)$$
|
||||
|
||||
gdzie $\#w$ to liczba wystąpień słowa $w$ w ciagu $w_1,\dots,w_{i-1}$ (w wielu przypadkach równa zero!).
|
||||
|
||||
Jeśli teraz zanurzenia będziemy reprezentować jako macierz $E$ (por. poprzedni wykład),
|
||||
wówczas sumę można przedstawić jako iloczyn macierzy $E$ i pewnego wektora:
|
||||
|
||||
$$A(w_1,\dots,w_{i-1}) = E(w) [\#w^1,\dots,\#w^{|V|}]^T.$$
|
||||
|
||||
(Odróżniamy $w^i$ jako $i$-ty wyraz w słowniku $V$ od $w_i$ jako $i$-tego wyraz w rozpatrywanym ciągu).
|
||||
|
||||
Zwróćmy uwagę, że wektor $[\#w_1,\dots,\#w_{|V|}]$ to po prostu
|
||||
reprezentacja wektora poprzedzającego tekstu (tj. ciągu
|
||||
$(w_1,\dots,w_{i-1})$) przy użyciu schematu wektoryzacji tf (/term
|
||||
frequency/). Przypomnijmy, że tf to reprezentacja tekstu przy użyciu
|
||||
wektorów o rozmiarze $|V|$ — na każdej pozycji odnotowujemy liczbę wystąpień.
|
||||
Wektory tf są *rzadkie*, tj. na wielu pozycjach zawierają zera.
|
||||
|
||||
Innymi słowy, nasz model języka /bag of words/ można przedstawić za pomocą wzoru:
|
||||
|
||||
$$y = \operatorname{softmax}(C\operatorname{tf}(w_1,\dots,w_{i-1})),$$
|
||||
|
||||
co można zilustrować w następujący sposób:
|
||||
|
||||
#+CAPTION: Model typu worek słów — alternatywna reprezentacja
|
||||
[[./08_Neuronowy_ngramowy_model/bow2.drawio.png]]
|
||||
|
||||
Można stwierdzić, że zanurzenie tekstu przekształca rzadki, długi wektor
|
||||
tf w gęsty, krótki wektor.
|
||||
|
||||
** Ważenie słów
|
||||
|
||||
Czy wszystkie słowa są tak samo istotne? Rzecz jasna, nie:
|
||||
|
||||
- jak już wiemy z naszych rozważań dotyczących n-gramowych modeli języka, słowa bezpośrednio
|
||||
poprzedzające odgadywany wyraz mają większy wpływ niż słowa wcześniejsze;
|
||||
intuicyjnie, wpływ słów stopniowo spada — tym bardziej, im bardziej słowo jest oddalone od słowa odgadywanego;
|
||||
- jak wiemy z wyszukiwania informacji, słowa, które występują w wielu tekstach czy dokumentach, powinny mieć
|
||||
mniejsze znaczenie, w skrajnym przypadku słowa występujące w prawie każdym tekście (/że/, /w/, /i/ itd.) powinny
|
||||
być praktycznie pomijane jako /stop words/ (jeśli rozpatrywać je w „masie” worka słów — oczywiście
|
||||
to, czy słowo poprzedzające odgadywane słowo to /że/, /w/ czy /i/ ma olbrzymie znaczenie!).
|
||||
|
||||
Zamiast po prostu dodawać zanurzenia, można operować na sumie (bądź średniej) ważonej:
|
||||
|
||||
$$\sum_{j=1}^{i-1} \omega(j, w_j)E(w_j),$$
|
||||
|
||||
gdzie $\omega(j, w_j)$ jest pewną wagą, która może zależeć od pozycji $j$ lub samego słowa $w_j$.
|
||||
|
||||
*** Uwzględnienie pozycji
|
||||
|
||||
Można w pewnym stopniu złamać „workowatość” naszej sieci przez proste
|
||||
uwzględnienie pozycji słowa, np. w taki sposób:
|
||||
|
||||
$$\omega(j, w_j) = \beta^{i-j-1},$$
|
||||
|
||||
dla pewnego hiperparametru $\beta$. Na przykład jeśli $\beta=0,9$,
|
||||
wówczas słowo bezpośrednio poprzedzające dane słowo ma $1 / 0,9^9 \approx 2,58$
|
||||
większy wpływ niż słowo występujące 10 pozycji wstecz.
|
||||
|
||||
*** Odwrócona częstość dokumentowa
|
||||
|
||||
Aby większą wagę przykładać do słów występujących w mniejszej liczbie
|
||||
dokumentów, możemy użyć, znanej z wyszukiwania informacji,
|
||||
odwrotnej częstości dokumentowej (/inverted document frequency/, /idf/):
|
||||
|
||||
$$\omega(j, w_j) = \operatorname{idf}_S(w_j) = \operatorname{log}\frac{|S|}{\operatorname{df}_S(w_j)},$$
|
||||
|
||||
gdzie:
|
||||
|
||||
- $S$ jest pewną kolekcją dokumentów czy tekstów, z którego pochodzi przedmiotowy ciąg słów,
|
||||
- $\operatorname{df}_S(w)$ to częstość dokumentowa słowa $w$ w kolekcji $S$, tzn. odpowiedź na pytanie,
|
||||
w ilu dokumentach występuje $w$.
|
||||
|
||||
Rzecz jasna, ten sposób ważenia oznacza tak naprawdę zastosowanie wektoryzacji tf-idf zamiast tf,
|
||||
nasza sieć będzie dana zatem wzorem:
|
||||
|
||||
$$y = \operatorname{softmax}(C\operatorname{tfidf}(w_1,\dots,w_{i-1})).$$
|
||||
|
||||
*** Bardziej skomplikowane sposoby ważenia słów
|
||||
|
||||
Można oczywiście połączyć odwrotną częstość dokumentową z uwzględnieniem pozycji słowa:
|
||||
|
||||
$$\omega(j, w_j) = \beta^{i-j-1}\operatorname{idf}_S(w_j).$$
|
||||
|
||||
*Uwaga*: „wagi” $\omega(j, w_j)$ nie są tak naprawdę wyuczalnymi
|
||||
wagami (parametrami) naszej sieci neuronowej, terminologia może być
|
||||
tutaj myląca. Z punktu widzenia sieci neuronowej $\omega(j, w_j)$ są
|
||||
stałe i *nie* są optymalizowane w procesie propagacji wstecznej. Innymi
|
||||
słowy, tak zdefiniowane $\omega(j, w_j)$ zależą tylko od:
|
||||
|
||||
- hiperparametru $\beta$, który może być optymalizowany już poza siecią (w procesie *hiperoptymalizacji*),
|
||||
- wartości $\operatorname{idf}_S(w_j)$ wyliczanych wcześniej na podstawie kolekcji $S$.
|
||||
|
||||
*Pytanie*: czy wagi $\omega(j, w_j)$ mogłyby sensownie uwzględniać
|
||||
jakieś parametry wyuczalne z całą siecią?
|
||||
|
||||
** Modelowanie języka przy użyciu bardziej złożonych neuronowych sieci /feed-forward/
|
||||
|
||||
Można połączyć zalety obu ogólnych podejść (n-gramowego modelu i worka
|
||||
słów) — można *równocześnie* traktować w specjalny sposób (na
|
||||
przykład) dwa poprzedzające wyrazy, wszystkie zaś inne wyrazy
|
||||
reprezentować jako „tło” modelowane za pomocą worka słów lub podobnej
|
||||
reprezentacji. Osiągamy to poprzez konkatenację wektora
|
||||
poprzedzającego słowa, słowa występującego dwie pozycje wstecz oraz
|
||||
zagregowanego zanurzenia całego wcześniejszego tekstu:
|
||||
|
||||
$$y = \operatorname{softmax}(C[E(w_{i-1}),E(w_{i-2}),A(w_1,\dots,w_{i-3})]),$$
|
||||
|
||||
czy lepiej z dodatkową warstwą ukrytą:
|
||||
|
||||
$$y = \operatorname{softmax}(C\operatorname{tgh}(W[E(w_{i-1}),E(w_{i-2}),A(w_1,\dots,w_{i-3})])),$$
|
||||
|
||||
W tak uzyskanym dwuwarstwowym neuronowym modelu języka, łączącym model
|
||||
trigramowy z workiem słów, macierz $W$ ma rozmiar $h \times 3m$.
|
||||
|
||||
*Pytanie*: jakie mamy możliwości, jeśli zamiast przewidywać kolejne słowo, mamy za zadanie
|
||||
odgadywać słowo w luce (jak w wyzwaniach typu /word gap/)?
|
||||
|
||||
** Literatura
|
||||
|
||||
Skuteczny n-gramowy neuronowy model języka opisano po raz pierwszy
|
||||
w pracy [[https://www.jmlr.org/papers/volume3/bengio03a/bengio03a.pdf][A Neural Probabilistic Language Model]] autorstwa Yoshua Bengio i in.
|
||||
|
414
wyk/11_Worek_slow.ipynb
Normal file
414
wyk/11_Worek_slow.ipynb
Normal file
@ -0,0 +1,414 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n",
|
||||
"<div class=\"alert alert-block alert-info\">\n",
|
||||
"<h1> Modelowanie języka</h1>\n",
|
||||
"<h2> 11. <i>Model worka słów w sieci feed-forward</i> [wykład]</h2> \n",
|
||||
"<h3> Filip Graliński (2022)</h3>\n",
|
||||
"</div>\n",
|
||||
"\n",
|
||||
"![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Model worka słów w sieci feed-forward\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Jak stwierdziliśmy w poprzednim wykładzie, dwuwarstwowy n-gramowy model języka\n",
|
||||
"może działać dla stosunkowo dużego $n$. Zauważmy jednak, że istnieje\n",
|
||||
"pewna słabość tego modelu. Otóż o ile intuicyjnie ma sens odróżniać\n",
|
||||
"słowo poprzedzające, słowo występujące dwie pozycje wstecz i zapewne\n",
|
||||
"trzy pozycje wstecz, a zatem uczyć się osobnych macierzy $C_{-1}$,\n",
|
||||
"$C_{-2}$, $C_{-3}$ to różnica między wpływem słowa\n",
|
||||
"występującego cztery pozycje wstecz i pięć pozycji wstecz jest już\n",
|
||||
"raczej nieistotna; innymi słowy różnica między macierzami $C_{-4}$ i\n",
|
||||
"$C_{-5}$ będzie raczej niewielka i sieć niepotrzebnie będzie uczyła\n",
|
||||
"się dwukrotnie podobnych wag. Im dalej wstecz, tym różnica wpływu\n",
|
||||
"będzie jeszcze mniej istotna, można np. przypuszczać, że różnica\n",
|
||||
"między $C_{-10}$ i $C_{-13}$ nie powinna być duża.\n",
|
||||
"\n",
|
||||
"Spróbujmy najpierw zaproponować radykalne podejście, w którym nie\n",
|
||||
"będziemy w ogóle uwzględniać pozycji słów (lub będziemy je uwzględniać\n",
|
||||
"w niewielkim stopniu), później połączymy to z omówionym wcześniej\n",
|
||||
"modelem $n$-gramowym.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Agregacja wektorów\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Zamiast patrzeć na kilka poprzedzających słów, można przewidywać na\n",
|
||||
"podstawie **całego** ciągu słów poprzedzających odgadywane słowo. Zauważmy jednak, że\n",
|
||||
"sieć neuronowa musi mieć ustaloną strukturę, nie możemy zmieniać jej\n",
|
||||
"rozmiaru. Musimy zatem najpierw zagregować cały ciąg do wektora o\n",
|
||||
"**stałej** długości. Potrzebujemy zatem pewnej funkcji agregującej $A$, takiej by\n",
|
||||
"$A(w_1,\\dots,w_{i-1})$ było wektorem o stałej długości, niezależnie od $i$.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Worek słów\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Najprostszą funkcją agregującą jest po prostu… suma. Dodajemy po\n",
|
||||
"prostu zanurzenia słów:\n",
|
||||
"\n",
|
||||
"$$A(w_1,\\dots,w_{i-1}) = E(w_1) + \\dots + E(w_{i-1}) = \\sum_{j=1}^{i-1} E(w_j).$$\n",
|
||||
"\n",
|
||||
"**Uwaga**: zanurzenia słów nie zależą od pozycji słowa (podobnie było w wypadku n-gramowego modelu!).\n",
|
||||
"\n",
|
||||
"Jeśli rozmiar zanurzenia (embeddingu) wynosi $m$, wówczas rozmiar\n",
|
||||
"wektora uzyskanego dla całego poprzedzającego tekstu wynosi również $m$.\n",
|
||||
"\n",
|
||||
"Proste dodawanie wydaje się bardzo „prostacką” metodą, a jednak\n",
|
||||
"suma wektorów słów jest **zaskakująco skuteczną metodą zanurzenia\n",
|
||||
"(embedowania) całych tekstów (doc2vec)**. Prostym wariantem dodawania jest obliczanie **średniej wektorów**:\n",
|
||||
"\n",
|
||||
"$$A(w_1,\\dots,w_{i-1}) = \\frac{E(w_1) + \\dots + E(w_{i-1})}{i-1} = \\frac{\\sum_{j=1}^{i-1} E(w_j)}{i-1}.$$\n",
|
||||
"\n",
|
||||
"Tak czy siak uzyskany wektor **nie zależy od kolejności słów**\n",
|
||||
"(dodawanie jest przemienne i łączne!). Mówimy więc o **worku słów**\n",
|
||||
"(*bag of words*, *BoW*) — co ma symbolizować fakt, że słowa są\n",
|
||||
"przemieszane, niczym produkty w torbie na zakupy.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Schemat graficzny modelu typu worek słów\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Po zanurzeniu całego poprzedzającego tekstu postępujemy podobnie jak w\n",
|
||||
"modelu bigramowym — rzutujemy embedding na długi wektor wartości, na\n",
|
||||
"którym stosujemy funkcję softmax:\n",
|
||||
"\n",
|
||||
"![img](./11_Worek_slow/bow1.drawio.png \"Model typu worek słów\")\n",
|
||||
"\n",
|
||||
"Odpowiada to wzorowi:\n",
|
||||
"\n",
|
||||
"$$y = \\operatorname{softmax}(C\\sum_{j=1}^{i-1} E(w_j)).$$\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Jak traktować powtarzające się słowa?\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Według wzoru podanego wyżej, jeśli słowo w poprzedzającym tekście\n",
|
||||
"pojawia się więcej niż raz, jego embedding zostanie zsumowany odpowiednią liczbę razy.\n",
|
||||
"Na przykład embedding tekstu *to be or not to be* będzie wynosił:\n",
|
||||
"\n",
|
||||
"$$E(\\mathrm{to}) + E(\\mathrm{be}) + E(\\mathrm{or}) + E(\\mathrm{not}) + E(\\mathrm{to}) + E(\\mathrm{be}) = 2E(\\mathrm{to}) + 2E(\\mathrm{be}) + E(\\mathrm{or}) + E(\\mathrm{not}).$$\n",
|
||||
"\n",
|
||||
"Innymi słowy, choć w worku słów nie uwzględniamy kolejności słów, to\n",
|
||||
"**liczba wystąpień** ma dla nas ciągle znaczenie. Można powiedzieć, że\n",
|
||||
"traktujemy poprzedzający tekst jako **multizbiór** (struktura\n",
|
||||
"matematyczna, w której nie uwzględnia się kolejności, choć zachowana\n",
|
||||
"jest informacja o liczbie wystąpień).\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Zbiór słów\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Oczywiście moglibyśmy przy agregowaniu zanurzeń pomijać powtarzające\n",
|
||||
"się słowa, a zatem zamiast multizbioru słów rozpatrywać po prostu ich zbiór:\n",
|
||||
"\n",
|
||||
"$$A(w_1,\\dots,w_{i-1}) = \\sum_{w \\in \\{w_1,\\dots,w_{i-1}\\}} E(w).$$\n",
|
||||
"\n",
|
||||
"Jest kwestią dyskusyjną, czy to lepsze czy gorsze podejście — w końcu\n",
|
||||
"liczba wystąpień np. słów *Ukraina* czy *Polska* może wpływać w jakimś\n",
|
||||
"stopniu na prawdopodobieństwo kolejnego słowa (*Kijów* czy\n",
|
||||
"*Warszawa*?).\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Worek słów a wektoryzacja tf\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Wzór na sumę zanurzeń słów można przekształcić w taki sposób, by\n",
|
||||
"sumować po wszystkich słowach ze słownika, zamiast po słowach rzeczywiście występujących w tekście:\n",
|
||||
"\n",
|
||||
"$$A(w_1,\\dots,w_{i-1}) = \\sum_{j=1}^{i-1} E(w_j) = \\sum_{w \\in V} \\#wE(w)$$\n",
|
||||
"\n",
|
||||
"gdzie $\\#w$ to liczba wystąpień słowa $w$ w ciagu $w_1,\\dots,w_{i-1}$ (w wielu przypadkach równa zero!).\n",
|
||||
"\n",
|
||||
"Jeśli teraz zanurzenia będziemy reprezentować jako macierz $E$ (por. poprzedni wykład),\n",
|
||||
"wówczas sumę można przedstawić jako iloczyn macierzy $E$ i pewnego wektora:\n",
|
||||
"\n",
|
||||
"$$A(w_1,\\dots,w_{i-1}) = E(w) [\\#w^1,\\dots,\\#w^{|V|}]^T.$$\n",
|
||||
"\n",
|
||||
"(Odróżniamy $w^i$ jako $i$-ty wyraz w słowniku $V$ od $w_i$ jako $i$-tego wyraz w rozpatrywanym ciągu).\n",
|
||||
"\n",
|
||||
"Zwróćmy uwagę, że wektor $[\\#w_1,\\dots,\\#w_{|V|}]$ to po prostu\n",
|
||||
"reprezentacja wektora poprzedzającego tekstu (tj. ciągu\n",
|
||||
"$(w_1,\\dots,w_{i-1})$) przy użyciu schematu wektoryzacji tf (*term\n",
|
||||
"frequency*). Przypomnijmy, że tf to reprezentacja tekstu przy użyciu\n",
|
||||
"wektorów o rozmiarze $|V|$ — na każdej pozycji odnotowujemy liczbę wystąpień.\n",
|
||||
"Wektory tf są **rzadkie**, tj. na wielu pozycjach zawierają zera.\n",
|
||||
"\n",
|
||||
"Innymi słowy, nasz model języka *bag of words* można przedstawić za pomocą wzoru:\n",
|
||||
"\n",
|
||||
"$$y = \\operatorname{softmax}(C\\operatorname{tf}(w_1,\\dots,w_{i-1})),$$\n",
|
||||
"\n",
|
||||
"co można zilustrować w następujący sposób:\n",
|
||||
"\n",
|
||||
"![img](./11_Worek_slow/bow2.drawio.png \"Model typu worek słów — alternatywna reprezentacja\")\n",
|
||||
"\n",
|
||||
"Można stwierdzić, że zanurzenie tekstu przekształca rzadki, długi wektor\n",
|
||||
"tf w gęsty, krótki wektor.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Ważenie słów\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Czy wszystkie słowa są tak samo istotne? Rzecz jasna, nie:\n",
|
||||
"\n",
|
||||
"- jak już wiemy z naszych rozważań dotyczących n-gramowych modeli języka, słowa bezpośrednio\n",
|
||||
" poprzedzające odgadywany wyraz mają większy wpływ niż słowa wcześniejsze;\n",
|
||||
" intuicyjnie, wpływ słów stopniowo spada — tym bardziej, im bardziej słowo jest oddalone od słowa odgadywanego;\n",
|
||||
"- jak wiemy z wyszukiwania informacji, słowa, które występują w wielu tekstach czy dokumentach, powinny mieć\n",
|
||||
" mniejsze znaczenie, w skrajnym przypadku słowa występujące w prawie każdym tekście (*że*, *w*, *i* itd.) powinny\n",
|
||||
" być praktycznie pomijane jako *stop words* (jeśli rozpatrywać je w „masie” worka słów — oczywiście\n",
|
||||
" to, czy słowo poprzedzające odgadywane słowo to *że*, *w* czy *i* ma olbrzymie znaczenie!).\n",
|
||||
"\n",
|
||||
"Zamiast po prostu dodawać zanurzenia, można operować na sumie (bądź średniej) ważonej:\n",
|
||||
"\n",
|
||||
"$$\\sum_{j=1}^{i-1} \\omega(j, w_j)E(w_j),$$\n",
|
||||
"\n",
|
||||
"gdzie $\\omega(j, w_j)$ jest pewną wagą, która może zależeć od pozycji $j$ lub samego słowa $w_j$.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Uwzględnienie pozycji\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Można w pewnym stopniu złamać „workowatość” naszej sieci przez proste\n",
|
||||
"uwzględnienie pozycji słowa, np. w taki sposób:\n",
|
||||
"\n",
|
||||
"$$\\omega(j, w_j) = \\beta^{i-j-1},$$\n",
|
||||
"\n",
|
||||
"dla pewnego hiperparametru $\\beta$. Na przykład jeśli $\\beta=0,9$,\n",
|
||||
"wówczas słowo bezpośrednio poprzedzające dane słowo ma $1 / 0,9^9 \\approx 2,58$\n",
|
||||
"większy wpływ niż słowo występujące 10 pozycji wstecz.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Odwrócona częstość dokumentowa\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Aby większą wagę przykładać do słów występujących w mniejszej liczbie\n",
|
||||
"dokumentów, możemy użyć, znanej z wyszukiwania informacji,\n",
|
||||
"odwrotnej częstości dokumentowej (*inverted document frequency*, *idf*):\n",
|
||||
"\n",
|
||||
"$$\\omega(j, w_j) = \\operatorname{idf}_S(w_j) = \\operatorname{log}\\frac{|S|}{\\operatorname{df}_S(w_j)},$$\n",
|
||||
"\n",
|
||||
"gdzie:\n",
|
||||
"\n",
|
||||
"- $S$ jest pewną kolekcją dokumentów czy tekstów, z którego pochodzi przedmiotowy ciąg słów,\n",
|
||||
"- $\\operatorname{df}_S(w)$ to częstość dokumentowa słowa $w$ w kolekcji $S$, tzn. odpowiedź na pytanie,\n",
|
||||
" w ilu dokumentach występuje $w$.\n",
|
||||
"\n",
|
||||
"Rzecz jasna, ten sposób ważenia oznacza tak naprawdę zastosowanie wektoryzacji tf-idf zamiast tf,\n",
|
||||
"nasza sieć będzie dana zatem wzorem:\n",
|
||||
"\n",
|
||||
"$$y = \\operatorname{softmax}(C\\operatorname{tfidf}(w_1,\\dots,w_{i-1})).$$\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Bardziej skomplikowane sposoby ważenia słów\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Można oczywiście połączyć odwrotną częstość dokumentową z uwzględnieniem pozycji słowa:\n",
|
||||
"\n",
|
||||
"$$\\omega(j, w_j) = \\beta^{i-j-1}\\operatorname{idf}_S(w_j).$$\n",
|
||||
"\n",
|
||||
"**Uwaga**: „wagi” $\\omega(j, w_j)$ nie są tak naprawdę wyuczalnymi\n",
|
||||
"wagami (parametrami) naszej sieci neuronowej, terminologia może być\n",
|
||||
"tutaj myląca. Z punktu widzenia sieci neuronowej $\\omega(j, w_j)$ są\n",
|
||||
"stałe i **nie** są optymalizowane w procesie propagacji wstecznej. Innymi\n",
|
||||
"słowy, tak zdefiniowane $\\omega(j, w_j)$ zależą tylko od:\n",
|
||||
"\n",
|
||||
"- hiperparametru $\\beta$, który może być optymalizowany już poza siecią (w procesie **hiperoptymalizacji**),\n",
|
||||
"- wartości $\\operatorname{idf}_S(w_j)$ wyliczanych wcześniej na podstawie kolekcji $S$.\n",
|
||||
"\n",
|
||||
"**Pytanie**: czy wagi $\\omega(j, w_j)$ mogłyby sensownie uwzględniać\n",
|
||||
"jakieś parametry wyuczalne z całą siecią?\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Modelowanie języka przy użyciu bardziej złożonych neuronowych sieci *feed-forward*\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Można połączyć zalety obu ogólnych podejść (n-gramowego modelu i worka\n",
|
||||
"słów) — można **równocześnie** traktować w specjalny sposób (na\n",
|
||||
"przykład) dwa poprzedzające wyrazy, wszystkie zaś inne wyrazy\n",
|
||||
"reprezentować jako „tło” modelowane za pomocą worka słów lub podobnej\n",
|
||||
"reprezentacji. Osiągamy to poprzez konkatenację wektora\n",
|
||||
"poprzedzającego słowa, słowa występującego dwie pozycje wstecz oraz\n",
|
||||
"zagregowanego zanurzenia całego wcześniejszego tekstu:\n",
|
||||
"\n",
|
||||
"$$y = \\operatorname{softmax}(C[E(w_{i-1}),E(w_{i-2}),A(w_1,\\dots,w_{i-3})]),$$\n",
|
||||
"\n",
|
||||
"czy lepiej z dodatkową warstwą ukrytą:\n",
|
||||
"\n",
|
||||
"$$y = \\operatorname{softmax}(C\\operatorname{tgh}(W[E(w_{i-1}),E(w_{i-2}),A(w_1,\\dots,w_{i-3})])),$$\n",
|
||||
"\n",
|
||||
"W tak uzyskanym dwuwarstwowym neuronowym modelu języka, łączącym model\n",
|
||||
"trigramowy z workiem słów, macierz $W$ ma rozmiar $h \\times 3m$.\n",
|
||||
"\n",
|
||||
"**Pytanie**: jakie mamy możliwości, jeśli zamiast przewidywać kolejne słowo, mamy za zadanie\n",
|
||||
"odgadywać słowo w luce (jak w wyzwaniach typu *word gap*)?\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Literatura\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Skuteczny n-gramowy neuronowy model języka opisano po raz pierwszy\n",
|
||||
"w pracy [A Neural Probabilistic Language Model](https://www.jmlr.org/papers/volume3/bengio03a/bengio03a.pdf) autorstwa Yoshua Bengio i in.\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.5"
|
||||
},
|
||||
"org": null
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 1
|
||||
}
|
218
wyk/11_Worek_slow.org
Normal file
218
wyk/11_Worek_slow.org
Normal file
@ -0,0 +1,218 @@
|
||||
* Model worka słów w sieci feed-forward
|
||||
|
||||
Jak stwierdziliśmy w poprzednim wykładzie, dwuwarstwowy n-gramowy model języka
|
||||
może działać dla stosunkowo dużego $n$. Zauważmy jednak, że istnieje
|
||||
pewna słabość tego modelu. Otóż o ile intuicyjnie ma sens odróżniać
|
||||
słowo poprzedzające, słowo występujące dwie pozycje wstecz i zapewne
|
||||
trzy pozycje wstecz, a zatem uczyć się osobnych macierzy $C_{-1}$,
|
||||
$C_{-2}$, $C_{-3}$ to różnica między wpływem słowa
|
||||
występującego cztery pozycje wstecz i pięć pozycji wstecz jest już
|
||||
raczej nieistotna; innymi słowy różnica między macierzami $C_{-4}$ i
|
||||
$C_{-5}$ będzie raczej niewielka i sieć niepotrzebnie będzie uczyła
|
||||
się dwukrotnie podobnych wag. Im dalej wstecz, tym różnica wpływu
|
||||
będzie jeszcze mniej istotna, można np. przypuszczać, że różnica
|
||||
między $C_{-10}$ i $C_{-13}$ nie powinna być duża.
|
||||
|
||||
Spróbujmy najpierw zaproponować radykalne podejście, w którym nie
|
||||
będziemy w ogóle uwzględniać pozycji słów (lub będziemy je uwzględniać
|
||||
w niewielkim stopniu), później połączymy to z omówionym wcześniej
|
||||
modelem $n$-gramowym.
|
||||
|
||||
** Agregacja wektorów
|
||||
|
||||
Zamiast patrzeć na kilka poprzedzających słów, można przewidywać na
|
||||
podstawie *całego* ciągu słów poprzedzających odgadywane słowo. Zauważmy jednak, że
|
||||
sieć neuronowa musi mieć ustaloną strukturę, nie możemy zmieniać jej
|
||||
rozmiaru. Musimy zatem najpierw zagregować cały ciąg do wektora o
|
||||
*stałej* długości. Potrzebujemy zatem pewnej funkcji agregującej $A$, takiej by
|
||||
$A(w_1,\dots,w_{i-1})$ było wektorem o stałej długości, niezależnie od $i$.
|
||||
|
||||
** Worek słów
|
||||
|
||||
Najprostszą funkcją agregującą jest po prostu… suma. Dodajemy po
|
||||
prostu zanurzenia słów:
|
||||
|
||||
$$A(w_1,\dots,w_{i-1}) = E(w_1) + \dots + E(w_{i-1}) = \sum_{j=1}^{i-1} E(w_j).$$
|
||||
|
||||
*Uwaga*: zanurzenia słów nie zależą od pozycji słowa (podobnie było w wypadku n-gramowego modelu!).
|
||||
|
||||
Jeśli rozmiar zanurzenia (embeddingu) wynosi $m$, wówczas rozmiar
|
||||
wektora uzyskanego dla całego poprzedzającego tekstu wynosi również $m$.
|
||||
|
||||
Proste dodawanie wydaje się bardzo „prostacką” metodą, a jednak
|
||||
suma wektorów słów jest *zaskakująco skuteczną metodą zanurzenia
|
||||
(embedowania) całych tekstów (doc2vec)*. Prostym wariantem dodawania jest obliczanie *średniej wektorów*:
|
||||
|
||||
$$A(w_1,\dots,w_{i-1}) = \frac{E(w_1) + \dots + E(w_{i-1})}{i-1} = \frac{\sum_{j=1}^{i-1} E(w_j)}{i-1}.$$
|
||||
|
||||
Tak czy siak uzyskany wektor *nie zależy od kolejności słów*
|
||||
(dodawanie jest przemienne i łączne!). Mówimy więc o *worku słów*
|
||||
(/bag of words/, /BoW/) — co ma symbolizować fakt, że słowa są
|
||||
przemieszane, niczym produkty w torbie na zakupy.
|
||||
|
||||
*** Schemat graficzny modelu typu worek słów
|
||||
|
||||
Po zanurzeniu całego poprzedzającego tekstu postępujemy podobnie jak w
|
||||
modelu bigramowym — rzutujemy embedding na długi wektor wartości, na
|
||||
którym stosujemy funkcję softmax:
|
||||
|
||||
#+CAPTION: Model typu worek słów
|
||||
[[./11_Worek_slow/bow1.drawio.png]]
|
||||
|
||||
Odpowiada to wzorowi:
|
||||
|
||||
$$y = \operatorname{softmax}(C\sum_{j=1}^{i-1} E(w_j)).$$
|
||||
|
||||
** Jak traktować powtarzające się słowa?
|
||||
|
||||
Według wzoru podanego wyżej, jeśli słowo w poprzedzającym tekście
|
||||
pojawia się więcej niż raz, jego embedding zostanie zsumowany odpowiednią liczbę razy.
|
||||
Na przykład embedding tekstu /to be or not to be/ będzie wynosił:
|
||||
|
||||
$$E(\mathrm{to}) + E(\mathrm{be}) + E(\mathrm{or}) + E(\mathrm{not}) + E(\mathrm{to}) + E(\mathrm{be}) = 2E(\mathrm{to}) + 2E(\mathrm{be}) + E(\mathrm{or}) + E(\mathrm{not}).$$
|
||||
|
||||
Innymi słowy, choć w worku słów nie uwzględniamy kolejności słów, to
|
||||
*liczba wystąpień* ma dla nas ciągle znaczenie. Można powiedzieć, że
|
||||
traktujemy poprzedzający tekst jako *multizbiór* (struktura
|
||||
matematyczna, w której nie uwzględnia się kolejności, choć zachowana
|
||||
jest informacja o liczbie wystąpień).
|
||||
|
||||
*** Zbiór słów
|
||||
|
||||
Oczywiście moglibyśmy przy agregowaniu zanurzeń pomijać powtarzające
|
||||
się słowa, a zatem zamiast multizbioru słów rozpatrywać po prostu ich zbiór:
|
||||
|
||||
$$A(w_1,\dots,w_{i-1}) = \sum_{w \in \{w_1,\dots,w_{i-1}\}} E(w).$$
|
||||
|
||||
Jest kwestią dyskusyjną, czy to lepsze czy gorsze podejście — w końcu
|
||||
liczba wystąpień np. słów /Ukraina/ czy /Polska/ może wpływać w jakimś
|
||||
stopniu na prawdopodobieństwo kolejnego słowa (/Kijów/ czy
|
||||
/Warszawa/?).
|
||||
|
||||
** Worek słów a wektoryzacja tf
|
||||
|
||||
Wzór na sumę zanurzeń słów można przekształcić w taki sposób, by
|
||||
sumować po wszystkich słowach ze słownika, zamiast po słowach rzeczywiście występujących w tekście:
|
||||
|
||||
$$A(w_1,\dots,w_{i-1}) = \sum_{j=1}^{i-1} E(w_j) = \sum_{w \in V} \#wE(w)$$
|
||||
|
||||
gdzie $\#w$ to liczba wystąpień słowa $w$ w ciagu $w_1,\dots,w_{i-1}$ (w wielu przypadkach równa zero!).
|
||||
|
||||
Jeśli teraz zanurzenia będziemy reprezentować jako macierz $E$ (por. poprzedni wykład),
|
||||
wówczas sumę można przedstawić jako iloczyn macierzy $E$ i pewnego wektora:
|
||||
|
||||
$$A(w_1,\dots,w_{i-1}) = E(w) [\#w^1,\dots,\#w^{|V|}]^T.$$
|
||||
|
||||
(Odróżniamy $w^i$ jako $i$-ty wyraz w słowniku $V$ od $w_i$ jako $i$-tego wyraz w rozpatrywanym ciągu).
|
||||
|
||||
Zwróćmy uwagę, że wektor $[\#w_1,\dots,\#w_{|V|}]$ to po prostu
|
||||
reprezentacja wektora poprzedzającego tekstu (tj. ciągu
|
||||
$(w_1,\dots,w_{i-1})$) przy użyciu schematu wektoryzacji tf (/term
|
||||
frequency/). Przypomnijmy, że tf to reprezentacja tekstu przy użyciu
|
||||
wektorów o rozmiarze $|V|$ — na każdej pozycji odnotowujemy liczbę wystąpień.
|
||||
Wektory tf są *rzadkie*, tj. na wielu pozycjach zawierają zera.
|
||||
|
||||
Innymi słowy, nasz model języka /bag of words/ można przedstawić za pomocą wzoru:
|
||||
|
||||
$$y = \operatorname{softmax}(C\operatorname{tf}(w_1,\dots,w_{i-1})),$$
|
||||
|
||||
co można zilustrować w następujący sposób:
|
||||
|
||||
#+CAPTION: Model typu worek słów — alternatywna reprezentacja
|
||||
[[./11_Worek_slow/bow2.drawio.png]]
|
||||
|
||||
Można stwierdzić, że zanurzenie tekstu przekształca rzadki, długi wektor
|
||||
tf w gęsty, krótki wektor.
|
||||
|
||||
** Ważenie słów
|
||||
|
||||
Czy wszystkie słowa są tak samo istotne? Rzecz jasna, nie:
|
||||
|
||||
- jak już wiemy z naszych rozważań dotyczących n-gramowych modeli języka, słowa bezpośrednio
|
||||
poprzedzające odgadywany wyraz mają większy wpływ niż słowa wcześniejsze;
|
||||
intuicyjnie, wpływ słów stopniowo spada — tym bardziej, im bardziej słowo jest oddalone od słowa odgadywanego;
|
||||
- jak wiemy z wyszukiwania informacji, słowa, które występują w wielu tekstach czy dokumentach, powinny mieć
|
||||
mniejsze znaczenie, w skrajnym przypadku słowa występujące w prawie każdym tekście (/że/, /w/, /i/ itd.) powinny
|
||||
być praktycznie pomijane jako /stop words/ (jeśli rozpatrywać je w „masie” worka słów — oczywiście
|
||||
to, czy słowo poprzedzające odgadywane słowo to /że/, /w/ czy /i/ ma olbrzymie znaczenie!).
|
||||
|
||||
Zamiast po prostu dodawać zanurzenia, można operować na sumie (bądź średniej) ważonej:
|
||||
|
||||
$$\sum_{j=1}^{i-1} \omega(j, w_j)E(w_j),$$
|
||||
|
||||
gdzie $\omega(j, w_j)$ jest pewną wagą, która może zależeć od pozycji $j$ lub samego słowa $w_j$.
|
||||
|
||||
*** Uwzględnienie pozycji
|
||||
|
||||
Można w pewnym stopniu złamać „workowatość” naszej sieci przez proste
|
||||
uwzględnienie pozycji słowa, np. w taki sposób:
|
||||
|
||||
$$\omega(j, w_j) = \beta^{i-j-1},$$
|
||||
|
||||
dla pewnego hiperparametru $\beta$. Na przykład jeśli $\beta=0,9$,
|
||||
wówczas słowo bezpośrednio poprzedzające dane słowo ma $1 / 0,9^9 \approx 2,58$
|
||||
większy wpływ niż słowo występujące 10 pozycji wstecz.
|
||||
|
||||
*** Odwrócona częstość dokumentowa
|
||||
|
||||
Aby większą wagę przykładać do słów występujących w mniejszej liczbie
|
||||
dokumentów, możemy użyć, znanej z wyszukiwania informacji,
|
||||
odwrotnej częstości dokumentowej (/inverted document frequency/, /idf/):
|
||||
|
||||
$$\omega(j, w_j) = \operatorname{idf}_S(w_j) = \operatorname{log}\frac{|S|}{\operatorname{df}_S(w_j)},$$
|
||||
|
||||
gdzie:
|
||||
|
||||
- $S$ jest pewną kolekcją dokumentów czy tekstów, z którego pochodzi przedmiotowy ciąg słów,
|
||||
- $\operatorname{df}_S(w)$ to częstość dokumentowa słowa $w$ w kolekcji $S$, tzn. odpowiedź na pytanie,
|
||||
w ilu dokumentach występuje $w$.
|
||||
|
||||
Rzecz jasna, ten sposób ważenia oznacza tak naprawdę zastosowanie wektoryzacji tf-idf zamiast tf,
|
||||
nasza sieć będzie dana zatem wzorem:
|
||||
|
||||
$$y = \operatorname{softmax}(C\operatorname{tfidf}(w_1,\dots,w_{i-1})).$$
|
||||
|
||||
*** Bardziej skomplikowane sposoby ważenia słów
|
||||
|
||||
Można oczywiście połączyć odwrotną częstość dokumentową z uwzględnieniem pozycji słowa:
|
||||
|
||||
$$\omega(j, w_j) = \beta^{i-j-1}\operatorname{idf}_S(w_j).$$
|
||||
|
||||
*Uwaga*: „wagi” $\omega(j, w_j)$ nie są tak naprawdę wyuczalnymi
|
||||
wagami (parametrami) naszej sieci neuronowej, terminologia może być
|
||||
tutaj myląca. Z punktu widzenia sieci neuronowej $\omega(j, w_j)$ są
|
||||
stałe i *nie* są optymalizowane w procesie propagacji wstecznej. Innymi
|
||||
słowy, tak zdefiniowane $\omega(j, w_j)$ zależą tylko od:
|
||||
|
||||
- hiperparametru $\beta$, który może być optymalizowany już poza siecią (w procesie *hiperoptymalizacji*),
|
||||
- wartości $\operatorname{idf}_S(w_j)$ wyliczanych wcześniej na podstawie kolekcji $S$.
|
||||
|
||||
*Pytanie*: czy wagi $\omega(j, w_j)$ mogłyby sensownie uwzględniać
|
||||
jakieś parametry wyuczalne z całą siecią?
|
||||
|
||||
** Modelowanie języka przy użyciu bardziej złożonych neuronowych sieci /feed-forward/
|
||||
|
||||
Można połączyć zalety obu ogólnych podejść (n-gramowego modelu i worka
|
||||
słów) — można *równocześnie* traktować w specjalny sposób (na
|
||||
przykład) dwa poprzedzające wyrazy, wszystkie zaś inne wyrazy
|
||||
reprezentować jako „tło” modelowane za pomocą worka słów lub podobnej
|
||||
reprezentacji. Osiągamy to poprzez konkatenację wektora
|
||||
poprzedzającego słowa, słowa występującego dwie pozycje wstecz oraz
|
||||
zagregowanego zanurzenia całego wcześniejszego tekstu:
|
||||
|
||||
$$y = \operatorname{softmax}(C[E(w_{i-1}),E(w_{i-2}),A(w_1,\dots,w_{i-3})]),$$
|
||||
|
||||
czy lepiej z dodatkową warstwą ukrytą:
|
||||
|
||||
$$y = \operatorname{softmax}(C\operatorname{tgh}(W[E(w_{i-1}),E(w_{i-2}),A(w_1,\dots,w_{i-3})])),$$
|
||||
|
||||
W tak uzyskanym dwuwarstwowym neuronowym modelu języka, łączącym model
|
||||
trigramowy z workiem słów, macierz $W$ ma rozmiar $h \times 3m$.
|
||||
|
||||
*Pytanie*: jakie mamy możliwości, jeśli zamiast przewidywać kolejne słowo, mamy za zadanie
|
||||
odgadywać słowo w luce (jak w wyzwaniach typu /word gap/)?
|
||||
|
||||
** Literatura
|
||||
|
||||
Skuteczny n-gramowy neuronowy model języka opisano po raz pierwszy
|
||||
w pracy [[https://www.jmlr.org/papers/volume3/bengio03a/bengio03a.pdf][A Neural Probabilistic Language Model]] autorstwa Yoshua Bengio i in.
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
Loading…
Reference in New Issue
Block a user