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", "cell_type": "markdown",
"execution_count": null,
"metadata": {}, "metadata": {},
"outputs": [],
"source": [ "source": [
"# Wyszukiwarki - wprowadzenie\n", "# Wyszukiwarki - wprowadzenie\n",
"\n", "\n",
"## Systemy wyszukiwania informacji (information retrieval systems)\n", "## Systemy wyszukiwania informacji (information retrieval systems)\n",
"\n", "\n",
"![System wyszukiwania informacji](system-wyszukiwania-informacji.png)" "![Schemat systemu wyszukiwania informacji](system-wyszukiwania-informacji.png)"
] ]
}, },
{ {
@ -36,7 +34,7 @@
"source": [ "source": [
"## Wyszukiwarki\n", "## Wyszukiwarki\n",
"\n", "\n",
"![Wyszukiwarki](wyszukiwarka-internetowa.png)" "![Schemat wyszukiwarki internetowej](wyszukiwarka-internetowa.png)"
] ]
}, },
{ {
@ -108,7 +106,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "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", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Odpytywać \"pasożytniczo\" inną wyszukiwarkę" "### Odpytywać „pasożytniczo” inną wyszukiwarkę"
] ]
}, },
{ {
@ -312,7 +310,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "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", "\n",
"import urllib\n", "import urllib\n",
"import requests\n", "import requests\n",

View File

@ -328,7 +328,7 @@
"\n", "\n",
"* urllib\n", "* urllib\n",
"* request\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", "\n",
"Zakładamy, że mamy dwie klasy: $c$ i jej dopełnienie ($\\bar{c}$).\n", "Zakładamy, że mamy dwie klasy: $c$ i jej dopełnienie ($\\bar{c}$).\n",
"\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", "\n",
"W klasyfikacji (i w ogóle w uczeniu nadzorowanym) można wskazać dwa podejścia:\n", "W klasyfikacji (i w ogóle w uczeniu nadzorowanym) można wskazać dwa podejścia:\n",
"\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", "\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", "\n",
"**Pytanie**: Jakie są wady i zalety obu podejść?" "**Pytanie**: Jakie są wady i zalety obu podejść?"
] ]
@ -146,11 +146,11 @@
"source": [ "source": [
"## Naiwny klasyfikator bayesowski\n", "## Naiwny klasyfikator bayesowski\n",
"\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", "* _klasyfikator_ \n",
"* _bayesowski_ - będzie odwoływać się do wzoru Bayesa.\n", "* _bayesowski_ będzie odwoływać się do wzoru Bayesa.\n",
"\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", "\n",
"Naiwny klasyfikator bayesowski ma dwie odmiany:\n", "Naiwny klasyfikator bayesowski ma dwie odmiany:\n",
"\n", "\n",
@ -221,14 +221,14 @@
"source": [ "source": [
"#### Prawdopodobieństwo _a priori_\n", "#### Prawdopodobieństwo _a priori_\n",
"\n", "\n",
"$P(c)$ - prawdopodobieństwo a priori klasy $c$\n", "$P(c)$ prawdopodobieństwo a priori klasy $c$\n",
"\n", "\n",
"$\\hat{P}(c) = \\frac{N_c}{N}$\n", "$\\hat{P}(c) = \\frac{N_c}{N}$\n",
"\n", "\n",
"gdzie\n", "gdzie\n",
"\n", "\n",
"* N - liczba wszystkich dokumentów w zbiorze uczącym\n", "* N liczba wszystkich dokumentów w zbiorze uczącym\n",
"* N_c - liczba dokumentow w zbiorze uczącym z klasą $c$\n", "* N_c liczba dokumentow w zbiorze uczącym z klasą $c$\n",
"\n", "\n",
"$\\hat{P}(c) = 0,75$\n", "$\\hat{P}(c) = 0,75$\n",
"\n", "\n",
@ -256,11 +256,11 @@
"source": [ "source": [
"$P(d|c) = P(t_1\\dots t_n|c)$\n", "$P(d|c) = P(t_1\\dots t_n|c)$\n",
"\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", "\n",
"**Pytanie:** Ile może wynosić $P(\\mathit{Viagra}|c)$?\n", "**Pytanie:** Ile może wynosić $P(\\mathit{Viagra}|c)$?\n",
"\n", "\n",
"Po przyjęciu takich \"naiwnych założeń\":\n", "Po przyjęciu takich „naiwnych założeń”:\n",
"\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)$$" "$$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", "\n",
"$$f(m, k, T) = \\frac{k+1}{T+m}$$\n", "$$f(m, k, T) = \\frac{k+1}{T+m}$$\n",
"\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", "\n",
"**Pytanie:** Wymyślić jakiś inny przykład funkcji, która będzie spełniała aksjomaty.\n", "**Pytanie:** Wymyślić jakiś inny przykład funkcji, która będzie spełniała aksjomaty.\n",
"\n", "\n",

View File

@ -144,7 +144,10 @@
{ {
"cell_type": "markdown", "cell_type": "markdown",
"id": "freelance-controversy", "id": "freelance-controversy",
"metadata": {}, "metadata": {
"jp-MarkdownHeadingCollapsed": true,
"tags": []
},
"source": [ "source": [
"## Uczenie\n", "## Uczenie\n",
"\n", "\n",
@ -154,13 +157,11 @@
"\n", "\n",
"### Metoda gradientu prostego\n", "### Metoda gradientu prostego\n",
"\n", "\n",
"![Morskie Oko - Krzysztof Dudzik](08_files/morskieoko.jpg)\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",
"(Ź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",
"\n", "\n",
"Schodź wzdłuż lokalnego spadku funkcji błędu.\n", "Schodź wzdłuż lokalnego spadku funkcji błędu.\n",
"\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", " metodą **gradientu prostego** (ang. _gradient descent_).\n",
"\n", "\n",
"1. Zacznij od byle jakich wag $w_i$ (np. wylosuj)\n", "1. Zacznij od byle jakich wag $w_i$ (np. wylosuj)\n",
@ -209,7 +210,7 @@
"\n", "\n",
"Czym jest wektor $\\vec{x} = (x_1,\\dots,x_n)$? Wiemy, np. reprezentacja tf-idf (być z trikiem z haszowaniem, Word2vec etc.).\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", "\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", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Kilka uwag dotyczących wektorów\n", "## Kilka uwag dotyczących wektorów\n",
"\n" "\n"
] ]
}, },
@ -78,7 +78,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Funkcja sigmoidalna\n", "## Funkcja sigmoidalna\n",
"\n" "\n"
] ]
}, },
@ -86,7 +86,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "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", "\n",
"$$\\sigma(x) = \\frac{1}{1 + e^{-x}}$$\n", "$$\\sigma(x) = \\frac{1}{1 + e^{-x}}$$\n",
"\n" "\n"
@ -175,7 +175,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"#### PyTorch\n", "### PyTorch\n",
"\n" "\n"
] ]
}, },
@ -283,7 +283,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"#### Wagi\n", "### Wagi\n",
"\n" "\n"
] ]
}, },
@ -307,7 +307,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Regresja liniowa\n", "## Regresja liniowa\n",
"\n" "\n"
] ]
}, },
@ -526,27 +526,25 @@
"Bezpośrednio możemy zastosować do zadania regresji dla tekstu (np.\n", "Bezpośrednio możemy zastosować do zadania regresji dla tekstu (np.\n",
"przewidywanie roku publikacji tekstu).\n", "przewidywanie roku publikacji tekstu).\n",
"\n", "\n",
"![img](./img-linear-regression.png)\n", "![Schemat regresji logistycznej dla tekstu](./img-linear-regression.png)\n",
"\n", "\n",
"W połączeniu z sigmoidą otrzymamy regresją logistyczną, np. dla zadania klasyfikacji tekstu:\n", "W połączeniu z sigmoidą otrzymamy regresją logistyczną, np. dla zadania klasyfikacji tekstu:\n",
"\n", "\n",
"$$p(c|\\vec{x}) = \\sigma(w_0 + w_1x_1 + w_2x_2 + \\dots + w_{|V|}x_{|v})\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", "= \\sigma(\\Sigma_{i=0}^{|V|} w_ix_i) = \\sigma(\\vec{w}\\vec{x})$$\n",
"\n", "\n",
"![img](./img-logistic-regression.png)\n",
"\n",
"Tak sieć będzie aktywowana dla tekstu <u>aardvark in Aachen</u>:\n", "Tak sieć będzie aktywowana dla tekstu <u>aardvark in Aachen</u>:\n",
"\n", "\n",
"![img](./img-logistic-regression-aardvark.png)\n", "![Schemat regresji logistycznej dla przykładowego tekstu](./img-logistic-regression-aardvark.png)\n",
"\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", "\n",
"$$p(c|\\vec{x}) = \\sigma(w_0 + w_1x_1 + w_2x_2 + \\dots + w_{2^b}x_{2^b})\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", "= \\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", "{\\small hashing function $H : V \\rightarrow \\{1,\\dots,2^b\\}$,\n",
" e.g. MurmurHash3}\n", " e.g. MurmurHash3}\n",
"\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", "\n",
"****Pytanie:**** Jaki tekst otrzyma na pewno taką samą klasę jak <u>aardvark in Aachen</u>?\n", "****Pytanie:**** Jaki tekst otrzyma na pewno taką samą klasę jak <u>aardvark in Aachen</u>?\n",
"\n" "\n"
@ -595,16 +593,16 @@
"Mnożenie macierzy przez wektor można interpretować jako zrównolegloną operację mnożenie wektora przez wektor.\n", "Mnożenie macierzy przez wektor można interpretować jako zrównolegloną operację mnożenie wektora przez wektor.\n",
"\n", "\n",
"$$\\left[\\begin{array}{ccc}\n", "$$\\left[\\begin{array}{ccc}\n",
" \\alert<2>{1.0} & \\alert<2>{-2.0} & \\alert<2>{3.0} \\\\\n", " 1.0 & -2.0 & 3.0 \\\\\n",
" \\alert<3>{-2.0} & \\alert<3>{0.0} & \\alert<3>{10.0}\\end{array}\\right]\n", " -2.0 & 0.0 & 10.0\\end{array}\\right]\n",
" \\left[\\begin{array}{c}\n", " \\left[\\begin{array}{c}\n",
" \\alert<2-3>{1.0} \\\\\n", " 1.0 \\\\\n",
" \\alert<2-3>{-0.5} \\\\\n", " -0.5 \\\\\n",
" \\alert<2-3>{2.0}\\end{array}\\right]\n", " 2.0\\end{array}\\right]\n",
" =\n", " =\n",
" \\left[\\begin{array}{c}\n", " \\left[\\begin{array}{c}\n",
" \\uncover<2->{\\alert<2>{8.0}} \\\\\n", " 8.0 \\\\\n",
" \\uncover<3->{\\alert<3>{18.0}}\\end{array}\\right]$$\n", " 8.0\\end{array}\\right]$$\n",
"\n", "\n",
"Jeśli przemnożymy macierz $n \\times m$ przez wektor kolumnowy o długości\n", "Jeśli przemnożymy macierz $n \\times m$ przez wektor kolumnowy o długości\n",
"$m$, otrzymamy wektor o rozmiarze $n$.\n", "$m$, otrzymamy wektor o rozmiarze $n$.\n",
@ -660,7 +658,7 @@
"metadata": {}, "metadata": {},
"source": [ "source": [
"Warstwa liniowa polega na przemnożeniu wejścia przez macierz. Można\n", "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", "uczymy czy wykonujemy $n$ regresji liniowych).\n",
"\n" "\n"
] ]
@ -731,7 +729,7 @@
"\n", "\n",
"Oto przykład prostej dwuwarstwowej sieci neuronowej do klasyfikacji binarnej.\n", "Oto przykład prostej dwuwarstwowej sieci neuronowej do klasyfikacji binarnej.\n",
"\n", "\n",
"![img](./img-feed-forward.png)\n", "![Schemat dwuwarstwowej sieci neuronowej do klasyfikacji binarnej tekstu](./img-feed-forward.png)\n",
"\n" "\n"
] ]
}, },
@ -747,7 +745,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "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", "prawdopodobieństwa po wszystkich klasach, w przeciwieństwie do\n",
"klasyfikacji binarnej, gdzie wystarczy zwrócić jedną liczbę —\n", "klasyfikacji binarnej, gdzie wystarczy zwrócić jedną liczbę —\n",
"prawdopodobieństwo pozytywnej klasy ($p$; prawdopodobieństwo drugiej\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", "$$s(z_i) = \\frac{z_i}{\\Sigma_{j=1}^k z_j}$$\n",
"\n", "\n",
"To rozwiązanie zadziała błędnie dla liczb ujemnych, trzeba najpierw\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", "Naturalna funkcja tego rodzaju to funkcja wykładnicza $\\exp{x} = e^x$.\n",
"Tym sposobem dochodzimy do funkcji softmax:\n", "Tym sposobem dochodzimy do funkcji softmax:\n",
"\n", "\n",
@ -815,7 +813,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"![img](./softmax.png \"Softmax\")\n", "![Schemat funkcji Softmax](./softmax.png \"Softmax\")\n",
"\n" "\n"
] ]
}, },
@ -1238,7 +1236,7 @@
"metadata": {}, "metadata": {},
"source": [ "source": [
"Ze względów obliczeniowych często korzysta się z funkcji **LogSoftmax**\n", "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", "\n",
"$$log s(z_i) = log \\frac{e^{z_i}}{\\Sigma_{j=1}^k e^{z_j}}$$\n", "$$log s(z_i) = log \\frac{e^{z_i}}{\\Sigma_{j=1}^k e^{z_j}}$$\n",
"\n" "\n"
@ -1776,7 +1774,7 @@
"metadata": {}, "metadata": {},
"source": [ "source": [
"W czasie inferencji mamy ustalone wagi funkcji $\\vec{v}(\\dots)$ oraz\n", "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", "\n",
"$$y = \\underset{l}{\\operatorname{argmax}} \\hat{p}(l|t^1,\\dots,t^K)$$\n", "$$y = \\underset{l}{\\operatorname{argmax}} \\hat{p}(l|t^1,\\dots,t^K)$$\n",
"\n", "\n",
@ -1819,7 +1817,7 @@
"\n", "\n",
"$$y^i = b[i, y^{i+1}]$$\n", "$$y^i = b[i, y^{i+1}]$$\n",
"\n", "\n",
"![img](./crf-viterbi.png)\n", "![CRF - Algorytm Viterbiego](./crf-viterbi.png)\n",
"\n" "\n"
] ]
}, },

View File

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

View File

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

View File

@ -36,11 +36,11 @@
"source": [ "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", "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", "\n",
"![img](./ie-seqlab.png)\n", "![Ekstrakcja informacji jako etykietowanie sekwencji, schemat](./ie-seqlab.png)\n",
"\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", "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", "\n",
"![img](./ie-gener.png)\n", "![Ekstrakcja informacji w podejściu generatywnym](./ie-gener.png)\n",
"\n", "\n",
"To podejście może się wydawać trudniejsze niż etykietowanie sekwencji, ale wystarczająco zaawansowanej architekturze sieci, jest wykonalne.\n", "To podejście może się wydawać trudniejsze niż etykietowanie sekwencji, ale wystarczająco zaawansowanej architekturze sieci, jest wykonalne.\n",
"\n", "\n",
@ -56,7 +56,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Atencja\n", "## Atencja\n",
"\n" "\n"
] ]
}, },

View File

@ -1,391 +1,389 @@
{ {
"cells": [ "cells": [
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": { "metadata": {},
"collapsed": false "source": [
}, "![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n",
"source": [ "<div class=\"alert alert-block alert-info\">\n",
"![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n", "<h1> Ekstrakcja informacji </h1>\n",
"<div class=\"alert alert-block alert-info\">\n", "<h2> 14. <i>Pretrenowane modele języka</i> [wykład]</h2> \n",
"<h1> Ekstrakcja informacji </h1>\n", "<h3> Filip Graliński (2021)</h3>\n",
"<h2> 14. <i>Pretrenowane modele j\u0119zyka</i> [wyk\u0142ad]</h2> \n", "</div>\n",
"<h3> Filip Grali\u0144ski (2021)</h3>\n", "\n",
"</div>\n", "![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)"
"\n", ]
"![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)" },
] {
}, "cell_type": "markdown",
{ "metadata": {},
"cell_type": "markdown", "source": [
"metadata": {}, "## Pretrenowanie modeli\n",
"source": [ "\n"
"## Pretrenowanie modeli\n", ]
"\n" },
] {
}, "cell_type": "markdown",
{ "metadata": {},
"cell_type": "markdown", "source": [
"metadata": {}, "System AlphaZero uczy się grając sam ze sobą — wystarczy 24 godziny,\n",
"source": [ "by system nauczył się grać w szachy lub go na nadludzkim poziomie.\n",
"System AlphaZero uczy si\u0119 graj\u0105c sam ze sob\u0105 \u2014 wystarczy 24 godziny,\n", "\n",
"by system nauczy\u0142 si\u0119 gra\u0107 w szachy lub go na nadludzkim poziomie.\n", "**Pytanie**: Dlaczego granie samemu ze sobą nie jest dobrym sposobem\n",
"\n", " nauczenia się grania w szachy dla człowieka, a dla maszyny jest?\n",
"**Pytanie**: Dlaczego granie samemu ze sob\u0105 nie jest dobrym sposobem\n", "\n",
" nauczenia si\u0119 grania w szachy dla cz\u0142owieka, a dla maszyny jest?\n", "Co jest odpowiednikiem grania samemu ze sobą w świecie przetwarzania tekstu?\n",
"\n", "Tzn. **pretrenowanie** (*pretraining*) na dużym korpusie tekstu. (Tekst jest tani!)\n",
"Co jest odpowiednikiem grania samemu ze sob\u0105 w \u015bwiecie przetwarzania tekstu?\n", "\n",
"Tzn. **pretrenowanie** (*pretraining*) na du\u017cym korpusie tekstu. (Tekst jest tani!)\n", "Jest kilka sposobów na pretrenowanie modelu, w każdym razie sprowadza\n",
"\n", "się do odgadywania następnego bądź zamaskowanego słowa.\n",
"Jest kilka sposob\u00f3w na pretrenowanie modelu, w ka\u017cdym razie sprowadza\n", "W każdym razie zawsze stosujemy softmax (być może ze „sztuczkami” takimi jak\n",
"si\u0119 do odgadywania nast\u0119pnego b\u0105d\u017a zamaskowanego s\u0142owa.\n", "negatywne próbkowanie albo hierarchiczny softmax) na pewnej **reprezentacji kontekstowej**:\n",
"W ka\u017cdym razie zawsze stosujemy softmax (by\u0107 mo\u017ce ze \u201esztuczkami\u201d takimi jak\n", "\n",
"negatywne pr\u00f3bkowanie albo hierarchiczny softmax) na pewnej **reprezentacji kontekstowej**:\n", "$$\\vec{p} = \\operatorname{softmax}(f(\\vec{c})).$$\n",
"\n", "\n",
"$$\\vec{p} = \\operatorname{softmax}(f(\\vec{c})).$$\n", "Model jest karany przy użyciu funkcji log loss:\n",
"\n", "\n",
"Model jest karany u\u017cywaj\u0105c funkcji log loss:\n", "$$-\\log(p_j),$$\n",
"\n", "\n",
"$$-\\log(p_j),$$\n", "gdzie $w_j$ jest wyrazem, który pojawił się rzeczywiście w korpusie.\n",
"\n", "\n"
"gdzie $w_j$ jest wyrazem, kt\u00f3ry pojawi\u0142 si\u0119 rzeczywi\u015bcie w korpusie.\n", ]
"\n" },
] {
}, "cell_type": "markdown",
{ "metadata": {},
"cell_type": "markdown", "source": [
"metadata": {}, "## Przewidywanie słowa (GPT-2)\n",
"source": [ "\n"
"### Przewidywanie s\u0142owa (GPT-2)\n", ]
"\n" },
] {
}, "cell_type": "markdown",
{ "metadata": {},
"cell_type": "markdown", "source": [
"metadata": {}, "Jeden ze sposobów pretrenowania modelu to po prostu przewidywanie\n",
"source": [ "następnego słowa.\n",
"Jeden ze sposob\u00f3w pretrenowania modelu to po prostu przewidywanie\n", "\n",
"nast\u0119pnego s\u0142owa.\n", "Zainstalujmy najpierw bibliotekę transformers.\n",
"\n", "\n"
"Zainstalujmy najpierw bibliotek\u0119 transformers.\n", ]
"\n" },
] {
}, "cell_type": "code",
{ "execution_count": 1,
"cell_type": "code", "metadata": {},
"execution_count": 1, "outputs": [],
"metadata": {}, "source": [
"outputs": [], "! pip install transformers"
"source": [ ]
"! pip install transformers" },
] {
}, "cell_type": "code",
{ "execution_count": 17,
"cell_type": "code", "metadata": {},
"execution_count": 17, "outputs": [
"metadata": {}, {
"outputs": [ "name": "stdout",
{ "output_type": "stream",
"name": "stdout", "text": [
"output_type": "stream", "50257\n"
"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"
}, },
"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", "- $V$ = $EW^V$\n",
"\n", "\n",
"W kolejnych warstwach zamiast $E$ wykorzystywane jest wyjście z poprzedniej warstwy.\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."
] ]
}, },
{ {