743 lines
38 KiB
Plaintext
743 lines
38 KiB
Plaintext
{
|
|
"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> 8. <i>Neuronowy model języka</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": [
|
|
"## Neuronowy n-gramowy model języka\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Omówiony w poprzedniej części neuronowy bigramowy model języka\n",
|
|
"warunkuje kolejny wyraz jedynie względem bezpośrednio poprzedzającego\n",
|
|
"— jak w każdym bigramowym modelu przyjmujemy założenie, że $w_i$\n",
|
|
"zależy tylko od $w_{i-1}$. Rzecz jasna jest to bardzo duże\n",
|
|
"ograniczenie, w rzeczywistości bardzo często prawdopodobieństwo\n",
|
|
"kolejnego wyrazu zależy od wyrazu dwie, trzy, cztery itd. pozycje\n",
|
|
"wstecz czy w ogólności od wszystkich wyrazów poprzedzających (bez\n",
|
|
"względu na ich pozycje).\n",
|
|
"\n",
|
|
"**Pytanie**: Wskaż zależności o zasięgu większym niż 1 wyraz w zdaniu\n",
|
|
"/Zatopieni w kłębach dymu cygar i pochyleni nad butelkami z ciemnego\n",
|
|
"szkła obywatele tej dzielnicy, jedni zakładali się o wygranę lub\n",
|
|
"przegranę Anglii, drudzy o bankructwo Wokulskiego; jedni nazywali\n",
|
|
"geniuszem Bismarcka, drudzy — awanturnikiem Wokulskiego; jedni\n",
|
|
"krytykowali postępowanie prezydenta MacMahona, inni twierdzili, że\n",
|
|
"Wokulski jest zdecydowanym wariatem, jeżeli nie czymś gorszym…/\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Trigramowy neuronowy model języka\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Spróbujmy najpierw rozszerzyć nasz model na trigramy, to znaczy\n",
|
|
"będziemy przewidywać słowo $w_i$ na podstawie słów $w_{i-2}$ i\n",
|
|
"$w_{i-1}$.\n",
|
|
"\n",
|
|
"Najprostsze rozwiązanie polegałoby na zanurzeniu pary $(w_{i-2},\n",
|
|
"w_{i-1})$ w całości i postępowaniu jak w przypadku modelu bigramowego.\n",
|
|
"Byłoby to jednak zupełnie niepraktyczne, jako że:\n",
|
|
"\n",
|
|
"- liczba zanurzeń do wyuczenia byłaby olbrzymia ($|V|^2$ — byłoby to\n",
|
|
" ewentualnie akceptowalne dla modeli operujących na krótszych\n",
|
|
" jednostkach niż słowa, np. na znakach),\n",
|
|
"- w szczególności zanurzenia dla par $(v, u)$, $(u, v)$, $(u, u)$ i\n",
|
|
" $(v, v)$ nie miałyby ze sobą nic wspólnego.\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### Konketanacja zanurzeń\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Właściwsze rozwiązanie polega na zanurzeniu dalej pojedynczych słów i\n",
|
|
"następnie ich **konkatenowaniu**.\n",
|
|
"\n",
|
|
"Przypomnijmy, że konkatenacja wektorów $\\vec{x_1}$ i $\\vec{x_2}$ to wektor o rozmiarze\n",
|
|
"$|\\vec{x_1}| + |\\vec{x_2}|$ powstały ze „sklejania” wektorów $\\vec{x_1}$ i $\\vec{x_2}$.\n",
|
|
"Konkatenację wektorów $\\vec{x_1}$ i $\\vec{x_2}$ będziemy oznaczać za pomocą $[\\vec{x_1}, \\vec{x_2}]$.\n",
|
|
"\n",
|
|
"Przykład: jeśli $\\vec{x_1} = [-1, 2, 0]$ i $\\vec{x_2} = [3, -3]$,\n",
|
|
"wówczas $[\\vec{x_1}, \\vec{x_2}] = [-1, 2, 0, 3, -3]$\n",
|
|
"\n",
|
|
"Oznacza to, że nasza macierz „kontekstowa” $C$ powinna mieć w modelu trigramowym rozmiar nie\n",
|
|
"$|V| \\times m$, lecz $|V| \\times (m+m)$ = $|V| \\times 2m$ i wyjście będzie zdefiniowane za pomocą wzoru:\n",
|
|
"\n",
|
|
"$$\\vec{y} = \\operatorname{softmax}(C[E(w_{i-2}),E(w_{i-1})]),$$\n",
|
|
"\n",
|
|
"co można przedstawić za pomocą następującego schematu:\n",
|
|
"\n",
|
|
"![img](./08_Neuronowy_ngramowy_model/trigram1.drawio.png \"Diagram prostego bigramowego neuronowego modelu języka\")\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"##### Rozbicie macierzy $C$\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Zamiast mnożyć macierz $C$ przez konkatenację dwóch wektorów, można\n",
|
|
"rozbić macierz $C$ na dwie, powiedzmy $C_{-2}$ i $C_{-1}$, przemnażać\n",
|
|
"je osobno przez odpowiadające im wektory i następnie **dodać** macierze,\n",
|
|
"tak aby:\n",
|
|
"\n",
|
|
"$$C[E(w_{i-2}),E(w_{i-1})] = C_{-2}E(w_{i-2}) + C_{-1}E(w_{i-1}).$$\n",
|
|
"\n",
|
|
"Macierze $C_{-2}$ i $C_{-1}$ będą miały rozmiar $|V| \\times m$.\n",
|
|
"\n",
|
|
"Przy tym podejściu możemy powiedzieć, że ostatni i przedostatni wyraz\n",
|
|
"mają swoje osobne macierze o potencjalnie różnych wagach — co ma sens,\n",
|
|
"jako że na inne aspekty zwracamy uwagę przewidując kolejne słowo na\n",
|
|
"podstawie wyrazu bezpośrednio poprzedzającego, a na inne — na\n",
|
|
"podstawie słowa występującego dwie pozycje wcześniej.\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Uogólnienie na $n$-gramowy model języka dla dowolnego $n$\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Łatwo uogólnić opisany wyżej trigramowy model języka dla dowolnego $n$.\n",
|
|
"Uogólniony model można przedstawić za pomocą wzoru:\n",
|
|
"\n",
|
|
"$$\\vec{y} = \\operatorname{softmax}(C[E(w_{i-n+1}),\\dots,E(w_{i-1})]),$$\n",
|
|
"\n",
|
|
"gdzie macierz $C$ ma rozmiar $|V| \\times nm$ lub za pomocą wzoru:\n",
|
|
"\n",
|
|
"$$\\vec{y} = \\operatorname{softmax}(C_{-(n-1)}E(w_{i-n+1}) + \\dots + C_{-1}E(w_{i-1}),$$\n",
|
|
"\n",
|
|
"gdzie macierze $C_{-(n-1)}$, …, $C_{-1}$ mają rozmiary $|V| \\times m$.\n",
|
|
"\n",
|
|
"Por. diagram:\n",
|
|
"\n",
|
|
"![img](./08_Neuronowy_ngramowy_model/ngram.drawio.png \"Diagram prostego n-gramowego neuronowego modelu języka\")\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Dodanie kolejnej warstwy\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"W wypadku trigramowego czy — ogólniej — n-gramowego modelu języka dla\n",
|
|
"$n \\geq 3$ warto dodać kolejną (**ukrytą**) warstwę, na którą będziemy rzutować\n",
|
|
"skonkatenowane embeddingi, zanim zrzutujemy je do długiego wektora\n",
|
|
"prawdopodobieństw.\n",
|
|
"\n",
|
|
"Zakładamy, że warstwa ukryta zawiera $h$ neuronów. Wartość $h$ powinna być mniejsza\n",
|
|
"niż $nm$ (a może nawet od $m$).\n",
|
|
"\n",
|
|
"**Pytanie**: Dlaczego wartość $h > nm$ nie jest racjonalnym wyborem?\n",
|
|
"\n",
|
|
"**Pytanie**: Dlaczego dodanie kolejnej warstwy nie ma sensu dla modelu bigramowego?\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### Funkcja aktywacji\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Aby warstwa ukryta wnosiła coś nowego, na wyjściu z tej funkcji musimy (dlaczego?)\n",
|
|
"zastosować nieliniową **funkcji aktywacji**. Zazwyczaj jako funkcji\n",
|
|
"aktywacji w sieciach neuronowych używa się funkcji ReLU albo funkcji\n",
|
|
"sigmoidalnej. W prostych neuronowych modelach języka sprawdza się też\n",
|
|
"**tangens hiperboliczny** (tgh, w literaturze anglojęzycznej tanh):\n",
|
|
"\n",
|
|
"$$\\operatorname{tgh}(x) = \\frac{e^x - e^{-x}}{e^x + e^{-x}}.$$\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "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",
|
|
"text/plain": [
|
|
"<matplotlib.figure.Figure>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"import matplotlib.pyplot as plt\n",
|
|
"import torch\n",
|
|
"import torch.nn as nn\n",
|
|
"\n",
|
|
"x = torch.linspace(-5,5,100)\n",
|
|
"plt.xlabel(\"x\")\n",
|
|
"plt.ylabel(\"y\")\n",
|
|
"a = torch.Tensor(x.size()[0]).fill_(2.)\n",
|
|
"m = torch.stack([x, a])\n",
|
|
"plt.plot(x, nn.functional.tanh(m)[0])\n",
|
|
"fname = '08_Neuronowy_ngramowy_model/tanh.png'\n",
|
|
"plt.savefig(fname)\n",
|
|
"fname"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"##### Tangens hiperboliczny zastosowany dla wektora\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Tangens hiperboliczny wektora będzie po prostu wektorem tangensów\n",
|
|
"hiperbolicznych poszczególnych wartości.\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import torch\n",
|
|
"import torch.nn as nn\n",
|
|
"\n",
|
|
"v = torch.Tensor([-100, -2.0, 0.0, 0.5, 1000.0])\n",
|
|
"nn.functional.tanh(v)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"[[[tensor](tensor)([-1.0000, -0.9640, 0.0000, 0.4621, 1.0000])]]\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### Wzór i schemat dwuwarstwowego n-gramowego neuronowego modelu języka\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Dwuwarstwowy model języka będzie określony następującym wzorem:\n",
|
|
"\n",
|
|
"$$\\vec{y} = \\operatorname{softmax}(C\\operatorname{tgh}(W[E(w_{i-n+1}),\\dots,E(w_{i-1})])),$$\n",
|
|
"\n",
|
|
"gdzie:\n",
|
|
"\n",
|
|
"- $W$ jest wyuczalną macierzą wag o rozmiarze $h \\times nm$,\n",
|
|
"- $C$ będzie macierzą o rozmiarze $|V| \\times h$.\n",
|
|
"\n",
|
|
"Zmodyfikowaną sieć można przedstawić za pomocą następującego schematu:\n",
|
|
"\n",
|
|
"![img](./08_Neuronowy_ngramowy_model/ngram-tgh.drawio.png \"Dwuwarstwowy n-gramowy neuronowy model języka\")\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### Liczba wag w modelu dwuwarstwowym\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Na wagi w modelu dwuwarstwowym składają się:\n",
|
|
"\n",
|
|
"- zanurzenia: $m|V|$,\n",
|
|
"- wagi warstwy ukrytej: $hnm$,\n",
|
|
"- wagi warstwy wyjściowej: $|V|h$,\n",
|
|
"\n",
|
|
"a zatem łącznie:\n",
|
|
"\n",
|
|
"$$m|V| + hnm + |V|h$$\n",
|
|
"\n",
|
|
"Jeśli $h \\approx m$ (co jest realistyczną opcją), wówczas otrzymamy oszacowanie:\n",
|
|
"\n",
|
|
"$$O(m|V| + nm^2).$$\n",
|
|
"\n",
|
|
"Zauważmy, że względem $n$ oznacza to bardzo korzystną złożoność\n",
|
|
"$O(n)$! Oznacza to, że nasz model może działać dla dużo większych\n",
|
|
"wartości $n$ niż tradycyjny, statystyczny n-gramowy model języka (dla którego\n",
|
|
"wartości $n > 5$ zazwyczaj nie mają sensu).\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Model worka słów\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Jak stwierdziliśmy przed chwilą, 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](./08_Neuronowy_ngramowy_model/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](./08_Neuronowy_ngramowy_model/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.2"
|
|
},
|
|
"org": null
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 1
|
|
}
|