{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Uczenie maszynowe\n", "# 7. Metody optymalizacji" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## 7.1. Warianty metody gradientu prostego\n", "\n", "* Batch gradient descent\n", "* Stochastic gradient descent\n", "* Mini-batch gradient descent" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### _Batch gradient descent_\n", "\n", "* Klasyczna wersja metody gradientu prostego\n", "* Obliczamy gradient funkcji kosztu względem całego zbioru treningowego:\n", " $$ \\theta := \\theta - \\alpha \\cdot \\nabla_\\theta J(\\theta) $$\n", "* Dlatego może działać bardzo powoli\n", "* Nie można dodawać nowych przykładów na bieżąco w trakcie trenowania modelu (*online learning*)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### *Stochastic gradient descent* (SGD)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### Algorytm\n", "\n", "Powtórz określoną liczbę razy (liczba epok):\n", " 1. Randomizuj dane treningowe\n", " 1. Powtórz dla każdego przykładu $i = 1, 2, \\ldots, m$:\n", " $$ \\theta := \\theta - \\alpha \\cdot \\nabla_\\theta \\, J \\! \\left( \\theta, x^{(i)}, y^{(i)} \\right) $$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "notes" } }, "source": [ "**Randomizacja danych** to losowe potasowanie przykładów uczących (wraz z odpowiedziami)." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### SGD – zalety\n", "\n", "* Dużo szybszy niż _batch gradient descent_\n", "* Można dodawać nowe przykłady na bieżąco w trakcie trenowania (*online learning*)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### SGD\n", "\n", "* Częsta aktualizacja parametrów z dużą wariancją:\n", "\n", "\n", "\n", "* Z jednej strony dzięki temu nie utyka w złych minimach lokalnych, ale z drugiej strony może „wyskoczyć” z dobrego minimum" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### _Mini-batch gradient descent_" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### Algorytm\n", "\n", "1. Ustal rozmiar \"paczki/wsadu\" (*batch*) $b \\leq m$.\n", "2. Powtórz określoną liczbę razy (liczba epok):\n", " 1. Powtórz dla każdego batcha (czyli dla $i = 1, 1 + b, 1 + 2 b, \\ldots$):\n", " $$ \\theta := \\theta - \\alpha \\cdot \\nabla_\\theta \\, J \\left( \\theta, x^{(i : i+b)}, y^{(i : i+b)} \\right) $$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### _Mini-batch gradient descent_\n", "\n", "* Kompromis między _batch gradient descent_ i SGD\n", "* Stabilniejsza zbieżność dzięki redukcji wariancji aktualizacji parametrów\n", "* Szybszy niż klasyczny _batch gradient descent_\n", "* Typowa wielkość batcha: między kilka a kilkaset przykładów\n", " * Im większy batch, tym bliżej do BGD; im mniejszy batch, tym bliżej do SGD\n", " * BGD i SGD można traktować jako odmiany MBGD dla $b = m$ i $b = 1$" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "# Mini-batch gradient descent - przykładowa implementacja\n", "\n", "def MiniBatchSGD(h, fJ, fdJ, theta, X, y, \n", " alpha=0.001, maxEpochs=1.0, batchSize=100, \n", " logError=True):\n", " errorsX, errorsY = [], []\n", " \n", " m, n = X.shape\n", " start, end = 0, batchSize\n", " \n", " maxSteps = (m * float(maxEpochs)) / batchSize\n", " for i in range(int(maxSteps)):\n", " XBatch, yBatch = X[start:end,:], y[start:end,:]\n", "\n", " theta = theta - alpha * fdJ(h, theta, XBatch, yBatch)\n", " \n", " if logError:\n", " errorsX.append(float(i*batchSize)/m)\n", " errorsY.append(fJ(h, theta, XBatch, yBatch).item())\n", " \n", " if start + batchSize < m:\n", " start += batchSize\n", " else:\n", " start = 0\n", " end = min(start + batchSize, m)\n", " \n", " return theta, (errorsX, errorsY)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Porównanie, jak zmienia się wartość funkcji kosztu podczas optymalizacji:\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Wady klasycznej metody gradientu prostego, czyli dlaczego potrzebujemy optymalizacji\n", "\n", "* Trudno dobrać właściwą szybkość uczenia (*learning rate*)\n", "* Jedna ustalona wartość stałej uczenia się dla wszystkich parametrów\n", "* Funkcja kosztu dla sieci neuronowych nie jest wypukła, więc uczenie może utknąć w złym minimum lokalnym lub punkcie siodłowym" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## 7.2. Algorytmy optymalizacji metody gradientu\n", "\n", "* Momentum\n", "* Nesterov Accelerated Gradient\n", "* Adagrad\n", "* Adadelta\n", "* RMSprop\n", "* Adam\n", "* Nadam\n", "* AMSGrad" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Momentum\n", "\n", "* SGD źle radzi sobie w „wąwozach” funkcji kosztu\n", "* Momentum rozwiązuje ten problem przez dodanie współczynnika $\\gamma$, który można trakować jako „pęd” spadającej piłki:\n", " $$ v_t := \\gamma \\, v_{t-1} + \\alpha \\, \\nabla_\\theta J(\\theta) $$\n", " $$ \\theta := \\theta - v_t $$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Przyspieszony gradient Nesterova (*Nesterov Accelerated Gradient*, NAG)\n", "\n", "* Momentum czasami powoduje niekontrolowane rozpędzanie się piłki, przez co staje się „mniej sterowna”\n", "* Nesterov do piłki posiadającej pęd dodaje „hamulec”, który spowalnia piłkę przed wzniesieniem:\n", " $$ v_t := \\gamma \\, v_{t-1} + \\alpha \\, \\nabla_\\theta J(\\theta - \\gamma \\, v_{t-1}) $$\n", " $$ \\theta := \\theta - v_t $$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Adagrad\n", "\n", "* “Adaptive gradient”\n", "* Adagrad dostosowuje współczynnik uczenia (*learning rate*) do parametrów: zmniejsza go dla cech występujących częściej, a zwiększa dla występujących rzadziej:\n", "* Świetny do trenowania na rzadkich (*sparse*) zbiorach danych\n", "* Wada: współczynnik uczenia może czasami gwałtownie maleć\n", "* Wyniki badań pokazują, że często **starannie** dobrane $\\alpha$ daje lepsze wyniki na zbiorze testowym" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Adadelta i RMSprop\n", "* Warianty algorytmu Adagrad, które radzą sobie z problemem gwałtownych zmian współczynnika uczenia" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Adam\n", "\n", "* “Adaptive moment estimation”\n", "* Łączy zalety algorytmów RMSprop i Momentum\n", "* Można go porównać do piłki mającej ciężar i opór\n", "* Obecnie jeden z najpopularniejszych algorytmów optymalizacji" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Nadam\n", "* “Nesterov-accelerated adaptive moment estimation”\n", "* Łączy zalety algorytmów Adam i Nesterov Accelerated Gradient" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### AMSGrad\n", "* Wariant algorytmu Adam lepiej dostosowany do zadań takich jak rozpoznawanie obiektów czy tłumaczenie maszynowe" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## 7.3. Metody zbiorcze" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ " * **Metody zbiorcze** (*ensemble methods*) używają połączonych sił wielu modeli uczenia maszynowego w celu uzyskania lepszej skuteczności niż mogłaby być osiągnięta przez każdy z tych modeli z osobna." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ " * Na metodę zbiorczą składa się:\n", " * dobór modeli\n", " * sposób agregacji wyników" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ " * Warto zastosować randomizację, czyli przetasować zbiór uczący przed trenowaniem każdego modelu." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Uśrednianie prawdopodobieństw" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### Przykład\n", "\n", "Mamy 3 modele, które dla klas $c=1, 2, 3, 4, 5$ zwróciły prawdopodobieństwa:\n", "\n", "* $M_1$: [0.10, 0.40, **0.50**, 0.00, 0.00]\n", "* $M_2$: [0.10, **0.60**, 0.20, 0.00, 0.10]\n", "* $M_3$: [0.10, 0.30, **0.40**, 0.00, 0.20]\n", "\n", "Która klasa zostanie wybrana według średnich prawdopodobieństw dla każdej klasy?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Średnie prawdopodobieństwo: [0.10, **0.43**, 0.36, 0.00, 0.10]\n", "\n", "Została wybrana klasa $c = 2$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Głosowanie klas" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#### Przykład\n", "\n", "Mamy 3 modele, które dla klas $c=1, 2, 3, 4, 5$ zwróciły prawdopodobieństwa:\n", "\n", "* $M_1$: [0.10, 0.40, **0.50**, 0.00, 0.00]\n", "* $M_2$: [0.10, **0.60**, 0.20, 0.00, 0.10]\n", "* $M_3$: [0.10, 0.30, **0.40**, 0.00, 0.20]\n", "\n", "Która klasa zostanie wybrana według głosowania?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Liczba głosów: [0, 1, **2**, 0, 0]\n", "\n", "Została wybrana klasa $c = 3$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Inne metody zbiorcze\n", "\n", " * Bagging\n", " * Boostng\n", " * Stacking\n", " \n", "https://towardsdatascience.com/ensemble-methods-bagging-boosting-and-stacking-c9214a10a205" ] } ], "metadata": { "celltoolbar": "Slideshow", "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.6" }, "livereveal": { "start_slideshow_at": "selected", "theme": "white" } }, "nbformat": 4, "nbformat_minor": 4 }