1
0
Fork 0

Drobne poprawki w wykładzie

This commit is contained in:
Filip Gralinski 2021-10-05 21:44:46 +02:00
parent f804311da1
commit 72db2aa687
11 changed files with 2095 additions and 2098 deletions

View File

@ -15,16 +15,14 @@
]
},
{
"cell_type": "code",
"execution_count": null,
"cell_type": "markdown",
"metadata": {},
"outputs": [],
"source": [
"# Wyszukiwarki - wprowadzenie\n",
"\n",
"## Systemy wyszukiwania informacji (information retrieval systems)\n",
"\n",
"![System wyszukiwania informacji](system-wyszukiwania-informacji.png)"
"![Schemat systemu wyszukiwania informacji](system-wyszukiwania-informacji.png)"
]
},
{
@ -36,7 +34,7 @@
"source": [
"## Wyszukiwarki\n",
"\n",
"![Wyszukiwarki](wyszukiwarka-internetowa.png)"
"![Schemat wyszukiwarki internetowej](wyszukiwarka-internetowa.png)"
]
},
{
@ -108,7 +106,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Dostępne są też \"ekstrakty\" czystego tekstu - zob. http://data.statmt.org/ngrams/raw/, np. 59 GB czystego tekstu po polsku z 2012 roku."
"Dostępne są też „ekstrakty” czystego tekstu — zob. http://data.statmt.org/ngrams/raw/, np. 59 GB czystego tekstu po polsku z 2012 roku."
]
},
{
@ -303,7 +301,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### Odpytywać \"pasożytniczo\" inną wyszukiwarkę"
"### Odpytywać „pasożytniczo” inną wyszukiwarkę"
]
},
{
@ -312,7 +310,7 @@
"metadata": {},
"outputs": [],
"source": [
"# see https://hackernoon.com/how-to-scrape-google-with-python-bo7d2tal\n",
"# zob. https://hackernoon.com/how-to-scrape-google-with-python-bo7d2tal\n",
"\n",
"import urllib\n",
"import requests\n",

View File

@ -328,7 +328,7 @@
"\n",
"* urllib\n",
"* request\n",
"* Beautiful Soup (do parsowania HTML-a)"
"* Beautiful Soup (do parsowania dokumentów HTML)"
]
},
{

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,7 @@
"\n",
"Zakładamy, że mamy dwie klasy: $c$ i jej dopełnienie ($\\bar{c}$).\n",
"\n",
"Typowym przykładem jest zadanie klasyfikacji mejla, czy należy do spamu, czy nie (_spam_ vs _ham_), czyli innymi słowy filtr antyspamowy."
"Typowym przykładem jest zadanie klasyfikacji mejla, czy należy do spamu, czy nie (_spam_ vs _ham_), czyli, innymi słowy, filtr antyspamowy."
]
},
{
@ -78,9 +78,9 @@
"\n",
"W klasyfikacji (i w ogóle w uczeniu nadzorowanym) można wskazać dwa podejścia:\n",
"\n",
"* generatywne - wymyślamy pewną \"historyjkę\", w jaki sposób powstaje tekst, \"historyjka\" powinna mieć miejsca do wypełnienia (parametry), np. częstości wyrazów, na podstawie zbioru uczącego dobieramy wartości parametrów (przez rachunki wprost); \"historyjka\" nie musi być prawdziwa, wystarczy, że jakoś przybliża rzeczywistość\n",
"* generatywne — wymyślamy pewną „historyjkę”, w jaki sposób powstaje tekst, „historyjka” powinna mieć miejsca do wypełnienia (parametry), np. częstości wyrazów, na podstawie zbioru uczącego dobieramy wartości parametrów (przez rachunki wprost); „historyjka” nie musi być prawdziwa, wystarczy, że jakoś przybliża rzeczywistość\n",
"\n",
"* dyskryminatywne - nie zastanawiamy się, w jaki sposób powstają teksty, po prostu \"na siłę\" dobieramy wartości parametrów (wag) modelu, tak aby uzyskać jak najmniejszą wartość funkcji kosztu na zbiorze uczącym; zwykle odbywa się to w iteracyjnym procesie (tak jak przedstawiono na schemacie na poprzednim wykładzie).\n",
"* dyskryminatywne — nie zastanawiamy się, w jaki sposób powstają teksty, po prostu „na siłę” dobieramy wartości parametrów (wag) modelu, tak aby uzyskać jak najmniejszą wartość funkcji kosztu na zbiorze uczącym; zwykle odbywa się to w iteracyjnym procesie (tak jak przedstawiono na schemacie na poprzednim wykładzie).\n",
"\n",
"**Pytanie**: Jakie są wady i zalety obu podejść?"
]
@ -146,11 +146,11 @@
"source": [
"## Naiwny klasyfikator bayesowski\n",
"\n",
"* _naiwny_ - niekoniecznie oznacza, że to \"głupi\", bezużyteczny klasyfikator\n",
"* _naiwny_— niekoniecznie oznacza, że to „głupi”, bezużyteczny klasyfikator\n",
"* _klasyfikator_ \n",
"* _bayesowski_ - będzie odwoływać się do wzoru Bayesa.\n",
"* _bayesowski_ będzie odwoływać się do wzoru Bayesa.\n",
"\n",
"Naiwny klasyfikator bayesowski raczej nie powinien być stosowany \"produkcyjnie\" (są lepsze metody). Natomiast jest to metoda bardzo prosta w implementacji dająca przyzwoity _baseline_.\n",
"Naiwny klasyfikator bayesowski raczej nie powinien być stosowany „produkcyjnie” (są lepsze metody). Natomiast jest to metoda bardzo prosta w implementacji dająca przyzwoity _baseline_.\n",
"\n",
"Naiwny klasyfikator bayesowski ma dwie odmiany:\n",
"\n",
@ -221,14 +221,14 @@
"source": [
"#### Prawdopodobieństwo _a priori_\n",
"\n",
"$P(c)$ - prawdopodobieństwo a priori klasy $c$\n",
"$P(c)$ prawdopodobieństwo a priori klasy $c$\n",
"\n",
"$\\hat{P}(c) = \\frac{N_c}{N}$\n",
"\n",
"gdzie\n",
"\n",
"* N - liczba wszystkich dokumentów w zbiorze uczącym\n",
"* N_c - liczba dokumentow w zbiorze uczącym z klasą $c$\n",
"* N liczba wszystkich dokumentów w zbiorze uczącym\n",
"* N_c liczba dokumentow w zbiorze uczącym z klasą $c$\n",
"\n",
"$\\hat{P}(c) = 0,75$\n",
"\n",
@ -256,11 +256,11 @@
"source": [
"$P(d|c) = P(t_1\\dots t_n|c)$\n",
"\n",
"Żeby pójść dalej musimy doszczegółowić nasz model generatywny. Przyjmijmy bardzo naiwny i niezgodny z rzeczywistością model spamera (i nie-spamera): spamer wyciąga wyrazy z worka i wrzuca je z powrotem (losowanie ze zwracaniem). Jedyne co odróżnia spamera i nie-spamera, to **prawdopodobieństwo wylosowania wyrazu** (np. spamer wylosuje słowo _Viagra_ z dość dużym prawdopodobieństwem, nie-spamer - z bardzo niskim).\n",
"Aby pójść dalej, musimy doszczegółowić nasz model generatywny. Przyjmijmy bardzo naiwny i niezgodny z rzeczywistością model spamera (i nie-spamera): spamer wyciąga wyrazy z worka i wrzuca je z powrotem (losowanie ze zwracaniem). Jedyne co odróżnia spamera i nie-spamera, to **prawdopodobieństwo wylosowania wyrazu** (np. spamer wylosuje słowo _Viagra_ z dość dużym prawdopodobieństwem, nie-spamer z bardzo niskim).\n",
"\n",
"**Pytanie:** Ile może wynosić $P(\\mathit{Viagra}|c)$?\n",
"\n",
"Po przyjęciu takich \"naiwnych założeń\":\n",
"Po przyjęciu takich „naiwnych założeń”:\n",
"\n",
"$$P(d|c) = P(t_1\\dots t_n|c) \\approx P(t_1|c)\\dots P(t_n|c) = \\prod_i^n P(t_i|c)$$"
]
@ -306,7 +306,7 @@
"\n",
"$$f(m, k, T) = \\frac{k+1}{T+m}$$\n",
"\n",
"Jest to wygładzanie +1, albo wygładzanie Laplace'a.\n",
"Jest to wygładzanie +1, inaczej wygładzanie Laplace'a.\n",
"\n",
"**Pytanie:** Wymyślić jakiś inny przykład funkcji, która będzie spełniała aksjomaty.\n",
"\n",

View File

@ -144,7 +144,10 @@
{
"cell_type": "markdown",
"id": "freelance-controversy",
"metadata": {},
"metadata": {
"jp-MarkdownHeadingCollapsed": true,
"tags": []
},
"source": [
"## Uczenie\n",
"\n",
@ -154,13 +157,11 @@
"\n",
"### Metoda gradientu prostego\n",
"\n",
"![Morskie Oko - Krzysztof Dudzik](08_files/morskieoko.jpg)\n",
"\n",
"(Źródło: https://pl.wikipedia.org/wiki/Morskie_Oko#/media/Plik:Morskie_Oko_ze_szlaku_przez_%C5%9Awist%C3%B3wk%C4%99.jpg, licencja CC BY 3.0)\n",
"![Morskie oko; Autor:Krzysztof Dudzik; Źródło: [https://pl.wikipedia.org/wiki/Morskie_Oko#/media/Plik:Morskie_Oko_ze_szlaku_przez_%C5%9Awist%C3%B3wk%C4%99.jpg](https://pl.wikipedia.org/wiki/Morskie_Oko#/media/Plik:Morskie_Oko_ze_szlaku_przez_%C5%9Awist%C3%B3wk%C4%99.jpg); Licencja: CC-BY 3.0](08_files/morskieoko.jpg)\n",
"\n",
"Schodź wzdłuż lokalnego spadku funkcji błędu.\n",
"\n",
"Tak więc w praktyce zamiast podstawiać do wzoru lepiej się uczyć iteracyjnie -\n",
"Tak więc w praktyce zamiast podstawiać do wzoru lepiej się uczyć iteracyjnie \n",
" metodą **gradientu prostego** (ang. _gradient descent_).\n",
"\n",
"1. Zacznij od byle jakich wag $w_i$ (np. wylosuj)\n",
@ -209,7 +210,7 @@
"\n",
"Czym jest wektor $\\vec{x} = (x_1,\\dots,x_n)$? Wiemy, np. reprezentacja tf-idf (być z trikiem z haszowaniem, Word2vec etc.).\n",
"\n",
"![schemat regresji liniowej](08_files/regresja-liniowa-tekst.png)\n"
"![Schemat regresji liniowej tekstu](08_files/regresja-liniowa-tekst.png)\n"
]
},
{

View File

@ -26,7 +26,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### Kilka uwag dotyczących wektorów\n",
"## Kilka uwag dotyczących wektorów\n",
"\n"
]
},
@ -78,7 +78,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### Funkcja sigmoidalna\n",
"## Funkcja sigmoidalna\n",
"\n"
]
},
@ -86,7 +86,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Funkcja sigmoidalna zamienia dowolną wartość („sygnał”) w wartość z przedziału $(0,1)$, czyli wartość, która może być interperetowana jako prawdopodobieństwo.\n",
"Funkcja sigmoidalna zamienia dowolną wartość („sygnał”) w wartość z przedziału $(0,1)$, czyli wartość, która może być interpretowana jako prawdopodobieństwo.\n",
"\n",
"$$\\sigma(x) = \\frac{1}{1 + e^{-x}}$$\n",
"\n"
@ -175,7 +175,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"#### PyTorch\n",
"### PyTorch\n",
"\n"
]
},
@ -283,7 +283,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Wagi\n",
"### Wagi\n",
"\n"
]
},
@ -307,7 +307,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### Regresja liniowa\n",
"## Regresja liniowa\n",
"\n"
]
},
@ -526,27 +526,25 @@
"Bezpośrednio możemy zastosować do zadania regresji dla tekstu (np.\n",
"przewidywanie roku publikacji tekstu).\n",
"\n",
"![img](./img-linear-regression.png)\n",
"![Schemat regresji logistycznej dla tekstu](./img-linear-regression.png)\n",
"\n",
"W połączeniu z sigmoidą otrzymamy regresją logistyczną, np. dla zadania klasyfikacji tekstu:\n",
"\n",
"$$p(c|\\vec{x}) = \\sigma(w_0 + w_1x_1 + w_2x_2 + \\dots + w_{|V|}x_{|v})\n",
"= \\sigma(\\Sigma_{i=0}^{|V|} w_ix_i) = \\sigma(\\vec{w}\\vec{x})$$\n",
"\n",
"![img](./img-logistic-regression.png)\n",
"\n",
"Tak sieć będzie aktywowana dla tekstu <u>aardvark in Aachen</u>:\n",
"\n",
"![img](./img-logistic-regression-aardvark.png)\n",
"![Schemat regresji logistycznej dla przykładowego tekstu](./img-logistic-regression-aardvark.png)\n",
"\n",
"Regresje logistyczną (liniową zresztą też) dla tekstu możemy połączyć z trikiem z haszowaniem:\n",
"Regresję logistyczną (liniową zresztą też) dla tekstu możemy połączyć z trikiem z haszowaniem:\n",
"\n",
"$$p(c|\\vec{x}) = \\sigma(w_0 + w_1x_1 + w_2x_2 + \\dots + w_{2^b}x_{2^b})\n",
"= \\sigma(\\Sigma_{i=0}^{2^b} w_ix_i) = \\sigma(\\vec{w}\\vec{x})$$ \n",
"{\\small hashing function $H : V \\rightarrow \\{1,\\dots,2^b\\}$,\n",
" e.g. MurmurHash3}\n",
"\n",
"![img](./img-logistic-regression-hashing.png)\n",
"![Schemat regresji logistycznej dla tekstu z zastosowaniem hashing trick](./img-logistic-regression-hashing.png)\n",
"\n",
"****Pytanie:**** Jaki tekst otrzyma na pewno taką samą klasę jak <u>aardvark in Aachen</u>?\n",
"\n"
@ -595,16 +593,16 @@
"Mnożenie macierzy przez wektor można interpretować jako zrównolegloną operację mnożenie wektora przez wektor.\n",
"\n",
"$$\\left[\\begin{array}{ccc}\n",
" \\alert<2>{1.0} & \\alert<2>{-2.0} & \\alert<2>{3.0} \\\\\n",
" \\alert<3>{-2.0} & \\alert<3>{0.0} & \\alert<3>{10.0}\\end{array}\\right]\n",
" 1.0 & -2.0 & 3.0 \\\\\n",
" -2.0 & 0.0 & 10.0\\end{array}\\right]\n",
" \\left[\\begin{array}{c}\n",
" \\alert<2-3>{1.0} \\\\\n",
" \\alert<2-3>{-0.5} \\\\\n",
" \\alert<2-3>{2.0}\\end{array}\\right]\n",
" 1.0 \\\\\n",
" -0.5 \\\\\n",
" 2.0\\end{array}\\right]\n",
" =\n",
" \\left[\\begin{array}{c}\n",
" \\uncover<2->{\\alert<2>{8.0}} \\\\\n",
" \\uncover<3->{\\alert<3>{18.0}}\\end{array}\\right]$$\n",
" 8.0 \\\\\n",
" 8.0\\end{array}\\right]$$\n",
"\n",
"Jeśli przemnożymy macierz $n \\times m$ przez wektor kolumnowy o długości\n",
"$m$, otrzymamy wektor o rozmiarze $n$.\n",
@ -660,7 +658,7 @@
"metadata": {},
"source": [
"Warstwa liniowa polega na przemnożeniu wejścia przez macierz. Można\n",
"to intepretować jako zrównolegloną operację regresji liniowej (równolegle\n",
"to interpretować jako zrównolegloną operację regresji liniowej (równolegle\n",
"uczymy czy wykonujemy $n$ regresji liniowych).\n",
"\n"
]
@ -731,7 +729,7 @@
"\n",
"Oto przykład prostej dwuwarstwowej sieci neuronowej do klasyfikacji binarnej.\n",
"\n",
"![img](./img-feed-forward.png)\n",
"![Schemat dwuwarstwowej sieci neuronowej do klasyfikacji binarnej tekstu](./img-feed-forward.png)\n",
"\n"
]
},
@ -747,7 +745,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"W klasyfikacji wieloklasowej należy zwrócić musimy zwrócić rozkład\n",
"W klasyfikacji wieloklasowej należy zwrócić rozkład\n",
"prawdopodobieństwa po wszystkich klasach, w przeciwieństwie do\n",
"klasyfikacji binarnej, gdzie wystarczy zwrócić jedną liczbę —\n",
"prawdopodobieństwo pozytywnej klasy ($p$; prawdopodobieństwo drugiej\n",
@ -770,7 +768,7 @@
"$$s(z_i) = \\frac{z_i}{\\Sigma_{j=1}^k z_j}$$\n",
"\n",
"To rozwiązanie zadziała błędnie dla liczb ujemnych, trzeba najpierw\n",
"użyć funkcji monotonicznej, która przekształaca $\\mathcal{R}$ na $\\mathcal{R^+}$.\n",
"użyć funkcji monotonicznej, która przekształca $\\mathcal{R}$ na $\\mathcal{R^+}$.\n",
"Naturalna funkcja tego rodzaju to funkcja wykładnicza $\\exp{x} = e^x$.\n",
"Tym sposobem dochodzimy do funkcji softmax:\n",
"\n",
@ -815,7 +813,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"![img](./softmax.png \"Softmax\")\n",
"![Schemat funkcji Softmax](./softmax.png \"Softmax\")\n",
"\n"
]
},
@ -1238,7 +1236,7 @@
"metadata": {},
"source": [
"Ze względów obliczeniowych często korzysta się z funkcji **LogSoftmax**\n",
"która zwraca logarytmy pradopodobieństw (*logproby*).\n",
"która zwraca logarytmy prawdopodobieństw (*logproby*).\n",
"\n",
"$$log s(z_i) = log \\frac{e^{z_i}}{\\Sigma_{j=1}^k e^{z_j}}$$\n",
"\n"
@ -1776,7 +1774,7 @@
"metadata": {},
"source": [
"W czasie inferencji mamy ustalone wagi funkcji $\\vec{v}(\\dots)$ oraz\n",
"macierz $V$. Szukamy sekwencji $y$ która maksymalizuje prawdopodobieństwo estymowane przez model:\n",
"macierz $V$. Szukamy sekwencji $y$, która maksymalizuje prawdopodobieństwo estymowane przez model:\n",
"\n",
"$$y = \\underset{l}{\\operatorname{argmax}} \\hat{p}(l|t^1,\\dots,t^K)$$\n",
"\n",
@ -1819,7 +1817,7 @@
"\n",
"$$y^i = b[i, y^{i+1}]$$\n",
"\n",
"![img](./crf-viterbi.png)\n",
"![CRF - Algorytm Viterbiego](./crf-viterbi.png)\n",
"\n"
]
},

View File

@ -34,7 +34,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Regresja liniowa/logistyczna lub klasyfikacja wieloklasowa na całym tekście\n",
"### Regresja liniowa/logistyczna lub klasyfikacja wieloklasowa na całym tekście\n",
"\n"
]
},
@ -179,7 +179,7 @@
"\n",
"Taką sieć RNN można przedstawić schematycznie w następujący sposób:\n",
"\n",
"![img](./img-rnn.png)\n",
"![Pojedynczy krok sieci rekurencyjnej](./img-rnn.png)\n",
"\n",
"Zauważmy, że zamiast macierzy $W$ działającej na konkatenacji wektorów można wprowadzić dwie\n",
"macierze $U$ i $V$ i tak zapisać wzór:\n",
@ -188,12 +188,12 @@
"\n",
"Jeszcze inne spojrzenie na sieć RNN:\n",
"\n",
"![img](./rnn.png)\n",
"![Pojedynczy krok sieci rekurencyjnej II](./rnn.png)\n",
"\n",
"Powyższy rysunek przedstawia pojedynczy krok sieci RNN. Dla całego\n",
"wejścia (powiedzmy, 3-wyrazowego) możemy sieć rozwinąć (*unroll*):\n",
"\n",
"![img](./rnn-seq.png)\n",
"![Rozwinięta sieć rekurencyjna](./rnn-seq.png)\n",
"\n"
]
},
@ -202,7 +202,8 @@
"metadata": {},
"source": [
"#### Zastosowanie sieci RNN do etykietowania sekwencji\n",
"\n"
"\n",
"Sieć RNN może w prosty sposób być użyta do etykietowania sekwencji (w każdym kroku zwracamy etykietę)."
]
},
{
@ -228,7 +229,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### Sieci RNN z bramkami\n",
"## Sieci RNN z bramkami\n",
"\n"
]
},

View File

@ -507,7 +507,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### BPE\n",
"## BPE\n",
"\n"
]
},
@ -532,7 +532,7 @@
"słownika. W każdym kroku szukamy najczęstszego bigramu, od tego\n",
"momentu traktujemy go jako całostkę (wkładamy go do „pudełka”).\n",
"\n",
"![img](./bpe.png)\n",
"![Sekwencja kroków algorytmu BPE dla przykładowego zdania](./bpe.png)\n",
"\n"
]
},

View File

@ -36,11 +36,11 @@
"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",
"![Ekstrakcja informacji jako etykietowanie sekwencji, schemat](./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",
"![Ekstrakcja informacji w podejściu generatywnym](./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",
@ -56,7 +56,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### Atencja\n",
"## Atencja\n",
"\n"
]
},

View File

@ -1,391 +1,389 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"collapsed": false
},
"source": [
"![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n",
"<div class=\"alert alert-block alert-info\">\n",
"<h1> Ekstrakcja informacji </h1>\n",
"<h2> 14. <i>Pretrenowane modele j\u0119zyka</i> [wyk\u0142ad]</h2> \n",
"<h3> Filip Grali\u0144ski (2021)</h3>\n",
"</div>\n",
"\n",
"![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Pretrenowanie modeli\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"System AlphaZero uczy si\u0119 graj\u0105c sam ze sob\u0105 \u2014 wystarczy 24 godziny,\n",
"by system nauczy\u0142 si\u0119 gra\u0107 w szachy lub go na nadludzkim poziomie.\n",
"\n",
"**Pytanie**: Dlaczego granie samemu ze sob\u0105 nie jest dobrym sposobem\n",
" nauczenia si\u0119 grania w szachy dla cz\u0142owieka, a dla maszyny jest?\n",
"\n",
"Co jest odpowiednikiem grania samemu ze sob\u0105 w \u015bwiecie przetwarzania tekstu?\n",
"Tzn. **pretrenowanie** (*pretraining*) na du\u017cym korpusie tekstu. (Tekst jest tani!)\n",
"\n",
"Jest kilka sposob\u00f3w na pretrenowanie modelu, w ka\u017cdym razie sprowadza\n",
"si\u0119 do odgadywania nast\u0119pnego b\u0105d\u017a zamaskowanego s\u0142owa.\n",
"W ka\u017cdym razie zawsze stosujemy softmax (by\u0107 mo\u017ce ze \u201esztuczkami\u201d takimi jak\n",
"negatywne pr\u00f3bkowanie albo hierarchiczny softmax) na pewnej **reprezentacji kontekstowej**:\n",
"\n",
"$$\\vec{p} = \\operatorname{softmax}(f(\\vec{c})).$$\n",
"\n",
"Model jest karany u\u017cywaj\u0105c funkcji log loss:\n",
"\n",
"$$-\\log(p_j),$$\n",
"\n",
"gdzie $w_j$ jest wyrazem, kt\u00f3ry pojawi\u0142 si\u0119 rzeczywi\u015bcie w korpusie.\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Przewidywanie s\u0142owa (GPT-2)\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Jeden ze sposob\u00f3w pretrenowania modelu to po prostu przewidywanie\n",
"nast\u0119pnego s\u0142owa.\n",
"\n",
"Zainstalujmy najpierw bibliotek\u0119 transformers.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"! pip install transformers"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"50257\n"
]
},
{
"data": {
"text/plain": [
"[('\u00c2\u0142', 0.6182783842086792),\n",
" ('\u00c8', 0.1154019758105278),\n",
" ('\u00d1\u0123', 0.026960616931319237),\n",
" ('_____', 0.024418892338871956),\n",
" ('________', 0.014962316490709782),\n",
" ('\u00c3\u0124', 0.010653386823832989),\n",
" ('\u00e4\u00b8\u0143', 0.008340531960129738),\n",
" ('\u00d1', 0.007557711564004421),\n",
" ('\u00ca', 0.007046067621558905),\n",
" ('\u00e3\u0122', 0.006875576451420784),\n",
" ('ile', 0.006685272324830294),\n",
" ('____', 0.006307446397840977),\n",
" ('\u00e2\u0122\u012d', 0.006306538358330727),\n",
" ('\u00d1\u0122', 0.006197483278810978),\n",
" ('\u0120Belarus', 0.006108700763434172),\n",
" ('\u00c6', 0.005720408633351326),\n",
" ('\u0120Poland', 0.0053678699769079685),\n",
" ('\u00e1\u00b9', 0.004606408067047596),\n",
" ('\u00ee\u0122', 0.004161055199801922),\n",
" ('????', 0.004056799225509167),\n",
" ('_______', 0.0038176667876541615),\n",
" ('\u00e4\u00b8', 0.0036082742735743523),\n",
" ('\u00cc', 0.003221835708245635),\n",
" ('urs', 0.003080119378864765),\n",
" ('________________', 0.0027312245219945908),\n",
" ('\u0120Lithuania', 0.0023860156070441008),\n",
" ('ich', 0.0021211160346865654),\n",
" ('iz', 0.002069818088784814),\n",
" ('vern', 0.002001357264816761),\n",
" ('\u00c5\u0124', 0.001717406208626926)]"
]
},
"execution_count": 17,
"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 = 'Warsaw is the capital city of'\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",
"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\u015bcia:\n",
"\n",
"- prostota,\n",
"- dobra podstawa do strojenia system\u00f3w generowania tekstu zw\u0142aszcza\n",
" \u201eotwartego\u201d (systemy dialogowe, generowanie (fake) news\u00f3w, streszczanie tekstu),\n",
" ale niekoniecznie t\u0142umaczenia maszynowego,\n",
"- zaskakuj\u0105ca skuteczno\u015b\u0107 przy uczeniu *few-shot* i *zero-shot*.\n",
"\n",
"Wady:\n",
"\n",
"- asymetryczno\u015b\u0107, przetwarzanie tylko z lewej do prawej, preferencja\n",
" dla lewego kontekstu,\n",
"- mniejsza skuteczno\u015b\u0107 przy dostrajaniu do zada\u0144 klasyfikacji i innych zada\u0144\n",
" niepolegaj\u0105cych na prostym generowaniu.\n",
"\n",
"Przyk\u0142ady modeli: GPT, GPT-2, GPT-3, DialoGPT.\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Maskowanie s\u0142\u00f3w (BERT)\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Inn\u0105 metod\u0105 jest maskowanie s\u0142\u00f3w (*Masked Language Modeling*, *MLM*).\n",
"\n",
"W tym podej\u015bciu losowe wybrane zast\u0119pujemy losowe s\u0142owa specjalnym\n",
"tokenem (`[MASK]`) i ka\u017cemy modelowi odgadywa\u0107 w ten spos\u00f3b\n",
"zamaskowane s\u0142owa (z uwzgl\u0119dnieniem r\u00f3wnie\u017c prawego kontekstu!).\n",
"\n",
"M\u00f3ci\u0105c \u015bci\u015ble, w jednym z pierwszych modeli tego typu (BERT)\n",
"zastosowano schemat, w kt\u00f3rym r\u00f3wnie\u017c niezamaskowane s\u0142owa s\u0105 odgadywane (!):\n",
"\n",
"- wybieramy losowe 15% wyraz\u00f3w do odgadni\u0119cia\n",
"- 80% z nich zast\u0119pujemy tokenem `[MASK]`,\n",
"- 10% zast\u0119pujemy innym losowym wyrazem,\n",
"- 10% pozostawiamy bez zmian.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/filipg/.local/lib/python3.9/site-packages/transformers/models/auto/modeling_auto.py:806: FutureWarning: The class `AutoModelWithLMHead` is deprecated and will be removed in a future version. Please use `AutoModelForCausalLM` for causal language models, `AutoModelForMaskedLM` for masked language models and `AutoModelForSeq2SeqLM` for encoder-decoder models.\n",
" warnings.warn(\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W USA. (score: 0.16715531051158905)\n",
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W India. (score: 0.09912960231304169)\n",
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W Indian. (score: 0.039642028510570526)\n",
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W Nepal. (score: 0.027137665078043938)\n",
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W Pakistan. (score: 0.027065709233283997)\n",
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W Polsce. (score: 0.023737527430057526)\n",
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W .... (score: 0.02306722290813923)\n",
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W Bangladesh. (score: 0.022106658667325974)\n",
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W .... (score: 0.01628892682492733)\n",
"W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W Niemczech. (score: 0.014501162804663181)\n"
]
}
],
"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'W kt\u00f3rym pa\u0144stwie le\u017cy Bombaj? W {tokenizer.mask_token}.'\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\u0142ady: BERT, RoBERTa (r\u00f3wnie\u017c Polish RoBERTa).\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Podej\u015bcie generatywne (koder-dekoder).\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"System ma wygenerowa\u0107 odpowied\u017a na r\u00f3\u017cne pytania (r\u00f3wnie\u017c\n",
"odpowiadaj\u0105ce 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&#x2026;\"\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": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['World War II ended in World War II.',\n",
" 'World War II ended in 1945..',\n",
" 'World War II ended in 1945.',\n",
" 'World War II ended in 1945.',\n",
" 'World War II ended in 1945.']"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"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'World War II ended in {slot}.'\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\u0142ad: T5, mT5\n",
"\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.6"
},
"org": null,
"author": "Filip Grali\u0144ski",
"email": "filipg@amu.edu.pl",
"lang": "pl",
"subtitle": "14.Pretrenowane modele j\u0119zyka[wyk\u0142ad]",
"title": "Ekstrakcja informacji",
"year": "2021"
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n",
"<div class=\"alert alert-block alert-info\">\n",
"<h1> Ekstrakcja informacji </h1>\n",
"<h2> 14. <i>Pretrenowane modele języka</i> [wykład]</h2> \n",
"<h3> Filip Graliński (2021)</h3>\n",
"</div>\n",
"\n",
"![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)"
]
},
{
"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 softmax) na pewnej **reprezentacji kontekstowej**:\n",
"\n",
"$$\\vec{p} = \\operatorname{softmax}(f(\\vec{c})).$$\n",
"\n",
"Model jest karany przy użyciu 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": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"50257\n"
]
},
"nbformat": 4,
"nbformat_minor": 4
}
{
"data": {
"text/plain": [
"[('Âł', 0.6182783842086792),\n",
" ('È', 0.1154019758105278),\n",
" ('Ñģ', 0.026960616931319237),\n",
" ('_____', 0.024418892338871956),\n",
" ('________', 0.014962316490709782),\n",
" ('ÃĤ', 0.010653386823832989),\n",
" ('ä¸Ń', 0.008340531960129738),\n",
" ('Ñ', 0.007557711564004421),\n",
" ('Ê', 0.007046067621558905),\n",
" ('ãĢ', 0.006875576451420784),\n",
" ('ile', 0.006685272324830294),\n",
" ('____', 0.006307446397840977),\n",
" ('âĢĭ', 0.006306538358330727),\n",
" ('ÑĢ', 0.006197483278810978),\n",
" ('ĠBelarus', 0.006108700763434172),\n",
" ('Æ', 0.005720408633351326),\n",
" ('ĠPoland', 0.0053678699769079685),\n",
" ('á¹', 0.004606408067047596),\n",
" ('îĢ', 0.004161055199801922),\n",
" ('????', 0.004056799225509167),\n",
" ('_______', 0.0038176667876541615),\n",
" ('ä¸', 0.0036082742735743523),\n",
" ('Ì', 0.003221835708245635),\n",
" ('urs', 0.003080119378864765),\n",
" ('________________', 0.0027312245219945908),\n",
" ('ĠLithuania', 0.0023860156070441008),\n",
" ('ich', 0.0021211160346865654),\n",
" ('iz', 0.002069818088784814),\n",
" ('vern', 0.002001357264816761),\n",
" ('ÅĤ', 0.001717406208626926)]"
]
},
"execution_count": 17,
"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 = 'Warsaw is the capital city of'\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",
"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": "stderr",
"output_type": "stream",
"text": [
"/home/filipg/.local/lib/python3.9/site-packages/transformers/models/auto/modeling_auto.py:806: FutureWarning: The class `AutoModelWithLMHead` is deprecated and will be removed in a future version. Please use `AutoModelForCausalLM` for causal language models, `AutoModelForMaskedLM` for masked language models and `AutoModelForSeq2SeqLM` for encoder-decoder models.\n",
" warnings.warn(\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"W którym państwie leży Bombaj? W USA. (score: 0.16715531051158905)\n",
"W którym państwie leży Bombaj? W India. (score: 0.09912960231304169)\n",
"W którym państwie leży Bombaj? W Indian. (score: 0.039642028510570526)\n",
"W którym państwie leży Bombaj? W Nepal. (score: 0.027137665078043938)\n",
"W którym państwie leży Bombaj? W Pakistan. (score: 0.027065709233283997)\n",
"W którym państwie leży Bombaj? W Polsce. (score: 0.023737527430057526)\n",
"W którym państwie leży Bombaj? W .... (score: 0.02306722290813923)\n",
"W którym państwie leży Bombaj? W Bangladesh. (score: 0.022106658667325974)\n",
"W którym państwie leży Bombaj? W .... (score: 0.01628892682492733)\n",
"W którym państwie leży Bombaj? W Niemczech. (score: 0.014501162804663181)\n"
]
}
],
"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'W którym państwie leży Bombaj? W {tokenizer.mask_token}.'\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&#x2026;\"\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": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['World War II ended in World War II.',\n",
" 'World War II ended in 1945..',\n",
" 'World War II ended in 1945.',\n",
" 'World War II ended in 1945.',\n",
" 'World War II ended in 1945.']"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"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'World War II ended in {slot}.'\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": {
"author": "Filip Graliński",
"email": "filipg@amu.edu.pl",
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"lang": "pl",
"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.6"
},
"org": null,
"subtitle": "14.Pretrenowane modele języka[wykład]",
"title": "Ekstrakcja informacji",
"year": "2021"
},
"nbformat": 4,
"nbformat_minor": 4
}

View File

@ -219,7 +219,10 @@
"- $V$ = $EW^V$\n",
"\n",
"W kolejnych warstwach zamiast $E$ wykorzystywane jest wyjście z poprzedniej warstwy.\n",
"\n"
"\n",
"## Zastosowanie w ekstrakcji informacji\n",
"\n",
"W prosty sposób możemy do sieci Transformer dołączyć głowicę realizującą etykietowanie sekwencji."
]
},
{