diff --git a/wyk/08_Neuronowy_ngramowy_model.ipynb b/wyk/08_Neuronowy_ngramowy_model.ipynb
new file mode 100644
index 0000000..607c5bc
--- /dev/null
+++ b/wyk/08_Neuronowy_ngramowy_model.ipynb
@@ -0,0 +1,19 @@
+
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n",
+ "
\n",
+ "
Modelowanie języka
\n",
+ " 8. Neuronowy model języka [wykład]
\n",
+ " Filip Graliński (2022)
\n",
+ "\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\nwarunkuje kolejny wyraz jedynie względem bezpośrednio poprzedzającego\n— jak w każdym bigramowym modelu przyjmujemy założenie, że $w_i$\nzależy tylko od $w_{i-1}$. Rzecz jasna jest to bardzo duże\nograniczenie, w rzeczywistości bardzo często prawdopodobieństwo\nkolejnego wyrazu zależy od wyrazu dwie, trzy, cztery itd. pozycje\nwstecz czy w ogólności od wszystkich wyrazów poprzedzających (bez\nwzglę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\nszkła obywatele tej dzielnicy, jedni zakładali się o wygranę lub\nprzegranę Anglii, drudzy o bankructwo Wokulskiego; jedni nazywali\ngeniuszem Bismarcka, drudzy — awanturnikiem Wokulskiego; jedni\nkrytykowali postępowanie prezydenta MacMahona, inni twierdzili, że\nWokulski 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\nbędziemy przewidywać słowo $w_i$ na podstawie słów $w_{i-2}$ i\n$w_{i-1}$.\n\nNajprostsze rozwiązanie polegałoby na zanurzeniu pary $(w_{i-2},\nw_{i-1})$ w całości i postępowaniu jak w przypadku modelu bigramowego.\nBył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\nnastępnie ich **konkatenowaniu**.\n\nPrzypomnijmy, ż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}$.\nKonkatenację wektorów $\\vec{x_1}$ i $\\vec{x_2}$ będziemy oznaczać za pomocą $[\\vec{x_1}, \\vec{x_2}]$.\n\nPrzykład: jeśli $\\vec{x_1} = [-1, 2, 0]$ i $\\vec{x_2} = [3, -3]$,\nwówczas $[\\vec{x_1}, \\vec{x_2}] = [-1, 2, 0, 3, -3]$\n\nOznacza 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\nco 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\nrozbić macierz $C$ na dwie, powiedzmy $C_{-2}$ i $C_{-1}$, przemnażać\nje osobno przez odpowiadające im wektory i następnie **dodać** macierze,\ntak 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\nMacierze $C_{-2}$ i $C_{-1}$ będą miały rozmiar $|V| \\times m$.\n\nPrzy tym podejściu możemy powiedzieć, że ostatni i przedostatni wyraz\nmają swoje osobne macierze o potencjalnie różnych wagach — co ma sens,\njako że na inne aspekty zwracamy uwagę przewidując kolejne słowo na\npodstawie wyrazu bezpośrednio poprzedzającego, a na inne — na\npodstawie 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$.\nUogó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\ngdzie 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\ngdzie macierze $C_{-(n-1)}$, …, $C_{-1}$ mają rozmiary $|V| \\times m$.\n\nPor. 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ć\nskonkatenowane embeddingi, zanim zrzutujemy je do długiego wektora\nprawdopodobieństw.\n\nZakładamy, że warstwa ukryta zawiera $h$ neuronów. Wartość $h$ powinna być mniejsza\nniż $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?)\nzastosować nieliniową **funkcji aktywacji**. Zazwyczaj jako funkcji\naktywacji w sieciach neuronowych używa się funkcji ReLU albo funkcji\nsigmoidalnej. 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":""},"metadata":{},"output_type":"display_data"}],"source":["import matplotlib.pyplot as plt\nimport torch\nimport torch.nn as nn\n\nx = torch.linspace(-5,5,100)\nplt.xlabel(\"x\")\nplt.ylabel(\"y\")\na = torch.Tensor(x.size()[0]).fill_(2.)\nm = torch.stack([x, a])\nplt.plot(x, nn.functional.tanh(m)[0])\nfname = '08_Neuronowy_ngramowy_model/tanh.png'\nplt.savefig(fname)\nfname"]},{"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\nhiperbolicznych poszczególnych wartości.\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[],"source":["import torch\nimport torch.nn as nn\n\nv = torch.Tensor([-100, -2.0, 0.0, 0.5, 1000.0])\nnn.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\ngdzie:\n\n- $W$ jest wyuczalną macierzą wag o rozmiarze $h \\times nm$,\n- $C$ będzie macierzą o rozmiarze $|V| \\times h$.\n\nZmodyfikowaną 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\na zatem łącznie:\n\n$$m|V| + hnm + |V|h$$\n\nJeśli $h \\approx m$ (co jest realistyczną opcją), wówczas otrzymamy oszacowanie:\n\n$$O(m|V| + nm^2).$$\n\nZauważ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\nwartości $n$ niż tradycyjny, statystyczny n-gramowy model języka (dla którego\nwartoś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\nmoże działać dla stosunkowo dużego $n$. Zauważmy jednak, że istnieje\npewna słabość tego modelu. Otóż o ile intuicyjnie ma sens odróżniać\nsłowo poprzedzające, słowo występujące dwie pozycje wstecz i zapewne\ntrzy pozycje wstecz, a zatem uczyć się osobnych macierzy $C_{-1}$,\n$C_{-2}$, $C_{-3}$ to różnica między wpływem słowa\nwystępującego cztery pozycje wstecz i pięć pozycji wstecz jest już\nraczej 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\nsię dwukrotnie podobnych wag. Im dalej wstecz, tym różnica wpływu\nbędzie jeszcze mniej istotna, można np. przypuszczać, że różnica\nmiędzy $C_{-10}$ i $C_{-13}$ nie powinna być duża.\n\nSpróbujmy najpierw zaproponować radykalne podejście, w którym nie\nbędziemy w ogóle uwzględniać pozycji słów (lub będziemy je uwzględniać\nw niewielkim stopniu), później połączymy to z omówionym wcześniej\nmodelem $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\npodstawie **całego** ciągu słów poprzedzających odgadywane słowo. Zauważmy jednak, że\nsieć neuronowa musi mieć ustaloną strukturę, nie możemy zmieniać jej\nrozmiaru. 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\nprostu 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\nJeśli rozmiar zanurzenia (embeddingu) wynosi $m$, wówczas rozmiar\nwektora uzyskanego dla całego poprzedzającego tekstu wynosi również $m$.\n\nProste dodawanie wydaje się bardzo „prostacką” metodą, a jednak\nsuma 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\nTak 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ą\nprzemieszane, 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\nmodelu bigramowym — rzutujemy embedding na długi wektor wartości, na\nktórym stosujemy funkcję softmax:\n\n![img](./08_Neuronowy_ngramowy_model/bow1.drawio.png \"Model typu worek słów\")\n\nOdpowiada 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\npojawia się więcej niż raz, jego embedding zostanie zsumowany odpowiednią liczbę razy.\nNa 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\nInnymi 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\ntraktujemy poprzedzający tekst jako **multizbiór** (struktura\nmatematyczna, w której nie uwzględnia się kolejności, choć zachowana\njest 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\nsię 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\nJest kwestią dyskusyjną, czy to lepsze czy gorsze podejście — w końcu\nliczba wystąpień np. słów *Ukraina* czy *Polska* może wpływać w jakimś\nstopniu 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\nsumować 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\ngdzie $\\#w$ to liczba wystąpień słowa $w$ w ciagu $w_1,\\dots,w_{i-1}$ (w wielu przypadkach równa zero!).\n\nJeśli teraz zanurzenia będziemy reprezentować jako macierz $E$ (por. poprzedni wykład),\nwó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\nZwróćmy uwagę, że wektor $[\\#w_1,\\dots,\\#w_{|V|}]$ to po prostu\nreprezentacja wektora poprzedzającego tekstu (tj. ciągu\n$(w_1,\\dots,w_{i-1})$) przy użyciu schematu wektoryzacji tf (*term\nfrequency*). Przypomnijmy, że tf to reprezentacja tekstu przy użyciu\nwektorów o rozmiarze $|V|$ — na każdej pozycji odnotowujemy liczbę wystąpień.\nWektory tf są **rzadkie**, tj. na wielu pozycjach zawierają zera.\n\nInnymi 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\nco 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\nMożna stwierdzić, że zanurzenie tekstu przekształca rzadki, długi wektor\ntf 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\nZamiast 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\ngdzie $\\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\nuwzględnienie pozycji słowa, np. w taki sposób:\n\n$$\\omega(j, w_j) = \\beta^{i-j-1},$$\n\ndla pewnego hiperparametru $\\beta$. Na przykład jeśli $\\beta=0,9$,\nwówczas słowo bezpośrednio poprzedzające dane słowo ma $1 / 0,9^9 \\approx 2,58$\nwię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\ndokumentów, możemy użyć, znanej z wyszukiwania informacji,\nodwrotnej 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\ngdzie:\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\nRzecz jasna, ten sposób ważenia oznacza tak naprawdę zastosowanie wektoryzacji tf-idf zamiast tf,\nnasza 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\nwagami (parametrami) naszej sieci neuronowej, terminologia może być\ntutaj myląca. Z punktu widzenia sieci neuronowej $\\omega(j, w_j)$ są\nstałe i **nie** są optymalizowane w procesie propagacji wstecznej. Innymi\nsł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ć\njakieś 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\nsłów) — można **równocześnie** traktować w specjalny sposób (na\nprzykład) dwa poprzedzające wyrazy, wszystkie zaś inne wyrazy\nreprezentować jako „tło” modelowane za pomocą worka słów lub podobnej\nreprezentacji. Osiągamy to poprzez konkatenację wektora\npoprzedzającego słowa, słowa występującego dwie pozycje wstecz oraz\nzagregowanego 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\nczy 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\nW tak uzyskanym dwuwarstwowym neuronowym modelu języka, łączącym model\ntrigramowy 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\nodgadywać 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\nw pracy [A Neural Probabilistic Language Model](https://www.jmlr.org/papers/volume3/bengio03a/bengio03a.pdf) autorstwa Yoshua Bengio i in.\n\n"]}],"metadata":{"org":null,"kernelspec":{"display_name":"Python 3","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.5.2"}},"nbformat":4,"nbformat_minor":0}
\ No newline at end of file