From 1dfc63d51489681ff5639e73b45c8d336e0c58a8 Mon Sep 17 00:00:00 2001 From: kubapok Date: Sun, 24 Apr 2022 17:40:24 +0200 Subject: [PATCH] add 08 --- cw/08_Model_neuronowy_typu_word2vec.ipynb | 159 ++++++++++++++++++++++ cw/bow1.drawio.png | Bin 0 -> 23080 bytes 2 files changed, 159 insertions(+) create mode 100644 cw/08_Model_neuronowy_typu_word2vec.ipynb create mode 100644 cw/bow1.drawio.png diff --git a/cw/08_Model_neuronowy_typu_word2vec.ipynb b/cw/08_Model_neuronowy_typu_word2vec.ipynb new file mode 100644 index 0000000..3c6a62b --- /dev/null +++ b/cw/08_Model_neuronowy_typu_word2vec.ipynb @@ -0,0 +1,159 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n", + "
\n", + "

Modelowanie Języka

\n", + "

8. Model neuronowy typu word2vec [ćwiczenia]

\n", + "

Jakub Pokrywka (2022)

\n", + "
\n", + "\n", + "![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Zadania" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Proszę wykonać zadanie 1 lub zadanie 2 (nie oba naraz). Zadanie 3 można zrobić niezależnie." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Zadanie 1\n", + "\n", + "Wzorując się na materiałach z wykładu stworzyć 5-gramowy model neuronowy oparty na jednym ze schematów z wykładu, np.\n", + "\n", + "\n", + "![img](bow1.drawio.png \"Model typu worek słów\")\n", + "\n", + "\n", + "Warunkiem koniecznym jest, żeby przewidywać słowo środkowe, np. Mając tekst ['Ala', 'ma', '[MASK]'\n", + " 'i', 'psa'] chcemy przewidzieć kontekst środkowego słowa (tutaj '[MASK]')\n", + "\n", + "\n", + "\n", + "\n", + "Warunki zaliczenia:\n", + "- wynik widoczny na platformie zarówno dla dev i dla test\n", + "- wynik dla dev i test lepszy (niższy) niż 6.50 (liczone przy pomocy geval)\n", + "- deadline do końca dnia 08.05\n", + "- commitując rozwiązanie proszę również umieścić rozwiązanie w pliku /run.py (czyli na szczycie katalogu). Można przekonwertować jupyter do pliku python przez File → Download as → Python. Rozwiązanie nie musi być w pythonie, może być w innym języku.\n", + "- zadania wykonujemy samodzielnie\n", + "- w nazwie commita podaj nr indeksu\n", + "- w tagach podaj **neural-network** oraz **5gram**!\n", + "- zadanie tym razem jest dla polskiego odpowiednika word-gap https://gonito.net/challenge-my-submissions/retro-gap\n", + "- metryka to LogLossHashed (praktycznie to samo, co PerlpexityHased). Przelicznik, to LogLossHased = log(PerplexityHashed). Podając równe prawd. dla każdego słowa dostaniemy 6.93, bo log(1024) = 6.93\n", + "\n", + "Punktacja:\n", + "- podstawa: 60 punktów\n", + "- 40 punktów z najlepszy wynik z 2 grup\n", + "- 20 punktów z 3 kolejno najlepszych wyników z 2 grup\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Jak stworzyć model?\n", + "- warto bazować na kodzie ze wykładu 7 Zanurzenia słów\n", + "- elementy, które na pewno trzeba będzie wykorzystać to: nn.Embedding, nn.Linear, nn.Softmax\n", + "- w odróżnieniu do materiałów z wykładu lepiej nie korzystać z nn.Sequential, tylko wszystki operacje zapisywać w model.forward. Przy użyciu sequential może być problem np. z dodawaniem lub konkatenacją tensorów" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### W jaki sposób uzyskać lepszy wynik?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- Po pierwsze proszę stosować sie do rad z poprzednich cwiczeń (trenowanie przez kilka epok i monitorowanie wyniku na zbiorze deweloperskim)\n", + "- dobry start to zawsze zaczęcie od jak najprostszego modelu (czyli 1 warstwa liniowa, zwykłe dodawanie embeddingów słów) i dopiero później go rozbudowywać monitorując wynik. Jest to rada uniwersalna w uczeniu maszynowym.\n", + "- Poza tym warto wypróbować przynajmniej kilka modeli z wykładu. Mając zaimplementowany cały kod dla jednego modelu, wystarczy jedynie delikatnie zmienić architekturę modelu i wytrenować go od nowa. Cała reszta kodu zostaje bez zmian.\n", + "- warto spróbować dodanie np 2 warstw liniowych (lub nawet 3) zamiast jednej warstwy (koniecznie trzeba dodać między nimi funkcję aktywacji, np RELU).\n", + "- poza tym można zmieniać różne parametry (np. wielkość słownika, wielkość warstwy ukrytej, różne funkcje aktywacji)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Zadanie 2\n", + "\n", + "Proszę zrobić parameter Hyperparameter Tuning dla zadania 1 i zaprezentować na forum grupy razem z wnioskami\n", + "\n", + "- wymóg wyniku najlepszego modelu, conajwyżej 6.10\n", + "- wnioski nie muszą być specjalnie rozbudowane, prezentacja może trwać 3-5minut lub dłużej\n", + "- należy wybrać dla siebie metodę hypermarameter tuningu\n", + "- należy stworzyć conajmniej 10 modeli, należy pokazać wyniku dla conajmniej paru\n", + "- oczywiście kod musi być automatyczny (a nie ręcznie zmieniamy paratery), natomiast nie ma wymogu korzystania ze specjalnych bibliotek\n", + "- podstawa punktów 100\n", + "- za wynik lepszy (niższy) niż 5.50 +20 punktów\n", + "- użycie GPU na dowolnym cloud lub od WMI + 30 punktów\n", + "- termin 16.05 na zajęciach\n", + "- punkty przyznam na MS TEAMS, ale proszę zgłosić te rozwiązanie na gonito (nie trzeba w żadnym challenge ani z konkretymi tagami)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Zadanie 3\n", + "\n", + "Zaangażowanie się w pygonito.\n", + "\n", + "- https://github.com/filipggg/pygonito\n", + "- dobra okazja, żeby nauczyć się tworzyć paczki pythonowe\n", + "- wsparcie ode mnie lub prof. Gralińskiego przy tworzeniu\n", + "- może się przydać przy pracy magisterskiej (jeżeli wyzwanie będzie na gonito)\n", + "- ilość punktów zależy od zakresu pracy. Sczególnie warto samemu zaproponować co zrobić) Zakres prac i punktów do dogdania\n", + "- w celu ustalenia szczegółów proszę sie zgłosić do mnie\n", + "- termin dowolny" + ] + } + ], + "metadata": { + "author": "Jakub Pokrywka", + "email": "kubapok@wmi.amu.edu.pl", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "lang": "pl", + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + }, + "subtitle": "0.Informacje na temat przedmiotu[ćwiczenia]", + "title": "Ekstrakcja informacji", + "year": "2021" + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/cw/bow1.drawio.png b/cw/bow1.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..c500af51b1ce9404a6c9f749b8e900b25f86bdbd GIT binary patch literal 23080 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