diff --git a/wyk/06_Podobienstwo_slow.org b/wyk/06_Podobienstwo_slow.org new file mode 100644 index 0000000..daac12f --- /dev/null +++ b/wyk/06_Podobienstwo_slow.org @@ -0,0 +1,155 @@ +* Podobieństwo słów + +** Słabości $n$-gramowych modeli języka + +Podstawowa słabość $n$-gramowych modeli języka polega na tym, że każde +słowo jest traktowane w izolacji. W, powiedzmy, bigramowym modelu +języka każda wartość $P(w_2|w_1)$ jest estymowana osobno, nawet dla — +w jakimś sensie podobnych słów. Na przykład: + +- $P(\mathit{zaszczekał}|\mathit{pies})$, $P(\mathit{zaszczekał}|\mathit{jamnik})$, $P(\mathit{zaszczekał}|\mathit{wilczur})$ są estymowane osobno, +- $P(\mathit{zaszczekał}|\mathit{pies})$, $P(\mathit{zamerdał}|\mathit{pies})$, $P(\mathit{ugryzł}|\mathit{pies})$ są estymowane osobno, +- dla każdej pary $u$, $v$, gdzie $u$ jest przyimkiem (np. /dla/), a $v$ — osobową formą czasownika (np. /napisał/) model musi się uczyć, że $P(v|u)$ powinno mieć bardzo niską wartość. + +** Podobieństwo słów jako sposób na słabości $n$-gramowych modeli języka? + +Intuicyjnie wydaje się, że potrzebujemy jakiegoś sposobu określania podobieństwa słów, tak aby +w naturalny sposób, jeśli słowa $u$ i $u'$ oraz $v$ i $v'$ są bardzo podobne, wówczas +$P(u|v) \approx P(u'|v')$. + +Można wskazać trzy sposoby określania podobieństwa słów: odległość +edycyjna Lewensztajna, hierarchie słów i odległość w przestrzeni wielowymiarowej. + +*** Odległość Lewensztajna + +Słowo /dom/ ma coś wspólnego z /domem/, /domkiem/, /domostwem/, + /domownikami/, /domowym/ i /udomowieniem/ (?? — tu już można mieć + wątpliwości). Więc może oprzeć podobieństwa na powierzchownym + podobieństwie? + +Możemy zastosować tutaj *odległość Lewensztajna*, czyli minimalną liczbę operacji edycyjnych, które +są potrzebne, aby przekształcić jedno słowo w drugie. Zazwyczaj jako elementarne operacje edycyjne +definiuje się: + +- usunięcie znaku, +- dodanie znaku, +- zamianu znaku. + +Na przykład odległość edycyjna między słowami /domkiem/ i /domostwem/ +wynosi 4: zamiana /k/ na /o/, /i/ na /s/, dodanie /t/, dodanie /w/. + +#+BEGIN_SRC python :session mysession :exports both :results raw drawer + import Levenshtein + Levenshtein.distance('domkiem', 'domostwem') +#+END_SRC + +#+RESULTS: +:results: +4 +:end: + +Niestety, to nie jest tak, że słowa są podobne wtedy i tylko wtedy, gdy /wyglądają/ podobnie: + +- /tapet/ nie ma nic wspólnego z /tapetą/, +- słowo /sowa/ nie wygląda jak /ptak/, /puszczyk/, /jastrząb/, /kura/ itd. + +Powierzchowne podobieństwo słów łączy się zazwyczaj z relacjami +*fleksyjnymi* i *słowotwórczymi* (choć też nie zawsze, por. np. pary +słów będące przykładem *supletywizmu*: /człowiek/-/ludzie/, +/brać/-/zwiąć/, /rok/-/lata/). A co z innymi własnościami wyrazów czy +raczej bytów przez nie denotowanych (słowa oznaczające zwierzęta +należące do gromady ptaków chcemy traktować jako, w jakiejś mierze przynajmnie, podobne)? + +Dodajmy jeszcze, że w miejsce odległości Lewensztajna warto czasami +używać podobieństwa Jaro-Winklera, które mniejszą wagę przywiązuje do zmian w końcówkach wyrazów: + +#+BEGIN_SRC python :session mysession :exports both :results raw drawer + import Levenshtein + Levenshtein.jaro_winkler('domu', 'domowy') + Levenshtein.jaro_winkler('domowy', 'maskowy') +#+END_SRC + +#+RESULTS: +:results: +0.6626984126984127 +:end: + +*** Klasy i hierarchie słów + +Innym sposobem określania podobieństwa między słowami jest zdefiniowanie klas słów. +Słowa należące do jednej klasy będą podobne, do różnych klas — niepodobne. + +**** Klasy gramatyczne + +Klasy mogą odpowiadać standardowym kategoriom gramatycznym znanym z +językoznawstwa, na przykład *częściom mowy* (rzeczownik, przymiotnik, +czasownik itd.). Wiele jest niejednoznacznych jeśli chodzi o kategorię części mowy: + +- /powieść/ — rzeczownik czy czasownik? +- /komputerowi/ — rzeczownik czy przymiotnik? +- /lecz/ — spójnik, czasownik (!) czy rzeczownik (!!)? + +Oznacza to, że musimy dysponować narzędziem, które pozwala +automatycznie, na podstawie kontekstu, tagować tekst częściami mowy +(ang. /POS tagger/). Takie narzędzia pozwalają na osiągnięcie wysokiej +dokładności, niestety zawsze wprowadzają jakieś błędy, które mogą +propagować się dalej. + +**** Klasy indukowane automatycznie + +Zamiast z góry zakładać klasy wyrazów można zastosować metody uczenia +nienadzorowanego (podobne do analizy skupień) w celu *wyindukowanie* +automatycznie klas (tagów) z korpusu. + +**** Użycie klas słów w modelu języka + +Najprostszy sposób uwzględnienia klas słów w $n$-gramowym modelowaniu +języka polega stworzeniu dwóch osobnych modeli: + +- tradycyjnego modelu języka $M_W$ operującego na słowach, +- modelu języka $M_T$ wyuczonego na klasach słów (czy to częściach + mowy, czy klasach wyindukowanych automatycznie). + +Zauważmy, że rząd modelu $M_T$ ($n_T$) może dużo większy niż rząd modelu $M_W$ ($n_W$) — klas będzie +dużo mniej niż wyrazów, więc problem rzadkości danych jest dużo mniejszy i można rozpatrywać dłuższe +$n$-gramy. + +Dwa modele możemy połączyć za pomocą prostej kombinacji liniowej sterowanej hiperparametrem $\lambda$: + +$$P(w_i|w_{i-n_T}+1\ldots w_{i-1}) = \lambda P_{M_T}(w_i|w_{i-n_W}+1\ldots w_{i-1}) + (1 - \lambda) P_{M_W}(w_i|w_{i-n_T}+1\ldots w_{i-1}).$$ + +**** Hierarchie słów + +Zamiast płaskiej klasyfikacji słów można zbudować hierarchię słów czy +pojęć. Taka hierarchia może dotyczyć właściwości gramatycznych +(na przykład rzeczownik w liczbie pojedynczej w dopełniaczu będzie podklasą +rzeczownika) lub własności denotowanych bytów. + +Niekiedy dość łatwo stworzyć hierarchie (taksonomię) pojęć. Na +przykład jamnik jest rodzajem psa (słowo /jamnik/ jest *hiponimem* +słowa /pies/, zaś słowo /pies/ hiperonimem słowa /jamnik/), pies — +ssaka, ssak — zwierzęcia, zwierzę — organizmu żywego, organizm — bytu +materialnego. + +***** Analityczny język Johna Wilkinsa + +Już od dawna filozofowie myśleli o stworzenie języka uniwersalnego, w +którym hierarchia bytów jest ułożona w „naturalny” sposób. + +Przykładem jest angielski uczony John Wilkins (1614-1672). W dziele +/An Essay towards a Real Character and a Philosophical Language/ +zaproponował on rozbudowaną hierarchię bytów. + +#+CAPTION: Fragment dzieła Johna Wilkinsa +[[./06_Podobienstwo_slow/wilkins.png]] + +***** Słowosieci + +Współczesnym odpowiednik hierarchii Wilkinsa są *słowosieci* (ang. /wordnets). +Przykłady: + +- dla języka polskiego: [[http://plwordnet.pwr.wroc.pl][Słowosieć]], +- dla języka angielskiego: [[https://wordnet.princeton.edu/][Princeton Wordnet]] (i Słowosieć!) + +#+CAPTION: Fragment Słowosieci +[[./06_Podobienstwo_slow/slowosiec.png]] diff --git a/wyk/06_Zanurzenia_slow.org b/wyk/06_Zanurzenia_slow.org deleted file mode 100644 index 656535a..0000000 --- a/wyk/06_Zanurzenia_slow.org +++ /dev/null @@ -1,434 +0,0 @@ -* Zanurzenia słów - -** Słabości $n$-gramowych modeli języka - -Podstawowa słabość $n$-gramowych modeli języka polega na tym, że każde -słowo jest traktowane w izolacji. W, powiedzmy, bigramowym modelu -języka każda wartość $P(w_2|w_1)$ jest estymowana osobno, nawet dla — -w jakimś sensie podobnych słów. Na przykład: - -- $P(\mathit{zaszczekał}|\mathit{pies})$, $P(\mathit{zaszczekał}|\mathit{jamnik})$, $P(\mathit{zaszczekał}|\mathit{wilczur})$ są estymowane osobno, -- $P(\mathit{zaszczekał}|\mathit{pies})$, $P(\mathit{zamerdał}|\mathit{pies})$, $P(\mathit{ugryzł}|\mathit{pies})$ są estymowane osobno, -- dla każdej pary $u$, $v$, gdzie $u$ jest przyimkiem (np. /dla/), a $v$ — osobową formą czasownika (np. /napisał/) model musi się uczyć, że $P(v|u)$ powinno mieć bardzo niską wartość. - -** Podobieństwo słów jako sposób na słabości $n$-gramowych modeli języka? - -Intuicyjnie wydaje się, że potrzebujemy jakiegoś sposobu określania podobieństwa słów, tak aby -w naturalny sposób, jeśli słowa $u$ i $u'$ oraz $v$ i $v'$ są bardzo podobne, wówczas -$P(u|v) \approx P(u'|v')$. - -Można wskazać trzy sposoby określania podobieństwa słów: odległość -edycyjna Lewensztajna, hierarchie słów i odległość w przestrzeni wielowymiarowej. - -*** Odległość Lewensztajna - -Słowo /dom/ ma coś wspólnego z /domem/, /domkiem/, /domostwem/, - /domownikami/, /domowym/ i /udomowieniem/ (?? — tu już można mieć - wątpliwości). Więc może oprzeć podobieństwa na powierzchownym - podobieństwie? - -Możemy zastosować tutaj *odległość Lewensztajna*, czyli minimalną liczbę operacji edycyjnych, które -są potrzebne, aby przekształcić jedno słowo w drugie. Zazwyczaj jako elementarne operacje edycyjne -definiuje się: - -- usunięcie znaku, -- dodanie znaku, -- zamianu znaku. - -Na przykład odległość edycyjna między słowami /domkiem/ i /domostwem/ -wynosi 4: zamiana /k/ na /o/, /i/ na /s/, dodanie /t/, dodanie /w/. - -#+BEGIN_SRC python :session mysession :exports both :results raw drawer - import Levenshtein - Levenshtein.distance('domkiem', 'domostwem') -#+END_SRC - -#+RESULTS: -:results: -4 -:end: - -Niestety, to nie jest tak, że słowa są podobne wtedy i tylko wtedy, gdy /wyglądają/ podobnie: - -- /tapet/ nie ma nic wspólnego z /tapetą/, -- słowo /sowa/ nie wygląda jak /ptak/, /puszczyk/, /jastrząb/, /kura/ itd. - -Powierzchowne podobieństwo słów łączy się zazwyczaj z relacjami -*fleksyjnymi* i *słowotwórczymi* (choć też nie zawsze, por. np. pary -słów będące przykładem *supletywizmu*: /człowiek/-/ludzie/, -/brać/-/zwiąć/, /rok/-/lata/). A co z innymi własnościami wyrazów czy -raczej bytów przez nie denotowanych (słowa oznaczające zwierzęta -należące do gromady ptaków chcemy traktować jako, w jakiejś mierze przynajmnie, podobne)? - -Dodajmy jeszcze, że w miejsce odległości Lewensztajna warto czasami -używać podobieństwa Jaro-Winklera, które mniejszą wagę przywiązuje do zmian w końcówkach wyrazów: - -#+BEGIN_SRC python :session mysession :exports both :results raw drawer - import Levenshtein - Levenshtein.jaro_winkler('domu', 'domowy') - Levenshtein.jaro_winkler('domowy', 'maskowy') -#+END_SRC - -#+RESULTS: -:results: -0.6626984126984127 -:end: - -*** Klasy i hierarchie słów - -Innym sposobem określania podobieństwa między słowami jest zdefiniowanie klas słów. -Słowa należące do jednej klasy będą podobne, do różnych klas — niepodobne. - -**** Klasy gramatyczne - -Klasy mogą odpowiadać standardowym kategoriom gramatycznym znanym z -językoznawstwa, na przykład *częściom mowy* (rzeczownik, przymiotnik, -czasownik itd.). Wiele jest niejednoznacznych jeśli chodzi o kategorię części mowy: - -- /powieść/ — rzeczownik czy czasownik? -- /komputerowi/ — rzeczownik czy przymiotnik? -- /lecz/ — spójnik, czasownik (!) czy rzeczownik (!!)? - -Oznacza to, że musimy dysponować narzędziem, które pozwala -automatycznie, na podstawie kontekstu, tagować tekst częściami mowy -(ang. /POS tagger/). Takie narzędzia pozwalają na osiągnięcie wysokiej -dokładności, niestety zawsze wprowadzają jakieś błędy, które mogą -propagować się dalej. - -**** Klasy indukowane automatycznie - -Zamiast z góry zakładać klasy wyrazów można zastosować metody uczenia -nienadzorowanego (podobne do analizy skupień) w celu *wyindukowanie* -automatycznie klas (tagów) z korpusu. - -**** Użycie klas słów w modelu języka - -Najprostszy sposób uwzględnienia klas słów w $n$-gramowym modelowaniu -języka polega stworzeniu dwóch osobnych modeli: - -- tradycyjnego modelu języka $M_W$ operującego na słowach, -- modelu języka $M_T$ wyuczonego na klasach słów (czy to częściach - mowy, czy klasach wyindukowanych automatycznie). - -Zauważmy, że rząd modelu $M_T$ ($n_T$) może dużo większy niż rząd modelu $M_W$ ($n_W$) — klas będzie -dużo mniej niż wyrazów, więc problem rzadkości danych jest dużo mniejszy i można rozpatrywać dłuższe -$n$-gramy. - -Dwa modele możemy połączyć za pomocą prostej kombinacji liniowej sterowanej hiperparametrem $\lambda$: - -$$P(w_i|w_{i-n_T}+1\ldots w_{i-1}) = \lambda P_{M_T}(w_i|w_{i-n_W}+1\ldots w_{i-1}) + (1 - \lambda) P_{M_W}(w_i|w_{i-n_T}+1\ldots w_{i-1}).$$ - -**** Hierarchie słów - -Zamiast płaskiej klasyfikacji słów można zbudować hierarchię słów czy -pojęć. Taka hierarchia może dotyczyć właściwości gramatycznych -(na przykład rzeczownik w liczbie pojedynczej w dopełniaczu będzie podklasą -rzeczownika) lub własności denotowanych bytów. - -Niekiedy dość łatwo stworzyć hierarchie (taksonomię) pojęć. Na -przykład jamnik jest rodzajem psa (słowo /jamnik/ jest *hiponimem* -słowa /pies/, zaś słowo /pies/ hiperonimem słowa /jamnik/), pies — -ssaka, ssak — zwierzęcia, zwierzę — organizmu żywego, organizm — bytu -materialnego. - -***** Analityczny język Johna Wilkinsa - -Już od dawna filozofowie myśleli o stworzenie języka uniwersalnego, w -którym hierarchia bytów jest ułożona w „naturalny” sposób. - -Przykładem jest angielski uczony John Wilkins (1614-1672). W dziele -/An Essay towards a Real Character and a Philosophical Language/ -zaproponował on rozbudowaną hierarchię bytów. - -#+CAPTION: Fragment dzieła Johna Wilkinsa -[[./06_Zanurzenia_slow/wilkins.png]] - -***** Słowosieci - -Współczesnym odpowiednik hierarchii Wilkinsa są *słowosieci* (ang. /wordnets). -Przykłady: - -- dla języka polskiego: [[http://plwordnet.pwr.wroc.pl][Słowosieć]], -- dla języka angielskiego: [[https://wordnet.princeton.edu/][Princeton Wordnet]] (i Słowosieć!) - -#+CAPTION: Fragment Słowosieci -[[./06_Zanurzenia_slow/slowosiec.png]] - -W praktyce stosowalność słowosieci okazała się zaskakująco -ograniczona. Większy przełom w przetwarzaniu języka naturalnego przyniosły -wielowymiarowe reprezentacje słów, inaczej: zanurzenia słów. - -** „Wymiary” słów - -Moglibyśmy zanurzyć (ang. /embed/) w wielowymiarowej przestrzeni, tzn. zdefiniować odwzorowanie -$E \colon V \rightarrow \mathcal{R}^m$ dla pewnego $m$ i określić taki sposób estymowania -prawdopodobieństw $P(u|v)$, by dla par $E(v)$ i $E(v')$ oraz $E(u)$ i $E(u')$ znajdujących się w pobliżu -(według jakiejś metryki odległości, na przykład zwykłej odległości euklidesowej): - -$$P(u|v) \approx P(u'|v').$$ - -$E(u)$ nazywamy zanurzeniem (embeddingiem) słowa. - -*** Wymiary określone z góry? - -Można by sobie wyobrazić, że $m$ wymiarów mogłoby być z góry -określonych przez lingwistę. Wymiary te byłyby związane z typowymi -„osiami” rozpatrywanymi w językoznawstwie, na przykład: - -- czy słowo jest wulgarne, pospolite, potoczne, neutralne czy książkowe? -- czy słowo jest archaiczne, wychodzące z użycia czy jest neologizmem? -- czy słowo dotyczy kobiet, czy mężczyzn (w sensie rodzaju gramatycznego i/lub - socjolingwistycznym)? -- czy słowo jest w liczbie pojedynczej czy mnogiej? -- czy słowo jest rzeczownikiem czy czasownikiem? -- czy słowo jest rdzennym słowem czy zapożyczeniem? -- czy słowo jest nazwą czy słowem pospolitym? -- czy słowo opisuje konkretną rzecz czy pojęcie abstrakcyjne? -- … - -W praktyce okazało się jednak, że lepiej, żeby komputer uczył się sam -możliwych wymiarów — z góry określamy tylko $m$ (liczbę wymiarów). - -** Bigramowy model języka oparty na zanurzeniach - -Zbudujemy teraz najprostszy model język oparty na zanurzeniach. Będzie to właściwie najprostszy -*neuronowy model języka*, jako że zbudowany model można traktować jako prostą sieć neuronową. - -*** Słownik - -W typowym neuronowym modelu języka rozmiar słownika musi być z góry -ograniczony. Zazwyczaj jest to liczba rzędu kilkudziesięciu wyrazów — -po prostu będziemy rozpatrywać $|V|$ najczęstszych wyrazów, pozostałe zamienimy -na specjalny token ~~ reprezentujący nieznany (/unknown/) wyraz. - -Aby utworzyć taki słownik użyjemy gotowej klasy ~Vocab~ z pakietu torchtext: - -#+BEGIN_SRC python :session mysession :exports both :results raw drawer - from itertools import islice - import regex as re - import sys - from torchtext.vocab import build_vocab_from_iterator - - - def get_words_from_line(line): - line = line.rstrip() - yield '' - for m in re.finditer(r'[\p{L}0-9\*]+|\p{P}+', line): - yield m.group(0).lower() - yield '' - - - def get_word_lines_from_file(file_name): - with open(file_name, 'r') as fh: - for line in fh: - yield get_words_from_line(line) - - vocab_size = 20000 - - vocab = build_vocab_from_iterator( - get_word_lines_from_file('opensubtitlesA.pl.txt'), - max_tokens = vocab_size, - specials = ['']) - - vocab['jest'] -#+END_SRC - -#+RESULTS: -:results: -16 -:end: - -#+BEGIN_SRC python :session mysession :exports both :results raw drawer -vocab.lookup_tokens([0, 1, 2, 10, 12345]) -#+END_SRC - -#+RESULTS: -:results: -['', '', '', 'w', 'wierzyli'] -:end: - -*** Definicja sieci - -Naszą prostą sieć neuronową zaimplementujemy używając frameworku PyTorch. - -#+BEGIN_SRC python :session mysession :exports both :results raw drawer - from torch import nn - import torch - - embed_size = 100 - - class SimpleBigramNeuralLanguageModel(nn.Module): - def __init__(self, vocabulary_size, embedding_size): - super(SimpleBigramNeuralLanguageModel, self).__init__() - self.model = nn.Sequential( - nn.Embedding(vocabulary_size, embedding_size), - nn.Linear(embedding_size, vocabulary_size), - nn.Softmax() - ) - - def forward(self, x): - return self.model(x) - - model = SimpleBigramNeuralLanguageModel(vocab_size, embed_size) - - vocab.set_default_index(vocab['']) - ixs = torch.tensor(vocab.forward(['pies'])) - out[0][vocab['jest']] -#+END_SRC - -#+RESULTS: -:results: -:end: - -Teraz wyuczmy model. Wpierw tylko potasujmy nasz plik: - -#+BEGIN_SRC -shuf < opensubtitlesA.pl.txt > opensubtitlesA.pl.shuf.txt -#+END_SRC - -#+BEGIN_SRC python :session mysession :exports both :results raw drawer - from torch.utils.data import IterableDataset - import itertools - - def look_ahead_iterator(gen): - prev = None - for item in gen: - if prev is not None: - yield (prev, item) - prev = item - - class Bigrams(IterableDataset): - def __init__(self, text_file, vocabulary_size): - self.vocab = build_vocab_from_iterator( - get_word_lines_from_file(text_file), - max_tokens = vocabulary_size, - specials = ['']) - self.vocab.set_default_index(self.vocab['']) - self.vocabulary_size = vocabulary_size - self.text_file = text_file - - def __iter__(self): - return look_ahead_iterator( - (self.vocab[t] for t in itertools.chain.from_iterable(get_word_lines_from_file(self.text_file)))) - - train_dataset = Bigrams('opensubtitlesA.pl.shuf.txt', vocab_size) -#+END_SRC - -#+RESULTS: -:results: -:end: - -#+BEGIN_SRC python :session mysession :exports both :results raw drawer - from torch.utils.data import DataLoader - - next(iter(train_dataset)) -#+END_SRC - -#+RESULTS: -:results: -(2, 5) -:end: - -#+BEGIN_SRC python :session mysession :exports both :results raw drawer - from torch.utils.data import DataLoader - - next(iter(DataLoader(train_dataset, batch_size=5))) -#+END_SRC - -#+RESULTS: -:results: -[tensor([ 2, 5, 51, 3481, 231]), tensor([ 5, 51, 3481, 231, 4])] -:end: - -#+BEGIN_SRC python :session mysession :exports both :results raw drawer - device = 'cuda' - model = SimpleBigramNeuralLanguageModel(vocab_size, embed_size).to(device) - data = DataLoader(train_dataset, batch_size=5000) - optimizer = torch.optim.Adam(model.parameters()) - criterion = torch.nn.NLLLoss() - - model.train() - step = 0 - for x, y in data: - x = x.to(device) - y = y.to(device) - optimizer.zero_grad() - ypredicted = model(x) - loss = criterion(torch.log(ypredicted), y) - if step % 100 == 0: - print(step, loss) - step += 1 - loss.backward() - optimizer.step() - - torch.save(model.state_dict(), 'model1.bin') -#+END_SRC - -#+RESULTS: -:results: -None -:end: - -Policzmy najbardziej prawdopodobne kontynuację dla zadanego słowa: - -#+BEGIN_SRC python :session mysession :exports both :results raw drawer - device = 'cuda' - model = SimpleBigramNeuralLanguageModel(vocab_size, embed_size).to(device) - model.load_state_dict(torch.load('model1.bin')) - model.eval() - - ixs = torch.tensor(vocab.forward(['dla'])).to(device) - - out = model(ixs) - top = torch.topk(out[0], 10) - top_indices = top.indices.tolist() - top_probs = top.values.tolist() - top_words = vocab.lookup_tokens(top_indices) - list(zip(top_words, top_indices, top_probs)) -#+END_SRC - -#+RESULTS: -:results: -[('ciebie', 73, 0.1580502986907959), ('mnie', 26, 0.15395283699035645), ('', 0, 0.12862136960029602), ('nas', 83, 0.0410110242664814), ('niego', 172, 0.03281523287296295), ('niej', 245, 0.02104802615940571), ('siebie', 181, 0.020788608118891716), ('którego', 365, 0.019379809498786926), ('was', 162, 0.013852755539119244), ('wszystkich', 235, 0.01381855271756649)] -:end: - -Teraz zbadajmy najbardziej podobne zanurzenia dla zadanego słowa: - -#+BEGIN_SRC python :session mysession :exports both :results raw drawer - vocab = train_dataset.vocab - ixs = torch.tensor(vocab.forward(['kłopot'])).to(device) - - out = model(ixs) - top = torch.topk(out[0], 10) - top_indices = top.indices.tolist() - top_probs = top.values.tolist() - top_words = vocab.lookup_tokens(top_indices) - list(zip(top_words, top_indices, top_probs)) -#+END_SRC - -#+RESULTS: -:results: -[('.', 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), ('', 0, 0.014571071602404118), ('...', 15, 0.01453721895813942), ('', 1, 0.011769450269639492)] -:end: - -#+BEGIN_SRC python :session mysession :exports both :results raw drawer - cos = nn.CosineSimilarity(dim=1, eps=1e-6) - - embeddings = model.model[0].weight - - vec = embeddings[vocab['poszedł']] - - similarities = cos(vec, embeddings) - - top = torch.topk(similarities, 10) - - top_indices = top.indices.tolist() - top_probs = top.values.tolist() - top_words = vocab.lookup_tokens(top_indices) - list(zip(top_words, top_indices, top_probs)) -#+END_SRC - -#+RESULTS: -:results: -[('poszedł', 1087, 1.0), ('idziesz', 1050, 0.4907470941543579), ('przyjeżdża', 4920, 0.45242372155189514), ('pojechałam', 12784, 0.4342481195926666), ('wrócił', 1023, 0.431664377450943), ('dobrać', 10351, 0.4312002956867218), ('stałeś', 5738, 0.4258835017681122), ('poszła', 1563, 0.41979148983955383), ('trafiłam', 18857, 0.4109022617340088), ('jedzie', 1674, 0.4091658890247345)] -:end: diff --git a/wyk/06_Zanurzenia_slow/slowosiec.png b/wyk/06_Zanurzenia_slow/slowosiec.png deleted file mode 100644 index a0d44cc..0000000 Binary files a/wyk/06_Zanurzenia_slow/slowosiec.png and /dev/null differ diff --git a/wyk/06_Zanurzenia_slow/wilkins.png b/wyk/06_Zanurzenia_slow/wilkins.png deleted file mode 100644 index 2ddc63e..0000000 Binary files a/wyk/06_Zanurzenia_slow/wilkins.png and /dev/null differ