8. Ciągła integracja i ewaluacja w projektach opartych na uczeniu maszynowym [wykład]
\n",
"
Filip Graliński (2022)
\n",
"
\n",
"\n",
"![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Ciągła integracja i ewaluacja w projektach opartych na uczeniu maszynowym"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Dobre praktyki w tradycyjnej inżynierii oprogramowania\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Ciągła integracja\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ciągła integracja (*continuous integration*, *CI*) to praktyka\n",
"stosowana w tworzeniu oprogramowania polegają na częstym integrowaniu\n",
"kodu opracowywanego przez programistów, zautomatyzowanym budowaniu\n",
"oprogramowania i poddawaniu go testom.\n",
"\n",
"![img](./obrazy/ci.drawio.png \"Schemat procesu ciągłej integracji\")\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Ciągłe wdrażanie\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ciągłe wdrażanie (*continuous deployment*, *CD*)\n",
"automatyzuje również proces wdrażania oprogramowania. Oznacza to, że\n",
"również procedura wdrażania musi zostać wyrażona jako kod\n",
"przechowywany w systemie kontroli wersji.\n",
"\n",
"![img](./obrazy/cd.drawio.png \"Schemat procesu ciągłego wdrażania\")\n",
"\n",
"Ciągła integracja/ciągłe wdrożenie zazwyczaj współwystępuje z metodyką **DevOps**.\n",
"\n",
"CI/CD/DevOps w jednym zdaniu: robię to tak często, że to „nic takiego”.\n",
"\n",
"![img](./obrazy/seul-metro.png \"Przykład — budowa metra, źródło Wikipedia\")\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### CI/CD a uczenie maszynowe\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Dodanie do systemu modułów opartych na uczeniu maszynowym bardzo\n",
"komplikuje proces CI/CD:\n",
"\n",
"- modele uczenia maszynowego (np. sieci neuronowe) powstają na bazie kodu źródłowego odpowiedzialnego za uczenie **i** danych uczących,\n",
"- osobny kod jest odpowiedzialny za inferencję,\n",
"- choć kod odpowiedzialny za uczenie i inferencję w miarę możliwości powinny podlegać standardowej metodologii testowania (np. testy jednostkowe), to ostatecznie testy systemów opartych na uczeniu maszynowym nie mają postaci zerojedynkowej\n",
"- … raczej system może uzyskać lepszy albo gorszy wynik,\n",
"- wdrożenie (a przynajmniej uczenie) wymaga często dużych zasobów obliczeniowych i specjalnego sprzętu (karty graficzne).\n",
"\n",
"Przy czym chcielibyśmy zachować „złote” zasady CI/CD.\n",
"\n",
"Wprowadzenie uczenia maszynowego do oprogramowania na tyle zmienia\n",
"sytuację, że mówi się o **MLOps** zamiast DevOps.\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Proces CI/CD rozszerzony o uczenie maszynowe\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![img](./obrazy/mlops.drawio.png \"Schemat CI/CD rozszerzony o MLOps\")\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Testowanie systemów opartych na uczeniu maszynowym\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Podobnie jak w wypadku tradycyjnego oprogramowania testowanie modeli\n",
"uczenia maszynowego przyjmuje wiele form:\n",
"\n",
"- testy jednostkowe fragmentu kodu odpowiedzialnego za uczenie i inferencję,\n",
"- testy uczenia i inferencji na spreparowanych danych\n",
" - *corner cases*\n",
" - uczenia „w kółko” na jednym przykładzie (czy funkcja kosztu spada do zera?)\n",
"- testy inferencji na danych „śmieciowych” (czy system jest w stanie „przetrwać” wszystko?)\n",
"- testy efektywności, przepustowości itp.\n",
"- … lecz ostatecznie najistotniejsza jest odpowiedź na pytanie, jak dobry jest wynik na danych zbliżonych do rzeczywistych (**ewaluacja**)\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Ewaluacja\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Rodzaje ewaluacji:\n",
"\n",
"- testy „na ludziach”,\n",
" - testy A/B, analiza zachowania użytkownika\n",
" - ewaluacja **manualna**, np. test MOS (*mean-opinion score*)\n",
"- ewaluacja **automatyczna**\n",
" - ewaluacja według wzoru\n",
" - ewaluacja wyuczana przy użyciu uczenia maszynowego (!)\n",
"\n",
"Ostateczne kryterium ewaluacji: *money in the bank*, a właściwie\n",
"*utility in the bank* (por. aksjomatyczna teoria użyteczności\n",
"sformułowana przez Johna von Neumanna i Oskara Morgensterna).\n",
"\n",
"![img](./obrazy/utility.jpg \"Okładka książki „Theory of Games and Economic Behaviour”\")\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Psychologiczne pułapki oceniania\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- efekt **pierwszeństwa** — *błędy pojawiające się na początku wypracowania oceniane są surowiej niż błędy na końcu wypracowania*\n",
"\n",
"- efekt **świeżości**\n",
"\n",
"- efekt „aureoli” — *mamy skłonność do przypisywania innych pozytywnych cech ludziom atrakcyjnym fizycznie*\n",
"\n",
"- wpływ **nastroju** na ocenianie — *w pochmurne dni ludzie gorzej oceniają stan gospodarki niż w słoneczne*\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Słabości „potocznej” matematyki\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Czy symptom świadczy o chorobie?\n",
"\n",
" | | | choroba | |\n",
" | | | obecna | nieobecna |\n",
" |---------+-----------+---------+---------------|\n",
" | symptom | obecny | 37 | 33 |\n",
" | | nieobecny | 17 | 13 |\n",
"\n",
"85% przepytanych pielęgniarek doszło do wniosku, że istnieje związek między symptomem a chorobą.\n",
"\n",
"**Korelacja** jest przez ludzi przeceniana, **regresja do średniej** — niedoceniania\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Jak uniknąć pułapek oceniania?\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- stosować obiektywne miary,\n",
"- najlepiej wymyślić syntetyczną funkcję oceny (pojedyncza liczba),\n",
"- jeśli to możliwe, stosować automatyczną ewaluację.\n",
"\n",
"Konkretny sposób ewaluacji nazywamy **miarą** lub **metryką** ewaluacji.\n",
"(Uwaga: nie ma nic wspólnego z terminami stosowanymi w matematyce!).\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Definicja metryki ewaluacji\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ewaluację przeprowadzamy na ciągu danych wejściowych $(x)_i$ biorąc\n",
"pod uwagę oczekiwane wyjście $(y)_i$ i rzeczywiste wyjście z systemu\n",
"$(\\hat{y})_i$. Funkcja (metryka, miara) ewaluacji $\\mu$ powinna\n",
"zwrócić skalarną wartość określającą jakość systemu, innymi słowy:\n",
"\n",
"$$\\mu \\colon X^{n} \\times Y^{n} \\times \\hat{Y}^{n} \\to \\mathcal{R},$$\n",
"\n",
"gdzie $X$ jest zbiorem możliwych wejść, $Y$ — zbiorem możliwych\n",
"specyfikacji oczekiwanych wyjść, $\\hat{Y}$ — zbiorem możliwych wyjść\n",
"(na ogół $Y = \\hat{Y}$, ale mogą być sytuacje, gdzie specyfikacja\n",
"oczekiwanego wyjścia jest bardziej skomplikowana).\n",
"\n",
"Olbrzymia większość metryk ewaluacji nie bierze pod uwagę wejścia,\n",
"lecz jedynie porównuje wyjście z systemu z oczekiwanym wyjściem, a zatem schemat upraszcza się do:\n",
"\n",
"$$\\mu \\colon Y^{n} \\times \\hat{Y}^{n} \\to \\mathcal{R}.$$\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Metryka ewaluacji — przykłady\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Jedną z najprostszych metryk ewaluacji jest **dokładność** (*accuracy*)\n",
"jest to po prostu odsetek przypadków, gdy wyjście z systemu jest identyczne z oczekiwanym wyjściem.\n",
"\n",
"Narzędzie ewaluacyjne GEval ma zaimplementowane kilkadziesiąt (!) metryk ewaluacji\n",
"\n",
" -m,--metric METRIC Metric to be used, e.g.:RMSE, MSE, MAE, SMAPE,\n",
" Pearson, Spearman, Accuracy, LogLoss, Likelihood,\n",
" F1.0, F2.0, F0.25, Macro-F1.0, Macro-F2.0,\n",
" Macro-F0.25, MultiLabel-F1.0, MultiLabel-F2.0,\n",
" MultiLabel-F0.25, Mean/MultiLabel-F1.0,\n",
" Probabilistic-MultiLabel-F1.0,\n",
" Probabilistic-MultiLabel-F2.0,\n",
" Probabilistic-MultiLabel-F0.25,\n",
" MultiLabel-Likelihood, MAP, NDCG@3, BLEU, GLEU\n",
" (\"Google GLEU\" not the grammar correction metric),\n",
" WER, CER (Character-Error Rate), WAR, CAR\n",
" (Character-Accuracy Rate (1-CER)), NMI, ClippEU,\n",
" LogLossHashed, LikelihoodHashed, PerplexityHashed,\n",
" BIO-F1, BIO-Weighted-F1, BIO-F1-Labels,\n",
" TokenAccuracy, SegmentAccuracy, Soft-F1.0, Soft-F2.0,\n",
" Soft-F0.25, Probabilistic-Soft-F1.0,\n",
" Probabilistic-Soft-F2.0, Probabilistic-Soft-F0.25,\n",
" Probabilistic-Soft2D-F1.0, Probabilistic-Soft2D-F2.0,\n",
" Probabilistic-Soft2D-F0.25, Soft2D-F1.0, Soft2D-F2.0,\n",
" Soft2D-F0.25, Haversine, CharMatch, Improvement@0.5,\n",
" MacroAvg/Likelihood, MSE-Against-Interval,\n",
" RMSE-Against-Interval, MAE-Against-Interval,\n",
" BLEU:lm<\\s+|[a-z0-9]+> (BLEU on lowercased strings,\n",
" only Latin characters and digits considered)\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Jakie własności ma dobra miara ewaluacji?\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- spełnia zdroworozsądkowe aksjomaty\n",
" - w szczególności dla przypadków brzegowych\n",
" - jest stabilna\n",
"\n",
"- koreluje z ludzką oceną\n",
" - a tak naprawdę z preferencjami użytkowników\n",
"\n",
"Ewaluacja ewaluacji! — czyli **metaewaluacja**\n",
"\n",
"![img](./obrazy/meta-eval.png \"Fragment artykułu o metaewaluacji\")\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Z powrotem do CI/CD\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ewaluację można zatem traktować jako rozszerzenie procesu testowania oprogramowania.\n",
"Ewaluacja nigdy nie powinna być jednorazowym procesem, powinna być wpleciona w proces CI/CD.\n",
"Możemy więc mówić o **ciągłej ewaluacji**.\n",
"\n",
"Potrzeba ciągłego procesu, by upewnić się, że nasz system oparty na uczeniu maszynowym:\n",
"\n",
"- jest lepszy od prostego punktu odniesienia (*naive baseline*),\n",
"- jest lepszy od rozwiązań konkurencji,\n",
"- jest lepszy od systemu, który mieliśmy wczoraj, tydzień temu, rok temu…\n",
"\n",
"![img](./obrazy/mlops2.drawio.png \"Schemat MLOps rozszerzony o ciągłą ewaluację\")\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Dobór metryki ewaluacji — tłumaczenie maszynowe\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Jaka metryka jest najlepsza do oceny systemu tłumaczenia maszynowego?\n",
"\n",
"To zależy!\n",
"\n",
"**Scanariusz A**. Automatyczne tłumaczenie jest używane przez osoby\n",
"nieznające języka docelowego w celu zrozumienia oryginalnego tekstu.\n",
"\n",
"**Scenariusz B**. Oczekujemy bardzo dobrej jakości tłumaczenia.\n",
"Tłumaczenia maszynowe są poprawiane przez profesjonalnych tłumaczy,\n",
"tłumaczenie maszynowe służy do przyspieszenia procesu.\n",
"\n",
"W scenariuszu A można zastosować standardowe metryki tłumaczenia\n",
"maszynowego sprawdzające, na ile w tłumaczeniu zachowane elementy\n",
"tłumaczenia referencyjnego, np. BLEU albo — lepiej — COMET, natomiast\n",
"w scenariuszu B lepiej zastosować odległość edycyjną w celu\n",
"oszacowania kosztu korekty.\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Przykład systemu ewaluacji — GEval i Gonito\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[GEval](https://gitlab.com/filipg/geval) to biblioteka w języku Haskell oraz narzędzie do ewaluacji uruchamiane z wiersza\n",
"poleceń, zaś [Gonito](https://gitlab.com/filipg/gonito) to oparta na bibliotece GEval aplikacja webowa, platforma do ewaluacji wyzwań\n",
"uczenia maszynowego.\n",
"\n",
"![img](./obrazy/gonito-platform.png \"Schemat platformy Gonito\")\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### System na produkcji, a my nie znamy oczekiwanych wartości!\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Estymacja jakości\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Uruchomiliśmy nasz system w wersji produkcyjnej, skąd wiemy, że system\n",
"zachowuje się poprawnie?\n",
"\n",
"Można anotować lub poprawiać manualnie próbki danych produkcyjnych,\n",
"rozszerzać w ten sposób zbiory testowe i dokonywać na nich ewaluacji.\n",
"\n",
"Można też stosować metody **estymacji jakości** (*quality estimation*),\n",
"tzn. przewidywać jakość wyłącznie na podstawie wyjścia (bez znajomości\n",
"oczekiwanego wyjścia). Na przykład w systemie tłumaczenia maszynowego\n",
"można w tym celu stosować model języka docelowego.\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Zadania proponowane na laboratoria\n",
"\n",
"### Zadanie 1.\n",
"\n",
"Skonfigurujcie minimalne zadanie uczenia maszynowego na dowolnym serwerze ciągłej integracji (Jenkins, GitLabCI, GitHub Actions itp.). Zadanie powinno obejmować wyuczenie prostego modelu i ewaluację.\n",
"\n",
"### Zadanie 2.\n",
"\n",
"Dokonajcie konwersji wybranego zbioru danych do standardu wyzwania [Gonito](https://gitlab.com/filipg/gonito). Zob. [szczegółowe instrukcje odnośnie do tworzenia wyzwania](https://gitlab.com/filipg/geval#preparing-a-gonito-challenge).\n",
"\n",
"### Zadanie 3.\n",
"\n",
"Dopiszcie nowe przypadki testowe dla wybranej metryki ewaluacji w programie [GEval](https://gitlab.com/filipg/geval). Zob. [przykład testów dla nowej metryki](https://gitlab.com/filipg/geval/-/commit/819fbecedc6f744a1a08f21c11067191837f87a2) (od pliku `test/Spec.hs`).\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.8"
},
"org": null
},
"nbformat": 4,
"nbformat_minor": 1
}