Fix 09
This commit is contained in:
parent
b343653f5e
commit
1e50331206
Binary file not shown.
@ -7,7 +7,7 @@
|
|||||||
"![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n",
|
"![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",
|
"<div class=\"alert alert-block alert-info\">\n",
|
||||||
"<h1> Modelowanie języka</h1>\n",
|
"<h1> Modelowanie języka</h1>\n",
|
||||||
"<h2> 7. <i>Zanurzenia słów</i> [wykład]</h2> \n",
|
"<h2> 09. <i>Zanurzenia słów (Word2vec)</i> [wykład]</h2> \n",
|
||||||
"<h3> Filip Graliński (2022)</h3>\n",
|
"<h3> Filip Graliński (2022)</h3>\n",
|
||||||
"</div>\n",
|
"</div>\n",
|
||||||
"\n",
|
"\n",
|
||||||
@ -19,7 +19,7 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Zanurzenia słów\n",
|
"## Zanurzenia słów (Word2vec)\n",
|
||||||
"\n"
|
"\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -122,7 +122,7 @@
|
|||||||
"po prostu będziemy rozpatrywać $|V|$ najczęstszych wyrazów, pozostałe zamienimy\n",
|
"po prostu będziemy rozpatrywać $|V|$ najczęstszych wyrazów, pozostałe zamienimy\n",
|
||||||
"na specjalny token `<unk>` reprezentujący nieznany (*unknown*) wyraz.\n",
|
"na specjalny token `<unk>` reprezentujący nieznany (*unknown*) wyraz.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Aby utworzyć taki słownik użyjemy gotowej klasy `Vocab` z pakietu torchtext:\n",
|
"Aby utworzyć taki słownik, użyjemy gotowej klasy `Vocab` z pakietu torchtext:\n",
|
||||||
"\n"
|
"\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -313,33 +313,48 @@
|
|||||||
"next(iter(DataLoader(train_dataset, batch_size=5)))"
|
"next(iter(DataLoader(train_dataset, batch_size=5)))"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 1,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"None"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"device = 'cuda'\n",
|
||||||
|
"model = SimpleBigramNeuralLanguageModel(vocab_size, embed_size).to(device)\n",
|
||||||
|
"data = DataLoader(train_dataset, batch_size=5000)\n",
|
||||||
|
"optimizer = torch.optim.Adam(model.parameters())\n",
|
||||||
|
"criterion = torch.nn.NLLLoss()\n",
|
||||||
|
"\n",
|
||||||
|
"model.train()\n",
|
||||||
|
"step = 0\n",
|
||||||
|
"for x, y in data:\n",
|
||||||
|
" x = x.to(device)\n",
|
||||||
|
" y = y.to(device)\n",
|
||||||
|
" optimizer.zero_grad()\n",
|
||||||
|
" ypredicted = model(x)\n",
|
||||||
|
" loss = criterion(torch.log(ypredicted), y)\n",
|
||||||
|
" if step % 100 == 0:\n",
|
||||||
|
" print(step, loss)\n",
|
||||||
|
" step += 1\n",
|
||||||
|
" loss.backward()\n",
|
||||||
|
" optimizer.step()\n",
|
||||||
|
"\n",
|
||||||
|
"torch.save(model.state_dict(), 'model1.bin')"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
" device = 'cuda'\n",
|
"Policzmy najbardziej prawdopodobne kontynuacje dla zadanego słowa:\n",
|
||||||
" model = SimpleBigramNeuralLanguageModel(vocab_size, embed_size).to(device)\n",
|
|
||||||
" data = DataLoader(train_dataset, batch_size=5000)\n",
|
|
||||||
" optimizer = torch.optim.Adam(model.parameters())\n",
|
|
||||||
" criterion = torch.nn.NLLLoss()\n",
|
|
||||||
" \n",
|
|
||||||
" model.train()\n",
|
|
||||||
" step = 0\n",
|
|
||||||
" for x, y in data:\n",
|
|
||||||
" x = x.to(device)\n",
|
|
||||||
" y = y.to(device)\n",
|
|
||||||
" optimizer.zero_grad()\n",
|
|
||||||
" ypredicted = model(x)\n",
|
|
||||||
" loss = criterion(torch.log(ypredicted), y)\n",
|
|
||||||
" if step % 100 == 0:\n",
|
|
||||||
" print(step, loss)\n",
|
|
||||||
" step += 1\n",
|
|
||||||
" loss.backward()\n",
|
|
||||||
" optimizer.step()\n",
|
|
||||||
" \n",
|
|
||||||
" torch.save(model.state_dict(), 'model1.bin')\n",
|
|
||||||
"\n",
|
|
||||||
"Policzmy najbardziej prawdopodobne kontynuację dla zadanego słowa:\n",
|
|
||||||
"\n"
|
"\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -502,7 +517,7 @@
|
|||||||
"warstwy liniowej, naszą sieć możemy interpretować jako jednowarstwową\n",
|
"warstwy liniowej, naszą sieć możemy interpretować jako jednowarstwową\n",
|
||||||
"sieć neuronową, co można zilustrować za pomocą następującego diagramu:\n",
|
"sieć neuronową, co można zilustrować za pomocą następującego diagramu:\n",
|
||||||
"\n",
|
"\n",
|
||||||
"![img](./07_Zanurzenia_slow/bigram1.drawio.png \"Diagram prostego bigramowego neuronowego modelu języka\")\n",
|
"![img](./09_Zanurzenia_slow/bigram1.drawio.png \"Diagram prostego bigramowego neuronowego modelu języka\")\n",
|
||||||
"\n"
|
"\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -535,7 +550,7 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"W postaci diagramu można tę interpretację zilustrować w następujący sposób:\n",
|
"W postaci diagramu można tę interpretację zilustrować w następujący sposób:\n",
|
||||||
"\n",
|
"\n",
|
||||||
"![img](./07_Zanurzenia_slow/bigram2.drawio.png \"Diagram prostego bigramowego neuronowego modelu języka z wejściem w postaci one-hot\")\n",
|
"![img](./09_Zanurzenia_slow/bigram2.drawio.png \"Diagram prostego bigramowego neuronowego modelu języka z wejściem w postaci one-hot\")\n",
|
||||||
"\n"
|
"\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -556,7 +571,7 @@
|
|||||||
"name": "python",
|
"name": "python",
|
||||||
"nbconvert_exporter": "python",
|
"nbconvert_exporter": "python",
|
||||||
"pygments_lexer": "ipython3",
|
"pygments_lexer": "ipython3",
|
||||||
"version": "3.10.2"
|
"version": "3.10.5"
|
||||||
},
|
},
|
||||||
"org": null
|
"org": null
|
||||||
},
|
},
|
@ -1,4 +1,4 @@
|
|||||||
* Zanurzenia słów
|
* Zanurzenia słów (Word2vec)
|
||||||
|
|
||||||
W praktyce stosowalność słowosieci okazała się zaskakująco
|
W praktyce stosowalność słowosieci okazała się zaskakująco
|
||||||
ograniczona. Większy przełom w przetwarzaniu języka naturalnego przyniosły
|
ograniczona. Większy przełom w przetwarzaniu języka naturalnego przyniosły
|
||||||
@ -47,9 +47,9 @@ ograniczony. Zazwyczaj jest to liczba rzędu kilkudziesięciu wyrazów —
|
|||||||
po prostu będziemy rozpatrywać $|V|$ najczęstszych wyrazów, pozostałe zamienimy
|
po prostu będziemy rozpatrywać $|V|$ najczęstszych wyrazów, pozostałe zamienimy
|
||||||
na specjalny token ~<unk>~ reprezentujący nieznany (/unknown/) wyraz.
|
na specjalny token ~<unk>~ reprezentujący nieznany (/unknown/) wyraz.
|
||||||
|
|
||||||
Aby utworzyć taki słownik użyjemy gotowej klasy ~Vocab~ z pakietu torchtext:
|
Aby utworzyć taki słownik, użyjemy gotowej klasy ~Vocab~ z pakietu torchtext:
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||||
from itertools import islice
|
from itertools import islice
|
||||||
import regex as re
|
import regex as re
|
||||||
import sys
|
import sys
|
||||||
@ -84,7 +84,7 @@ Aby utworzyć taki słownik użyjemy gotowej klasy ~Vocab~ z pakietu torchtext:
|
|||||||
16
|
16
|
||||||
:end:
|
:end:
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||||
vocab.lookup_tokens([0, 1, 2, 10, 12345])
|
vocab.lookup_tokens([0, 1, 2, 10, 12345])
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ vocab.lookup_tokens([0, 1, 2, 10, 12345])
|
|||||||
|
|
||||||
Naszą prostą sieć neuronową zaimplementujemy używając frameworku PyTorch.
|
Naszą prostą sieć neuronową zaimplementujemy używając frameworku PyTorch.
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||||
from torch import nn
|
from torch import nn
|
||||||
import torch
|
import torch
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ Teraz wyuczmy model. Wpierw tylko potasujmy nasz plik:
|
|||||||
shuf < opensubtitlesA.pl.txt > opensubtitlesA.pl.shuf.txt
|
shuf < opensubtitlesA.pl.txt > opensubtitlesA.pl.shuf.txt
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||||
from torch.utils.data import IterableDataset
|
from torch.utils.data import IterableDataset
|
||||||
import itertools
|
import itertools
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ shuf < opensubtitlesA.pl.txt > opensubtitlesA.pl.shuf.txt
|
|||||||
:results:
|
:results:
|
||||||
:end:
|
:end:
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||||
from torch.utils.data import DataLoader
|
from torch.utils.data import DataLoader
|
||||||
|
|
||||||
next(iter(train_dataset))
|
next(iter(train_dataset))
|
||||||
@ -175,7 +175,7 @@ shuf < opensubtitlesA.pl.txt > opensubtitlesA.pl.shuf.txt
|
|||||||
(2, 5)
|
(2, 5)
|
||||||
:end:
|
:end:
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||||
from torch.utils.data import DataLoader
|
from torch.utils.data import DataLoader
|
||||||
|
|
||||||
next(iter(DataLoader(train_dataset, batch_size=5)))
|
next(iter(DataLoader(train_dataset, batch_size=5)))
|
||||||
@ -186,7 +186,7 @@ shuf < opensubtitlesA.pl.txt > opensubtitlesA.pl.shuf.txt
|
|||||||
[tensor([ 2, 5, 51, 3481, 231]), tensor([ 5, 51, 3481, 231, 4])]
|
[tensor([ 2, 5, 51, 3481, 231]), tensor([ 5, 51, 3481, 231, 4])]
|
||||||
:end:
|
:end:
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||||
device = 'cuda'
|
device = 'cuda'
|
||||||
model = SimpleBigramNeuralLanguageModel(vocab_size, embed_size).to(device)
|
model = SimpleBigramNeuralLanguageModel(vocab_size, embed_size).to(device)
|
||||||
data = DataLoader(train_dataset, batch_size=5000)
|
data = DataLoader(train_dataset, batch_size=5000)
|
||||||
@ -215,9 +215,9 @@ shuf < opensubtitlesA.pl.txt > opensubtitlesA.pl.shuf.txt
|
|||||||
None
|
None
|
||||||
:end:
|
:end:
|
||||||
|
|
||||||
Policzmy najbardziej prawdopodobne kontynuację dla zadanego słowa:
|
Policzmy najbardziej prawdopodobne kontynuacje dla zadanego słowa:
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||||
device = 'cuda'
|
device = 'cuda'
|
||||||
model = SimpleBigramNeuralLanguageModel(vocab_size, embed_size).to(device)
|
model = SimpleBigramNeuralLanguageModel(vocab_size, embed_size).to(device)
|
||||||
model.load_state_dict(torch.load('model1.bin'))
|
model.load_state_dict(torch.load('model1.bin'))
|
||||||
@ -240,7 +240,7 @@ Policzmy najbardziej prawdopodobne kontynuację dla zadanego słowa:
|
|||||||
|
|
||||||
Teraz zbadajmy najbardziej podobne zanurzenia dla zadanego słowa:
|
Teraz zbadajmy najbardziej podobne zanurzenia dla zadanego słowa:
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||||
vocab = train_dataset.vocab
|
vocab = train_dataset.vocab
|
||||||
ixs = torch.tensor(vocab.forward(['kłopot'])).to(device)
|
ixs = torch.tensor(vocab.forward(['kłopot'])).to(device)
|
||||||
|
|
||||||
@ -257,7 +257,7 @@ Teraz zbadajmy najbardziej podobne zanurzenia dla zadanego słowa:
|
|||||||
[('.', 3, 0.404473215341568), (',', 4, 0.14222915470600128), ('z', 14, 0.10945753753185272), ('?', 6, 0.09583134204149246), ('w', 10, 0.050338443368673325), ('na', 12, 0.020703863352537155), ('i', 11, 0.016762692481279373), ('<unk>', 0, 0.014571071602404118), ('...', 15, 0.01453721895813942), ('</s>', 1, 0.011769450269639492)]
|
[('.', 3, 0.404473215341568), (',', 4, 0.14222915470600128), ('z', 14, 0.10945753753185272), ('?', 6, 0.09583134204149246), ('w', 10, 0.050338443368673325), ('na', 12, 0.020703863352537155), ('i', 11, 0.016762692481279373), ('<unk>', 0, 0.014571071602404118), ('...', 15, 0.01453721895813942), ('</s>', 1, 0.011769450269639492)]
|
||||||
:end:
|
:end:
|
||||||
|
|
||||||
#+BEGIN_SRC python :session mysession :exports both :results raw drawer
|
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||||
cos = nn.CosineSimilarity(dim=1, eps=1e-6)
|
cos = nn.CosineSimilarity(dim=1, eps=1e-6)
|
||||||
|
|
||||||
embeddings = model.model[0].weight
|
embeddings = model.model[0].weight
|
||||||
@ -313,7 +313,7 @@ warstwy liniowej, naszą sieć możemy interpretować jako jednowarstwową
|
|||||||
sieć neuronową, co można zilustrować za pomocą następującego diagramu:
|
sieć neuronową, co można zilustrować za pomocą następującego diagramu:
|
||||||
|
|
||||||
#+CAPTION: Diagram prostego bigramowego neuronowego modelu języka
|
#+CAPTION: Diagram prostego bigramowego neuronowego modelu języka
|
||||||
[[./07_Zanurzenia_slow/bigram1.drawio.png]]
|
[[./09_Zanurzenia_slow/bigram1.drawio.png]]
|
||||||
|
|
||||||
*** Zanurzenie jako mnożenie przez macierz
|
*** Zanurzenie jako mnożenie przez macierz
|
||||||
|
|
||||||
@ -335,4 +335,4 @@ gdzie $E$ będzie tym razem macierzą $m \times |V|$.
|
|||||||
W postaci diagramu można tę interpretację zilustrować w następujący sposób:
|
W postaci diagramu można tę interpretację zilustrować w następujący sposób:
|
||||||
|
|
||||||
#+CAPTION: Diagram prostego bigramowego neuronowego modelu języka z wejściem w postaci one-hot
|
#+CAPTION: Diagram prostego bigramowego neuronowego modelu języka z wejściem w postaci one-hot
|
||||||
[[./07_Zanurzenia_slow/bigram2.drawio.png]]
|
[[./09_Zanurzenia_slow/bigram2.drawio.png]]
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user