forked from pms/uczenie-maszynowe
399 lines
10 KiB
Plaintext
399 lines
10 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"slideshow": {
|
||
"slide_type": "slide"
|
||
}
|
||
},
|
||
"source": [
|
||
"### Uczenie maszynowe\n",
|
||
"# 12. Metody optymalizacji"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"slideshow": {
|
||
"slide_type": "slide"
|
||
}
|
||
},
|
||
"source": [
|
||
"## 12.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 uczącego:\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",
|
||
"<img src=\"http://ruder.io/content/images/2016/09/sgd_fluctuation.png\" style=\"margin: auto;\" width=\"50%\" />\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",
|
||
"<img src=\"https://miro.medium.com/max/1400/1*R12QVNFn-46IPewAMxde2w.png\" style=\"margin: auto;\" width=\"100%\" />"
|
||
]
|
||
},
|
||
{
|
||
"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": [
|
||
"## 12.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",
|
||
"* “<b>Ada</b>ptive <b>grad</b>ient”\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",
|
||
"* 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",
|
||
"* “<b>Ada</b>ptive <b>m</b>oment 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",
|
||
"* “<b>N</b>esterov-accelerated <b>ada</b>ptive <b>m</b>oment 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": [
|
||
"<img src=\"contours_evaluation_optimizers.gif\" style=\"margin: auto;\" width=\"60%\" />"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"slideshow": {
|
||
"slide_type": "subslide"
|
||
}
|
||
},
|
||
"source": [
|
||
"<img src=\"saddle_point_evaluation_optimizers.gif\" style=\"margin: auto;\" width=\"60%\" />"
|
||
]
|
||
}
|
||
],
|
||
"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
|
||
}
|