From 429caef49c09830026143f02ee85329fdca48f73 Mon Sep 17 00:00:00 2001 From: Filip Gralinski Date: Wed, 9 Jun 2021 12:43:29 +0200 Subject: [PATCH 1/4] Atencja --- wyk/09_neurozoo.org | 6 +- wyk/12_bpe.ipynb | 834 +++++++++++++++++++++++++++++++ wyk/12_bpe.org | 4 +- wyk/13_generative_approach.ipynb | 1 + wyk/13_generative_approach.org | 55 ++ wyk/bpe.png | Bin 0 -> 126875 bytes wyk/ie-gener.drawio | 1 + wyk/ie-gener.png | Bin 0 -> 30341 bytes wyk/ie-seqlab.drawio | 1 + wyk/ie-seqlab.png | Bin 0 -> 25792 bytes wyk/rnn-seq.drawio | 1 + wyk/rnn-seq.png | Bin 0 -> 41684 bytes wyk/rnn.drawio | 1 + wyk/rnn.png | Bin 0 -> 20759 bytes wyk/word-distribution.png | Bin 0 -> 3983 bytes 15 files changed, 899 insertions(+), 5 deletions(-) create mode 100644 wyk/12_bpe.ipynb create mode 100644 wyk/13_generative_approach.ipynb create mode 100644 wyk/13_generative_approach.org create mode 100644 wyk/bpe.png create mode 100644 wyk/ie-gener.drawio create mode 100644 wyk/ie-gener.png create mode 100644 wyk/ie-seqlab.drawio create mode 100644 wyk/ie-seqlab.png create mode 100644 wyk/rnn-seq.drawio create mode 100644 wyk/rnn-seq.png create mode 100644 wyk/rnn.drawio create mode 100644 wyk/rnn.png create mode 100644 wyk/word-distribution.png diff --git a/wyk/09_neurozoo.org b/wyk/09_neurozoo.org index d95c66c..cc72bb5 100644 --- a/wyk/09_neurozoo.org +++ b/wyk/09_neurozoo.org @@ -375,13 +375,13 @@ Definicja w PyTorchu: z_plus = torch.exp(z) return z_plus / torch.sum(z_plus) - softmax(torch.tensor([3., -1., 0., 5.])) + softmax(torch.tensor([3., 1., -1., 1.])) #+END_SRC #+RESULTS: :results: -# Out[75]: -: tensor([0.1182, 0.0022, 0.0059, 0.8737]) +# Out[3]: +: tensor([7.8678e-01, 1.0648e-01, 2.6393e-04, 1.0648e-01]) :end: #+CAPTION: Softmax diff --git a/wyk/12_bpe.ipynb b/wyk/12_bpe.ipynb new file mode 100644 index 0000000..9a04687 --- /dev/null +++ b/wyk/12_bpe.ipynb @@ -0,0 +1,834 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Podział na jednostki podwyrazowe\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Słownik nie może być za duży…\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Jeśli używamy wyuczalnych zanurzeń słów (embeddingów), wówczas musimy\n", + "je dopisać do listy parametrów całego modelu — jest to $|V|n$ wag,\n", + "gdzie $n$ to rozmiar embeddingów; w wypadku uczenia dodatkowo musimy\n", + "jeszcze pamiętać związane z embeddingami gradienty. Pamięć RAM karty\n", + "graficznej jest rzecz jasna ograniczona, słownik więc nie może być\n", + "dowolnie duży. Dla danego modelu karty graficznej dość łatwo ustalić\n", + "maksymalny rozmiar słownika — jest „twarde” ograniczenie, które musimy\n", + "spełnić.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Czy rzeczywiście słownik może być taki duży?\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ile jest różnych form fleksyjnych w języku polskim? Zobaczmy w słowniku PoliMorf…\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a\n", + "aa\n", + "AA\n", + "Aachen\n", + "Aalborg\n", + "Aalborgiem\n", + "Aalborgowi\n", + "Aalborgu\n", + "AAP\n", + "Aar\n", + "Aarem\n", + "Aarowi\n", + "Aaru\n", + "Aarze\n", + "Aara\n", + "Aarą\n", + "Aarę\n", + "Aaro\n", + "Aary\n", + "Aarze\n", + "uniq: błąd zapisu: Przerwany potok\n" + ] + } + ], + "source": [ + "! wget -q 'http://zil.ipipan.waw.pl/PoliMorf?action=AttachFile&do=get&target=PoliMorf-0.6.7.tab.gz' -O - | zcat | cut -f 1 | uniq | head -n 20" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3844535\r\n" + ] + } + ], + "source": [ + "! wget -q 'http://zil.ipipan.waw.pl/PoliMorf?action=AttachFile&do=get&target=PoliMorf-0.6.7.tab.gz' -O - | zcat | cut -f 1 | sort -u | wc -l" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Pytanie** W którym języku europejskim wyrazów będzie jeszcze więcej niż języku polskim?\n", + "\n", + "Tak naprawdę form jest jeszcze więcej, oczywiście PoliMorf nie wyczerpuje zbioru…\n", + "\n", + "**Pytanie** Podaj przykłady „oczywistych” wyrazów, których w PoliMorfie. Jak w sposób systematyczny szukać takich wyrazów?\n", + "\n", + "Z drugiej strony, w PoliMorfie jest dużo dziwnych, „sztucznych” wyrazów.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "niemałomieszczańskiej\r\n", + "kwatereczki\r\n", + "słowniejszej\r\n", + "oranżysta\r\n", + "myrmekofagów\r\n", + "hipokratesowego\r\n", + "rozdziałująca\r\n", + "wielosettysięczne\r\n", + "redempcyjno\r\n", + "łącznikowce\r\n", + "niesłowacyzowana\r\n", + "sosnowieckościach\r\n", + "niewschodoznawczy\r\n", + "niekłosokształtnego\r\n", + "niegenialności\r\n", + "Gierowskiego\r\n", + "nieumierzwiających\r\n", + "bezzakłóceniowości\r\n", + "niedziurkowatościach\r\n", + "Krzaklewskich\r\n" + ] + } + ], + "source": [ + "! wget -q 'http://zil.ipipan.waw.pl/PoliMorf?action=AttachFile&do=get&target=PoliMorf-0.6.7.tab.gz' -O - | zcat | cut -f 1 | shuf -n 20" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Inaczej, zobaczmy, ile różnych wyrazów jest w jakimś rzeczywistym zbiorze tekstów, rozpatrzmy\n", + "teksty zebrane na potrzeby identyfikacji płci autora tekstu:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# Out[7]:" + ] + } + ], + "source": [ + "! git clone --single-branch --depth 1 git://gonito.net/petite-difference-challenge2" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "! xzcat petite-difference-challenge2/train/in.tsv.xz | perl -C -ne 'print \"$&\\n\" while/\\p{L}+/g;' | sort -u > vocab.txt" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ˆ\r\n", + "ˇ\r\n", + "゚\r\n", + "a\r\n", + "A\r\n", + "á\r\n", + "Á\r\n", + "à\r\n", + "À\r\n", + "ă\r\n", + "Ă\r\n", + "â\r\n", + "Â\r\n", + "å\r\n", + "Å\r\n", + "ä\r\n", + "Ä\r\n", + "Ã\r\n", + "ā\r\n", + "aa\r\n", + "aA\r\n", + "Aa\r\n", + "AA\r\n", + "aĂ\r\n", + "AĂ\r\n", + "aâ\r\n", + "aÂ\r\n", + "Aâ\r\n", + "aÅ\r\n", + "aÄ\r\n", + "ª\r\n", + "aaa\r\n", + "aAa\r\n", + "Aaa\r\n", + "AaA\r\n", + "AAa\r\n", + "AAA\r\n", + "aaaa\r\n", + "aAaa\r\n", + "Aaaa\r\n", + "AaAa\r\n", + "AAaa\r\n", + "AAAa\r\n", + "AAAA\r\n", + "aaaaa\r\n", + "Aaaaa\r\n", + "AaaaA\r\n", + "AAaaa\r\n", + "AAAAA\r\n", + "aaaaaa\r\n" + ] + } + ], + "source": [ + "! head -n 50 vocab.txt" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2974556 vocab.txt\r\n" + ] + } + ], + "source": [ + "! wc -l vocab.txt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Co gorsza, nawet jak weźmiemy cały taki słownik bez ograniczeń i tak\n", + "nie pokryje on sporej części tekstów przetwarzanych w czasie inferencji.\n", + "Zobaczmy, ilu wyrazów ze zbioru deweloperskiego nie będzie w słowniku.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "81380\r\n" + ] + } + ], + "source": [ + "! cat petite-difference-challenge2/dev-0/in.tsv | perl -C -ne 'print \"$&\\n\" while/\\p{L}+/g;' | sort -u | comm vocab.txt - -13 | wc -l" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Takie wyrazy nazywamy wyrazami **OOV** (*out-of-vocabulary*).\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Obcięcie słownika\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Najprostszy sposób ograniczenia słownika to po prostu obcięcie do $N$ najczęstszych słów.\n", + "\n", + "Spróbujmy zastosować do korpusu „płci”:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# Out[8]:" + ] + } + ], + "source": [ + "! xzcat petite-difference-challenge2/train/in.tsv.xz | perl -C -ne 'print \"$&\\n\" while/\\p{L}+/g;' | sort | uniq -c | sort -k 1rn | head -n 50000 | sort -k 2 > vocab50000.txt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Daje to lepszy efekt niż można się spodziewać. Odrzucamy w ten sposób\n", + "tylko bardzo rzadkie słowa (albo takie, które wystąpiły tylko raz w\n", + "korpusie — tzw. *hapax legomena*), choć tych słów jest bardzo dużo.\n", + "\n", + "**Zagadka**: 50000 najczęstszych słów (1,9% **typów**) pokrywa jaki odsetek **wystąpień**?\n", + "\n", + "Rozkład normalny w języku nie jest… normalny — nie spotkamy się z nim\n", + "badając języki. W tekstach dominują „skrzywione” rozkłady z długimi,\n", + "„chudymi” ogonami.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "! xzcat petite-difference-challenge2/train/in.tsv.xz | perl -C -ne 'print \"$&\\n\" while/\\p{L}+/g;' | sort | uniq -c | sort -k 1rn | cut -f 1 > freqs.txt" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'word-distribution.png'" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAWoAAAEQCAYAAACZYT5EAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Z1A+gAAAACXBIWXMAAAsTAAALEwEAmpwYAAAOL0lEQVR4nO3da4hc5R3H8d/PJN6IYEtWKka7rUTFhnpbrBeQGHyRaqlvVBRroQSDhYpCtfQCLdJ3fSFF0Jalhir1QkQrIl6Q1tQoRt2kRk2i1kttQwNZL1FDpVX774s5iTt7JjsnM3Nm/id+P7A4u+eZOf9nn/jLyZlnnscRIQBAXgeMugAAwNwIagBIjqAGgOQIagBIjqAGgOQIagBIrragtr3a9g7bL1Vsf4ntLbY3276zrroAoGlc1zxq2+dI2iXp9ohY2qXtEklrJC2PiPdsHxERO2opDAAaprYr6oh4QtK7M39m+1jbj9jeYHud7ROKQ1dKujki3iueS0gDQGHY96gnJV0dEadJuk7SLcXPj5N0nO2nbK+3vWLIdQFAWvOHdSLbCyWdJeke27t/fNCMOpZIWiZpsaR1tpdGxM5h1QcAWQ0tqNW6et8ZESd3OLZN0vqI+FjSm7ZfUSu4nxtifQCQ0tBufUTEB2qF8MWS5JaTisP3Szq3+PkitW6FvDGs2gAgszqn590l6WlJx9veZnulpMslrbS9SdJmSRcWzR+V9I7tLZIel3R9RLxTV20A0CS1Tc8DAAwGn0wEgORqeTNx0aJFMT4+XsdLA8B+acOGDW9HxFinY7UE9fj4uKampup4aQDYL9l+a2/HuPUBAMkR1ACQHEENAMkR1ACQHEENAMkR1ACQHEENAMmlCuqb/vQ3/eXV6VGXAQCppArq36x9XU+99vaoywCAVFIFNQCgjKAGgOQIagBIrnJQ255n+6+2H6yzIABAu325or5G0ta6CgEAdFYpqG0vlnSBpN/VW47EjjMA0K7qFfWvJf1I0v/21sD2KttTtqemp3ubC2339DQA2K91DWrb35K0IyI2zNUuIiYjYiIiJsbGOm5SAADoQZUr6rMlfdv23yXdLWm57T/UWhUAYI+uQR0RP4mIxRExLulSSX+OiO/UXhkAQBLzqAEgvX3a3DYi1kpaW0sle85R56sDQPOkuqJm0gcAlKUKagBAGUENAMkR1ACQHEENAMkR1ACQXLqgZnYeALRLFdRmVSYAKEkV1ACAMoIaAJIjqAEgOYIaAJJLF9QsygQA7VIFNXM+AKAsVVADAMoIagBIjqAGgOQIagBIjqAGgOTSBXWwLBMAtMkV1MzPA4CSXEENACghqAEgOYIaAJIjqAEgOYIaAJJLF9SsngcA7VIFNbPzAKAsVVADAMoIagBIjqAGgOQIagBIjqAGgORSBbXNvA8AmC1VUAMAyghqAEiOoAaA5AhqAEiua1DbPtj2s7Y32d5s+4ZhFAYAaJlfoc1/JC2PiF22F0h60vbDEbG+joKCVZkAoE3XoI5Wcu4qvl1QfNWSpszOA4CySveobc+z/bykHZIei4hnOrRZZXvK9tT09PSAywSAz69KQR0Rn0bEyZIWSzrd9tIObSYjYiIiJsbGxgZcJgB8fu3TrI+I2ClpraQVdRQDACirMutjzPbhxeNDJJ0n6eWa6wIAFKrM+jhS0m2256kV7Gsi4sG6CmLOBwC0qzLr4wVJpwyhFrbiAoAO+GQiACRHUANAcgQ1ACRHUANAcgQ1ACSXLqhZkwkA2qUKavZMBICyVEENACgjqAEgOYIaAJIjqAEguXRBHSzLBABt0gU1AKBdqqBmch4AlKUKagBAGUENAMkR1ACQHEENAMmlC2oWZQKAdqmCmjWZAKAsVVADAMoIagBIjqAGgOQIagBIjqAGgOTSBTWz8wCgXbKgZn4eAMyWLKgBALMR1ACQHEENAMkR1ACQXLqgZlEmAGiXKqhZlAkAylIFNQCgjKAGgOQIagBIjqAGgOQIagBILmFQMz8PAGbqGtS2j7b9uO2ttjfbvqauYpidBwBl8yu0+UTSDyNio+3DJG2w/VhEbKm5NgCAKlxRR8T2iNhYPP5Q0lZJR9VdGACgZZ/uUdsel3SKpGc6HFtle8r21PT09IDKAwBUDmrbCyXdK+naiPhg9vGImIyIiYiYGBsbG2SNAPC5VimobS9QK6TviIj76iyIRZkAoF2VWR+WdKukrRFxY53FsCgTAJRVuaI+W9IVkpbbfr74Or/mugAAha7T8yLiSTHFGQBGJuEnEwEAMxHUAJAcQQ0AyaULaqbnAUC7VEFt3rMEgJJUQQ0AKCOoASA5ghoAkiOoASA5ghoAkksX1MGeiQDQJlVQs3oeAJSlCmoAQBlBDQDJEdQAkBxBDQDJpQtqFmUCgHapgppJHwBQliqoAQBlBDUAJEdQA0ByBDUAJEdQA0By6YKa2XkA0C5VUJtVmQCgJFVQAwDKCGoASI6gBoDkCGoASC5dULMoEwC0SxfUAIB2BDUAJEdQA0ByBDUAJEdQA0ByBDUAJJcuqINlmQCgTaqgZk0mAChLFdQAgLKuQW17te0dtl8aRkEAgHZVrqh/L2lFzXUAAPaia1BHxBOS3h1CLQCADgZ2j9r2KttTtqemp6cH9bIA8Lk3sKCOiMmImIiIibGxsT5eaFAVAcD+IdWsD6bnAUBZqqAGAJRVmZ53l6SnJR1ve5vtlfWXBQDYbX63BhFx2TAKAQB0xq0PAEguXVAz6QMA2qUKaotpHwAwW6qgBgCUEdQAkBxBDQDJEdQAkBxBDQDJpQvqCCboAcBMqYKaRZkAoCxVUAMAyghqAEiOoAaA5AhqAEguXVAz5wMA2qUKaiZ9AEBZqqAGAJQR1ACQHEENAMkR1ACQHEENAMmlC2rWZAKAdqmC2qzKBAAlqYIaAFBGUANAcgQ1ACRHUANAcumCmkkfANAuXVADANqlCmom5wFAWaqgBgCUEdQAkBxBDQDJEdQAkFy6oA5WZQKANrmCmmkfAFCSK6gBACUENQAkR1ADQHKVgtr2Ctuv2H7N9o/rLgoA8JmuQW17nqSbJX1T0omSLrN9Yl0FMecDANrNr9DmdEmvRcQbkmT7bkkXStoy6GK+cOiBeujF7Trtl4/1/Bq97+bV+5STXs/ZzySX3s/ZtH4OfypQz/3so9Rex6W/c/b4vB5P2tdINuTP3hcPPVBrrjqzj7N2ViWoj5L0zxnfb5P0jdmNbK+StEqSjjnmmJ6K+dVFX9fdz/5DH338aU/P73UKdj9X8b1P++79rD33s4+ORo/19nfOHp83gn7284eo9372OCY9nq91zh6f19c5h9/PXp982MFVInXfVXnVTn+tlLoREZOSJiVpYmKip24eO7ZQP7ugtrsqANBIVd5M3Cbp6BnfL5b0r3rKAQDMViWon5O0xPZXbB8o6VJJD9RbFgBgt663PiLiE9s/kPSopHmSVkfE5torAwBIqnaPWhHxkKSHaq4FANABn0wEgOQIagBIjqAGgOQIagBIznXsqGJ7WtJbPT59kaS3B1jOKNGXnOhLXvtTf/a1L1+OiLFOB2oJ6n7YnoqIiVHXMQj0JSf6ktf+1J9B9oVbHwCQHEENAMllDOrJURcwQPQlJ/qS1/7Un4H1Jd09agBAu4xX1ACAGQhqAEhuJEHdbbNct9xUHH/B9qmjqLOqCv1ZZvt9288XXz8fRZ3d2F5te4ftl/ZyvDHjUqEvjRgTSbJ9tO3HbW+1vdn2NR3aNGJsKvalEWNj+2Dbz9reVPTlhg5tBjMuETHUL7WWSn1d0lclHShpk6QTZ7U5X9LDau0uc4akZ4Zd54D7s0zSg6OutUJfzpF0qqSX9nK8SePSrS+NGJOi1iMlnVo8PkzSq039f6ZiXxoxNsXvemHxeIGkZySdUce4jOKKes9muRHxX0m7N8ud6UJJt0fLekmH2z5y2IVWVKU/jRART0h6d44mjRmXCn1pjIjYHhEbi8cfStqq1l6mMzVibCr2pRGK3/Wu4tsFxdfs2RkDGZdRBHWnzXJnD1SVNllUrfXM4p9ID9v+2nBKG7gmjUsVjRsT2+OSTlHr6m2mxo3NHH2RGjI2tufZfl7SDkmPRUQt41LPlrlzq7JZbqUNdZOoUutGtT7Hv8v2+ZLul7Sk7sJq0KRx6aZxY2J7oaR7JV0bER/MPtzhKWnHpktfGjM2EfGppJNtHy7pj7aXRsTM90UGMi6juKKusllukzbU7VprRHyw+59I0dotZ4HtRcMrcWCaNC5zatqY2F6gVrDdERH3dWjSmLHp1pemjY0kRcROSWslrZh1aCDjMoqgrrJZ7gOSvlu8Y3qGpPcjYvuwC62oa39sf8m2i8enq/V7f2folfavSeMypyaNSVHnrZK2RsSNe2nWiLGp0pemjI3tseJKWrYPkXSepJdnNRvIuAz91kfsZbNc21cVx3+r1v6M50t6TdK/JX1v2HVWVbE/F0n6vu1PJH0k6dIo3hLOxPZdar3jvsj2Nkm/UOsNksaNS4W+NGJMCmdLukLSi8X9UEn6qaRjpMaNTZW+NGVsjpR0m+15av1lsiYiHqwjy/gIOQAkxycTASA5ghoAkiOoASA5ghoAkiOoAaBP7rIIWIf2l9jeUizmdGfX9sz6AID+2D5H0i611vVY2qXtEklrJC2PiPdsHxERO+Z6DlfUANCnTouA2T7W9iO2N9heZ/uE4tCVkm6OiPeK584Z0hJBDQB1mZR0dUScJuk6SbcUPz9O0nG2n7K93vbsj52XjGJRJgDYrxWLTp0l6Z7i0/CSdFDx3/lqLTK1TK21P9YViznt3NvrEdQAMHgHSNoZESd3OLZN0vqI+FjSm7ZfUSu4n5vrxQAAA1Qs3fqm7YulPVtynVQcvl/SucXPF6l1K+SNuV6PoAaAPhWLgD0t6Xjb22yvlHS5pJW2N0narM92fnpU0ju2t0h6XNL1ETHn6oBMzwOA5LiiBoDkCGoASI6gBoDkCGoASI6gBoDkCGoASI6gBoDk/g+8/49zSz53DwAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import re\n", + "from math import log\n", + "\n", + "freqs = []\n", + "\n", + "with open('freqs.txt', 'r') as fh:\n", + " for line in fh:\n", + " m = re.match(r'\\s*(\\d+)', line)\n", + " if m:\n", + " freqs.append(int(m.group(1)))\n", + "\n", + "plt.plot(range(len(freqs)), freqs)\n", + "fname = 'word-distribution.png'\n", + "plt.savefig(fname)\n", + "fname" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[[file:# Out[25]:\n", + "\n", + " 'word-distribution.png'\n", + "\n", + "![img](./obipy-resources/c0TrCn.png)]]\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Lematyzacja\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Lematyzacja wydaje się dobrym pomysłem, zwłaszcza dla języków dla bogatej fleksji:\n", + "\n", + "- znacznie redukujemy słownik,\n", + "- formy fleksyjne tego samego wyrazu są traktowane tak samo (co wydaje się słuszne).\n", + "\n", + "W praktyce współcześnie **nie** stosuje się lematyzacji (w połączeniu z\n", + "metodami opartymi na sieciach neuronowych):\n", + "\n", + "- lematyzacja wymaga wiedzy językowej (reguł lub słownika),\n", + " wytworzenie takiej wiedzy może być kosztowne, obecnie preferowane\n", + " są metody niezależne od języka;\n", + "- tracimy pewną informację niesioną przez formę fleksyjną (co w szczególnych\n", + " przypadkach może być niefortunne, np. *aspiracja* i *aspiracje*);\n", + "- lematyzacja nie jest trywialnym problemem ze względu na niejednoznaczności\n", + " (*Lekarzu, lecz się sam*);\n", + "- niektóre niejednoznaczności są seryjne, wybór lematu może być arbitralny,\n", + " np. czy *posiadanie*, *gotowanie*, *skakanie* to rzeczowniki czy czasowniki?\n", + " a *urządzenie*, *mieszkanie*?\n", + "- zazwyczaj sieci neuronowe (czy nawet prostsze modele typu Word2vec)\n", + " są w stanie nauczyć się rekonstruowania zależności między formami fleksyjnymi\n", + " (i więcej: błędnych form, błędów ortograficznych, form archaicznych itd.)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Zejście na poziom znaków\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Skoro słownik wyrazów jest zbyt duży, to może zejść na poziom znaków?\n", + "\n", + "- pojedynczy znak alfabetu wprawdzie nic nie znaczy (co znaczy *h*?)\n", + "\n", + "- … ale rozmiar wejścia przy kodowaniu gorącą jedynką\n", + " dramatycznie się zmniejsza\n", + "\n", + "- może działać, jeśli dodać wielowarstwową sieć\n", + " neuronową\n", + "\n", + "- … ale może być bardzo kosztowne obliczeniowo\n", + "\n", + "A może coś pośredniego między znakami a wyrazami?\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### BPE\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ani znaki, ani wyrazy — coś pomiędzy: jednostki podwyrazowe (*subword\n", + "units*). Moglibyśmy np. dzielić wyraz *superkomputera* na dwie\n", + "jednostki *super/+/komputera*, a może nawet trzy: *super/+/komputer/+/a*?\n", + "\n", + "Najpopularniejszy algorytm podziału na jednostki podwyrazowe to BPE\n", + "(*byte-pair encoding*), zainspirowany algorytmami kompresji danych.\n", + "Lista jednostek jest automatycznie indukowana na podstawie tekstu (nie\n", + "potrzeba żadnej wiedzy o języku!). Ich liczba musi być natomiast z góry\n", + "określona.\n", + "\n", + "W kroku początkowym zaznaczamy końce wyrazów (tokenów), robimy to po\n", + "to, żeby jednostki podwyrazowe nie przekraczały granic wyrazów.\n", + "\n", + "Następnie wykonujemy tyle kroków iteracji, ile wynosi rozmiar zadanego\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", + "\n", + "![img](./bpe.png)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Implementacja w Pythonie\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['e$', 'to', 'to$', 'be$', 't$', 'th', 'or', 'or$', 'no', 'not$']" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from collections import Counter\n", + "\n", + "def replace_bigram(l, b, r):\n", + " i = 0\n", + " while i < len(l) - 1:\n", + " if (l[i], l[i+1]) == b:\n", + " l[i:i+2] = [r]\n", + " i += 1\n", + " return l\n", + "\n", + "def learn_bpe_vocab(d, max_vocab_size):\n", + " d = list(d.replace(' ', '$') + '$')\n", + "\n", + " vocab = []\n", + "\n", + " for ix in range(0, max_vocab_size):\n", + " bigrams = [(d[i], d[i+1]) for i in range(0, len(d) - 1) if d[i][-1] != '$']\n", + " selected_bigram = Counter(bigrams).most_common(1)[0][0]\n", + "\n", + " new_subword = selected_bigram[0] + selected_bigram[1]\n", + " d = replace_bigram(d, selected_bigram, new_subword)\n", + "\n", + " vocab.append(new_subword)\n", + "\n", + " return vocab\n", + "\n", + "vocab1 = learn_bpe_vocab('to be or not to be that is the question', 10)\n", + "vocab1" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Słownik jednostek podwyrazowych możemy zastosować do dowolnego tekstu, np. do tekstu,\n", + "na którym słownik był wyuczony:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'to$ b e$ or$ no t$ to$ b e$ th a t$ i s $ th e$ q u e s t i o n $'" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def apply_bpe_vocab(vocab, d):\n", + " d = list(d.replace(' ', '$') + '$')\n", + " vocab_set = set(vocab)\n", + "\n", + " ix = 0\n", + " while ix < len(d) - 1:\n", + " bigram = d[ix] + d[ix+1]\n", + " if bigram in vocab_set:\n", + " d[ix:ix+2] = [bigram]\n", + " else:\n", + " ix += 1\n", + "\n", + " return d\n", + "\n", + "' '.join(apply_bpe_vocab(vocab1, 'to be or not to be that is the question'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Zauważmy, że oprócz jednostek podwyrazowych zostały izolowane litery,\n", + "zazwyczaj dodajemy je do słownika. (I zazwyczaj, słownik jest trochę\n", + "większy niż wartość podana jako parametr przy uczeniu BPE — jest\n", + "większy o znaki i specjalne tokeny typu `UNK`, `BOS`, `EOS`, `PAD`.)\n", + "\n", + "**Pytanie**: Jaki problem może pojawić przy zastosowaniu BPE dla tekstu,\n", + "gdzie pojawiają się chińskie znaki? Jak można sobie z nim poradzić?\n", + "\n", + "Słownik jednostek podwyrazowych można stosować dla dowolnego tekstu:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'to m $ w i l l $ b e$ th e$ b e s t$'" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "' '.join(apply_bpe_vocab(vocab1, 'tom will be the best'))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Jak można zauważyć algorytm BPE daje dwa rodzaje jednostek podwyrazowych:\n", + "\n", + "- jednostki, które mogą doklejane na początku wyrazu;\n", + "- jednostki, które stanowią koniec wyrazu, w szczególności są całym wyrazem.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Gotowa implementacja\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Po raz pierwszy BPE użyto do neuronowego tłumaczenia maszynowego.\n", + "Użyjmy modułu autorstwa Rica Sennricha ([https://github.com/rsennrich/subword-nmt](https://github.com/rsennrich/subword-nmt)).\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "! pip install subword-nmt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wyindukujmy słownik dla zbioru uczącego zadania identyfikacji płci\n", + "autora tekstu:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "! xzcat petite-difference-challenge2/train/in.tsv.xz | perl -C -ne 'print \"$&\\n\" while/\\p{L}+/g;' | python -m subword_nmt.learn_bpe -s 50000 -v > bpe_vocab.txt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Procedura trwa kilka minut, trzeba uzbroić się w cierpliwość (ale wypisywanie bigramów przyspieszy!).\n", + "\n", + " pair 0: n i -> ni (frequency 17625075)\n", + " pair 1: i e -> ie (frequency 11471590)\n", + " pair 2: c z -> cz (frequency 9143490)\n", + " pair 3: ni e -> nie (frequency 7901783)\n", + " pair 4: p o -> po (frequency 7790826)\n", + " pair 5: r z -> rz (frequency 7542046)\n", + " pair 6: s t -> st (frequency 7269069)\n", + " pair 7: e m -> em (frequency 7207280)\n", + " pair 8: d z -> dz (frequency 6860931)\n", + " pair 9: s z -> sz (frequency 6609907)\n", + " pair 10: r a -> ra (frequency 6601618)\n", + " pair 11: o w -> ow (frequency 6395963)\n", + " pair 12: i e -> ie (frequency 5906869)\n", + " pair 13: n a -> na (frequency 5300380)\n", + " pair 14: r o -> ro (frequency 5181363)\n", + " pair 15: n a -> na (frequency 5125807)\n", + " pair 16: a ł -> ał (frequency 4786696)\n", + " pair 17: j e -> je (frequency 4599579)\n", + " pair 18: s i -> si (frequency 4300984)\n", + " pair 19: a l -> al (frequency 4276823)\n", + " pair 20: t e -> te (frequency 4033344)\n", + " pair 21: w i -> wi (frequency 3939063)\n", + " pair 22: c h -> ch (frequency 3919410)\n", + " pair 23: c h -> ch (frequency 3661410)\n", + " pair 24: k o -> ko (frequency 3629840)\n", + " pair 25: z a -> za (frequency 3625424)\n", + " pair 26: t a -> ta (frequency 3570094)\n", + " pair 27: p rz -> prz (frequency 3494551)\n", + " pair 28: g o -> go (frequency 3279997)\n", + " pair 29: a r -> ar (frequency 3081492)\n", + " pair 30: si ę -> się (frequency 2973681)\n", + " ...\n", + " pair 49970: brz mieniu -> brzmieniu (frequency 483)\n", + " pair 49971: bieżą cych -> bieżących (frequency 483)\n", + " pair 49972: biegu nkę -> biegunkę (frequency 483)\n", + " pair 49973: ban kowości -> bankowości (frequency 483)\n", + " pair 49974: ba ku -> baku (frequency 483)\n", + " pair 49975: ba cznie -> bacznie (frequency 483)\n", + " pair 49976: Przypad kowo -> Przypadkowo (frequency 483)\n", + " pair 49977: MA Ł -> MAŁ (frequency 483)\n", + " pair 49978: Lep pera -> Leppera (frequency 483)\n", + " pair 49979: Ko za -> Koza (frequency 483)\n", + " pair 49980: Jak byś -> Jakbyś (frequency 483)\n", + " pair 49981: Geni alne -> Genialne (frequency 483)\n", + " pair 49982: Że nada -> Żenada (frequency 482)\n", + " pair 49983: ń czykiem -> ńczykiem (frequency 482)\n", + " pair 49984: zwie ń -> zwień (frequency 482)\n", + " pair 49985: zost ałaś -> zostałaś (frequency 482)\n", + " pair 49986: zni szczona -> zniszczona (frequency 482)\n", + " pair 49987: ze stawi -> zestawi (frequency 482)\n", + " pair 49988: za sób -> zasób (frequency 482)\n", + " pair 49989: węd rówkę -> wędrówkę (frequency 482)\n", + " pair 49990: wysko czyła -> wyskoczyła (frequency 482)\n", + " pair 49991: wyle czenia -> wyleczenia (frequency 482)\n", + " pair 49992: wychowaw cze -> wychowawcze (frequency 482)\n", + " pair 49993: w t -> wt (frequency 482)\n", + " pair 49994: un da -> unda (frequency 482)\n", + " pair 49995: udzie lałem -> udzielałem (frequency 482)\n", + " pair 49996: tę czy -> tęczy (frequency 482)\n", + " pair 49997: tro sce -> trosce (frequency 482)\n", + " pair 49998: słusz ności -> słuszności (frequency 482)\n", + " pair 49999: su me -> sume (frequency 482\n", + "\n", + "Zastosujmy teraz wyindukowany słownik BPE dla jakiegoś rzeczywistego tekstu.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cier@@ piałem na straszne la@@ gi kilkanaście sekund lub dłużej czarnego ekranu przy próbie przełą@@ czenia się uruchomienia prawie każdej aplikacji Dodatkowo telefon mi się wyłą@@ czał czasem bez powodu sam z siebie albo rese@@ tował Ostatnio nawet przeglądarka zaczęła się często zawie@@ szać i Android proponował wymu@@ szone zamknięcie Do tego te problemy z połączeniem do komputera przez USB " + ] + } + ], + "source": [ + "! echo 'Cierpiałem na straszne lagi – kilkanaście sekund lub dłużej czarnego ekranu przy próbie przełączenia się / uruchomienia prawie każdej aplikacji. Dodatkowo telefon mi się wyłączał czasem bez powodu – sam z siebie, albo resetował. Ostatnio nawet przeglądarka zaczęła się często zawieszać i Android proponował wymuszone zamknięcie. Do tego te problemy z połączeniem do komputera przez USB.' | perl -C -ne 'print \"$& \" while/\\p{L}+/g;' | python -m subword_nmt.apply_bpe -c bpe_vocab.txt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ta konkretna implementacja zaznacza za pomocą sekwencji ~@@ ~ koniec jednostki podwyrazowej.\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.2" + }, + "org": null + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/wyk/12_bpe.org b/wyk/12_bpe.org index 9829c85..17adf4e 100644 --- a/wyk/12_bpe.org +++ b/wyk/12_bpe.org @@ -88,7 +88,7 @@ nie pokryje on sporej części tekstów przetwarzanych w czasie inferencji. Zobaczmy, ilu wyrazów ze zbioru deweloperskiego nie będzie w słowniku. #+BEGIN_SRC ipython :session mysession :exports both :results raw drawer -! cat petite-difference-challenge2/dev-0/in.tsv.xz | perl -C -ne 'print "$&\n" while/\p{L}+/g;' | sort -u | comm vocab.txt - -13 | wc -l +! cat petite-difference-challenge2/dev-0/in.tsv | perl -C -ne 'print "$&\n" while/\p{L}+/g;' | sort -u | comm vocab.txt - -13 | wc -l #+END_SRC Takie wyrazy nazywamy wyrazami *OOV* (/out-of-vocabulary/). @@ -112,7 +112,7 @@ Daje to lepszy efekt niż można się spodziewać. Odrzucamy w ten sposób tylko bardzo rzadkie słowa (albo takie, które wystąpiły tylko raz w korpusie — tzw. /hapax legomena/), choć tych słów jest bardzo dużo. -*Zagadka*: 50000 najczęstszych słów (1,9\% *typów*) pokrywa jaki odsetek *wystąpień*? +*Zagadka*: 50000 najczęstszych słów (1,9% *typów*) pokrywa jaki odsetek *wystąpień*? Rozkład normalny w języku nie jest… normalny — nie spotkamy się z nim badając języki. W tekstach dominują „skrzywione” rozkłady z długimi, diff --git a/wyk/13_generative_approach.ipynb b/wyk/13_generative_approach.ipynb new file mode 100644 index 0000000..11c1953 --- /dev/null +++ b/wyk/13_generative_approach.ipynb @@ -0,0 +1 @@ +{"cells":[{"cell_type":"markdown","metadata":{},"source":["## Ekstrakcja informacji a podejście generatywne\n\n"]},{"cell_type":"markdown","metadata":{},"source":["### Podejście generatywne\n\n"]},{"cell_type":"markdown","metadata":{},"source":["Do tej pory zadanie ekstrakcji informacji traktowaliśmy jako zadanie etykietowania sekwencji, tzn. uczyliśmy system zaznaczać tokeny składające się na ekstrahowane informacje.\n\n![img](./ie-seqlab.png)\n\nMoż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\nTo podejście może się wydawać trudniejsze niż etykietowanie sekwencji, ale wystarczająco zaawansowanej architekturze sieci, jest wykonalne.\n\nZalety:\n\n- informacja nie musi być dosłownie zapisana w tekście, ekstraktor może nauczyć się również normalizacji czy parafrazowania,\n- nie wprowadzamy wielu kroków przetwarzania (gdzie błędy mogą się\n namnażać), system działa na zasadzie *end-to-end*.\n\n"]},{"cell_type":"markdown","metadata":{},"source":["### Atencja\n\n"]},{"cell_type":"markdown","metadata":{},"source":["Pierwsze systemu neuronowego tłumaczenia maszynowego używały siecie LSTM. Dopiero jednak dodanie tzw. atencji (*attention*) umożliwiło duży przeskok jakościowy. Najpierw atencję dodano do sieci rekurencyjnych, później powstały sieci oparte *wyłącznie* na atencji — modele Transformer.\n\nIdea atencji polega na tym, że sieć może kierować selektywnie „snop” uwagi na wyrazy na wejściu lub do tej pory wygenerowane wyrazy.\n\nMechanizm atencji korzysta z:\n\n- z poprzedniego stanu sieci $\\vec{s^{k-1}}$ (to jest „miejsce”, z którego „kierujemy” atencję),\n- z wektora reprezentującego słowo $\\vec{v}(t_i)$ (to jest „miejsce”, na które kierujemy atencję), gdzie\n $\\vec{v}(t_i)$ to reprezentacja wektorowa wyrazu $t_i$ (statyczny embedding lub reprezentacja wektorowa\n z poprzedniej warstwy dla sieci wielowarstwowej),\n\naby wytworzyć wektor kontekstu $\\vec{\\xi^k}$ (który z kolei będzie w jakiś sposób wnosił wkład do wyliczenia nowej wartości stanu $\\vec{s^k}$ lub wyjścia $y^k$.\n\nNajpierw wyliczymy skalarne wartości atencji, tzn. liczby, które będą sygnalizowały, jak bardzo wektor $\\vec{v}(t_i)$ „pasuje” do $\\vec{s^{k-1}}$, w najprostszej wersji można po prostu skorzystać z iloczynu skalarnego (o ile $n=m$),\n\n$$a(\\vec{s^{k-1}}, \\vec{v}(t_i)) = \\vec{s^{k-1}}\\vec{v}(t_i).$$\n\n**Pytanie**: co jeśli $n$ nie jest równe $m$, tzn. rozmiar embeddingu nie jest równy rozmiarowi wektora stanu?\n\nW przypadku sieci LSTM korzysta się częściej z bardziej skomplikowanego wzoru zawierającego dodatkowe wyuczalne wagi:\n\n$$a(\\vec{s^{k-1}}, \\vec{v}(t_i)) = \\vec{w_a}\\operatorname{tanh}(W_a\\vec{s^{k-1}} + U_a\\vec{v}(t_i))$$\n\n**Pytanie**: jakie rozmiary mają macierze $W_a$, $U_a$ i wektor $w_a$?\n\nPowtórzmy, że wartości $a$ są wartościami skalarnymi, natomiast nie są one znormalizowane (nie sumują się do jedynki), normalizujemy je używając schematu podobnego do softmaxa:\n\n$$\\alpha_{i} = \\frac{e^{a(\\vec{s^{k-1}}, \\vec{v}(t_i))}}{\\sum_j e^{a(\\vec{s^{k-1}}, \\vec{v}(t_j))}}$$\n\nWektor kontekstu $\\vec{\\xi^k}$ będzie po prostu średnią ważoną wektorowych reprezentacji słów:\n\n$$\\vec{\\xi^k} = \\sum_i \\alpha_i\\vec{v}(t_i)$$\n\n**Pytanie**: zasadniczo atencja jest środkiem do celu (żeby sieć się sprawniej uczyła), czy można atencja sama w sobie może być do czegoś przydatna?\n\n"]}],"metadata":{"org":null,"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.5.2"}},"nbformat":4,"nbformat_minor":0} \ No newline at end of file diff --git a/wyk/13_generative_approach.org b/wyk/13_generative_approach.org new file mode 100644 index 0000000..3d0885b --- /dev/null +++ b/wyk/13_generative_approach.org @@ -0,0 +1,55 @@ +* Ekstrakcja informacji a podejście generatywne +** Podejście generatywne + +Do tej pory zadanie ekstrakcji informacji traktowaliśmy jako zadanie etykietowania sekwencji, tzn. uczyliśmy system zaznaczać tokeny składające się na ekstrahowane informacje. + +[[./ie-seqlab.png]] + +Możliwe jest inne podeście, *generatywne*, w którym podchodzimy do problemu ekstrakcji informacji jak do swego rodzaju *tłumaczenia maszynowego* — „tłumaczymy” tekst (wraz z pytaniem lub etykietą) na informację. + +[[./ie-gener.png]] + +To podejście może się wydawać trudniejsze niż etykietowanie sekwencji, ale wystarczająco zaawansowanej architekturze sieci, jest wykonalne. + +Zalety: + +- informacja nie musi być dosłownie zapisana w tekście, ekstraktor może nauczyć się również normalizacji czy parafrazowania, +- nie wprowadzamy wielu kroków przetwarzania (gdzie błędy mogą się + namnażać), system działa na zasadzie /end-to-end/. + +** Atencja + +Pierwsze systemu neuronowego tłumaczenia maszynowego używały siecie LSTM. Dopiero jednak dodanie tzw. atencji (/attention/) umożliwiło duży przeskok jakościowy. Najpierw atencję dodano do sieci rekurencyjnych, później powstały sieci oparte /wyłącznie/ na atencji — modele Transformer. + +Idea atencji polega na tym, że sieć może kierować selektywnie „snop” uwagi na wyrazy na wejściu lub do tej pory wygenerowane wyrazy. + +Mechanizm atencji korzysta z: + +- z poprzedniego stanu sieci $\vec{s^{k-1}}$ (to jest „miejsce”, z którego „kierujemy” atencję), +- z wektora reprezentującego słowo $\vec{v}(t_i)$ (to jest „miejsce”, na które kierujemy atencję), gdzie + $\vec{v}(t_i)$ to reprezentacja wektorowa wyrazu $t_i$ (statyczny embedding lub reprezentacja wektorowa + z poprzedniej warstwy dla sieci wielowarstwowej), + +aby wytworzyć wektor kontekstu $\vec{\xi^k}$ (który z kolei będzie w jakiś sposób wnosił wkład do wyliczenia nowej wartości stanu $\vec{s^k}$ lub wyjścia $y^k$. + +Najpierw wyliczymy skalarne wartości atencji, tzn. liczby, które będą sygnalizowały, jak bardzo wektor $\vec{v}(t_i)$ „pasuje” do $\vec{s^{k-1}}$, w najprostszej wersji można po prostu skorzystać z iloczynu skalarnego (o ile $n=m$), + +$$a(\vec{s^{k-1}}, \vec{v}(t_i)) = \vec{s^{k-1}}\vec{v}(t_i).$$ + +*Pytanie*: co jeśli $n$ nie jest równe $m$, tzn. rozmiar embeddingu nie jest równy rozmiarowi wektora stanu? + +W przypadku sieci LSTM korzysta się częściej z bardziej skomplikowanego wzoru zawierającego dodatkowe wyuczalne wagi: + +$$a(\vec{s^{k-1}}, \vec{v}(t_i)) = \vec{w_a}\operatorname{tanh}(W_a\vec{s^{k-1}} + U_a\vec{v}(t_i))$$ + +*Pytanie*: jakie rozmiary mają macierze $W_a$, $U_a$ i wektor $w_a$? + +Powtórzmy, że wartości $a$ są wartościami skalarnymi, natomiast nie są one znormalizowane (nie sumują się do jedynki), normalizujemy je używając schematu podobnego do softmaxa: + +$$\alpha_{i} = \frac{e^{a(\vec{s^{k-1}}, \vec{v}(t_i))}}{\sum_j e^{a(\vec{s^{k-1}}, \vec{v}(t_j))}}$$ + +Wektor kontekstu $\vec{\xi^k}$ będzie po prostu średnią ważoną wektorowych reprezentacji słów: + +$$\vec{\xi^k} = \sum_i \alpha_i\vec{v}(t_i)$$ + +*Pytanie*: zasadniczo atencja jest środkiem do celu (żeby sieć się sprawniej uczyła), czy można atencja sama w sobie może być do czegoś przydatna? diff --git a/wyk/bpe.png b/wyk/bpe.png new file mode 100644 index 0000000000000000000000000000000000000000..5e0e835b7773143ebb2ccfb02c6861c7413b0d1d GIT binary patch literal 126875 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 A%>V!Z literal 0 HcmV?d00001 diff --git a/wyk/ie-gener.drawio b/wyk/ie-gener.drawio new file mode 100644 index 0000000..7e34f99 --- /dev/null +++ b/wyk/ie-gener.drawio @@ -0,0 +1 @@ +3Vjbbts4EP0aAe2DF9bNiR9jO9lisVekQLF9Y8SxRJsSVYqKrHz9Di+SJctF0m6TtvGDRB2RM+QcnhnKXrjOD79KUmZ/CArcC+b04IUbLwiWkY9XDbQWiMPQAqlk1EL+EbhlD+DAuUNrRqEadVRCcMXKMZiIooBEjTAipWjG3baCj72WJIUJcJsQPkU/MKoyi14GF0f8HbA06zz7i6V9k5Ous1tJlREqmgEUXnvhWgqhbCs/rIHr2HVxseNuPvO2n5iEQj1lgPgrjt7/+du/G76THw8f5Wyxv545K/eE127BXrDgaG+V4atFqlsdUpWk0OtQrQvO4lOtJ7+6I8k+laIu6CwRXEgvvMJ+Mr17E8Sxp6e1xutJ++1xfOfoHRDKirTzh0uxLsfTQHg6t/LFJ/u7kJDr8JZVre/UGEOPTOmtl4Oyo3FjVrgxQdX6LS6wZBVLzDLnwJnrVQE1NjTI6ioX+lFBXhqbrEgYZbQutOlaXzi5Q/+6t+p8g9l0aUG0G84+1eSXxyM5iFswCleg4GC2gco5Aj42t4zztQ3ZphAF2CibpYSb+Pj0XpQIzDB84arJmIJbxLXVBjMEYuIe5JYbKWSMUigQM4SA3ql6VKWk2EPnywvCufn100QDOL3P6sDv1YVZCQRSIVvs0g24dIJ0GclfuufmqO8gclg20rYDicspaW/7KDtsOOV9gQqDiQoV7CvNbAM7bx17y1XCRNM+gaRx6BxNZ5jDHZJi4DcJRg0QX+mYMsx7V+5FjtRoN2cpHNP1LUjxHyflHCfBc1ESnkmMJ8HHhF7q5pbD4UqXGgwFFNQ1NwknFSp9TI81AnRSdB4N1CAQ8ZlAdJgEThS7H5s/Fx3n4W/BTFZxPERRPOIBpTc2UYlaJuBGDavNiaHYf8SQIjIFNTFkyOqX/fX8RRP+tKIk2Sc7nSBNlnwgFaEPDEymtymRdfkQiZwpMcPbIFuyL8iWP6kQo8WJEC++sxCXEyK7SquLXV19XeH6llF/1moVh2M++kAP+Fi+JB9doh4Q0rR9kYJOLXey08qbprXSy0RDCjDHma2QOUl28Pb1Cik+PWYspsT1Ve9lmDtX0yxblN13dP1Tm7MnVP3B0gtvpqwOsuJg8P8TI4et+oGlODk4Rk88OD4fo9MqV7aKFFqGN6DaPQNFXq/E/PkJIeF3rlXdmWeUGwfJrzUfdfZkb0ia53XF9A0f1pF3eWE84PLb5KHAoz9GQ1QKv6rsV+KO7PXqrJVByn2tBMfLk+J3+Xw5FB+P/8XYU+jxD63w+j8= \ No newline at end of file diff --git a/wyk/ie-gener.png b/wyk/ie-gener.png new file mode 100644 index 0000000000000000000000000000000000000000..8b2dc9fb9d59ae69d2693e151a73872fb39cec68 GIT binary patch literal 30341 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 \ No newline at end of file diff --git a/wyk/ie-seqlab.png b/wyk/ie-seqlab.png new file mode 100644 index 0000000000000000000000000000000000000000..79bd0fe0f493073aa66146cccef1e666c5f73c24 GIT binary patch literal 25792 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 \ No newline at end of file diff --git a/wyk/rnn-seq.png b/wyk/rnn-seq.png new file mode 100644 index 0000000000000000000000000000000000000000..1d2c06d66a45159318921bc70890b88f94b28e09 GIT binary patch literal 41684 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∨@0o%cN64&ijW!VL@td;jJ%M-=W??+o^6W{{p{9 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 \ No newline at end of file diff --git a/wyk/rnn.png b/wyk/rnn.png new file mode 100644 index 0000000000000000000000000000000000000000..c082f7661fa7f6d274f8a0a46c879e8ad6d3e4a9 GIT binary patch literal 20759 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 literal 0 HcmV?d00001 diff --git a/wyk/word-distribution.png b/wyk/word-distribution.png new file mode 100644 index 0000000000000000000000000000000000000000..413a6461bd96655dd437bbc13111c4b97236a660 GIT binary patch literal 3983 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 NAbR Date: Sat, 12 Jun 2021 15:47:37 +0200 Subject: [PATCH 2/4] Up --- wyk/11_rnn.ipynb | 523 ++++++++++++++++++++++++++++++- wyk/11_rnn.org | 12 +- wyk/12_bpe.ipynb | 201 ++++++------ wyk/12_bpe.org | 30 +- wyk/13_generative_approach.ipynb | 114 ++++++- wyk/word-distribution.png | Bin 3983 -> 6402 bytes 6 files changed, 764 insertions(+), 116 deletions(-) diff --git a/wyk/11_rnn.ipynb b/wyk/11_rnn.ipynb index aedf48a..89ec808 100644 --- a/wyk/11_rnn.ipynb +++ b/wyk/11_rnn.ipynb @@ -1 +1,522 @@ -{"cells":[{"cell_type":"markdown","metadata":{},"source":["## Rekurencyjne sieci neuronowe\n\n"]},{"cell_type":"markdown","metadata":{},"source":["### Inne spojrzenie na sieci przedstawione do tej pory\n\n"]},{"cell_type":"markdown","metadata":{},"source":["#### Regresja liniowa/logistyczna lub klasyfikacja wieloklasowa na całym tekście\n\n"]},{"cell_type":"markdown","metadata":{},"source":["W regresji liniowej czy logistycznej bądź w klasyfikacji wieloklasowej\n(z funkcją Softmax) stosowaliśmy następujący schemat:\n\nDo tej pory patrzyliśmy na to tak, że po prostu cały tekst jest od\nrazu przetwarzany przez (prostą) sieć neuronową, popatrzmy na ten\nprzypadek, jak na sytuację przetwarzania sekwencyjnego. Będzie to\ntrochę sztuczne, ale uogólnimy to potem w sensowny sposób.\n\n"]},{"cell_type":"markdown","metadata":{},"source":["##### Wektoryzacja\n\n"]},{"cell_type":"markdown","metadata":{},"source":["Po pierwsze, zauważmy, że w wielu schematach wektoryzacji (np. tf), wektor\ndokumentów jest po prostu sumą wektorów poszczególnych składowych:\n\n$$\\vec{v}(d) = \\vec{v}(t^1,\\ldots,t^K) = \\vec{v}(t^1) + \\ldots + \\vec{v}(t^K) = \\sum_{k=1}^K \\vec{v}(t^i),$$\n\ngdzie w schemacie tf \\vec{v}(ti) to po prostu wektor *one-hot* dla słowa.\n\n**Pytanie** Jak postać przyjmie w \\vec{v}(ti) dla wektoryzacji tf-idf?\n\nWektory $\\vec{v}(t^k)$ mogą być również gęstymi wektorami\n($\\vec{v}(t^k) \\in \\mathcal{R}^n$, gdzie $n$ jest rzędu 10-1000), np.\nw modelu Word2vec albo mogą to być **wyuczalne** wektory (zanurzenia\nsłów, *embeddings*), tzn. wektory, które są parametrami uczonej sieci!\n\n**Pytanie** Ile wag (parametrów) wnoszą wyuczalne wektory do sieci?\n\n"]},{"cell_type":"markdown","metadata":{},"source":["##### Prosta wektoryzacja wyrażona w modelu sekwencyjnym\n\n"]},{"cell_type":"markdown","metadata":{},"source":["Jak zapisać równoważnie powyższą wektoryzację w modelu **sekwencyjnym**, tj. przy założeniu, że\nprzetwarzamy wejście token po tokenie (a nie „naraz”)? Ogólnie wprowadzimy bardzo\nogólny model sieci **rekurencyjnej**.\n\nPo pierwsze zakładamy, że sieć ma pewien stan $\\vec{s^k} \\in\n\\mathcal{R}^m$ (stan jest wektorem o długości $m$), który może\nzmieniać się z każdym krokiem (przetwarzanym tokenem). Zmiana stanu\njest określona przez pewną funkcję $R : \\mathcal{R}^m \\times\n\\mathcal{R}^n \\rightarrow \\mathcal{R}^m$ ($n$ to rozmiar wektorów\n$\\vec{v}(t^k)$):\n\n$$\\vec{s^k} = R(\\vec{s^{k-1}}, \\vec{v}(t^k)).$$\n\nW przypadku wektoryzacji tf-idf mamy do czynienia z prostym\nsumowaniem, więc $R$ przyjmuje bardzo prostą postać:\n\n$$\\vec{s^0} = [0,\\dots,0],$$\n\n$$R(\\vec{s}, \\vec{x}) = \\vec{s} + \\vec{x}.$$\n\n"]},{"cell_type":"markdown","metadata":{},"source":["##### Wyjście z modelu\n\n"]},{"cell_type":"markdown","metadata":{},"source":["Dla regresji liniowej/logistycznej, oprócz funkcji $R$, która określa\nzmianę stanu, potrzebujemy funkcji $O$, która określa wyjście systemu w każdym kroku.\n\n$$y^k = O(\\vec{s^k})$$\n\nW zadaniach klasyfikacji czy regresji, kiedy patrzymy na cały tekst w\nzasadzie wystarczy wziąć *ostatnią* wartość (tj. $y^K$). Można sobie\nwyobrazić sytuację, kiedy wartości $y^k$ dla $k < k$ również mogą być jakoś przydatne\n(np. klasyfikujemy na bieżąco tekst wpisywany przez użytkownika).\n\nW każdym razie dla regresji liniowej funkcja $O$ przyjmie postać:\n\n$$O(\\vec{s}) = \\vec{w}\\vec{s}$$,\n\ngdzie $\\vec{w}$ jest wektorem wyuczylnych wag, dla regresji zaś logistycznej:\n\n$$O(\\vec{s}) = \\operatorname{softmax}(\\vec{w}\\vec{s})$$\n\n**Pytanie**: jaką postać przyjmie $O$ dla klasyfikacji wieloklasowej\n\n"]},{"cell_type":"markdown","metadata":{},"source":["### Prosta sieć rekurencyjna\n\n"]},{"cell_type":"markdown","metadata":{},"source":["W najprostszej sieci rekurencyjnej (*Vanilla RNN*, sieć Elmana,\nczasami po prostu RNN) w każdym kroku oprócz właściwego wejścia\n($\\vec{v}(t^k)$) będziemy również podawać na wejściu poprzedni stan\nsieci ($\\vec{s^{k-1}}$).\n\nInnymi słowy, funkcje $R$ przyjmie następującą postać:\n\n$$s^k = \\sigma(W\\langle\\vec{v}(t^k), \\vec{s^{k-1}}\\rangle + \\vec{b}),$$\n\ngdzie:\n\n- $\\langle\\vec{x},\\vec{y}\\rangle$ to konkatenacja dwóch wektorów,\n- $W ∈ \\mathcal{R}m × \\mathcal{R}n+m $ — macierz wag,\n- $b \\in \\mathcal{R}^m$ — wektor obciążeń (*biases*).\n\nTaką sieć RNN można przedstawić schematycznie w następujący sposób:\n\n![img](./img-rnn.png)\n\nZauważmy, że zamiast macierzy $W$ działającej na konkatenacji wektorów można wprowadzić dwie\nmacierze $U$ i $V$ i tak zapisać wzór:\n\n$$s^k = \\sigma(U\\vec{v}(t^k) + V\\vec{s^{k-1}} + \\vec{b}).$$\n\nJeszcze inne spojrzenie na sieć RNN:\n\n![img](./rnn.png)\n\nPowyższy rysunek przedstawia pojedynczy krok sieci RNN. Dla całego\nwejścia (powiedzmy, 3-wyrazowego) możemy sieć rozwinąć (*unroll*):\n\n![img](./rnn-seq.png)\n\n"]},{"cell_type":"markdown","metadata":{},"source":["#### Zastosowanie sieci RNN do etykietowania sekwencji\n\n"]},{"cell_type":"markdown","metadata":{},"source":["#### Problemy z prostymi sieciami RNN\n\n"]},{"cell_type":"markdown","metadata":{},"source":["W praktyce proste sieci RNN są bardzo trudne w uczenia, zazwyczaj\npojawia się problem **zanikających** (rzadziej: **eksplodujących**)\ngradientów: w propagacji wstecznej błąd szybko zanika i nie jest w\nstanie dotrzeć do początkowych wejść.\n\n"]},{"cell_type":"markdown","metadata":{},"source":["### Sieci RNN z bramkami\n\n"]},{"cell_type":"markdown","metadata":{},"source":["W prostych sieciach RNN podstawowa trudność polega na tym, że mamy\nniewielką kontrolę nad tym jak pamięć (stan) jest aktualizowana. Aby\nzwiększyć tę kontrolę, potrzebujemy **bramek**.\n\n"]},{"cell_type":"markdown","metadata":{},"source":["#### Bramki\n\n"]},{"cell_type":"markdown","metadata":{},"source":["Zazwyczaj do tej pory rozpatrywaliśmy iloczyn skalarny wektorów, w\nwyniku którego otrzymujemy liczbę (w PyTorchu wyrażany za pomocą operatora `@`), np.\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":"# Out[2]:\ntensor(-5)"}],"source":["import torch\n\na = torch.tensor([-1, 0, 3])\nb = torch.tensor([2, 5, -1])\na @ b"]},{"cell_type":"markdown","metadata":{},"source":["Czasami przydatny jest **iloczyn Hadamarda**, czyli przemnożenie\nwektorów (albo macierzy) po współrzędnych. W PyTorchu taki iloczyn\nwyrażany jest za pomocą operatora `*`, w notacji matematycznej będziemy używali\nznaku $\\odot$.\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":"# Out[3]:\ntensor([-2, 0, -3])"}],"source":["import torch\n\na = torch.tensor([-1, 0, 3])\nb = torch.tensor([2, 5, -1])\na * b"]},{"cell_type":"markdown","metadata":{},"source":["Zauważmy, że iloczyn Hadamarda przez wektor złożony z zer i jedynek daje nam *filtr*, możemy\nselektywnie wygaszać pozycje wektora, np. tutaj wyzerowaliśmy 2. i 5. pozycję wektora:\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":"# Out[4]:\ntensor([1., 0., 3., 4., 0.])"}],"source":["import torch\n\na = torch.tensor([1., 2., 3., 4., 5.])\nb = torch.tensor([1., 0., 1., 1., 0.])\na * b"]},{"cell_type":"markdown","metadata":{},"source":["Co więcej, za pomocą bramki możemy selektywnie kontrolować, co\nzapamiętujemy, a co zapominamy. Rozpatrzmy mianowicie wektor zer i\njedynek $\\vec{g} \\in \\{0,1}^m$, dla stanu (pamięci) $\\vec{s}$ i nowej informacji\n$\\vec{x}$ możemy dokonywać aktualizacji w następujący sposób:\n\n$$\\vec{s} \\leftarrow \\vec{g} \\odot \\vec{x} + (1 - \\vec{g}) \\odot \\vec{s}$$\n\nNa przykład, za pomocą bramki można wpisać nową wartość na 2. i 5. pozycję wektora.\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":"# Out[8]:\ntensor([ 1., 7., 3., 4., -8.])"}],"source":["import torch\n\ns = torch.tensor([1., 2., 3., 4., 5.])\nx = torch.tensor([8., 7., 15., -3., -8.])\n\ng = torch.tensor([0., 1., 0., 0., 1.])\n\ns = g * x + (1 - g) * s\ns"]},{"cell_type":"markdown","metadata":{},"source":["Wektor bramki nie musi być z góry określony, może być wyuczalny. Wtedy\njednak lepiej założyć, że bramka jest „miękka”, np. jej wartości\npochodzi z sigmoidy zastosowanej do jakiejś wcześniejszej warstwy.\n\n"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":"# Out[14]:\ntensor([ 1.5310, 6.9998, 5.7777, 4.0000, -5.2159])"}],"source":["import torch\n\ns = torch.tensor([1., 2., 3., 4., 5.])\nx = torch.tensor([8., 7., 15., -3., -8.])\n\npre_g = torch.tensor([-2.5, 10.0, -1.2, -101., 1.3])\ng = torch.sigmoid(pre_g)\n\ns = g * x + (1 - g) * s\ns"]},{"cell_type":"markdown","metadata":{},"source":["**Pytanie:** dlaczego sigmoida zamiast tanh?\n\n"]},{"cell_type":"markdown","metadata":{},"source":["#### Sieć LSTM\n\n"]},{"cell_type":"markdown","metadata":{},"source":["Architektura LSTM (*Long Short-Term Memory*) pozwala rozwiązać problem\nznikających gradientów — za cenę komplikacji obliczeń.\n\nW sieci LSTM stan $\\vec{s^k}$ ma dwie połówki, tj. $\\vec{s^k} =\n\\langle\\vec{c^k},\\vec{h^k}\\rangle$, gdzie\n\n- $\\vec{c^k}$ to **komórka pamięci**, która nie zmienia swojej, chyba że celowo zmodyfikujemy jej wartość\n za pomocą bramek,\n- $\\vec{h^k}$ to ukryty stan (przypominający $\\vec{s^k}$ ze zwykłej sieci RNN).\n\nSieć LSTM zawiera 3 bramki:\n\n- bramkę zapominania (*forget gate*), która steruje wymazywaniem informacji z komórki\n pamięci $\\vec{c^k}$,\n- bramkę wejścia (*input gate*), która steruje tym, na ile nowe informacje aktualizują\n komórkę pamięci $\\vec{c^k}$,\n- bramkę wyjścia (*output gate*), która steruje tym, co z komórki\n pamięci przekazywane jest na wyjście.\n\nWszystkie trzy bramki definiowane są za pomocą bardzo podobnego wzoru — warstwy liniowej na\npoprzedniej wartości warstwy ukrytej i bieżącego wejścia.\n\n$$\\vec{i} = \\sigma(W_i\\langle\\vec{v}(t^k),\\vec{h^{k-1}}\\rangle)$$\n\n$$\\vec{f} = \\sigma(W_f\\langle\\vec{v}(t^k),\\vec{h^{k-1}}\\rangle)$$\n\n$$\\vec{o} = \\sigma(W_f\\langle\\vec{v}(t^k),\\vec{h^{k-1}}\\rangle)$$\n\nJak widać, wzory różnią się tylko macierzami wag $W_*$.\n\nZmiana komórki pamięci jest zdefiniowana jak następuje:\n\n$$\\vec{c^k} = \\vec{f} \\odot \\vec{c^{k-1}} + \\vec{i} \\vec{z^k}$$,\n\ngdzie\n\n$$\\vec{z^k} = \\operatorname{tanh}(W_z\\langle\\vec{v}(t^k),\\vec{h^{k-1}}\\rangle)$$\n\nStan ukryty zmienia się w następujący sposób:\n\n$$\\vec{h^K} = \\vec{o} \\odot \\operatorname{tanh}(\\vec{c^k})$$.\n\nOstateczne wyjście może być wyliczane na podstawie wektora $\\vec{h^k}$:\n\n$$O(\\vec{s}) = O(\\langle\\vec{c},\\vec{h}\\rangle) = \\vec{h}$$\n\n**Pytanie**: Ile wag/parametrów ma sieć RNN o rozmiarze wejścia $n$ i\n\n"]},{"cell_type":"markdown","metadata":{},"source":["### Literatura\n\n"]},{"cell_type":"markdown","metadata":{},"source":["Yoav Goldberg, *Neural Network Methods for Natural Language\nProcessing*, Morgan & Claypool Publishers, 2017\n\n"]}],"metadata":{"org":null,"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.5.2"}},"nbformat":4,"nbformat_minor":0} \ No newline at end of file +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Rekurencyjne sieci neuronowe\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Inne spojrzenie na sieci przedstawione do tej pory\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Regresja liniowa/logistyczna lub klasyfikacja wieloklasowa na całym tekście\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "W regresji liniowej czy logistycznej bądź w klasyfikacji wieloklasowej\n", + "(z funkcją Softmax) stosowaliśmy następujący schemat:\n", + "\n", + "Do tej pory patrzyliśmy na to tak, że po prostu cały tekst jest od\n", + "razu przetwarzany przez (prostą) sieć neuronową, popatrzmy na ten\n", + "przypadek, jak na sytuację przetwarzania sekwencyjnego. Będzie to\n", + "trochę sztuczne, ale uogólnimy to potem w sensowny sposób.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Wektoryzacja\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Po pierwsze, zauważmy, że w wielu schematach wektoryzacji (np. tf), wektor\n", + "dokumentów jest po prostu sumą wektorów poszczególnych składowych:\n", + "\n", + "$$\\vec{v}(d) = \\vec{v}(t^1,\\ldots,t^K) = \\vec{v}(t^1) + \\ldots + \\vec{v}(t^K) = \\sum_{k=1}^K \\vec{v}(t^i),$$\n", + "\n", + "gdzie w schemacie tf \\vec{v}(ti) to po prostu wektor *one-hot* dla słowa.\n", + "\n", + "**Pytanie** Jak postać przyjmie w \\vec{v}(ti) dla wektoryzacji tf-idf?\n", + "\n", + "Wektory $\\vec{v}(t^k)$ mogą być również gęstymi wektorami\n", + "($\\vec{v}(t^k) \\in \\mathcal{R}^n$, gdzie $n$ jest rzędu 10-1000), np.\n", + "w modelu Word2vec albo mogą to być **wyuczalne** wektory (zanurzenia\n", + "słów, *embeddings*), tzn. wektory, które są parametrami uczonej sieci!\n", + "\n", + "**Pytanie** Ile wag (parametrów) wnoszą wyuczalne wektory do sieci?\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Prosta wektoryzacja wyrażona w modelu sekwencyjnym\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Jak zapisać równoważnie powyższą wektoryzację w modelu **sekwencyjnym**, tj. przy założeniu, że\n", + "przetwarzamy wejście token po tokenie (a nie „naraz”)? Ogólnie wprowadzimy bardzo\n", + "ogólny model sieci **rekurencyjnej**.\n", + "\n", + "Po pierwsze zakładamy, że sieć ma pewien stan $\\vec{s^k} \\in\n", + "\\mathcal{R}^m$ (stan jest wektorem o długości $m$), który może\n", + "zmieniać się z każdym krokiem (przetwarzanym tokenem). Zmiana stanu\n", + "jest określona przez pewną funkcję $R : \\mathcal{R}^m \\times\n", + "\\mathcal{R}^n \\rightarrow \\mathcal{R}^m$ ($n$ to rozmiar wektorów\n", + "$\\vec{v}(t^k)$):\n", + "\n", + "$$\\vec{s^k} = R(\\vec{s^{k-1}}, \\vec{v}(t^k)).$$\n", + "\n", + "W przypadku wektoryzacji tf-idf mamy do czynienia z prostym\n", + "sumowaniem, więc $R$ przyjmuje bardzo prostą postać:\n", + "\n", + "$$\\vec{s^0} = [0,\\dots,0],$$\n", + "\n", + "$$R(\\vec{s}, \\vec{x}) = \\vec{s} + \\vec{x}.$$\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "##### Wyjście z modelu\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Dla regresji liniowej/logistycznej, oprócz funkcji $R$, która określa\n", + "zmianę stanu, potrzebujemy funkcji $O$, która określa wyjście systemu w każdym kroku.\n", + "\n", + "$$y^k = O(\\vec{s^k})$$\n", + "\n", + "W zadaniach klasyfikacji czy regresji, kiedy patrzymy na cały tekst w\n", + "zasadzie wystarczy wziąć *ostatnią* wartość (tj. $y^K$). Można sobie\n", + "wyobrazić sytuację, kiedy wartości $y^k$ dla $k < k$ również mogą być jakoś przydatne\n", + "(np. klasyfikujemy na bieżąco tekst wpisywany przez użytkownika).\n", + "\n", + "W każdym razie dla regresji liniowej funkcja $O$ przyjmie postać:\n", + "\n", + "$$O(\\vec{s}) = \\vec{w}\\vec{s}$$,\n", + "\n", + "gdzie $\\vec{w}$ jest wektorem wyuczylnych wag, dla regresji zaś logistycznej:\n", + "\n", + "$$O(\\vec{s}) = \\operatorname{softmax}(\\vec{w}\\vec{s})$$\n", + "\n", + "**Pytanie**: jaką postać przyjmie $O$ dla klasyfikacji wieloklasowej\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Prosta sieć rekurencyjna\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "W najprostszej sieci rekurencyjnej (*Vanilla RNN*, sieć Elmana,\n", + "czasami po prostu RNN) w każdym kroku oprócz właściwego wejścia\n", + "($\\vec{v}(t^k)$) będziemy również podawać na wejściu poprzedni stan\n", + "sieci ($\\vec{s^{k-1}}$).\n", + "\n", + "Innymi słowy, funkcje $R$ przyjmie następującą postać:\n", + "\n", + "$$s^k = \\sigma(W\\langle\\vec{v}(t^k), \\vec{s^{k-1}}\\rangle + \\vec{b}),$$\n", + "\n", + "gdzie:\n", + "\n", + "- $\\langle\\vec{x},\\vec{y}\\rangle$ to konkatenacja dwóch wektorów,\n", + "- $W \\in \\mathcal{R}^m \\times \\mathcal{R}^{n+m}$ — macierz wag,\n", + "- $b \\in \\mathcal{R}^m$ — wektor obciążeń (*biases*).\n", + "\n", + "Taką sieć RNN można przedstawić schematycznie w następujący sposób:\n", + "\n", + "![img](./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", + "\n", + "$$s^k = \\sigma(U\\vec{v}(t^k) + V\\vec{s^{k-1}} + \\vec{b}).$$\n", + "\n", + "Jeszcze inne spojrzenie na sieć RNN:\n", + "\n", + "![img](./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", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Zastosowanie sieci RNN do etykietowania sekwencji\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Problemy z prostymi sieciami RNN\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "W praktyce proste sieci RNN są bardzo trudne w uczenia, zazwyczaj\n", + "pojawia się problem **zanikających** (rzadziej: **eksplodujących**)\n", + "gradientów: w propagacji wstecznej błąd szybko zanika i nie jest w\n", + "stanie dotrzeć do początkowych wejść.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Sieci RNN z bramkami\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "W prostych sieciach RNN podstawowa trudność polega na tym, że mamy\n", + "niewielką kontrolę nad tym jak pamięć (stan) jest aktualizowana. Aby\n", + "zwiększyć tę kontrolę, potrzebujemy **bramek**.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Bramki\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Zazwyczaj do tej pory rozpatrywaliśmy iloczyn skalarny wektorów, w\n", + "wyniku którego otrzymujemy liczbę (w PyTorchu wyrażany za pomocą operatora `@`), np.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# Out[2]:\n", + "tensor(-5)" + ] + } + ], + "source": [ + "import torch\n", + "\n", + "a = torch.tensor([-1, 0, 3])\n", + "b = torch.tensor([2, 5, -1])\n", + "a @ b" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Czasami przydatny jest **iloczyn Hadamarda**, czyli przemnożenie\n", + "wektorów (albo macierzy) po współrzędnych. W PyTorchu taki iloczyn\n", + "wyrażany jest za pomocą operatora `*`, w notacji matematycznej będziemy używali\n", + "znaku $\\odot$.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# Out[3]:\n", + "tensor([-2, 0, -3])" + ] + } + ], + "source": [ + "import torch\n", + "\n", + "a = torch.tensor([-1, 0, 3])\n", + "b = torch.tensor([2, 5, -1])\n", + "a * b" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Zauważmy, że iloczyn Hadamarda przez wektor złożony z zer i jedynek daje nam *filtr*, możemy\n", + "selektywnie wygaszać pozycje wektora, np. tutaj wyzerowaliśmy 2. i 5. pozycję wektora:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# Out[4]:\n", + "tensor([1., 0., 3., 4., 0.])" + ] + } + ], + "source": [ + "import torch\n", + "\n", + "a = torch.tensor([1., 2., 3., 4., 5.])\n", + "b = torch.tensor([1., 0., 1., 1., 0.])\n", + "a * b" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Co więcej, za pomocą bramki możemy selektywnie kontrolować, co\n", + "zapamiętujemy, a co zapominamy. Rozpatrzmy mianowicie wektor zer i\n", + "jedynek $\\vec{g} \\in \\{0,1\\}^m$, dla stanu (pamięci) $\\vec{s}$ i nowej informacji\n", + "$\\vec{x}$ możemy dokonywać aktualizacji w następujący sposób:\n", + "\n", + "$$\\vec{s} \\leftarrow \\vec{g} \\odot \\vec{x} + (1 - \\vec{g}) \\odot \\vec{s}$$\n", + "\n", + "Na przykład, za pomocą bramki można wpisać nową wartość na 2. i 5. pozycję wektora.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# Out[8]:\n", + "tensor([ 1., 7., 3., 4., -8.])" + ] + } + ], + "source": [ + "import torch\n", + "\n", + "s = torch.tensor([1., 2., 3., 4., 5.])\n", + "x = torch.tensor([8., 7., 15., -3., -8.])\n", + "\n", + "g = torch.tensor([0., 1., 0., 0., 1.])\n", + "\n", + "s = g * x + (1 - g) * s\n", + "s" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Wektor bramki nie musi być z góry określony, może być wyuczalny. Wtedy\n", + "jednak lepiej założyć, że bramka jest „miękka”, np. jej wartości\n", + "pochodzi z sigmoidy zastosowanej do jakiejś wcześniejszej warstwy.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# Out[14]:\n", + "tensor([ 1.5310, 6.9998, 5.7777, 4.0000, -5.2159])" + ] + } + ], + "source": [ + "import torch\n", + "\n", + "s = torch.tensor([1., 2., 3., 4., 5.])\n", + "x = torch.tensor([8., 7., 15., -3., -8.])\n", + "\n", + "pre_g = torch.tensor([-2.5, 10.0, -1.2, -101., 1.3])\n", + "g = torch.sigmoid(pre_g)\n", + "\n", + "s = g * x + (1 - g) * s\n", + "s" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Pytanie:** dlaczego sigmoida zamiast tanh?\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Sieć LSTM\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Architektura LSTM (*Long Short-Term Memory*) pozwala rozwiązać problem\n", + "znikających gradientów — za cenę komplikacji obliczeń.\n", + "\n", + "W sieci LSTM stan $\\vec{s^k}$ ma dwie połówki, tj. $\\vec{s^k} =\n", + "\\langle\\vec{c^k},\\vec{h^k}\\rangle$, gdzie\n", + "\n", + "- $\\vec{c^k}$ to **komórka pamięci**, która nie zmienia swojej, chyba że celowo zmodyfikujemy jej wartość\n", + " za pomocą bramek,\n", + "- $\\vec{h^k}$ to ukryty stan (przypominający $\\vec{s^k}$ ze zwykłej sieci RNN).\n", + "\n", + "Sieć LSTM zawiera 3 bramki:\n", + "\n", + "- bramkę zapominania (*forget gate*), która steruje wymazywaniem informacji z komórki\n", + " pamięci $\\vec{c^k}$,\n", + "- bramkę wejścia (*input gate*), która steruje tym, na ile nowe informacje aktualizują\n", + " komórkę pamięci $\\vec{c^k}$,\n", + "- bramkę wyjścia (*output gate*), która steruje tym, co z komórki\n", + " pamięci przekazywane jest na wyjście.\n", + "\n", + "Wszystkie trzy bramki definiowane są za pomocą bardzo podobnego wzoru — warstwy liniowej na\n", + "poprzedniej wartości warstwy ukrytej i bieżącego wejścia.\n", + "\n", + "$$\\vec{i} = \\sigma(W_i\\langle\\vec{v}(t^k),\\vec{h^{k-1}}\\rangle)$$\n", + "\n", + "$$\\vec{f} = \\sigma(W_f\\langle\\vec{v}(t^k),\\vec{h^{k-1}}\\rangle)$$\n", + "\n", + "$$\\vec{o} = \\sigma(W_o\\langle\\vec{v}(t^k),\\vec{h^{k-1}}\\rangle)$$\n", + "\n", + "Jak widać, wzory różnią się tylko macierzami wag $W_*$.\n", + "\n", + "Zmiana komórki pamięci jest zdefiniowana jak następuje:\n", + "\n", + "$$\\vec{c^k} = \\vec{f} \\odot \\vec{c^{k-1}} + \\vec{i} \\vec{z^k}$$,\n", + "\n", + "gdzie\n", + "\n", + "$$\\vec{z^k} = \\operatorname{tanh}(W_z\\langle\\vec{v}(t^k),\\vec{h^{k-1}}\\rangle)$$\n", + "\n", + "Stan ukryty zmienia się w następujący sposób:\n", + "\n", + "$$\\vec{h^K} = \\vec{o} \\odot \\operatorname{tanh}(\\vec{c^k})$$.\n", + "\n", + "Ostateczne wyjście może być wyliczane na podstawie wektora $\\vec{h^k}$:\n", + "\n", + "$$O(\\vec{s}) = O(\\langle\\vec{c},\\vec{h}\\rangle) = \\vec{h}$$\n", + "\n", + "**Pytanie**: Ile wag/parametrów ma sieć RNN o rozmiarze wejścia $n$ i rozmiarze warstwy ukrytej $m$?\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Literatura\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Yoav Goldberg, *Neural Network Methods for Natural Language Processing*,\n", + "Morgan & Claypool Publishers, 2017\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.2" + }, + "org": null + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/wyk/11_rnn.org b/wyk/11_rnn.org index 1efba6a..606a6eb 100644 --- a/wyk/11_rnn.org +++ b/wyk/11_rnn.org @@ -87,7 +87,7 @@ $$s^k = \sigma(W\langle\vec{v}(t^k), \vec{s^{k-1}}\rangle + \vec{b}),$$ gdzie: - $\langle\vec{x},\vec{y}\rangle$ to konkatenacja dwóch wektorów, -- $W \in \mathcal{R}^m \times \mathcal{R}^{n+m} $ — macierz wag, +- $W \in \mathcal{R}^m \times \mathcal{R}^{n+m}$ — macierz wag, - $b \in \mathcal{R}^m$ — wektor obciążeń (/biases/). Taką sieć RNN można przedstawić schematycznie w następujący sposób: @@ -181,7 +181,7 @@ selektywnie wygaszać pozycje wektora, np. tutaj wyzerowaliśmy 2. i 5. pozycję Co więcej, za pomocą bramki możemy selektywnie kontrolować, co zapamiętujemy, a co zapominamy. Rozpatrzmy mianowicie wektor zer i -jedynek $\vec{g} \in \{0,1}^m$, dla stanu (pamięci) $\vec{s}$ i nowej informacji +jedynek $\vec{g} \in \{0,1\}^m$, dla stanu (pamięci) $\vec{s}$ i nowej informacji $\vec{x}$ możemy dokonywać aktualizacji w następujący sposób: $$\vec{s} \leftarrow \vec{g} \odot \vec{x} + (1 - \vec{g}) \odot \vec{s}$$ @@ -259,7 +259,7 @@ $$\vec{i} = \sigma(W_i\langle\vec{v}(t^k),\vec{h^{k-1}}\rangle)$$ $$\vec{f} = \sigma(W_f\langle\vec{v}(t^k),\vec{h^{k-1}}\rangle)$$ -$$\vec{o} = \sigma(W_f\langle\vec{v}(t^k),\vec{h^{k-1}}\rangle)$$ +$$\vec{o} = \sigma(W_o\langle\vec{v}(t^k),\vec{h^{k-1}}\rangle)$$ Jak widać, wzory różnią się tylko macierzami wag $W_*$. @@ -279,10 +279,10 @@ Ostateczne wyjście może być wyliczane na podstawie wektora $\vec{h^k}$: $$O(\vec{s}) = O(\langle\vec{c},\vec{h}\rangle) = \vec{h}$$ -*Pytanie*: Ile wag/parametrów ma sieć RNN o rozmiarze wejścia $n$ i +*Pytanie*: Ile wag/parametrów ma sieć RNN o rozmiarze wejścia $n$ i rozmiarze warstwy ukrytej $m$? ** Literatura -Yoav Goldberg, /Neural Network Methods for Natural Language -Processing/, Morgan & Claypool Publishers, 2017 +Yoav Goldberg, /Neural Network Methods for Natural Language Processing/, +Morgan & Claypool Publishers, 2017 diff --git a/wyk/12_bpe.ipynb b/wyk/12_bpe.ipynb index 9a04687..0220f04 100644 --- a/wyk/12_bpe.ipynb +++ b/wyk/12_bpe.ipynb @@ -93,7 +93,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "3844535\r\n" + "3844535\n" ] } ], @@ -109,7 +109,7 @@ "\n", "Tak naprawdę form jest jeszcze więcej, oczywiście PoliMorf nie wyczerpuje zbioru…\n", "\n", - "**Pytanie** Podaj przykłady „oczywistych” wyrazów, których w PoliMorfie. Jak w sposób systematyczny szukać takich wyrazów?\n", + "**Pytanie** Podaj przykłady „oczywistych” wyrazów, których nie ma w PoliMorfie. Jak w sposób systematyczny szukać takich wyrazów?\n", "\n", "Z drugiej strony, w PoliMorfie jest dużo dziwnych, „sztucznych” wyrazów.\n", "\n" @@ -124,26 +124,26 @@ "name": "stdout", "output_type": "stream", "text": [ - "niemałomieszczańskiej\r\n", - "kwatereczki\r\n", - "słowniejszej\r\n", - "oranżysta\r\n", - "myrmekofagów\r\n", - "hipokratesowego\r\n", - "rozdziałująca\r\n", - "wielosettysięczne\r\n", - "redempcyjno\r\n", - "łącznikowce\r\n", - "niesłowacyzowana\r\n", - "sosnowieckościach\r\n", - "niewschodoznawczy\r\n", - "niekłosokształtnego\r\n", - "niegenialności\r\n", - "Gierowskiego\r\n", - "nieumierzwiających\r\n", - "bezzakłóceniowości\r\n", - "niedziurkowatościach\r\n", - "Krzaklewskich\r\n" + "niebiałościenną\n", + "nieponadosobowości\n", + "nieknerający\n", + "inspektoratów\n", + "Korytkowskich\n", + "elektrostatyczności\n", + "Okola\n", + "bezsłowny\n", + "indygowcu\n", + "gadany\n", + "nieładowarkowościach\n", + "niepawężnicowate\n", + "Thom\n", + "poradlmy\n", + "olejący\n", + "Ziemianinów\n", + "stenotropizmami\n", + "wigiliowości\n", + "pognanej\n", + "niekinezyterapeutycznym\n" ] } ], @@ -195,56 +195,56 @@ "name": "stdout", "output_type": "stream", "text": [ - "ˆ\r\n", - "ˇ\r\n", - "゚\r\n", - "a\r\n", - "A\r\n", - "á\r\n", - "Á\r\n", - "à\r\n", - "À\r\n", - "ă\r\n", - "Ă\r\n", - "â\r\n", - "Â\r\n", - "å\r\n", - "Å\r\n", - "ä\r\n", - "Ä\r\n", - "Ã\r\n", - "ā\r\n", - "aa\r\n", - "aA\r\n", - "Aa\r\n", - "AA\r\n", - "aĂ\r\n", - "AĂ\r\n", - "aâ\r\n", - "aÂ\r\n", - "Aâ\r\n", - "aÅ\r\n", - "aÄ\r\n", - "ª\r\n", - "aaa\r\n", - "aAa\r\n", - "Aaa\r\n", - "AaA\r\n", - "AAa\r\n", - "AAA\r\n", - "aaaa\r\n", - "aAaa\r\n", - "Aaaa\r\n", - "AaAa\r\n", - "AAaa\r\n", - "AAAa\r\n", - "AAAA\r\n", - "aaaaa\r\n", - "Aaaaa\r\n", - "AaaaA\r\n", - "AAaaa\r\n", - "AAAAA\r\n", - "aaaaaa\r\n" + "ˆ\n", + "ˇ\n", + "゚\n", + "a\n", + "A\n", + "á\n", + "Á\n", + "à\n", + "À\n", + "ă\n", + "Ă\n", + "â\n", + "Â\n", + "å\n", + "Å\n", + "ä\n", + "Ä\n", + "Ã\n", + "ā\n", + "aa\n", + "aA\n", + "Aa\n", + "AA\n", + "aĂ\n", + "AĂ\n", + "aâ\n", + "aÂ\n", + "Aâ\n", + "aÅ\n", + "aÄ\n", + "ª\n", + "aaa\n", + "aAa\n", + "Aaa\n", + "AaA\n", + "AAa\n", + "AAA\n", + "aaaa\n", + "aAaa\n", + "Aaaa\n", + "AaAa\n", + "AAaa\n", + "AAAa\n", + "AAAA\n", + "aaaaa\n", + "Aaaaa\n", + "AaaaA\n", + "AAaaa\n", + "AAAAA\n", + "aaaaaa\n" ] } ], @@ -261,7 +261,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "2974556 vocab.txt\r\n" + "2974556 vocab.txt\n" ] } ], @@ -281,14 +281,14 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "81380\r\n" + "81380\n" ] } ], @@ -324,14 +324,15 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "# Out[8]:" + "sort: błąd zapisu: 'standardowe wyjście': Przerwany potok\n", + "sort: błąd zapisu\n" ] } ], @@ -366,7 +367,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -375,13 +376,13 @@ "'word-distribution.png'" ] }, - "execution_count": 8, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -404,7 +405,7 @@ " for line in fh:\n", " m = re.match(r'\\s*(\\d+)', line)\n", " if m:\n", - " freqs.append(int(m.group(1)))\n", + " freqs.append(log(float(m.group(1))))\n", "\n", "plt.plot(range(len(freqs)), freqs)\n", "fname = 'word-distribution.png'\n", @@ -531,7 +532,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -540,7 +541,7 @@ "['e$', 'to', 'to$', 'be$', 't$', 'th', 'or', 'or$', 'no', 'not$']" ] }, - "execution_count": 9, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -587,16 +588,16 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "'to$ b e$ or$ no t$ to$ b e$ th a t$ i s $ th e$ q u e s t i o n $'" + "'to$ be$ or$ not$ to$ be$ th a t$ i s $ th e$ q u e s t i o n $'" ] }, - "execution_count": 10, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -606,13 +607,17 @@ " d = list(d.replace(' ', '$') + '$')\n", " vocab_set = set(vocab)\n", "\n", - " ix = 0\n", - " while ix < len(d) - 1:\n", - " bigram = d[ix] + d[ix+1]\n", - " if bigram in vocab_set:\n", - " d[ix:ix+2] = [bigram]\n", - " else:\n", - " ix += 1\n", + " modified = True\n", + " while modified:\n", + " ix = 0\n", + " modified = False\n", + " while ix < len(d) - 1:\n", + " bigram = d[ix] + d[ix+1]\n", + " if bigram in vocab_set:\n", + " d[ix:ix+2] = [bigram]\n", + " modified = True\n", + " else:\n", + " ix += 1\n", "\n", " return d\n", "\n", @@ -637,16 +642,16 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "'to m $ w i l l $ b e$ th e$ b e s t$'" + "'to m $ w i l l $ be$ th e$ b e s t$'" ] }, - "execution_count": 11, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -785,7 +790,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -830,5 +835,5 @@ "org": null }, "nbformat": 4, - "nbformat_minor": 1 + "nbformat_minor": 4 } diff --git a/wyk/12_bpe.org b/wyk/12_bpe.org index 17adf4e..486ef45 100644 --- a/wyk/12_bpe.org +++ b/wyk/12_bpe.org @@ -36,7 +36,7 @@ Ile jest różnych form fleksyjnych w języku polskim? Zobaczmy w słowniku Poli Tak naprawdę form jest jeszcze więcej, oczywiście PoliMorf nie wyczerpuje zbioru… -*Pytanie* Podaj przykłady „oczywistych” wyrazów, których w PoliMorfie. Jak w sposób systematyczny szukać takich wyrazów? +*Pytanie* Podaj przykłady „oczywistych” wyrazów, których nie ma w PoliMorfie. Jak w sposób systematyczny szukać takich wyrazów? Z drugiej strony, w PoliMorfie jest dużo dziwnych, „sztucznych” wyrazów. @@ -244,7 +244,7 @@ momentu traktujemy go jako całostkę (wkładamy go do „pudełka”). #+RESULTS: :results: -# Out[4]: +# Out[1]: : ['e$', 'to', 'to$', 'be$', 't$', 'th', 'or', 'or$', 'no', 'not$'] :end: @@ -256,13 +256,17 @@ na którym słownik był wyuczony: d = list(d.replace(' ', '$') + '$') vocab_set = set(vocab) - ix = 0 - while ix < len(d) - 1: - bigram = d[ix] + d[ix+1] - if bigram in vocab_set: - d[ix:ix+2] = [bigram] - else: - ix += 1 + modified = True + while modified: + ix = 0 + modified = False + while ix < len(d) - 1: + bigram = d[ix] + d[ix+1] + if bigram in vocab_set: + d[ix:ix+2] = [bigram] + modified = True + else: + ix += 1 return d @@ -272,7 +276,7 @@ na którym słownik był wyuczony: #+RESULTS: :results: # Out[5]: -: 'to$ b e$ or$ no t$ to$ b e$ th a t$ i s $ th e$ q u e s t i o n $' +: 'to$ be$ or$ not$ to$ be$ th a t$ i s $ th e$ q u e s t i o n $' :end: Zauważmy, że oprócz jednostek podwyrazowych zostały izolowane litery, @@ -289,6 +293,12 @@ Słownik jednostek podwyrazowych można stosować dla dowolnego tekstu: ' '.join(apply_bpe_vocab(vocab1, 'tom will be the best')) #+END_SRC +#+RESULTS: +:results: +# Out[6]: +: 'to m $ w i l l $ be$ th e$ b e s t$' +:end: + Jak można zauważyć algorytm BPE daje dwa rodzaje jednostek podwyrazowych: - jednostki, które mogą doklejane na początku wyrazu; diff --git a/wyk/13_generative_approach.ipynb b/wyk/13_generative_approach.ipynb index 11c1953..8234d7a 100644 --- a/wyk/13_generative_approach.ipynb +++ b/wyk/13_generative_approach.ipynb @@ -1 +1,113 @@ -{"cells":[{"cell_type":"markdown","metadata":{},"source":["## Ekstrakcja informacji a podejście generatywne\n\n"]},{"cell_type":"markdown","metadata":{},"source":["### Podejście generatywne\n\n"]},{"cell_type":"markdown","metadata":{},"source":["Do tej pory zadanie ekstrakcji informacji traktowaliśmy jako zadanie etykietowania sekwencji, tzn. uczyliśmy system zaznaczać tokeny składające się na ekstrahowane informacje.\n\n![img](./ie-seqlab.png)\n\nMoż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\nTo podejście może się wydawać trudniejsze niż etykietowanie sekwencji, ale wystarczająco zaawansowanej architekturze sieci, jest wykonalne.\n\nZalety:\n\n- informacja nie musi być dosłownie zapisana w tekście, ekstraktor może nauczyć się również normalizacji czy parafrazowania,\n- nie wprowadzamy wielu kroków przetwarzania (gdzie błędy mogą się\n namnażać), system działa na zasadzie *end-to-end*.\n\n"]},{"cell_type":"markdown","metadata":{},"source":["### Atencja\n\n"]},{"cell_type":"markdown","metadata":{},"source":["Pierwsze systemu neuronowego tłumaczenia maszynowego używały siecie LSTM. Dopiero jednak dodanie tzw. atencji (*attention*) umożliwiło duży przeskok jakościowy. Najpierw atencję dodano do sieci rekurencyjnych, później powstały sieci oparte *wyłącznie* na atencji — modele Transformer.\n\nIdea atencji polega na tym, że sieć może kierować selektywnie „snop” uwagi na wyrazy na wejściu lub do tej pory wygenerowane wyrazy.\n\nMechanizm atencji korzysta z:\n\n- z poprzedniego stanu sieci $\\vec{s^{k-1}}$ (to jest „miejsce”, z którego „kierujemy” atencję),\n- z wektora reprezentującego słowo $\\vec{v}(t_i)$ (to jest „miejsce”, na które kierujemy atencję), gdzie\n $\\vec{v}(t_i)$ to reprezentacja wektorowa wyrazu $t_i$ (statyczny embedding lub reprezentacja wektorowa\n z poprzedniej warstwy dla sieci wielowarstwowej),\n\naby wytworzyć wektor kontekstu $\\vec{\\xi^k}$ (który z kolei będzie w jakiś sposób wnosił wkład do wyliczenia nowej wartości stanu $\\vec{s^k}$ lub wyjścia $y^k$.\n\nNajpierw wyliczymy skalarne wartości atencji, tzn. liczby, które będą sygnalizowały, jak bardzo wektor $\\vec{v}(t_i)$ „pasuje” do $\\vec{s^{k-1}}$, w najprostszej wersji można po prostu skorzystać z iloczynu skalarnego (o ile $n=m$),\n\n$$a(\\vec{s^{k-1}}, \\vec{v}(t_i)) = \\vec{s^{k-1}}\\vec{v}(t_i).$$\n\n**Pytanie**: co jeśli $n$ nie jest równe $m$, tzn. rozmiar embeddingu nie jest równy rozmiarowi wektora stanu?\n\nW przypadku sieci LSTM korzysta się częściej z bardziej skomplikowanego wzoru zawierającego dodatkowe wyuczalne wagi:\n\n$$a(\\vec{s^{k-1}}, \\vec{v}(t_i)) = \\vec{w_a}\\operatorname{tanh}(W_a\\vec{s^{k-1}} + U_a\\vec{v}(t_i))$$\n\n**Pytanie**: jakie rozmiary mają macierze $W_a$, $U_a$ i wektor $w_a$?\n\nPowtórzmy, że wartości $a$ są wartościami skalarnymi, natomiast nie są one znormalizowane (nie sumują się do jedynki), normalizujemy je używając schematu podobnego do softmaxa:\n\n$$\\alpha_{i} = \\frac{e^{a(\\vec{s^{k-1}}, \\vec{v}(t_i))}}{\\sum_j e^{a(\\vec{s^{k-1}}, \\vec{v}(t_j))}}$$\n\nWektor kontekstu $\\vec{\\xi^k}$ będzie po prostu średnią ważoną wektorowych reprezentacji słów:\n\n$$\\vec{\\xi^k} = \\sum_i \\alpha_i\\vec{v}(t_i)$$\n\n**Pytanie**: zasadniczo atencja jest środkiem do celu (żeby sieć się sprawniej uczyła), czy można atencja sama w sobie może być do czegoś przydatna?\n\n"]}],"metadata":{"org":null,"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.5.2"}},"nbformat":4,"nbformat_minor":0} \ No newline at end of file +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Ekstrakcja informacji a podejście generatywne\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Podejście generatywne\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Do tej pory zadanie ekstrakcji informacji traktowaliśmy jako zadanie etykietowania sekwencji, tzn. uczyliśmy system zaznaczać tokeny składające się na ekstrahowane informacje.\n", + "\n", + "![img](./ie-seqlab.png)\n", + "\n", + "Możliwe jest inne podeście, **generatywne**, w którym podchodzimy do problemu ekstrakcji informacji jak do swego rodzaju **tłumaczenia maszynowego** — „tłumaczymy” tekst (wraz z pytaniem lub etykietą) na informację.\n", + "\n", + "![img](./ie-gener.png)\n", + "\n", + "To podejście może się wydawać trudniejsze niż etykietowanie sekwencji, ale wystarczająco zaawansowanej architekturze sieci, jest wykonalne.\n", + "\n", + "Zalety:\n", + "\n", + "- informacja nie musi być dosłownie zapisana w tekście, ekstraktor może nauczyć się również normalizacji czy parafrazowania,\n", + "- nie wprowadzamy wielu kroków przetwarzania (gdzie błędy mogą się\n", + " namnażać), system działa na zasadzie *end-to-end*.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Atencja\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Pierwsze systemu neuronowego tłumaczenia maszynowego używały siecie LSTM. Dopiero jednak dodanie tzw. atencji (*attention*) umożliwiło duży przeskok jakościowy. Najpierw atencję dodano do sieci rekurencyjnych, później powstały sieci oparte *wyłącznie* na atencji — modele Transformer.\n", + "\n", + "Idea atencji polega na tym, że sieć może kierować selektywnie „snop” uwagi na wyrazy na wejściu lub do tej pory wygenerowane wyrazy.\n", + "\n", + "Mechanizm atencji korzysta z:\n", + "\n", + "- z poprzedniego stanu sieci $\\vec{s^{k-1}}$ (to jest „miejsce”, z którego „kierujemy” atencję),\n", + "- z wektora reprezentującego słowo $\\vec{v}(t_i)$ (to jest „miejsce”, na które kierujemy atencję), gdzie\n", + " $\\vec{v}(t_i)$ to reprezentacja wektorowa wyrazu $t_i$ (statyczny embedding lub reprezentacja wektorowa\n", + " z poprzedniej warstwy dla sieci wielowarstwowej),\n", + "\n", + "aby wytworzyć wektor kontekstu $\\vec{\\xi^k}$ (który z kolei będzie w jakiś sposób wnosił wkład do wyliczenia nowej wartości stanu $\\vec{s^k}$ lub wyjścia $y^k$.\n", + "\n", + "Najpierw wyliczymy skalarne wartości atencji, tzn. liczby, które będą sygnalizowały, jak bardzo wektor $\\vec{v}(t_i)$ „pasuje” do $\\vec{s^{k-1}}$, w najprostszej wersji można po prostu skorzystać z iloczynu skalarnego (o ile $n=m$),\n", + "\n", + "$$a(\\vec{s^{k-1}}, \\vec{v}(t_i)) = \\vec{s^{k-1}}\\vec{v}(t_i).$$\n", + "\n", + "**Pytanie**: co jeśli $n$ nie jest równe $m$, tzn. rozmiar embeddingu nie jest równy rozmiarowi wektora stanu?\n", + "\n", + "W przypadku sieci LSTM korzysta się częściej z bardziej skomplikowanego wzoru zawierającego dodatkowe wyuczalne wagi:\n", + "\n", + "$$a(\\vec{s^{k-1}}, \\vec{v}(t_i)) = \\vec{w_a}\\operatorname{tanh}(W_a\\vec{s^{k-1}} + U_a\\vec{v}(t_i))$$\n", + "\n", + "**Pytanie**: jakie rozmiary mają macierze $W_a$, $U_a$ i wektor $w_a$?\n", + "\n", + "Powtórzmy, że wartości $a$ są wartościami skalarnymi, natomiast nie są one znormalizowane (nie sumują się do jedynki), normalizujemy je używając schematu podobnego do softmaxa:\n", + "\n", + "$$\\alpha_{i} = \\frac{e^{a(\\vec{s^{k-1}}, \\vec{v}(t_i))}}{\\sum_j e^{a(\\vec{s^{k-1}}, \\vec{v}(t_j))}}$$\n", + "\n", + "Wektor kontekstu $\\vec{\\xi^k}$ będzie po prostu średnią ważoną wektorowych reprezentacji słów:\n", + "\n", + "$$\\vec{\\xi^k} = \\sum_i \\alpha_i\\vec{v}(t_i)$$\n", + "\n", + "**Pytanie**: zasadniczo atencja jest środkiem do celu (żeby sieć się sprawniej uczyła), czy można atencja sama w sobie może być do czegoś przydatna?\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.2" + }, + "org": null + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/wyk/word-distribution.png b/wyk/word-distribution.png index 413a6461bd96655dd437bbc13111c4b97236a660..6622d701ef3e98e79f847feceab223865b92e96c 100644 GIT binary patch literal 6402 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 B&hP*L literal 3983 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 NAbR Date: Mon, 14 Jun 2021 08:23:02 +0200 Subject: [PATCH 3/4] new --- wyk/14_pretrenowanie.org | 155 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 wyk/14_pretrenowanie.org diff --git a/wyk/14_pretrenowanie.org b/wyk/14_pretrenowanie.org new file mode 100644 index 0000000..1b33f10 --- /dev/null +++ b/wyk/14_pretrenowanie.org @@ -0,0 +1,155 @@ +* Pretrenowanie modeli + +System AlphaZero uczy się grając sam ze sobą — wystarczy 24 godziny, +by system nauczył się grać w szachy lub go na nadludzkim poziomie. + +*Pytanie*: Dlaczego granie samemu ze sobą nie jest dobrym sposobem + nauczenia się grania w szachy dla człowieka, a dla maszyny jest? + +Co jest odpowiednikiem grania samemu ze sobą w świecie przetwarzania tekstu? +Tzn. *pretrenowanie* (/pretraining/) na dużym korpusie tekstu. (Tekst jest tani!) + +Jest kilka sposobów na pretrenowanie modelu, w każdym razie sprowadza +się do odgadywania następnego bądź zamaskowanego słowa. +W każdym razie zawsze stosujemy softmax (być może ze „sztuczkami” takimi jak +negatywne próbkowanie albo hierarchiczny softamx) na pewnej *representecji kontekstowej*: + +$$\vec{p} = \operatorname{softmax}(f(\vec{c})).$$ + +Model jest karany używając funkcji log loss: + +$$-\log(p_j),$$ + +gdzie $w_j$ jest wyrazem, który pojawił się rzeczywiście w korpusie. + +** Przewidywanie słowa (GPT-2) + +Jeden ze sposobów pretrenowania modelu to po prostu przewidywanie +następnego słowa. + +Zainstalujmy najpierw bibliotekę transformers. + +#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer +! pip install transformers +#+END_SRC + +#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer + import torch + from transformers import GPT2Tokenizer, GPT2LMHeadModel + tokenizer = GPT2Tokenizer.from_pretrained('gpt2-large') + model = GPT2LMHeadModel.from_pretrained('gpt2-large') + text = "Warsaw is the capital city of" + encoded_input = tokenizer(text, return_tensors='pt') + output = model(**encoded_input) + next_token_probs = torch.softmax(output[0][:, -1, :][0], dim=0) + + nb_of_tokens = next_token_probs.size()[0] + + _, top_k_indices = torch.topk(next_token_probs, 30, sorted=True) + top_k_indices + # words = tokenizer.convert_ids_to_tokens(top) + + # top_probs = [] + + # for ix in range(len(top)): + # top_probs.append((words[ix], next_token_probs[top[ix]].item())) + + # top_probs +#+END_SRC + +#+RESULTS: +:results: +# Out[8]: +#+BEGIN_EXAMPLE + [('Ġthe', 0.4415026307106018), + ('ĠPoland', 0.236798495054245), + ('ĠBelarus', 0.10114768147468567), + ('ĠUkraine', 0.058283545076847076), + ('Ġeastern', 0.020564062520861626), + ('ĠEastern', 0.011137397028505802), + ('ĠPolish', 0.010205904021859169), + ('ĠWestern', 0.00833223108202219), + ('Ġwestern', 0.006872199941426516), + ('Ġa', 0.004939113277941942), + ('ĠSlovakia', 0.003553805174306035), + ('ĠLithuania', 0.003335304092615843), + ('ĠRussia', 0.002872465644031763), + ('Ġcentral', 0.002493523992598057), + ('Ġmodern', 0.0022767107002437115), + ('ĠCzech', 0.0022264323197305202), + ('ĠPr', 0.002146221464499831), + ('Ġformer', 0.0021054286044090986), + ('Ġwhat', 0.0017435317859053612), + ('ĠSlov', 0.0014634730760008097), + ('ĠUkrainian', 0.0014347084797918797), + ('ĠCentral', 0.0013676199596375227), + ('ĠSouth', 0.0013484350638464093), + ('Ġone', 0.001204205909743905), + ('ĠNorthern', 0.0011802552035078406), + ('ĠWest', 0.001175572513602674), + ('ĠEast', 0.0011596156982704997), + ('Ġsouthern', 0.0011580033460631967), + ('Ġnorthern', 0.001110077602788806), + ('Ġ"', 0.0010494199814274907)] +#+END_EXAMPLE +:end: + +Zalety tego podejścia: + +- prostota, +- dobra podstawa do strojenia systemów generowania tekstu zwłaszcza + „otwartego” (systemy dialogowe, generowanie (fake) newsów, streszczanie tekstu), + ale niekoniecznie tłumaczenia maszynowego, +- zaskakująca skuteczność przy uczeniu /few-shot/ i /zero-shot/. + +Wady: + +- asymetryczność, przetwarzanie tylko z lewej do prawej, preferencja + dla lewego kontekstu, +- mniejsza skuteczność przy dostrajaniu do zadań klasyfikacji i innych zadań + niepolegających na prostym generowaniu. + +Przykłady modeli: GPT, GPT-2, GPT-3, DialoGPT. + +** Maskowanie słów (BERT) + +Inną metodą jest maskowanie słów (/Masked Language Modeling/, /MLM/). + +W tym podejściu losowe wybrane zastępujemy losowe słowa specjalnym +tokenem (~[MASK]~) i każemy modelowi odgadywać w ten sposób +zamaskowane słowa (z uwzględnieniem również prawego kontekstu!). + +Móciąc ściśle, w jednym z pierwszych modeli tego typu (BERT) +zastosowano schemat, w którym również niezamaskowane słowa są odgadywane (!): + +- wybieramy losowe 15% wyrazów do odgadnięcia +- 80% z nich zastępujemy tokenem ~[MASK]~, +- 10% zastępujemy innym losowym wyrazem, +- 10% pozostawiamy bez zmian. + + +#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer +from transformers import AutoModelWithLMHead, AutoTokenizer +import torch + +tokenizer = AutoTokenizer.from_pretrained("distilroberta-base") +model = AutoModelWithLMHead.from_pretrained("distilroberta-base") + +sequence = f"Hugging Face is a French company based in {tokenizer.mask_token}" + +input_ids = tokenizer.encode(sequence, return_tensors="pt") +mask_token_index = torch.where(input_ids == tokenizer.mask_token_id)[1] + +token_logits = model(input_ids)[0] +mask_token_logits = token_logits[0, mask_token_index, :] +mask_token_logits = torch.softmax(mask_token_logits, dim=1) + +top_5 = torch.topk(mask_token_logits, 5, dim=1) +top_5_tokens = zip(top_5.indices[0].tolist(), top_5.values[0].tolist()) + +for token, score in top_5_tokens: + print(sequence.replace(tokenizer.mask_token, tokenizer.decode([token])), f"(score: {score})") +#+END_SRC + + +Przykłady: BERT, RoBERTa (również Polish RoBERTa). From 78fb510cba3fae1b53c3d47a071013ab0b32112d Mon Sep 17 00:00:00 2001 From: Filip Gralinski Date: Mon, 14 Jun 2021 15:39:15 +0200 Subject: [PATCH 4/4] 14 --- wyk/14_pretrenowanie.ipynb | 338 +++++++++++++++++++++++++++++++++++++ wyk/14_pretrenowanie.org | 69 +++++++- 2 files changed, 401 insertions(+), 6 deletions(-) create mode 100644 wyk/14_pretrenowanie.ipynb diff --git a/wyk/14_pretrenowanie.ipynb b/wyk/14_pretrenowanie.ipynb new file mode 100644 index 0000000..ae7721a --- /dev/null +++ b/wyk/14_pretrenowanie.ipynb @@ -0,0 +1,338 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Pretrenowanie modeli\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "System AlphaZero uczy się grając sam ze sobą — wystarczy 24 godziny,\n", + "by system nauczył się grać w szachy lub go na nadludzkim poziomie.\n", + "\n", + "**Pytanie**: Dlaczego granie samemu ze sobą nie jest dobrym sposobem\n", + " nauczenia się grania w szachy dla człowieka, a dla maszyny jest?\n", + "\n", + "Co jest odpowiednikiem grania samemu ze sobą w świecie przetwarzania tekstu?\n", + "Tzn. **pretrenowanie** (*pretraining*) na dużym korpusie tekstu. (Tekst jest tani!)\n", + "\n", + "Jest kilka sposobów na pretrenowanie modelu, w każdym razie sprowadza\n", + "się do odgadywania następnego bądź zamaskowanego słowa.\n", + "W każdym razie zawsze stosujemy softmax (być może ze „sztuczkami” takimi jak\n", + "negatywne próbkowanie albo hierarchiczny softamx) na pewnej **representecji kontekstowej**:\n", + "\n", + "$$\\vec{p} = \\operatorname{softmax}(f(\\vec{c})).$$\n", + "\n", + "Model jest karany używając funkcji log loss:\n", + "\n", + "$$-\\log(p_j),$$\n", + "\n", + "gdzie $w_j$ jest wyrazem, który pojawił się rzeczywiście w korpusie.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Przewidywanie słowa (GPT-2)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Jeden ze sposobów pretrenowania modelu to po prostu przewidywanie\n", + "następnego słowa.\n", + "\n", + "Zainstalujmy najpierw bibliotekę transformers.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "! pip install transformers" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "50257\n" + ] + }, + { + "data": { + "text/plain": [ + "[('Ġon', 0.6786560416221619),\n", + " ('Ġupon', 0.04339785501360893),\n", + " ('Ġheavily', 0.02208443358540535),\n", + " ('Ġin', 0.021049050614237785),\n", + " (',', 0.020188499242067337),\n", + " ('Ġa', 0.01833895780146122),\n", + " ('Ġvery', 0.017935041338205338),\n", + " ('Ġentirely', 0.017528969794511795),\n", + " ('Ġlargely', 0.016769640147686005),\n", + " ('Ġto', 0.01009418722242117),\n", + " ('Ġgreatly', 0.010009866207838058),\n", + " ('Ġnot', 0.009016563184559345),\n", + " ('Ġmore', 0.005853226874023676),\n", + " ('Ġprimarily', 0.005203146021813154),\n", + " ('Ġstrongly', 0.0034501152113080025),\n", + " ('Ġpartly', 0.0033184229396283627),\n", + " ('Ġmuch', 0.0033095215912908316),\n", + " ('Ġmostly', 0.0032150144688785076),\n", + " ('Ġmainly', 0.0030899408739060163),\n", + " ('Ġfor', 0.003034428460523486),\n", + " ('.', 0.0028878094162791967),\n", + " ('Ġboth', 0.0028405177872627974),\n", + " ('Ġsomewhat', 0.0028194624464958906),\n", + " ('Ġcru', 0.002263976726680994),\n", + " ('Ġas', 0.00221616611815989),\n", + " ('Ġof', 0.0022000609897077084),\n", + " ('Ġalmost', 0.001968063646927476),\n", + " ('Ġat', 0.0018015997484326363),\n", + " ('Ġhighly', 0.0017461496172472835),\n", + " ('Ġcompletely', 0.001692073536105454)]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import torch\n", + "from transformers import GPT2Tokenizer, GPT2LMHeadModel\n", + "tokenizer = GPT2Tokenizer.from_pretrained('gpt2-large')\n", + "model = GPT2LMHeadModel.from_pretrained('gpt2-large')\n", + "text = \"This issue depends\"\n", + "encoded_input = tokenizer(text, return_tensors='pt')\n", + "output = model(**encoded_input)\n", + "next_token_probs = torch.softmax(output[0][:, -1, :][0], dim=0)\n", + "\n", + "next_token_probs\n", + "nb_of_tokens = next_token_probs.size()[0]\n", + "print(nb_of_tokens)\n", + "\n", + "_, top_k_indices = torch.topk(next_token_probs, 30, sorted=True)\n", + "\n", + "words = tokenizer.convert_ids_to_tokens(top_k_indices)\n", + "\n", + "top_probs = []\n", + "\n", + "for ix in range(len(top_k_indices)):\n", + " top_probs.append((words[ix], next_token_probs[top_k_indices[ix]].item()))\n", + "\n", + "top_probs" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Zalety tego podejścia:\n", + "\n", + "- prostota,\n", + "- dobra podstawa do strojenia systemów generowania tekstu zwłaszcza\n", + " „otwartego” (systemy dialogowe, generowanie (fake) newsów, streszczanie tekstu),\n", + " ale niekoniecznie tłumaczenia maszynowego,\n", + "- zaskakująca skuteczność przy uczeniu *few-shot* i *zero-shot*.\n", + "\n", + "Wady:\n", + "\n", + "- asymetryczność, przetwarzanie tylko z lewej do prawej, preferencja\n", + " dla lewego kontekstu,\n", + "- mniejsza skuteczność przy dostrajaniu do zadań klasyfikacji i innych zadań\n", + " niepolegających na prostym generowaniu.\n", + "\n", + "Przykłady modeli: GPT, GPT-2, GPT-3, DialoGPT.\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Maskowanie słów (BERT)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Inną metodą jest maskowanie słów (*Masked Language Modeling*, *MLM*).\n", + "\n", + "W tym podejściu losowe wybrane zastępujemy losowe słowa specjalnym\n", + "tokenem (`[MASK]`) i każemy modelowi odgadywać w ten sposób\n", + "zamaskowane słowa (z uwzględnieniem również prawego kontekstu!).\n", + "\n", + "Móciąc ściśle, w jednym z pierwszych modeli tego typu (BERT)\n", + "zastosowano schemat, w którym również niezamaskowane słowa są odgadywane (!):\n", + "\n", + "- wybieramy losowe 15% wyrazów do odgadnięcia\n", + "- 80% z nich zastępujemy tokenem `[MASK]`,\n", + "- 10% zastępujemy innym losowym wyrazem,\n", + "- 10% pozostawiamy bez zmian.\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# Out[3]:" + ] + } + ], + "source": [ + "from transformers import AutoModelWithLMHead, AutoTokenizer\n", + "import torch\n", + "\n", + "tokenizer = AutoTokenizer.from_pretrained(\"xlm-roberta-large\")\n", + "model = AutoModelWithLMHead.from_pretrained(\"xlm-roberta-large\")\n", + "\n", + "sequence = f'II wojna światowa zakończyła się w {tokenizer.mask_token} roku.'\n", + "\n", + "input_ids = tokenizer.encode(sequence, return_tensors=\"pt\")\n", + "mask_token_index = torch.where(input_ids == tokenizer.mask_token_id)[1]\n", + "\n", + "token_logits = model(input_ids)[0]\n", + "mask_token_logits = token_logits[0, mask_token_index, :]\n", + "mask_token_logits = torch.softmax(mask_token_logits, dim=1)\n", + "\n", + "top_10 = torch.topk(mask_token_logits, 10, dim=1)\n", + "top_10_tokens = zip(top_10.indices[0].tolist(), top_10.values[0].tolist())\n", + "\n", + "for token, score in top_10_tokens:\n", + " print(sequence.replace(tokenizer.mask_token, tokenizer.decode([token])), f\"(score: {score})\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Przykłady: BERT, RoBERTa (również Polish RoBERTa).\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Podejście generatywne (koder-dekoder).\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "System ma wygenerować odpowiedź na różne pytania (również\n", + "odpowiadające zadaniu MLM), np.:\n", + "\n", + "- \"translate English to German: That is good.\" => \"Das ist gut.\"\n", + "- \"cola sentence: The course is jumping well.\" => \"not acceptable\"\n", + "- \"summarize: state authorities dispatched emergency crews tuesday to survey the damage after an onslaught of severe weather in mississippi…\"\n", + " => \"six people hospitalized after a storm in attala county\"\n", + "- \"Thank you for me to your party week.\" => for inviting last \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from transformers import T5Tokenizer, T5Config, T5ForConditionalGeneration\n", + "\n", + "T5_PATH = 't5-base'\n", + "\n", + "t5_tokenizer = T5Tokenizer.from_pretrained(T5_PATH)\n", + "t5_config = T5Config.from_pretrained(T5_PATH)\n", + "t5_mlm = T5ForConditionalGeneration.from_pretrained(T5_PATH, config=t5_config)\n", + "\n", + "slot = ''\n", + "\n", + "text = f'Warsaw is the {slot} of Poland.'\n", + "\n", + "encoded = t5_tokenizer.encode_plus(text, add_special_tokens=True, return_tensors='pt')\n", + "input_ids = encoded['input_ids']\n", + "\n", + "outputs = t5_mlm.generate(input_ids=input_ids,\n", + " num_beams=200, num_return_sequences=5,\n", + " max_length=5)\n", + "\n", + "_0_index = text.index(slot)\n", + "_result_prefix = text[:_0_index]\n", + "_result_suffix = text[_0_index+len(slot):]\n", + "\n", + "def _filter(output, end_token=''):\n", + " _txt = t5_tokenizer.decode(output[2:], skip_special_tokens=False, clean_up_tokenization_spaces=False)\n", + " if end_token in _txt:\n", + " _end_token_index = _txt.index(end_token)\n", + " return _result_prefix + _txt[:_end_token_index] + _result_suffix\n", + " else:\n", + " return _result_prefix + _txt + _result_suffix\n", + "\n", + "\n", + "results = [_filter(out) for out in outputs]\n", + "results" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(Zob. [https://arxiv.org/pdf/1910.10683.pdf](https://arxiv.org/pdf/1910.10683.pdf))\n", + "\n", + "Przykład: T5, mT5\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.2" + }, + "org": null + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/wyk/14_pretrenowanie.org b/wyk/14_pretrenowanie.org index 1b33f10..cc46039 100644 --- a/wyk/14_pretrenowanie.org +++ b/wyk/14_pretrenowanie.org @@ -132,10 +132,10 @@ zastosowano schemat, w którym również niezamaskowane słowa są odgadywane (! from transformers import AutoModelWithLMHead, AutoTokenizer import torch -tokenizer = AutoTokenizer.from_pretrained("distilroberta-base") -model = AutoModelWithLMHead.from_pretrained("distilroberta-base") +tokenizer = AutoTokenizer.from_pretrained("xlm-roberta-large") +model = AutoModelWithLMHead.from_pretrained("xlm-roberta-large") -sequence = f"Hugging Face is a French company based in {tokenizer.mask_token}" +sequence = f'II wojna światowa zakończyła się w {tokenizer.mask_token} roku.' input_ids = tokenizer.encode(sequence, return_tensors="pt") mask_token_index = torch.where(input_ids == tokenizer.mask_token_id)[1] @@ -144,12 +144,69 @@ token_logits = model(input_ids)[0] mask_token_logits = token_logits[0, mask_token_index, :] mask_token_logits = torch.softmax(mask_token_logits, dim=1) -top_5 = torch.topk(mask_token_logits, 5, dim=1) -top_5_tokens = zip(top_5.indices[0].tolist(), top_5.values[0].tolist()) +top_10 = torch.topk(mask_token_logits, 10, dim=1) +top_10_tokens = zip(top_10.indices[0].tolist(), top_10.values[0].tolist()) -for token, score in top_5_tokens: +for token, score in top_10_tokens: print(sequence.replace(tokenizer.mask_token, tokenizer.decode([token])), f"(score: {score})") #+END_SRC +#+RESULTS: +:results: +# Out[3]: +:end: + Przykłady: BERT, RoBERTa (również Polish RoBERTa). + +** Podejście generatywne (koder-dekoder). + +System ma wygenerować odpowiedź na różne pytania (również +odpowiadające zadaniu MLM), np.: + +- "translate English to German: That is good." => "Das ist gut." +- "cola sentence: The course is jumping well." => "not acceptable" +- "summarize: state authorities dispatched emergency crews tuesday to survey the damage after an onslaught of severe weather in mississippi..." + => "six people hospitalized after a storm in attala county" +- "Thank you for me to your party week." => for inviting last + +#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer +from transformers import T5Tokenizer, T5Config, T5ForConditionalGeneration + +T5_PATH = 't5-base' + +t5_tokenizer = T5Tokenizer.from_pretrained(T5_PATH) +t5_config = T5Config.from_pretrained(T5_PATH) +t5_mlm = T5ForConditionalGeneration.from_pretrained(T5_PATH, config=t5_config) + +slot = '' + +text = f'Warsaw is the {slot} of Poland.' + +encoded = t5_tokenizer.encode_plus(text, add_special_tokens=True, return_tensors='pt') +input_ids = encoded['input_ids'] + +outputs = t5_mlm.generate(input_ids=input_ids, + num_beams=200, num_return_sequences=5, + max_length=5) + +_0_index = text.index(slot) +_result_prefix = text[:_0_index] +_result_suffix = text[_0_index+len(slot):] + +def _filter(output, end_token=''): + _txt = t5_tokenizer.decode(output[2:], skip_special_tokens=False, clean_up_tokenization_spaces=False) + if end_token in _txt: + _end_token_index = _txt.index(end_token) + return _result_prefix + _txt[:_end_token_index] + _result_suffix + else: + return _result_prefix + _txt + _result_suffix + + +results = [_filter(out) for out in outputs] +results +#+END_SRC + +(Zob. https://arxiv.org/pdf/1910.10683.pdf) + +Przykład: T5, mT5