forked from filipg/aitech-eks-pub
Merge branch 'master' of git.wmi.amu.edu.pl:filipg/aitech-eks
This commit is contained in:
commit
9d96c9ec4f
@ -375,13 +375,13 @@ Definicja w PyTorchu:
|
||||
z_plus = torch.exp(z)
|
||||
return z_plus / torch.sum(z_plus)
|
||||
|
||||
softmax(torch.tensor([3., -1., 0., 5.]))
|
||||
softmax(torch.tensor([3., 1., -1., 1.]))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
# Out[75]:
|
||||
: tensor([0.1182, 0.0022, 0.0059, 0.8737])
|
||||
# Out[3]:
|
||||
: tensor([7.8678e-01, 1.0648e-01, 2.6393e-04, 1.0648e-01])
|
||||
:end:
|
||||
|
||||
#+CAPTION: Softmax
|
||||
|
523
wyk/11_rnn.ipynb
523
wyk/11_rnn.ipynb
File diff suppressed because one or more lines are too long
@ -181,7 +181,7 @@ selektywnie wygaszać pozycje wektora, np. tutaj wyzerowaliśmy 2. i 5. pozycję
|
||||
|
||||
Co więcej, za pomocą bramki możemy selektywnie kontrolować, co
|
||||
zapamiętujemy, a co zapominamy. Rozpatrzmy mianowicie wektor zer i
|
||||
jedynek $\vec{g} \in \{0,1}^m$, dla stanu (pamięci) $\vec{s}$ i nowej informacji
|
||||
jedynek $\vec{g} \in \{0,1\}^m$, dla stanu (pamięci) $\vec{s}$ i nowej informacji
|
||||
$\vec{x}$ możemy dokonywać aktualizacji w następujący sposób:
|
||||
|
||||
$$\vec{s} \leftarrow \vec{g} \odot \vec{x} + (1 - \vec{g}) \odot \vec{s}$$
|
||||
@ -259,7 +259,7 @@ $$\vec{i} = \sigma(W_i\langle\vec{v}(t^k),\vec{h^{k-1}}\rangle)$$
|
||||
|
||||
$$\vec{f} = \sigma(W_f\langle\vec{v}(t^k),\vec{h^{k-1}}\rangle)$$
|
||||
|
||||
$$\vec{o} = \sigma(W_f\langle\vec{v}(t^k),\vec{h^{k-1}}\rangle)$$
|
||||
$$\vec{o} = \sigma(W_o\langle\vec{v}(t^k),\vec{h^{k-1}}\rangle)$$
|
||||
|
||||
Jak widać, wzory różnią się tylko macierzami wag $W_*$.
|
||||
|
||||
@ -279,10 +279,10 @@ Ostateczne wyjście może być wyliczane na podstawie wektora $\vec{h^k}$:
|
||||
|
||||
$$O(\vec{s}) = O(\langle\vec{c},\vec{h}\rangle) = \vec{h}$$
|
||||
|
||||
*Pytanie*: Ile wag/parametrów ma sieć RNN o rozmiarze wejścia $n$ i
|
||||
*Pytanie*: Ile wag/parametrów ma sieć RNN o rozmiarze wejścia $n$ i rozmiarze warstwy ukrytej $m$?
|
||||
|
||||
|
||||
** Literatura
|
||||
|
||||
Yoav Goldberg, /Neural Network Methods for Natural Language
|
||||
Processing/, Morgan & Claypool Publishers, 2017
|
||||
Yoav Goldberg, /Neural Network Methods for Natural Language Processing/,
|
||||
Morgan & Claypool Publishers, 2017
|
||||
|
839
wyk/12_bpe.ipynb
Normal file
839
wyk/12_bpe.ipynb
Normal file
File diff suppressed because one or more lines are too long
@ -36,7 +36,7 @@ Ile jest różnych form fleksyjnych w języku polskim? Zobaczmy w słowniku Poli
|
||||
|
||||
Tak naprawdę form jest jeszcze więcej, oczywiście PoliMorf nie wyczerpuje zbioru…
|
||||
|
||||
*Pytanie* Podaj przykłady „oczywistych” wyrazów, których w PoliMorfie. Jak w sposób systematyczny szukać takich wyrazów?
|
||||
*Pytanie* Podaj przykłady „oczywistych” wyrazów, których nie ma w PoliMorfie. Jak w sposób systematyczny szukać takich wyrazów?
|
||||
|
||||
Z drugiej strony, w PoliMorfie jest dużo dziwnych, „sztucznych” wyrazów.
|
||||
|
||||
@ -88,7 +88,7 @@ nie pokryje on sporej części tekstów przetwarzanych w czasie inferencji.
|
||||
Zobaczmy, ilu wyrazów ze zbioru deweloperskiego nie będzie w słowniku.
|
||||
|
||||
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||
! cat petite-difference-challenge2/dev-0/in.tsv.xz | perl -C -ne 'print "$&\n" while/\p{L}+/g;' | sort -u | comm vocab.txt - -13 | wc -l
|
||||
! cat petite-difference-challenge2/dev-0/in.tsv | perl -C -ne 'print "$&\n" while/\p{L}+/g;' | sort -u | comm vocab.txt - -13 | wc -l
|
||||
#+END_SRC
|
||||
|
||||
Takie wyrazy nazywamy wyrazami *OOV* (/out-of-vocabulary/).
|
||||
@ -112,7 +112,7 @@ Daje to lepszy efekt niż można się spodziewać. Odrzucamy w ten sposób
|
||||
tylko bardzo rzadkie słowa (albo takie, które wystąpiły tylko raz w
|
||||
korpusie — tzw. /hapax legomena/), choć tych słów jest bardzo dużo.
|
||||
|
||||
*Zagadka*: 50000 najczęstszych słów (1,9\% *typów*) pokrywa jaki odsetek *wystąpień*?
|
||||
*Zagadka*: 50000 najczęstszych słów (1,9% *typów*) pokrywa jaki odsetek *wystąpień*?
|
||||
|
||||
Rozkład normalny w języku nie jest… normalny — nie spotkamy się z nim
|
||||
badając języki. W tekstach dominują „skrzywione” rozkłady z długimi,
|
||||
@ -244,7 +244,7 @@ momentu traktujemy go jako całostkę (wkładamy go do „pudełka”).
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
# Out[4]:
|
||||
# Out[1]:
|
||||
: ['e$', 'to', 'to$', 'be$', 't$', 'th', 'or', 'or$', 'no', 'not$']
|
||||
:end:
|
||||
|
||||
@ -256,11 +256,15 @@ na którym słownik był wyuczony:
|
||||
d = list(d.replace(' ', '$') + '$')
|
||||
vocab_set = set(vocab)
|
||||
|
||||
modified = True
|
||||
while modified:
|
||||
ix = 0
|
||||
modified = False
|
||||
while ix < len(d) - 1:
|
||||
bigram = d[ix] + d[ix+1]
|
||||
if bigram in vocab_set:
|
||||
d[ix:ix+2] = [bigram]
|
||||
modified = True
|
||||
else:
|
||||
ix += 1
|
||||
|
||||
@ -289,6 +293,12 @@ Słownik jednostek podwyrazowych można stosować dla dowolnego tekstu:
|
||||
' '.join(apply_bpe_vocab(vocab1, 'tom will be the best'))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
# Out[6]:
|
||||
: 'to m $ w i l l $ be$ th e$ b e s t$'
|
||||
:end:
|
||||
|
||||
Jak można zauważyć algorytm BPE daje dwa rodzaje jednostek podwyrazowych:
|
||||
|
||||
- jednostki, które mogą doklejane na początku wyrazu;
|
||||
|
113
wyk/13_generative_approach.ipynb
Normal file
113
wyk/13_generative_approach.ipynb
Normal file
@ -0,0 +1,113 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Ekstrakcja informacji a podejście generatywne\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Podejście generatywne\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Do tej pory zadanie ekstrakcji informacji traktowaliśmy jako zadanie etykietowania sekwencji, tzn. uczyliśmy system zaznaczać tokeny składające się na ekstrahowane informacje.\n",
|
||||
"\n",
|
||||
"![img](./ie-seqlab.png)\n",
|
||||
"\n",
|
||||
"Możliwe jest inne podeście, **generatywne**, w którym podchodzimy do problemu ekstrakcji informacji jak do swego rodzaju **tłumaczenia maszynowego** — „tłumaczymy” tekst (wraz z pytaniem lub etykietą) na informację.\n",
|
||||
"\n",
|
||||
"![img](./ie-gener.png)\n",
|
||||
"\n",
|
||||
"To podejście może się wydawać trudniejsze niż etykietowanie sekwencji, ale wystarczająco zaawansowanej architekturze sieci, jest wykonalne.\n",
|
||||
"\n",
|
||||
"Zalety:\n",
|
||||
"\n",
|
||||
"- informacja nie musi być dosłownie zapisana w tekście, ekstraktor może nauczyć się również normalizacji czy parafrazowania,\n",
|
||||
"- nie wprowadzamy wielu kroków przetwarzania (gdzie błędy mogą się\n",
|
||||
" namnażać), system działa na zasadzie *end-to-end*.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Atencja\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Pierwsze systemu neuronowego tłumaczenia maszynowego używały siecie LSTM. Dopiero jednak dodanie tzw. atencji (*attention*) umożliwiło duży przeskok jakościowy. Najpierw atencję dodano do sieci rekurencyjnych, później powstały sieci oparte *wyłącznie* na atencji — modele Transformer.\n",
|
||||
"\n",
|
||||
"Idea atencji polega na tym, że sieć może kierować selektywnie „snop” uwagi na wyrazy na wejściu lub do tej pory wygenerowane wyrazy.\n",
|
||||
"\n",
|
||||
"Mechanizm atencji korzysta z:\n",
|
||||
"\n",
|
||||
"- z poprzedniego stanu sieci $\\vec{s^{k-1}}$ (to jest „miejsce”, z którego „kierujemy” atencję),\n",
|
||||
"- z wektora reprezentującego słowo $\\vec{v}(t_i)$ (to jest „miejsce”, na które kierujemy atencję), gdzie\n",
|
||||
" $\\vec{v}(t_i)$ to reprezentacja wektorowa wyrazu $t_i$ (statyczny embedding lub reprezentacja wektorowa\n",
|
||||
" z poprzedniej warstwy dla sieci wielowarstwowej),\n",
|
||||
"\n",
|
||||
"aby wytworzyć wektor kontekstu $\\vec{\\xi^k}$ (który z kolei będzie w jakiś sposób wnosił wkład do wyliczenia nowej wartości stanu $\\vec{s^k}$ lub wyjścia $y^k$.\n",
|
||||
"\n",
|
||||
"Najpierw wyliczymy skalarne wartości atencji, tzn. liczby, które będą sygnalizowały, jak bardzo wektor $\\vec{v}(t_i)$ „pasuje” do $\\vec{s^{k-1}}$, w najprostszej wersji można po prostu skorzystać z iloczynu skalarnego (o ile $n=m$),\n",
|
||||
"\n",
|
||||
"$$a(\\vec{s^{k-1}}, \\vec{v}(t_i)) = \\vec{s^{k-1}}\\vec{v}(t_i).$$\n",
|
||||
"\n",
|
||||
"**Pytanie**: co jeśli $n$ nie jest równe $m$, tzn. rozmiar embeddingu nie jest równy rozmiarowi wektora stanu?\n",
|
||||
"\n",
|
||||
"W przypadku sieci LSTM korzysta się częściej z bardziej skomplikowanego wzoru zawierającego dodatkowe wyuczalne wagi:\n",
|
||||
"\n",
|
||||
"$$a(\\vec{s^{k-1}}, \\vec{v}(t_i)) = \\vec{w_a}\\operatorname{tanh}(W_a\\vec{s^{k-1}} + U_a\\vec{v}(t_i))$$\n",
|
||||
"\n",
|
||||
"**Pytanie**: jakie rozmiary mają macierze $W_a$, $U_a$ i wektor $w_a$?\n",
|
||||
"\n",
|
||||
"Powtórzmy, że wartości $a$ są wartościami skalarnymi, natomiast nie są one znormalizowane (nie sumują się do jedynki), normalizujemy je używając schematu podobnego do softmaxa:\n",
|
||||
"\n",
|
||||
"$$\\alpha_{i} = \\frac{e^{a(\\vec{s^{k-1}}, \\vec{v}(t_i))}}{\\sum_j e^{a(\\vec{s^{k-1}}, \\vec{v}(t_j))}}$$\n",
|
||||
"\n",
|
||||
"Wektor kontekstu $\\vec{\\xi^k}$ będzie po prostu średnią ważoną wektorowych reprezentacji słów:\n",
|
||||
"\n",
|
||||
"$$\\vec{\\xi^k} = \\sum_i \\alpha_i\\vec{v}(t_i)$$\n",
|
||||
"\n",
|
||||
"**Pytanie**: zasadniczo atencja jest środkiem do celu (żeby sieć się sprawniej uczyła), czy można atencja sama w sobie może być do czegoś przydatna?\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"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.9.2"
|
||||
},
|
||||
"org": null
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 1
|
||||
}
|
55
wyk/13_generative_approach.org
Normal file
55
wyk/13_generative_approach.org
Normal file
@ -0,0 +1,55 @@
|
||||
* Ekstrakcja informacji a podejście generatywne
|
||||
** Podejście generatywne
|
||||
|
||||
Do tej pory zadanie ekstrakcji informacji traktowaliśmy jako zadanie etykietowania sekwencji, tzn. uczyliśmy system zaznaczać tokeny składające się na ekstrahowane informacje.
|
||||
|
||||
[[./ie-seqlab.png]]
|
||||
|
||||
Możliwe jest inne podeście, *generatywne*, w którym podchodzimy do problemu ekstrakcji informacji jak do swego rodzaju *tłumaczenia maszynowego* — „tłumaczymy” tekst (wraz z pytaniem lub etykietą) na informację.
|
||||
|
||||
[[./ie-gener.png]]
|
||||
|
||||
To podejście może się wydawać trudniejsze niż etykietowanie sekwencji, ale wystarczająco zaawansowanej architekturze sieci, jest wykonalne.
|
||||
|
||||
Zalety:
|
||||
|
||||
- informacja nie musi być dosłownie zapisana w tekście, ekstraktor może nauczyć się również normalizacji czy parafrazowania,
|
||||
- nie wprowadzamy wielu kroków przetwarzania (gdzie błędy mogą się
|
||||
namnażać), system działa na zasadzie /end-to-end/.
|
||||
|
||||
** Atencja
|
||||
|
||||
Pierwsze systemu neuronowego tłumaczenia maszynowego używały siecie LSTM. Dopiero jednak dodanie tzw. atencji (/attention/) umożliwiło duży przeskok jakościowy. Najpierw atencję dodano do sieci rekurencyjnych, później powstały sieci oparte /wyłącznie/ na atencji — modele Transformer.
|
||||
|
||||
Idea atencji polega na tym, że sieć może kierować selektywnie „snop” uwagi na wyrazy na wejściu lub do tej pory wygenerowane wyrazy.
|
||||
|
||||
Mechanizm atencji korzysta z:
|
||||
|
||||
- z poprzedniego stanu sieci $\vec{s^{k-1}}$ (to jest „miejsce”, z którego „kierujemy” atencję),
|
||||
- z wektora reprezentującego słowo $\vec{v}(t_i)$ (to jest „miejsce”, na które kierujemy atencję), gdzie
|
||||
$\vec{v}(t_i)$ to reprezentacja wektorowa wyrazu $t_i$ (statyczny embedding lub reprezentacja wektorowa
|
||||
z poprzedniej warstwy dla sieci wielowarstwowej),
|
||||
|
||||
aby wytworzyć wektor kontekstu $\vec{\xi^k}$ (który z kolei będzie w jakiś sposób wnosił wkład do wyliczenia nowej wartości stanu $\vec{s^k}$ lub wyjścia $y^k$.
|
||||
|
||||
Najpierw wyliczymy skalarne wartości atencji, tzn. liczby, które będą sygnalizowały, jak bardzo wektor $\vec{v}(t_i)$ „pasuje” do $\vec{s^{k-1}}$, w najprostszej wersji można po prostu skorzystać z iloczynu skalarnego (o ile $n=m$),
|
||||
|
||||
$$a(\vec{s^{k-1}}, \vec{v}(t_i)) = \vec{s^{k-1}}\vec{v}(t_i).$$
|
||||
|
||||
*Pytanie*: co jeśli $n$ nie jest równe $m$, tzn. rozmiar embeddingu nie jest równy rozmiarowi wektora stanu?
|
||||
|
||||
W przypadku sieci LSTM korzysta się częściej z bardziej skomplikowanego wzoru zawierającego dodatkowe wyuczalne wagi:
|
||||
|
||||
$$a(\vec{s^{k-1}}, \vec{v}(t_i)) = \vec{w_a}\operatorname{tanh}(W_a\vec{s^{k-1}} + U_a\vec{v}(t_i))$$
|
||||
|
||||
*Pytanie*: jakie rozmiary mają macierze $W_a$, $U_a$ i wektor $w_a$?
|
||||
|
||||
Powtórzmy, że wartości $a$ są wartościami skalarnymi, natomiast nie są one znormalizowane (nie sumują się do jedynki), normalizujemy je używając schematu podobnego do softmaxa:
|
||||
|
||||
$$\alpha_{i} = \frac{e^{a(\vec{s^{k-1}}, \vec{v}(t_i))}}{\sum_j e^{a(\vec{s^{k-1}}, \vec{v}(t_j))}}$$
|
||||
|
||||
Wektor kontekstu $\vec{\xi^k}$ będzie po prostu średnią ważoną wektorowych reprezentacji słów:
|
||||
|
||||
$$\vec{\xi^k} = \sum_i \alpha_i\vec{v}(t_i)$$
|
||||
|
||||
*Pytanie*: zasadniczo atencja jest środkiem do celu (żeby sieć się sprawniej uczyła), czy można atencja sama w sobie może być do czegoś przydatna?
|
338
wyk/14_pretrenowanie.ipynb
Normal file
338
wyk/14_pretrenowanie.ipynb
Normal file
@ -0,0 +1,338 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Pretrenowanie modeli\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"System AlphaZero uczy się grając sam ze sobą — wystarczy 24 godziny,\n",
|
||||
"by system nauczył się grać w szachy lub go na nadludzkim poziomie.\n",
|
||||
"\n",
|
||||
"**Pytanie**: Dlaczego granie samemu ze sobą nie jest dobrym sposobem\n",
|
||||
" nauczenia się grania w szachy dla człowieka, a dla maszyny jest?\n",
|
||||
"\n",
|
||||
"Co jest odpowiednikiem grania samemu ze sobą w świecie przetwarzania tekstu?\n",
|
||||
"Tzn. **pretrenowanie** (*pretraining*) na dużym korpusie tekstu. (Tekst jest tani!)\n",
|
||||
"\n",
|
||||
"Jest kilka sposobów na pretrenowanie modelu, w każdym razie sprowadza\n",
|
||||
"się do odgadywania następnego bądź zamaskowanego słowa.\n",
|
||||
"W każdym razie zawsze stosujemy softmax (być może ze „sztuczkami” takimi jak\n",
|
||||
"negatywne próbkowanie albo hierarchiczny softamx) na pewnej **representecji kontekstowej**:\n",
|
||||
"\n",
|
||||
"$$\\vec{p} = \\operatorname{softmax}(f(\\vec{c})).$$\n",
|
||||
"\n",
|
||||
"Model jest karany używając funkcji log loss:\n",
|
||||
"\n",
|
||||
"$$-\\log(p_j),$$\n",
|
||||
"\n",
|
||||
"gdzie $w_j$ jest wyrazem, który pojawił się rzeczywiście w korpusie.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Przewidywanie słowa (GPT-2)\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Jeden ze sposobów pretrenowania modelu to po prostu przewidywanie\n",
|
||||
"następnego słowa.\n",
|
||||
"\n",
|
||||
"Zainstalujmy najpierw bibliotekę transformers.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"! pip install transformers"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"50257\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[('Ġon', 0.6786560416221619),\n",
|
||||
" ('Ġupon', 0.04339785501360893),\n",
|
||||
" ('Ġheavily', 0.02208443358540535),\n",
|
||||
" ('Ġin', 0.021049050614237785),\n",
|
||||
" (',', 0.020188499242067337),\n",
|
||||
" ('Ġa', 0.01833895780146122),\n",
|
||||
" ('Ġvery', 0.017935041338205338),\n",
|
||||
" ('Ġentirely', 0.017528969794511795),\n",
|
||||
" ('Ġlargely', 0.016769640147686005),\n",
|
||||
" ('Ġto', 0.01009418722242117),\n",
|
||||
" ('Ġgreatly', 0.010009866207838058),\n",
|
||||
" ('Ġnot', 0.009016563184559345),\n",
|
||||
" ('Ġmore', 0.005853226874023676),\n",
|
||||
" ('Ġprimarily', 0.005203146021813154),\n",
|
||||
" ('Ġstrongly', 0.0034501152113080025),\n",
|
||||
" ('Ġpartly', 0.0033184229396283627),\n",
|
||||
" ('Ġmuch', 0.0033095215912908316),\n",
|
||||
" ('Ġmostly', 0.0032150144688785076),\n",
|
||||
" ('Ġmainly', 0.0030899408739060163),\n",
|
||||
" ('Ġfor', 0.003034428460523486),\n",
|
||||
" ('.', 0.0028878094162791967),\n",
|
||||
" ('Ġboth', 0.0028405177872627974),\n",
|
||||
" ('Ġsomewhat', 0.0028194624464958906),\n",
|
||||
" ('Ġcru', 0.002263976726680994),\n",
|
||||
" ('Ġas', 0.00221616611815989),\n",
|
||||
" ('Ġof', 0.0022000609897077084),\n",
|
||||
" ('Ġalmost', 0.001968063646927476),\n",
|
||||
" ('Ġat', 0.0018015997484326363),\n",
|
||||
" ('Ġhighly', 0.0017461496172472835),\n",
|
||||
" ('Ġcompletely', 0.001692073536105454)]"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import torch\n",
|
||||
"from transformers import GPT2Tokenizer, GPT2LMHeadModel\n",
|
||||
"tokenizer = GPT2Tokenizer.from_pretrained('gpt2-large')\n",
|
||||
"model = GPT2LMHeadModel.from_pretrained('gpt2-large')\n",
|
||||
"text = \"This issue depends\"\n",
|
||||
"encoded_input = tokenizer(text, return_tensors='pt')\n",
|
||||
"output = model(**encoded_input)\n",
|
||||
"next_token_probs = torch.softmax(output[0][:, -1, :][0], dim=0)\n",
|
||||
"\n",
|
||||
"next_token_probs\n",
|
||||
"nb_of_tokens = next_token_probs.size()[0]\n",
|
||||
"print(nb_of_tokens)\n",
|
||||
"\n",
|
||||
"_, top_k_indices = torch.topk(next_token_probs, 30, sorted=True)\n",
|
||||
"\n",
|
||||
"words = tokenizer.convert_ids_to_tokens(top_k_indices)\n",
|
||||
"\n",
|
||||
"top_probs = []\n",
|
||||
"\n",
|
||||
"for ix in range(len(top_k_indices)):\n",
|
||||
" top_probs.append((words[ix], next_token_probs[top_k_indices[ix]].item()))\n",
|
||||
"\n",
|
||||
"top_probs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Zalety tego podejścia:\n",
|
||||
"\n",
|
||||
"- prostota,\n",
|
||||
"- dobra podstawa do strojenia systemów generowania tekstu zwłaszcza\n",
|
||||
" „otwartego” (systemy dialogowe, generowanie (fake) newsów, streszczanie tekstu),\n",
|
||||
" ale niekoniecznie tłumaczenia maszynowego,\n",
|
||||
"- zaskakująca skuteczność przy uczeniu *few-shot* i *zero-shot*.\n",
|
||||
"\n",
|
||||
"Wady:\n",
|
||||
"\n",
|
||||
"- asymetryczność, przetwarzanie tylko z lewej do prawej, preferencja\n",
|
||||
" dla lewego kontekstu,\n",
|
||||
"- mniejsza skuteczność przy dostrajaniu do zadań klasyfikacji i innych zadań\n",
|
||||
" niepolegających na prostym generowaniu.\n",
|
||||
"\n",
|
||||
"Przykłady modeli: GPT, GPT-2, GPT-3, DialoGPT.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Maskowanie słów (BERT)\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Inną metodą jest maskowanie słów (*Masked Language Modeling*, *MLM*).\n",
|
||||
"\n",
|
||||
"W tym podejściu losowe wybrane zastępujemy losowe słowa specjalnym\n",
|
||||
"tokenem (`[MASK]`) i każemy modelowi odgadywać w ten sposób\n",
|
||||
"zamaskowane słowa (z uwzględnieniem również prawego kontekstu!).\n",
|
||||
"\n",
|
||||
"Móciąc ściśle, w jednym z pierwszych modeli tego typu (BERT)\n",
|
||||
"zastosowano schemat, w którym również niezamaskowane słowa są odgadywane (!):\n",
|
||||
"\n",
|
||||
"- wybieramy losowe 15% wyrazów do odgadnięcia\n",
|
||||
"- 80% z nich zastępujemy tokenem `[MASK]`,\n",
|
||||
"- 10% zastępujemy innym losowym wyrazem,\n",
|
||||
"- 10% pozostawiamy bez zmian.\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"# Out[3]:"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from transformers import AutoModelWithLMHead, AutoTokenizer\n",
|
||||
"import torch\n",
|
||||
"\n",
|
||||
"tokenizer = AutoTokenizer.from_pretrained(\"xlm-roberta-large\")\n",
|
||||
"model = AutoModelWithLMHead.from_pretrained(\"xlm-roberta-large\")\n",
|
||||
"\n",
|
||||
"sequence = f'II wojna światowa zakończyła się w {tokenizer.mask_token} roku.'\n",
|
||||
"\n",
|
||||
"input_ids = tokenizer.encode(sequence, return_tensors=\"pt\")\n",
|
||||
"mask_token_index = torch.where(input_ids == tokenizer.mask_token_id)[1]\n",
|
||||
"\n",
|
||||
"token_logits = model(input_ids)[0]\n",
|
||||
"mask_token_logits = token_logits[0, mask_token_index, :]\n",
|
||||
"mask_token_logits = torch.softmax(mask_token_logits, dim=1)\n",
|
||||
"\n",
|
||||
"top_10 = torch.topk(mask_token_logits, 10, dim=1)\n",
|
||||
"top_10_tokens = zip(top_10.indices[0].tolist(), top_10.values[0].tolist())\n",
|
||||
"\n",
|
||||
"for token, score in top_10_tokens:\n",
|
||||
" print(sequence.replace(tokenizer.mask_token, tokenizer.decode([token])), f\"(score: {score})\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Przykłady: BERT, RoBERTa (również Polish RoBERTa).\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Podejście generatywne (koder-dekoder).\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"System ma wygenerować odpowiedź na różne pytania (również\n",
|
||||
"odpowiadające zadaniu MLM), np.:\n",
|
||||
"\n",
|
||||
"- \"translate English to German: That is good.\" => \"Das ist gut.\"\n",
|
||||
"- \"cola sentence: The course is jumping well.\" => \"not acceptable\"\n",
|
||||
"- \"summarize: state authorities dispatched emergency crews tuesday to survey the damage after an onslaught of severe weather in mississippi…\"\n",
|
||||
" => \"six people hospitalized after a storm in attala county\"\n",
|
||||
"- \"Thank you for <X> me to your party <Y> week.\" => <X> for inviting <Y> last <Z>\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from transformers import T5Tokenizer, T5Config, T5ForConditionalGeneration\n",
|
||||
"\n",
|
||||
"T5_PATH = 't5-base'\n",
|
||||
"\n",
|
||||
"t5_tokenizer = T5Tokenizer.from_pretrained(T5_PATH)\n",
|
||||
"t5_config = T5Config.from_pretrained(T5_PATH)\n",
|
||||
"t5_mlm = T5ForConditionalGeneration.from_pretrained(T5_PATH, config=t5_config)\n",
|
||||
"\n",
|
||||
"slot = '<extra_id_0>'\n",
|
||||
"\n",
|
||||
"text = f'Warsaw is the {slot} of Poland.'\n",
|
||||
"\n",
|
||||
"encoded = t5_tokenizer.encode_plus(text, add_special_tokens=True, return_tensors='pt')\n",
|
||||
"input_ids = encoded['input_ids']\n",
|
||||
"\n",
|
||||
"outputs = t5_mlm.generate(input_ids=input_ids,\n",
|
||||
" num_beams=200, num_return_sequences=5,\n",
|
||||
" max_length=5)\n",
|
||||
"\n",
|
||||
"_0_index = text.index(slot)\n",
|
||||
"_result_prefix = text[:_0_index]\n",
|
||||
"_result_suffix = text[_0_index+len(slot):]\n",
|
||||
"\n",
|
||||
"def _filter(output, end_token='<extra_id_1>'):\n",
|
||||
" _txt = t5_tokenizer.decode(output[2:], skip_special_tokens=False, clean_up_tokenization_spaces=False)\n",
|
||||
" if end_token in _txt:\n",
|
||||
" _end_token_index = _txt.index(end_token)\n",
|
||||
" return _result_prefix + _txt[:_end_token_index] + _result_suffix\n",
|
||||
" else:\n",
|
||||
" return _result_prefix + _txt + _result_suffix\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"results = [_filter(out) for out in outputs]\n",
|
||||
"results"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"(Zob. [https://arxiv.org/pdf/1910.10683.pdf](https://arxiv.org/pdf/1910.10683.pdf))\n",
|
||||
"\n",
|
||||
"Przykład: T5, mT5\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"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.9.2"
|
||||
},
|
||||
"org": null
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 1
|
||||
}
|
212
wyk/14_pretrenowanie.org
Normal file
212
wyk/14_pretrenowanie.org
Normal file
@ -0,0 +1,212 @@
|
||||
* Pretrenowanie modeli
|
||||
|
||||
System AlphaZero uczy się grając sam ze sobą — wystarczy 24 godziny,
|
||||
by system nauczył się grać w szachy lub go na nadludzkim poziomie.
|
||||
|
||||
*Pytanie*: Dlaczego granie samemu ze sobą nie jest dobrym sposobem
|
||||
nauczenia się grania w szachy dla człowieka, a dla maszyny jest?
|
||||
|
||||
Co jest odpowiednikiem grania samemu ze sobą w świecie przetwarzania tekstu?
|
||||
Tzn. *pretrenowanie* (/pretraining/) na dużym korpusie tekstu. (Tekst jest tani!)
|
||||
|
||||
Jest kilka sposobów na pretrenowanie modelu, w każdym razie sprowadza
|
||||
się do odgadywania następnego bądź zamaskowanego słowa.
|
||||
W każdym razie zawsze stosujemy softmax (być może ze „sztuczkami” takimi jak
|
||||
negatywne próbkowanie albo hierarchiczny softamx) na pewnej *representecji kontekstowej*:
|
||||
|
||||
$$\vec{p} = \operatorname{softmax}(f(\vec{c})).$$
|
||||
|
||||
Model jest karany używając funkcji log loss:
|
||||
|
||||
$$-\log(p_j),$$
|
||||
|
||||
gdzie $w_j$ jest wyrazem, który pojawił się rzeczywiście w korpusie.
|
||||
|
||||
** Przewidywanie słowa (GPT-2)
|
||||
|
||||
Jeden ze sposobów pretrenowania modelu to po prostu przewidywanie
|
||||
następnego słowa.
|
||||
|
||||
Zainstalujmy najpierw bibliotekę transformers.
|
||||
|
||||
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||
! pip install transformers
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||
import torch
|
||||
from transformers import GPT2Tokenizer, GPT2LMHeadModel
|
||||
tokenizer = GPT2Tokenizer.from_pretrained('gpt2-large')
|
||||
model = GPT2LMHeadModel.from_pretrained('gpt2-large')
|
||||
text = "Warsaw is the capital city of"
|
||||
encoded_input = tokenizer(text, return_tensors='pt')
|
||||
output = model(**encoded_input)
|
||||
next_token_probs = torch.softmax(output[0][:, -1, :][0], dim=0)
|
||||
|
||||
nb_of_tokens = next_token_probs.size()[0]
|
||||
|
||||
_, top_k_indices = torch.topk(next_token_probs, 30, sorted=True)
|
||||
top_k_indices
|
||||
# words = tokenizer.convert_ids_to_tokens(top)
|
||||
|
||||
# top_probs = []
|
||||
|
||||
# for ix in range(len(top)):
|
||||
# top_probs.append((words[ix], next_token_probs[top[ix]].item()))
|
||||
|
||||
# top_probs
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
# Out[8]:
|
||||
#+BEGIN_EXAMPLE
|
||||
[('Ġthe', 0.4415026307106018),
|
||||
('ĠPoland', 0.236798495054245),
|
||||
('ĠBelarus', 0.10114768147468567),
|
||||
('ĠUkraine', 0.058283545076847076),
|
||||
('Ġeastern', 0.020564062520861626),
|
||||
('ĠEastern', 0.011137397028505802),
|
||||
('ĠPolish', 0.010205904021859169),
|
||||
('ĠWestern', 0.00833223108202219),
|
||||
('Ġwestern', 0.006872199941426516),
|
||||
('Ġa', 0.004939113277941942),
|
||||
('ĠSlovakia', 0.003553805174306035),
|
||||
('ĠLithuania', 0.003335304092615843),
|
||||
('ĠRussia', 0.002872465644031763),
|
||||
('Ġcentral', 0.002493523992598057),
|
||||
('Ġmodern', 0.0022767107002437115),
|
||||
('ĠCzech', 0.0022264323197305202),
|
||||
('ĠPr', 0.002146221464499831),
|
||||
('Ġformer', 0.0021054286044090986),
|
||||
('Ġwhat', 0.0017435317859053612),
|
||||
('ĠSlov', 0.0014634730760008097),
|
||||
('ĠUkrainian', 0.0014347084797918797),
|
||||
('ĠCentral', 0.0013676199596375227),
|
||||
('ĠSouth', 0.0013484350638464093),
|
||||
('Ġone', 0.001204205909743905),
|
||||
('ĠNorthern', 0.0011802552035078406),
|
||||
('ĠWest', 0.001175572513602674),
|
||||
('ĠEast', 0.0011596156982704997),
|
||||
('Ġsouthern', 0.0011580033460631967),
|
||||
('Ġnorthern', 0.001110077602788806),
|
||||
('Ġ"', 0.0010494199814274907)]
|
||||
#+END_EXAMPLE
|
||||
:end:
|
||||
|
||||
Zalety tego podejścia:
|
||||
|
||||
- prostota,
|
||||
- dobra podstawa do strojenia systemów generowania tekstu zwłaszcza
|
||||
„otwartego” (systemy dialogowe, generowanie (fake) newsów, streszczanie tekstu),
|
||||
ale niekoniecznie tłumaczenia maszynowego,
|
||||
- zaskakująca skuteczność przy uczeniu /few-shot/ i /zero-shot/.
|
||||
|
||||
Wady:
|
||||
|
||||
- asymetryczność, przetwarzanie tylko z lewej do prawej, preferencja
|
||||
dla lewego kontekstu,
|
||||
- mniejsza skuteczność przy dostrajaniu do zadań klasyfikacji i innych zadań
|
||||
niepolegających na prostym generowaniu.
|
||||
|
||||
Przykłady modeli: GPT, GPT-2, GPT-3, DialoGPT.
|
||||
|
||||
** Maskowanie słów (BERT)
|
||||
|
||||
Inną metodą jest maskowanie słów (/Masked Language Modeling/, /MLM/).
|
||||
|
||||
W tym podejściu losowe wybrane zastępujemy losowe słowa specjalnym
|
||||
tokenem (~[MASK]~) i każemy modelowi odgadywać w ten sposób
|
||||
zamaskowane słowa (z uwzględnieniem również prawego kontekstu!).
|
||||
|
||||
Móciąc ściśle, w jednym z pierwszych modeli tego typu (BERT)
|
||||
zastosowano schemat, w którym również niezamaskowane słowa są odgadywane (!):
|
||||
|
||||
- wybieramy losowe 15% wyrazów do odgadnięcia
|
||||
- 80% z nich zastępujemy tokenem ~[MASK]~,
|
||||
- 10% zastępujemy innym losowym wyrazem,
|
||||
- 10% pozostawiamy bez zmian.
|
||||
|
||||
|
||||
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||
from transformers import AutoModelWithLMHead, AutoTokenizer
|
||||
import torch
|
||||
|
||||
tokenizer = AutoTokenizer.from_pretrained("xlm-roberta-large")
|
||||
model = AutoModelWithLMHead.from_pretrained("xlm-roberta-large")
|
||||
|
||||
sequence = f'II wojna światowa zakończyła się w {tokenizer.mask_token} roku.'
|
||||
|
||||
input_ids = tokenizer.encode(sequence, return_tensors="pt")
|
||||
mask_token_index = torch.where(input_ids == tokenizer.mask_token_id)[1]
|
||||
|
||||
token_logits = model(input_ids)[0]
|
||||
mask_token_logits = token_logits[0, mask_token_index, :]
|
||||
mask_token_logits = torch.softmax(mask_token_logits, dim=1)
|
||||
|
||||
top_10 = torch.topk(mask_token_logits, 10, dim=1)
|
||||
top_10_tokens = zip(top_10.indices[0].tolist(), top_10.values[0].tolist())
|
||||
|
||||
for token, score in top_10_tokens:
|
||||
print(sequence.replace(tokenizer.mask_token, tokenizer.decode([token])), f"(score: {score})")
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
# Out[3]:
|
||||
:end:
|
||||
|
||||
|
||||
Przykłady: BERT, RoBERTa (również Polish RoBERTa).
|
||||
|
||||
** Podejście generatywne (koder-dekoder).
|
||||
|
||||
System ma wygenerować odpowiedź na różne pytania (również
|
||||
odpowiadające zadaniu MLM), np.:
|
||||
|
||||
- "translate English to German: That is good." => "Das ist gut."
|
||||
- "cola sentence: The course is jumping well." => "not acceptable"
|
||||
- "summarize: state authorities dispatched emergency crews tuesday to survey the damage after an onslaught of severe weather in mississippi..."
|
||||
=> "six people hospitalized after a storm in attala county"
|
||||
- "Thank you for <X> me to your party <Y> week." => <X> for inviting <Y> last <Z>
|
||||
|
||||
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||
from transformers import T5Tokenizer, T5Config, T5ForConditionalGeneration
|
||||
|
||||
T5_PATH = 't5-base'
|
||||
|
||||
t5_tokenizer = T5Tokenizer.from_pretrained(T5_PATH)
|
||||
t5_config = T5Config.from_pretrained(T5_PATH)
|
||||
t5_mlm = T5ForConditionalGeneration.from_pretrained(T5_PATH, config=t5_config)
|
||||
|
||||
slot = '<extra_id_0>'
|
||||
|
||||
text = f'Warsaw is the {slot} of Poland.'
|
||||
|
||||
encoded = t5_tokenizer.encode_plus(text, add_special_tokens=True, return_tensors='pt')
|
||||
input_ids = encoded['input_ids']
|
||||
|
||||
outputs = t5_mlm.generate(input_ids=input_ids,
|
||||
num_beams=200, num_return_sequences=5,
|
||||
max_length=5)
|
||||
|
||||
_0_index = text.index(slot)
|
||||
_result_prefix = text[:_0_index]
|
||||
_result_suffix = text[_0_index+len(slot):]
|
||||
|
||||
def _filter(output, end_token='<extra_id_1>'):
|
||||
_txt = t5_tokenizer.decode(output[2:], skip_special_tokens=False, clean_up_tokenization_spaces=False)
|
||||
if end_token in _txt:
|
||||
_end_token_index = _txt.index(end_token)
|
||||
return _result_prefix + _txt[:_end_token_index] + _result_suffix
|
||||
else:
|
||||
return _result_prefix + _txt + _result_suffix
|
||||
|
||||
|
||||
results = [_filter(out) for out in outputs]
|
||||
results
|
||||
#+END_SRC
|
||||
|
||||
(Zob. https://arxiv.org/pdf/1910.10683.pdf)
|
||||
|
||||
Przykład: T5, mT5
|
BIN
wyk/bpe.png
Normal file
BIN
wyk/bpe.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 124 KiB |
1
wyk/ie-gener.drawio
Normal file
1
wyk/ie-gener.drawio
Normal file
@ -0,0 +1 @@
|
||||
<mxfile host="app.diagrams.net" modified="2021-06-09T07:54:35.721Z" agent="5.0 (X11)" etag="NciLNBJF1axAiSJ0r0sv" version="14.7.3" type="device"><diagram id="HvCQlNLg7fWOxGx64C6g" name="Page-1">3Vjbbts4EP0aAe2DF9bNiR9jO9lisVekQLF9Y8SxRJsSVYqKrHz9Di+SJctF0m6TtvGDRB2RM+QcnhnKXrjOD79KUmZ/CArcC+b04IUbLwiWkY9XDbQWiMPQAqlk1EL+EbhlD+DAuUNrRqEadVRCcMXKMZiIooBEjTAipWjG3baCj72WJIUJcJsQPkU/MKoyi14GF0f8HbA06zz7i6V9k5Ous1tJlREqmgEUXnvhWgqhbCs/rIHr2HVxseNuPvO2n5iEQj1lgPgrjt7/+du/G76THw8f5Wyxv545K/eE127BXrDgaG+V4atFqlsdUpWk0OtQrQvO4lOtJ7+6I8k+laIu6CwRXEgvvMJ+Mr17E8Sxp6e1xutJ++1xfOfoHRDKirTzh0uxLsfTQHg6t/LFJ/u7kJDr8JZVre/UGEOPTOmtl4Oyo3FjVrgxQdX6LS6wZBVLzDLnwJnrVQE1NjTI6ioX+lFBXhqbrEgYZbQutOlaXzi5Q/+6t+p8g9l0aUG0G84+1eSXxyM5iFswCleg4GC2gco5Aj42t4zztQ3ZphAF2CibpYSb+Pj0XpQIzDB84arJmIJbxLXVBjMEYuIe5JYbKWSMUigQM4SA3ql6VKWk2EPnywvCufn100QDOL3P6sDv1YVZCQRSIVvs0g24dIJ0GclfuufmqO8gclg20rYDicspaW/7KDtsOOV9gQqDiQoV7CvNbAM7bx17y1XCRNM+gaRx6BxNZ5jDHZJi4DcJRg0QX+mYMsx7V+5FjtRoN2cpHNP1LUjxHyflHCfBc1ESnkmMJ8HHhF7q5pbD4UqXGgwFFNQ1NwknFSp9TI81AnRSdB4N1CAQ8ZlAdJgEThS7H5s/Fx3n4W/BTFZxPERRPOIBpTc2UYlaJuBGDavNiaHYf8SQIjIFNTFkyOqX/fX8RRP+tKIk2Sc7nSBNlnwgFaEPDEymtymRdfkQiZwpMcPbIFuyL8iWP6kQo8WJEC++sxCXEyK7SquLXV19XeH6llF/1moVh2M++kAP+Fi+JB9doh4Q0rR9kYJOLXey08qbprXSy0RDCjDHma2QOUl28Pb1Cik+PWYspsT1Ve9lmDtX0yxblN13dP1Tm7MnVP3B0gtvpqwOsuJg8P8TI4et+oGlODk4Rk88OD4fo9MqV7aKFFqGN6DaPQNFXq/E/PkJIeF3rlXdmWeUGwfJrzUfdfZkb0ia53XF9A0f1pF3eWE84PLb5KHAoz9GQ1QKv6rsV+KO7PXqrJVByn2tBMfLk+J3+Xw5FB+P/8XYU+jxD63w+j8=</diagram></mxfile>
|
BIN
wyk/ie-gener.png
Normal file
BIN
wyk/ie-gener.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
1
wyk/ie-seqlab.drawio
Normal file
1
wyk/ie-seqlab.drawio
Normal file
@ -0,0 +1 @@
|
||||
<mxfile host="app.diagrams.net" modified="2021-06-09T07:51:04.277Z" agent="5.0 (X11)" etag="tdTX7mJTGI1dKBKJk9w0" version="14.7.3" type="device"><diagram id="HvCQlNLg7fWOxGx64C6g" name="Page-1">7Vhtk5MwEP41zOiHOhQKd/14bc+3Uet4zjj6LSVbyDUQDOEo/no3EEp5uempd+qc9kMbHpLd7PNkl6WWu4z3LyRJo7eCArccm+4td2U5znw2xW8NlDXguW4NhJLRGpq2wBX7Bga0DZozCllnohKCK5Z2wUAkCQSqgxEpRdGdthW86zUlIQyAq4DwIfqJURXV6Llz1uIvgYVR43nqz+s7MWkmm0iyiFBRHEHupeUupRCqHsX7JXDNXcNLve75LXcPG5OQqLssEGtv9vHd688rfi2/7L/Iib+7nBgrN4TnJmDL8TnaW0R4yw/1qEGylCQ6DlUacvyvud78YkOCXShFntBJILiQlnuB82S4eeJ4nqW3tcTv3vhpu75x9BIIZUnY+MNQapfdbSA83Fv62zf7RkiINb1plutfWhlDj0zpoxeDqlfjwczwYILK9V0MMGUZC6owbeDMzMqAVjY0yPIsFvpSQZxWNlkSMMponmjTuf7iZIP+9WzV+Ibq0IUJ0W44+5qTZ6eZPOLN6dDlKNhXx0DFHIEpDreM82VN2SoRCdQsV6G4K6+9+ihSBCZIn7soIqbgCnFttcAKgZi4AbnlVSpEjFJIEKsEAX1S9apMSbGDxpfluHb1OWwTDeD2bs2D6SG7sCqBQClkiVOaBecmIU1Fmvrmumjz25kZLOrktgGJqSnhwXabdjgwmfcDWegMslDBLtPKFnBtLT1rvgiYKMo7iNSlzsg0ohyekBCJXwXIGiC+0JwyrHsX5kaM0mg3oxJ25boPUaY9Uc6Gooxp4jyUJO5IYeyRjwU91cMth/2FftQgFZBQM1wFnGSY6V15aiNABw+dk0QdEeGNENFgEjhR7KZrfowd4+G9YFVVMTrMvK4OA4IzkcsAzKrjp03PkOecMKSIDEENDFViHcL+ef1mA/1AlTsGShQkYfB4M2nm/2WZ5P1vMR5Bi/EAQXvTkZj7rcwtOvU7nI3sq7MVVSjbOttaR0ssYAx0yO+gGPrHXxLrxEw2WTp6ba9Pz7nLmtswezFZrd+sP+Do1WG0PmKijqwb7TD+/z3fUVH0vDv0fP5Yzzd7qLLo/5sNxrl7Tw3G3P6zDcbZQL9Uikzp0lWUVGzKQHcZdtXI54+33Tif/WXtxnygS/+R8jNF7z5Zf9BKN+/nl+0N9Jj/Tj2aF7sjQYry8FILwwfYk6LUOSNJpFt1qHqTrZAxCa7h6eNNpPnZ6UfU4S35F5XDy/Z/x7ogtn/eupffAQ==</diagram></mxfile>
|
BIN
wyk/ie-seqlab.png
Normal file
BIN
wyk/ie-seqlab.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
1
wyk/rnn-seq.drawio
Normal file
1
wyk/rnn-seq.drawio
Normal file
@ -0,0 +1 @@
|
||||
<mxfile host="app.diagrams.net" modified="2021-06-01T16:04:31.943Z" agent="5.0 (X11)" etag="_GtJ7cj7F7SQ6oQHAF32" version="14.6.13" type="device"><diagram id="Q_5Aon-lI3fA6Ftl2Xdk" name="Page-1">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</diagram></mxfile>
|
BIN
wyk/rnn-seq.png
Normal file
BIN
wyk/rnn-seq.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
1
wyk/rnn.drawio
Normal file
1
wyk/rnn.drawio
Normal file
@ -0,0 +1 @@
|
||||
<mxfile host="app.diagrams.net" modified="2021-06-01T15:52:54.501Z" agent="5.0 (X11)" etag="o_4DnBy9wLtBbjAQzQYJ" version="14.6.13" type="device"><diagram id="Q_5Aon-lI3fA6Ftl2Xdk" name="Page-1">5Vltj5s4EP41SO2HXcUYwuZjQ3J3H1pdpb3TtffNBRfcAI6M88L++hsH8w45qk2W7FbarDyPX7Bn5pkZjIHd+Pi7INvwE/dpZJgz/2jglWGaCwvBfwVkOYDmjpkjgWC+xirgkT1RDc40umM+TRsDJeeRZNsm6PEkoZ5sYEQIfmgO+86j5lO3JKAd4NEjURf9h/kyzNEH06nwPygLwuLJaL7Ie2JSDNZLpCHx+SGHTofDawO7gnOZt+KjSyOlvEIvuQZ+G+gtNyZoIsdM+Fu6u39ttrGyB2edrZxPf338cadX2ZNopw+sNyuzQgOC7xKfqkVmBl4eQibp45Z4qvcANgcslHEEEoKmXo4KSY+D+0Tl6cFtKI+pFBkM0ROwpU1fuAzW8qHSP9JnnYV13TsaJNrmQbl2pRZoaM38hJbmHaVQH7xEi1zIkAc8IdG6QpdNtVVjPnK+1cr6QaXMtMuTneRNVdIjk1/U9HtbS1/1Yqq9OtaFrBASOG5tkhK/FuspoZp2kop5+fnUoc4bDXTAd8KjZ3SlHUgSEVB5ZhzudwJBIyLZvrmPixvU7HF7C/6kYa83ebNjcvBo2bRQKgXfUJdHXACS8ETZ/TuLohZEIhYkIHqgTAr4UvGDQYz5oDti5vsnp+ljV9ORLkGwhybB8KJLMKuHX/ha9LJfC70uSBM8kiZoPiVPcIcnNP5GfZ8lAcCG7b6D3556hrPcG87q3Yk/7wF7fyaNoJdJIwjdm3bT0a2eTOI49/YL+nqRuKZxdlR39dLx/y+X1DNJLbFcP5c4r4IkzkAySYEMQIwNFFnO6q0nlaL6LLhmWvaopGJei2jIPmOWN5/jbXxj5ig5f/NJ/gZqaDQfG/icKQNfsc0axQ5EpPJADHMeKSJ9E9AKVCtiCeOqY+qywG7WBGZPTbB4yeIXLV4fMSYrCNDoisCekhgmfn02nS7YjbVpfjc1WbAbKvPgbSdlQUwGSorJA9xsXIC7Xubv6uRGyXBBp362r+qpnzmDR5fGtWatu9FZy2o5ifSsluHKbTzDlkMXZ3/eqPejken9et4/9BqS/QqvIe2rRmfcTePVrIFHfO/wdmJfeixN/A/qK5JSaUTSlHnPDzM+ScPyAUr4TCQYKzkh5gxdOL0OVEI1E9g9JiiwZwYsu/Uxp2PafP+dgNVZyGwvZI2LfGA9ktWGbdWA9MyGF/0bHtqX3YrId/b58e1z3KHGeGjkO75o2MbdsJ1uxZPhWsZiYbi2sXRpwiiMeIJfQlKZd22TLAZgA7GHUdXynkjKDwp8sxEL99uncWd8oZgFYvX5N7d19REdr/8D</diagram></mxfile>
|
BIN
wyk/rnn.png
Normal file
BIN
wyk/rnn.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
BIN
wyk/word-distribution.png
Normal file
BIN
wyk/word-distribution.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.3 KiB |
Loading…
Reference in New Issue
Block a user