{ "cells": [ { "cell_type": "code", "execution_count": 59, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "import matplotlib as mpl\n", "import matplotlib.pyplot as plot\n", "\n", "%matplotlib inline\n", "mpl.rcParams['figure.dpi'] = 125" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Machine Learning 101\n", "===========\n", "\n", "KharkivPy #17
\n", "November 25th, 2017\n", "\n", "by Roman Podoliaka, Software Engineer at DataRobot\n", "\n", "twitter: @rpodoliaka
\n", "email: roman.podoliaka@gmail.com
\n", "blog: http://podoliaka.org
\n", "slides: http://podoliaka.org/talks/" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Goal\n", "\n", "Take a close look at one of the simplest machine learning algorithms - *logistic regression* - to understand how it works internally and how it can be applied for the task of image classification.\n", "\n", "... and, hopefully, dispel at least some hype around machine learning. " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Problem\n", "\n", "Create an algorithm (also called a **model**) to classify whether images contain either a *dog* or a *cat*.\n", "\n", "\n", "\n", "Kaggle competition: https://www.kaggle.com/c/dogs-vs-cats\n", "\n", "There are much better algorithms for this task, but we'll stick to logistic regression *for the sake of simplicity*." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Input data\n", "\n", "25000 **labeled** examples of JPEG images (of **different sizes**) of cats and dogs, e.g.: *cat.0.jpg*, *cat.1.jpg*, ..., *dog.1.jpg*, *dog.2.jpg*...\n", "\n", "
\n", "\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Terminology and notation\n", "\n", "This task is an example of:\n", "\n", "1) **supervised learning** problem (we are given training examples with \"correct\" answers, as opposed to unlabeled examples in **unsupervised learning**)\n", "\n", "2) **binary classification** problem (the output is a categorical value denoting one of two classes - *0* or *1*, as opposed to **multiclass classification**, where there are more than two classes, or **regression**, where the output is a real number)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Terminology and notation\n", "\n", "Let a column vector $ x = [x_1, x_2, \\ldots, x_n] $ represent a single training example, where $ x_1, x_2, \\ldots, x_n $ are values of its **features**.\n", "\n", "For the task of image classification it's very common to treat **pixels** of a given image as its features.\n", "\n", "If we were to build a machine learning model for medical diagnosis, we would need to come up with a list of features, that would be suitable for that task (e.g. age, weight, height of a person, whether they have been vaccinated, etc)." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Terminology and notation\n", "\n", "Each training example is also accompanied by a **true label** (i.e. the \"correct\" answer) - $ y $.\n", "\n", "For a *binary* classification problem $ y \\in \\{0, 1\\} $\n", "\n", "For a regression problem (e.g. \"How many kgs of noodles will we sell next month?\") $ y \\in \\mathbb{R} $" ] }, { "cell_type": "code", "execution_count": 60, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "import concurrent.futures\n", "import enum\n", "import multiprocessing\n", "import os\n", "import random\n", "import sys\n", "\n", "import numpy as np\n", "from PIL import Image" ] }, { "cell_type": "code", "execution_count": 61, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "class Category(enum.Enum):\n", " dog = 0\n", " cat = 1" ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "def image_to_example(path, width=64, height=64):\n", " filename = os.path.basename(path)\n", "\n", " # normalize the input image, so that we only work with images of the same size\n", " with Image.open(path) as img:\n", " resized = img.resize((width, height))\n", "\n", " # encoding of string labels: \"dog\" -> 0, \"cat\" -> 1 \n", " y = Category[filename.split('.')[0]].value\n", " \n", " # RGB image is flattened into a one long column vector of floats,\n", " # that denote color intensity\n", " x = np.array(resized, dtype=np.float64) \\\n", " .reshape(width * height * 3, 1) / 256.\n", "\n", " return x, y, path" ] }, { "cell_type": "code", "execution_count": 63, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "# preprocessing of a given example\n", "x, y, _ = image_to_example('train/cat.1.jpg')" ] }, { "cell_type": "code", "execution_count": 64, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# true label\n", "y" ] }, { "cell_type": "code", "execution_count": 65, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/plain": [ "array([[ 0.15625 ],\n", " [ 0.171875 ],\n", " [ 0.16796875],\n", " ..., \n", " [ 0.140625 ],\n", " [ 0.08984375],\n", " [ 0.06640625]])" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# normalized example\n", "x" ] }, { "cell_type": "code", "execution_count": 66, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/plain": [ "(12288, 1)" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# feature-vector dimensions\n", "x.shape" ] }, { "cell_type": "code", "execution_count": 67, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\nx3EcJ0v+Bw2//8hYLbz7AAAAAElFTkSuQmCC\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# restored image\n", "plot.imshow(x.reshape(64, 64, 3))" ] }, { "cell_type": "code", "execution_count": 68, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "# load and preprocess images in parallel\n", "def load_examples(path, width=64, height=64):\n", " concurrency = multiprocessing.cpu_count()\n", " \n", " with concurrent.futures.ThreadPoolExecutor(concurrency) as executor:\n", " images_futures = [\n", " executor.submit(\n", " image_to_example,\n", " os.path.join(path, name), width, height\n", " )\n", " for name in os.listdir(path)\n", " ]\n", "\n", " return [\n", " i.result()\n", " for i in concurrent.futures.as_completed(images_futures)\n", " ]" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Task\n", "\n", "Using a training set of labeled examples of images of dogs and cats, come up with a definition of function $ \\hat{y}(x) $, that would output the probability of the fact, that a **new** example (i.e. not seen by this model before) is an image of a cat.\n", "\n", "How do we teach a computer to do that?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Logistic regression: hypothesis\n", "\n", "$$ z = w_1 x_1 + w_2 x_2 + \\ldots + w_n x_n + b $$\n", "\n", "$$ \\hat{y} = \\frac{1}{1 + e^{-z}} $$\n", "\n", "where:\n", "* $ w_1, w_2, \\ldots w_n $ (**weights**) and $ b $ (**bias**) are *parameters* of the algorithm that are learned during training\n", "* $ x_1, x_2, \\ldots, x_n $ are **features** or a training/test example\n", "* $ \\hat{y} $ is the **logistic function**, that outputs **probability** that the given example belongs to class 1" ] }, { "cell_type": "code", "execution_count": 69, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAqkAAAHNCAYAAAA9q+IWAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAATOQAAEzkBj8JWAQAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4wLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvpW3flQAAIABJREFUeJzs3XmcXHWd7//Xt/csnXT2PQQSSEKA\nSAKMbLIo2yhel1FwHXEcxxVRZpSRO1fn6sCol7mMekfx5ww6IwjuoCACjrLKmkASEggJCdn3dLqy\n9Fb1/f1xqjudpjvp9Haqul/Px6MeVfU9S336003lzfnWORVijEiSJEmFpCTtAiRJkqT2DKmSJEkq\nOIZUSZIkFRxDqiRJkgqOIVWSJEkFx5AqSZKkgmNIlSRJUsExpEqSJKngGFIlSZJUcAypkiRJKjiG\nVEmSJBUcQ6okSZIKjiFVkiRJBceQKkmSpIJTlnYBA0kIYQxwCbAWqE+3GkmSpNRUATOA38UYd3Zn\nB4bU3nUJcFvaRUiSJBWI9wG3d2dDQ2rvWgvwox/9iLlz5/bZi2QyGZ599lkWLlxIdXV1n71OobMP\nCfuQsA8H2YuEfUjYh4R9SPRXH1asWMH73/9+yGej7jCk9q56gLlz57JgwYI+e5Ha2lpqa2uZP38+\nNTU1ffY6hc4+JOxDwj4cZC8S9iFhHxL2IZFCH7r98UdPnJIkSVLBMaRKkiSp4BhSJUmSVHAMqZIk\nSSo4hlRJkiQVHEOqJEmSCo4hVZIkSQXHkCpJkqSCU7QhNYQwPITw5RDCr0MIm0MIMYTwg6Pcx0kh\nhHtDCHX5270hhJP6qGRJkiR1UdGGVGAs8CVgIfDM0W4cQjgeeBSYk9/Pl4C5wCP5ZZIkSUpJMX8t\n6mZgaoxxYwihDGg6yu1vJPn5z4sxrgcIIfwMWAHcALyrN4uVJElS1xXtkdQYY0OMcWN3tg0hDAcu\nB37eElDz+1wP/By4PIQwrHcqlSRJ0tEq5iOpPXEyUAH8qYNlTwAfzK/zRH8WJUmSuifGSIyQi5Fs\nm8e5/H1dfTP7mmD3/iaayxrIxQiR1uURyOVifl8Qifn7/L7bvAa0jCfrtW7T7vnB2l47HluXxXbP\nD/mpOvg5O14aX7tq677b2rt3L6vq4NyONigwgzWkTs7fd3QktmVsyuF2EEKYBExqNzwHIJPJUFtb\n26MCDyeTyRxyP1jZh4R9SNiHg+xFwj4ketqHGCP1zTkONGY50JRjf2OW+uYc9U05GpqTW31TloZs\njsbmSGNzLv84R2M20pTN0ZS/b/u8ORdpzkaac7nWx9lccmuOLY9JnudiEj7zy3MRsjGSa3mcix3E\nuY6UwTNPdasPA0sZbz+3jpIQ+uwVeuO/u8EaUofm7xs6WFafvx9yhH38DcnJVq/x7LPP9mlIbbFo\n0aI+f41iYB8S9iFhHw6yFwn7AE05+P2fFrG3CfY2B/Y3w/5mONAM+/PP67NwIAsN2UB9FurzY405\niPRdmFE6Fi9+jrI+/NDn6tWre7yPwRpS9+fvKztYVpW/P3CEfdwC3N1ubA5w28KFC5k/f34Pyju8\nTCbDokWLWLBgAdXV1X32OoXOPiTsQ8I+HGQvEoOhD43NObZkGti8p4GtmUZ27G1ke5vbjr2N7Nrf\nxIGmXNqlEoCKshLKSgLlpYGykkBZaaCspKTN40Bp/lZeEigJLc+hNARKSkL+/uDzkpB/HMg/zz8O\ngZBfFgI0NTWxbetWJk6cQFVlJSUhqSnklweSbWjZFmg50JgMtx87+Lwlwoc2RyZb1+PQfbQdDK9Z\nNxwy3v5JR6/TyaqvqaPFgfp6Xl27loULTqVm5IgO99MbampqeryPwRpSN+XvO5rSbxk77ElZMcbN\nJFcYaNXyR1NdXd0rv5wj6a/XKXT2IWEfEvbhIHuRKPY+ZOqbWLNjH69s38crO/axdsc+Nuzez4bd\nB9i+t6HDzyIerRBgeGUZI6rKGV5ZxvCqsuS+soyhFaUMqyxjSEUpwypKGVJRxpDyUoZUlFBVVkpV\nRSlVZaVUlifPK8pKqCwrobK8hMrS5Hl5aRI2OwtX/aG2tpaHHtrMeeedUNR/Dz1VW1vLQ/vWUDNy\nRJ/2oTf+x3CwhtSlQCNwJvDddsten1+2rL+LkiQNXvVNWVZt28uKzXW8uCXDis11rNy6lx17O/pk\n2uENqyhlwogqxlZXMqIicKB2O/NmHcOUMSMYPayCUUMrGDmkPLkNLae6soySEqf0VVgGfEgNIZQD\nM4E9+aOfxBj3hhB+A7wzhHB9jHFDft1pwDuB38QY96ZWtCRpQMvlIq/s2MuiV2tZvH43i9fV8vK2\nvWRzRz4sWl4amFIzhKmjhjKlZghTRg1h6qghTBxZxcQRVYwfUcXwyoP/vCdHELdy3rnTB/URRBWf\nog6pIYRPATUcvN7rKSGE/5l/fHeMcQnJ9P0K4IfAh9ps/kXgTcDDIYRv5seuBrL5ZZIk9YpcLrJ8\ncx2PrtrBn1bvZPG63dTVNx92mzHDKpg9sZqZ44Zz3LhhHDt2GMeNHc6UUUMo9ainBoGiDqnA3wLH\ntHl+av4GsAFY0tmGMcaXQgjnAl8DvpIffhT4QozxpT6oVZI0iGytq+ePL23j0VU7eXzVDnbua+x0\n3ePGDuOUqSOZO2kEcyeNYM6kasZXV3W6vjQYFHVIjTHO6MI6a+n4hDfyR1ov692qJEmD1Ybd+7lv\n2RZ+u2wLz766u8N1hlaUsmD6KE6dXsOC6aN43bQaRg2r6OdKpcJX1CFVkqS0bcvU88tFG7ln6WaW\nbNjzmuWlJYH5U0dyzqyxnHP8OF43rYaKvrxApTRAGFIlSTpK2Vzk4ZXbuePpdfx+xTaa253wNLyy\njDfOHc+l8yZy9vFjGVFVnlKlUvEypEqS1EXbMvX86Il1/PSZ9WzeU3/IspFDyrnoxAlcdtJEzjl+\nLJVlpSlVKQ0MhlRJko5g/a793PLwan7yzAYamw9+e1MIcM6ssVx5+nQuOnGC0/hSLzKkSpLUiZVb\nM3znj6u5+/lNh1zDdMKISt592jTefdo0po0emmKF0sBlSJUkqZ31u/bzz799kXuWHvLt18yZWM3H\nz5/Jm0+eRFmpR02lvmRIlSQpb29DM//vD6v490fW0Jg9OK2/YHoNn7xgFhfOGZ/q989Lg4khVZI0\n6GVzkZ8/u4Gv/+4lduxtaB0/fcYorr14Nn927GjDqdTPDKmSpEFt+aY6Pv/z51m2sa51bOqoIXzx\nz+dy2UkTDadSSgypkqRBqTmb45aHX+HmB1fSlE1OihpWUconLpjFX51zLFXlXkJKSpMhVZI06KzZ\nsY/P/eQ5Fq+rbR17+6lT+PvL5jB+RFWKlUlqYUiVJA0auVzkR0++yg33rqC+KTkxasywCm54x8lc\nMm9iytVJasuQKkkaFPY2NPPZO5/jgeVbW8cuPnECN7zjZMYOr0yxMkkdMaRKkga8V3fu46//8xlW\nbt0LQHVlGV9+6zzesWCKJ0ZJBcqQKkka0J5cW8sX7l5J7f4mAOZOGsH3PrDQb4qSCpwhVZI0IMUY\neXhz4FdPvED+5H3+/OSJ/J93zWdohf/8SYXO/0olSQNONhf5p9+t5udrD15G6nMXncCnL5zl9L5U\nJAypkqQBpTmb49qfPs9dzyUnSA0pL+H/XnEql57k2ftSMTGkSpIGjKZsjs/csZh7l24BYER55N8/\ncAqnn2BAlYqNIVWSNCA0NGf55G2LeXBFcgR14ogKPnLcfo4fPyzlyiR1R0naBUiS1FP1TVn+5r+e\nbQ2oU0cN4d/fezLjhqRcmKRu80iqJKmoHWjM8pH/fJrHVu0EYMaYodz+169nKA2sSrk2Sd3nkVRJ\nUtHK5iLX3Lm4NaDOHDeMn/zNmUyu8RCqVOw8kipJKlr/dM8KfvdCMsU/c9ww7vjomYyr9itOpYHA\nI6mSpKL0H4+u4T8eWwPA2OGV/OCqMwyo0gBiSJUkFZ37lm3hK/csB2BIeSm3fuh0v+ZUGmAMqZKk\norJ43W4+c8diYoSSAN9+76mcPHVk2mVJ6mWGVElS0Xh15z4+8sNnaGjOAfCP/+Mk3jh3QspVSeoL\nhlRJUlFouRbqzn2NAPzNG47jA68/JuWqJPUVQ6okqSj8798s58UtGQAuO2kiX7h0TsoVSepLhlRJ\nUsH79fObuP3JdUBysf6v/8UplJSElKuS1JcMqZKkgrZ2xz7+/hdLAagoLeHb711AdVV5ylVJ6muG\nVElSwWpozvKpHy9ib0MzANe/eS4nTfFMfmkwMKRKkgrWjfe+yLKNdQBcOm8iHzzTE6WkwcKQKkkq\nSPct28wPHl8LwNRRQ/jaX5xCCH4OVRosDKmSpIKzra6ez/9sCQBlJYFvvedURg7xc6jSYGJIlSQV\nnC/d/QJ19cnnUD9/6WxOnT4q5Yok9TdDqiSpoPzuhS38dtkWAE6dXsNfnXNcyhVJSoMhVZJUMOrq\nm/hfdy0DoLw08LV3nkKp10OVBiVDqiSpYHztty+yta4BgI+fP4sTJlSnXJGktBhSJUkF4ak1u7gt\n/61SM8cN45MXzEy5IklpMqRKklJX35Tlul8saX3+tXeeQmVZaYoVSUqbIVWSlLr/94dVvLJ9HwAf\neP0xnDZjdMoVSUqbIVWSlKqVWzN854+rAZg4oorPXzo75YokFQJDqiQpVV+9ZwXNuQjAV952EtVV\nXrRfkiFVkpSih1Zu5+GV2wG4cM54LjpxQsoVSSoUhlRJUiqyucgN96wAoCTA3182J+WKJBUSQ6ok\nKRU/fWY9L23NAHDlGdM53muiSmrDkCpJ6nf7Gpq56YGVAAyrKOWzbzoh5YokFRpDqiSp393y8Cts\nz7R8s9RMxlVXplyRpEJjSJUk9aste+r53sPJJacmjazir845LuWKJBUiQ6okqV/ddP9L1DflAPjb\ni2czpMJvlpL0WoZUSVK/Wb6pjp8t2gDAvMkjePupU1KuSFKhMqRKkvrN1+57kZhct5/r3zyXkpKQ\nbkGSCpYhVZLUL55bX8tD+Qv3XzB7HGfNHJtyRZIKWdGG1BBCaQjhuhDCqhBCQ/7+uhBClz7cFEK4\nMoTwpxDC7hBCbQjhmRDCR0MIRdsTSSpk3/7vl1sfX+MlpyQdQTEHsm8BNwIPA58EHsk//+aRNgwh\nXAf8GNgDXJ+/1QG3AF/vo3oladB6YdMeHlyxDYA3nDCO+dNqUq5IUqErS7uA7gghnAx8DPhmjPEz\n+eHvhxDqgE+HEL4bY1x6mF18FngGuCzG5NNRIYTvAIuAjwB/23fVS9Lg8+3/XtX6+OoLZ6VYiaRi\nUaxHUq8EAnBzu/Gb8+NXHGH7EcDWloAKEGPMAVuB/b1YpyQNei9tyfDbZVsAOGvmGE6bMTrliiQV\ng6I8kgqcRhIy17QdjDGuCSFsyy8/nD8Al4UQPgvcRRJs3wW8CfhUH9QrSYPWt/9w8Cjqpy88PsVK\nJBWTYg2pk4GNnSzbCBzpwnsfAX4E/Ev+BlAP/GWM8UddKSCEMAmY1G54DkAmk6G2trYru+mWTCZz\nyP1gZR8S9iFhHw4qpF6s3bmf3zy/CYBTp45gzuiSPn1/bKuQ+pAm+5CwD4n+6kNv7D+0mfEuGiGE\n1SRHUs/qYNnjwPgYY6cfegohjCQ5yWoocC9QDnwQuBB4T4zxZ12o4cvAlzpadtNNNzFz5swu/CSS\nNLD9aFUJT29PPln28blZ5tQU3785ko7e6tWrufbaawEWxhgXdWcfxXokdT9Q2cmyKuBAZxvmLzH1\nILAmxvjuNuO3A48C3w0h3BNj7HQfebcAd7cbmwPctnDhQubPn3+Ezbsvk8mwaNEiFixYQHV1dZ+9\nTqGzDwn7kLAPBxVKL9bvPsCiJ5J/m06aNJyPvvUUQui/i/cXSh/SZh8S9iHRX32oqen5FTyKNaRu\nAjpLgVOAxYfZ9lySz6x+o+1gjDGGEH4B/B9gHsnZ/52KMW4GNrcda3nzra6u7pVfzpH01+sUOvuQ\nsA8J+3BQ2r248cF1ZPMHTj93yRxGjRqVSh1p96FQ2IeEfUj0dR96IwAX69n9zwITQgjHth3MPx+f\nX96Zyfn7ji76X9buXpLUDVv21PPzRRsAOGnKCC6YPT7liiQVm2INqXcCEbim3fg1+fE7AUII5SGE\nOfmTnFq8mL//YNsNQwhlwHtITqBa1hdFS9Jg8V9PrKU5lxxG/cT5s/p1ml/SwFCURwxjjM+HEL4H\nXB1CqAYeA84GrgJuiTEuya86BVgB/BD4UH7bxSGEe4A3hxD+CPyCpA/vJ/kIwT/GGPf2448jSQNK\nfVOW259cB8CUmiFcfOKElCuSVIyKMqTmfQpYR3I5qfeRXHrqerr2tabvBD5BcjT1K0AFsBz46xjj\n9/ukWkkaJH61eCO79zcB8JdnHUNZabFO2klKU9GG1BhjM3BD/tbZOmtJLtTffrwB+L/5mySpl8QY\nufWxtQAMrSjlitOmp1uQpKLl/95KknrN46t38tLW5CLe71wwlZFDy1OuSFKxMqRKknrNrY8d/Lbq\nD509I71CJBU9Q6okqVes3bGP37+4DYDzZ49j5rjhKVckqZgZUiVJveIHj6+l5Zu2P3z2sYdfWZKO\nwJAqSeqxuvomfvrMegBmjR/OucePTbkiScXOkCpJ6rGfPrOBfY1ZAK46e4YX75fUY4ZUSVKPZHOR\nHzyenDA1ckg57zh1asoVSRoIDKmSpB757xe3sX7XAQDec8Z0hlSUplyRpIHAkCpJ6pHbn3wVgJIA\nHzjzmJSrkTRQGFIlSd22qfYAD63cDsD5s8czpWZIyhVJGigMqZKkbvvpMxvI5S87deXp09ItRtKA\nYkiVJHVLNhf5Sf6yU+OrK7lwzviUK5I0kBhSJUnd8sjL29lYm5ww9a7TplJW6j8pknqP7yiSpG65\n46n1rY/ffZpT/ZJ6lyFVknTUtmcaeHDFVgDOnjWGY8YMS7kiSQONIVWSdNR+vmgDzfkzpq48fXrK\n1UgaiAypkqSjEmPkzqeTqf5RQ8u5eN6ElCuSNBAZUiVJR+WJV3axZsc+AN6xYCqVZX7DlKTeZ0iV\nJB2VO55e1/r4PWd4wpSkvmFIlSR1We3+Rn67bAsApx0zilnjq1OuSNJAZUiVJHXZLxdvpLE5B8CV\nZ3jClKS+Y0iVJHXZT57ZAEB1ZRlvPnlSytVIGsgMqZKkLnlxSx0rNtcB8Jb5kxhS4QlTkvqOIVWS\n1CW/XLyx9fHbT52aYiWSBgNDqiTpiHK5yF2LNwEwddQQTjtmVMoVSRroDKmSpCN64pWdbKmrB+Bt\nr5tCSUlIuSJJA50hVZJ0RG2n+t926pQUK5E0WBhSJUmHdaAx23pt1FOmjmTW+OEpVyRpMDCkSpIO\n68EVW9nb0AwkU/2S1B8MqZKkw/pVfqq/tCRw+fzJKVcjabAwpEqSOrVzbwMPrdwOwLnHj2VcdWXK\nFUkaLAypkqRO/WbJZppzEYC3e8KUpH5kSJUkdeoX+an+YRWlXHzixJSrkTSYGFIlSR16Zftenl9f\nC8AlJ030a1Al9StDqiSpQ79qc23Ud/g1qJL6mSFVkvQaMUZ++VwSUieMqOTMmWNSrkjSYGNIlSS9\nxnPra1m/6wAAb50/mVK/BlVSPzOkSpJe4zdLNrc+fut8z+qX1P8MqZKkQ+RykXuXJiF1+uihnDRl\nRMoVSRqMDKmSpEMsXr+bzXvqAXjLKZMIwal+Sf3PkCpJOkTbqf43nzIpxUokDWaGVElSq7ZT/ceO\nHcaJk5zql5QOQ6okqdUzr+5ma10D4FS/pHQZUiVJre5Zsqn1sVP9ktJkSJUkAZDNRe5dtgWAWeOH\nM3tCdcoVSRrMDKmSJACeWrOL7Zlkqv/NJzvVLyldhlRJEgD3LD041f8Wp/olpcyQKkmiOZvjt0uT\nqf7ZE6o53ql+SSkzpEqSeHLNLnbuawQ8YUpSYTCkSpK8gL+kgmNIlaRBrimb475lSUidO2kEM8cN\nT7kiSTKkStKg96fVO9m9vwnwhClJhcOQKkmD3G/z10aF5NJTklQIDKmSNIhlc5EHlichdc7EamaM\nHZZyRZKUKNqQGkIoDSFcF0JYFUJoyN9fF0IoPYp9vDuE8EgIoS6EsDeEsCSE8Jm+rFuSCskza3ex\nY29yVv+lJ01MuRpJOqgs7QJ64FvAx4FbgceBs4EbgWnAJ4+0cQjhJuAa4GfA7UAEZgLH9FG9klRw\n7nvh4FT/ZSc51S+pcBRlSA0hnAx8DPhmjLHlyOf3Qwh1wKdDCN+NMS49zPZvAT4HfDDG+F99X7Ek\nFZ4YI7/Lfx712LHDOGGCZ/VLKhzFOt1/JRCAm9uN35wfv+II238eWNQSUEMIfrWKpEFn6cY9bNpT\nD8Al8yYSQki5Ikk6qFhD6mnA1hjjmraD+efb8ss7FEIYTvLRgD+FEP5nCGEnUBdC2BVC+EYIobwv\nC5ekQnFfm7P6/TyqpEJTlNP9wGRgYyfLNgJTDrPtLJJw/m6gHPgqsBZ4K/C3wCTg/UcqIIQwKb9u\nW3MAMpkMtbW1R9pFt2UymUPuByv7kLAPCftwUFd6EWPkniXJ2+iE6gqmD499+r6VBv8mEvYhYR8S\n/dWH3th/iDH2Qin9K4SwmuRI6lkdLHscGB9jnNXJtucAj+SfXhhj/EObZT8C3gfMizEuP0INXwa+\n1NGym266iZkzZ3blR5GkVGzeD//8fHKc4g0Tc7zz2FzKFUkaSFavXs21114LsDDGuKg7+yjWI6n7\ngcpOllUBBw6zbcuyDW0Dat4PSULqecBhQypwC3B3u7E5wG0LFy5k/vz5R9i8+zKZDIsWLWLBggVU\nVw/ej9Pah4R9SNiHg7rSi+89th5YB8AHLjiF048Z2Y8V9g//JhL2IWEfEv3Vh5qamh7vo1hD6iag\nsxQ4BVh8mG1bPiawtYNlm/P3o45UQIxxc5v1AVpPOqiuru6VX86R9NfrFDr7kLAPCftw0OF68cdV\nyQVQxgyr4MKTp1NaMnBPmvJvImEfEvYh0dd96I0AXKwnTj0LTAghHNt2MP98fH55h2KMW4ANdPy5\n1Wn5+229VKckFZx1O/ezfHMdABedOGFAB1RJxatYQ+qdJBffv6bd+DX58TsBQgjlIYQ5+ZOc2rod\nmBhCeFvLQEgOg34cyAIP9lXhkpS237W5gP8lntUvqUAV5XR/jPH5EML3gKvz1zh9jOSyUlcBt8QY\nl+RXnQKsIPms6Yfa7OKfgb8AfhxC+BbJ2f2XA5cC/xxjXNsPP4YkpeK3y5JPKlVXlnHWzDEpVyNJ\nHSvKkJr3KZJP/X+E5GSnjcD1wNePtGGMcXf+LP8bScLrSGAV8IkY43f6qmBJStvWunoWrUsuNXXh\n3PFUlpWmXJEkdaxoQ2qMsRm4IX/rbJ21JN9A1dGyzRx6dFWSBrz720z1XzrPqX5JhatYP5MqSeqG\n+/Ihtaq8hPNmj0u5GknqnCFVkgaJPfubeOKVXQCce/w4hlYU7WSapEHAkCpJg8QfXtpGNpd8y+Al\nTvVLKnCGVEkaJO5fnkz1lwS4cM74lKuRpMMzpErSIFDflOWPL20H4PQZoxk9rCLliiTp8AypkjQI\nPL56B/sbswBc7FS/pCJgSJWkQeCB5VtbH1984oQUK5GkrjGkStIAl83F1pA6Z2I100YPTbkiSToy\nQ6okDXDPrd/Njr2NgFP9koqHIVWSBrj7neqXVIQMqZI0gMUYuf+FJKROqRnCvMkjUq5IkrrGkCpJ\nA9jq7XtZs2MfABedOIEQQsoVSVLXGFIlaQBzql9SsTKkStIA1jLVP6KqjNOPHZ1yNZLUdYZUSRqg\ntmUaeG59LQBvnDuB8lLf8iUVD9+xJGmAemjVrtbHTvVLKjaGVEkaoP74chJSK8pKeMMJ41KuRpKO\njiFVkgag+mZ4cu0eAM6ZNZZhlWUpVyRJR8eQKkkD0IraQHMuAsmlpySp2BhSJWkAWro7uR5qCPDG\nueNTrkaSjp4hVZIGmKZsjuX5kPq6aTWMr65KuSJJOnqGVEkaYBatr+NANgmpTvVLKla9GlJDCAt7\nc3+SpKPXclY/eOkpScWrRyE1hDCp3dBTIYT/DCFM68l+JUndE2NsDanTR1Uxc9zwlCuSpO7pVkgN\nIZSFEL4ALGm36Frgz4EXQwj/FELw3VGS+tHyzXVsrmsA4PzjRxNCSLkiSeqeow6pIYQzgKXAXwDn\nt10WY7wZmAXcQhJYV4UQPhZC8LOvktQPHly+rfXxBcePSbESSeqZ7oTHS4FJwFUxxhfaL4wx1sYY\nPwfMAx4F/g1YFkJ4c48qlSQd0QMrtgAwrCxyypTqlKuRpO7rTki9GfgB8FgI4XOdrRRjXB1j/Avg\nXCAD3B1CeDCEML9blUqSDmtT7QGWbawDYN6oSGmJU/2SitdRh9QYY12M8RrgbOAtXdjkaeAzwCPA\nhcCzIYRbOzjpSpLUAw+u2Nr6+OTRMcVKJKnnuv1lzjHGZSShs1UIoRw4BTitze3E/OsEYAfwLHA5\n8M4QwudjjN/tbg2SpIMeWJ6E1MqyEmaPbE65GknqmW6H1E7s5WAgbQCeA74DPAk8GWN8BSCEUA38\nb+DbIYSaGOM/93IdkjSo1NU38cQrOwF4/YyRVJZuT7kiSeqZ3g6pPwWeIAmlz8UYmzpaKcaYAT4b\nQojApwFDqiT1wB9f2k5TNpniP//4MVBrSJVU3Hr10lAxxvfHGL8dY3y6s4DazlMkVwqQJPVAy1R/\nCPCGWaNSrkaSei7t65f+Drgy5Rokqag1Nuf440vJ9VEXTB/FmGEVKVckST3X29P9RyXGuBv4SZo1\nSFKxe2rNLjL1yYlSb5o7IeVqJKl3pH0kVZLUQw8s39L6+KITDamSBgZDqiQVsRgj9+c/j3rcuGHM\nGj885YokqXcYUiWpiC3bWMfmPfUAXHzixJSrkaTeY0iVpCJ2f5up/ovnOdUvaeAwpEpSEWu59NS4\n6kpeN7Um5WokqfcYUiWpSL26cx8vbskAyVn9JSUh5YokqfcYUiWpSLUcRQWn+iUNPIZUSSpSLWf1\nD6so5ayZY1KuRpJ6lyFVkorQzr0NPLN2FwDnzx5PZVlpyhVJUu8ypEpSEfr9i9vIxeSxU/2SBiJD\nqiQVoftfSKb6y0oC588en3KypBBcAAAgAElEQVQ1ktT7DKmSVGQONGZ5dNV2AF5/3BhGDilPuSJJ\n6n2GVEkqMg+/vJ36phzgVL+kgcuQKklFpmWqH5Lro0rSQGRIlaQi0pzN8d8vJiH15CkjmVwzJOWK\nJKlvGFIlqYg88+pudu9vAuDiEz2KKmngMqRKUhFpO9V/8byJKVYiSX3LkCpJRSLGyP3LtwAwffRQ\nTpgwPOWKJKnvGFIlqUi8sKmODbsPAHDpSRMJIaRckST1HUOqJBWJ+5ZtaX18iVP9kga4og2pIYTS\nEMJ1IYRVIYSG/P11IYSj/gLrEMJDIYQYQvhRX9QqSb3hvheSkDphRCWnTqtJuRpJ6ltlaRfQA98C\nPg7cCjwOnA3cCEwDPtnVnYQQPgAs7IsCJam3rNqWYdW2vUByFLWkxKl+SQNbUR5JDSGcDHwM+GaM\n8cMxxu/HGK8Cvgl8PL+8K/upAb4BfLXvqpWknvtdm7P6L3WqX9IgUJQhFbgSCMDN7cZvzo9f0cX9\nfBWoA/6l90qTpN7X8nnUmqHlnHHs6JSrkaS+V6zT/acBW2OMa9oOxhjXhBC25ZcfVghhAcnHBS6P\nMTZ6lqykQrVh936WbtwDwEVzJ1BWWqzHFySp64o1pE4GNnaybCMw5XAbhxBKgH8D7okx3tudAkII\nk4BJ7YbnAGQyGWpra7uz2y7JZDKH3A9W9iFhHxIDuQ+/emZT6+Nzj60+4vvLQO7F0bAPCfuQsA+J\n/upDb+w/xBh7oZT+FUJYTXIk9awOlj0OjI8xzjrM9h8l+fzqvBjj6vxYBG6LMb6/izV8GfhSR8tu\nuukmZs6c2ZXdSNIR/euyUl7JBCpLIv90epZyD6RKKnCrV6/m2muvBVgYY1zUnX0U65HU/UBlJ8uq\ngAOdbRhCGEtyFYBvtATUbroFuLvd2BzgtoULFzJ//vwe7PrwMpkMixYtYsGCBVRXV/fZ6xQ6+5Cw\nD4mB2ocdextZ86enAbhg9jjedMHsI24zUHtxtOxDwj4k7EOiv/pQU9Pzy+QVa0jdBHSWAqcAiw+z\n7T/k738cQpjRbtmw/NiuGGPd4QqIMW4GNrcda/lca3V1da/8co6kv16n0NmHhH1IDLQ+3PPSq7TM\nd11+6vSj+tkGWi+6yz4k7EPCPiT6ug+9EYCLddLoWWBCCOHYtoP55+PzyztzDDAaeAFY0+YG8Lb8\n44/2dsGS1B0tZ/VXlJVw/uxxKVcjSf2nWEPqnUAErmk3fk1+/E6AEEJ5CGFO/iSnFjcCb+/gBvBQ\n/vGv+q50SeqaPfub+NPqnQC84fhxDKss1skvSTp6RfmOF2N8PoTwPeDqEEI18BjJN05dBdwSY1yS\nX3UKsAL4IfCh/LZPdrTP/FT9hhijAVVSQfj9i1tpziWT/Zee5AX8JQ0uRRlS8z4FrAM+AryP5NJT\n1wNfT7MoSeotLVP9ZSWBN80dn3I1ktS/ijakxhibgRvyt87WWUvyDVRd2Z9X85dUMPY1NPPQyu0A\nnDlzDDVDK1KuSJL6V7F+JlWSBrT/fnEbDc05AC6Z51S/pMHHkCpJBeg3S5JvmSoJfh5V0uBkSJWk\nArO3oZk/vHRwqn/s8M6+u0SSBi5DqiQVmN+v2Epjfqr/LadMTrkaSUqHIVWSCsyvn0++zK60JPh5\nVEmDliFVkgpIXX0TD+fP6j9r5hhGD/OsfkmDkyFVkgrIAy9spTGbTPVf7lS/pEHMkCpJBeSepclU\nf1lJ4OJ5E1KuRpLSY0iVpAKxZ38Tj7ycTPWfc/xYL+AvaVAzpEpSgfjd8i00ZSPgWf2SZEiVpAJx\nz5Jkqr+8NHDRiU71SxrcDKmSVAB272vksVU7AHjD8eMYOaQ85YokKV2GVEkqAL97YQvNufxU//xJ\nKVcjSekzpEpSAWg5q7+irIQ3zXWqX5IMqZKUsp17G3h89U4AzjthHNVVTvVLkiFVklL222VbyLZM\n9Z/iVL8kgSFVklL3q8UbAagqL+GNTvVLEmBIlaRUrdu5n2de3Q3AxSdOZHhlWcoVSVJhMKRKUoru\nem5j6+O3L5iSYiWSVFgMqZKUkhgjv8xP9Y8dXsG5s8amXJEkFQ5DqiSlZMmGPbyyYx8Al8+fTFmp\nb8mS1MJ3RElKSctRVIC3n+pUvyS1ZUiVpBQ0ZXP8+vlNABw3bhgnTxmZckWSVFgMqZKUgkdf3sHO\nfY0AvOPUKYQQUq5IkgqLIVWSUvCLNlP9/+N1TvVLUnuGVEnqZ5n6Ju5/YQsAZ8wYzbTRQ1OuSJIK\njyFVkvrZfcu20NCcA+BtnjAlSR0ypEpSP/tV/gL+FaUlvPnkSSlXI0mFyZAqSf1oy556Hl+9E4AL\n54xn5NDylCuSpMJkSJWkfnTXcxuJMXns16BKUucMqZLUT2KM/HzRBgBGDinn/NnjUq5IkgqXIVWS\n+sni9bWs3LoXgLfOn0xlWWnKFUlS4TKkSlI/ueOpda2PrzxjWoqVSFLhM6RKUj/I1Dfx6+c3A3DK\n1JHMm+zXoErS4RhSJakf3P38Jg40ZQG44nSPokrSkRhSJakf3PHUegCGlJfy1vmTU65GkgqfIVWS\n+tiyjXtYunEPAJfPn0R1lddGlaQjMaRKUh+78+n1rY+vPGN6ipVIUvEwpEpSHzrQmG39GtTZE6o5\ndVpNyhVJUnEwpEpSH7pn6WYy9c1AcsJUCCHliiSpOBhSJakPtVwbtaKshHf4NaiS1GWGVEnqI6u2\nZXjm1d0AXHbSRGqGVqRckSQVD0OqJPWRlstOAVx5uidMSdLRMKRKUh9oaM7y80UbAJgxZiivP250\nyhVJUnExpEpSH/j185vZvb8JgCtOn+4JU5J0lAypktTLYozc+tgaACrLSvwaVEnqBkOqJPWyp9fu\n5oVNdQC8/dQpjB7mCVOSdLQMqZLUy/7j0TWtj686+9gUK5Gk4mVIlaRetH7Xfu5fvgWAs2eNYfbE\n6pQrkqTiZEiVpF70n39aSy4mjz/sUVRJ6jZDqiT1kn0NzdzxdHJt1BljhnLB7PEpVyRJxcuQKkm9\n5OeLNpCpbwbgQ2fNoKTEy05JUncZUiWpF+RykR88thaA6soy/uI0LzslST1hSJWkXvDQyu28smMf\nAO8+fRrDK8tSrkiSipshVZJ6wX/kL94fAvzlmTPSLUaSBoCiDakhhNIQwnUhhFUhhIb8/XUhhNIj\nbDc0hPCxEMK9IYQNIYT9IYTlIYSvhxBq+qt+SQPHy1szPPLyDgAumjuB6WOGplyRJBW/og2pwLeA\nG4GHgU8Cj+Sff/MI2x0H/BswLH9/NfAQ8Fng6RDCiL4qWNLA9N2HXml97MX7Jal3FOWHpkIIJwMf\nA74ZY/xMfvj7IYQ64NMhhO/GGJd2svkW4HUxxiVtxr4fQnga+HfgI8C/9FXtkgaWdTv386vnNgJw\nytSRvP640SlXJEkDQ7EeSb0SCMDN7cZvzo9f0dmGMcYd7QJqi5/m70/slQolDQrfeWgV2fzV+6++\n8HhC8LJTktQbijWkngZsjTGuaTuYf74tv/xoTc7fb+9hbZIGiY21B/jZsxsAOHHSCN4414v3S1Jv\nKcrpfpJAubGTZRuBKd3Y5/VABO7oysohhEnApHbDcwAymQy1tbXdKKFrMpnMIfeDlX1I2IdEGn34\n1/tX05RNjqJ++M8msWfPnn577cPxbyJhHxL2IWEfEv3Vh97Yf4gx9kIp/SuEsJrkSOpZHSx7HBgf\nY5x1FPv7KHALcHOM8bNd3ObLwJc6WnbTTTcxc+bMrr68pCK0pxH+96JSmmNg4pDIF+Zn8QumJCmx\nevVqrr32WoCFMcZF3dlHsR5J3Q9UdrKsCjjQ1R2FEN5Gcpb/PcDfHUUNtwB3txubA9y2cOFC5s+f\nfxS7OjqZTIZFixaxYMECqqur++x1Cp19SNiHRH/34RsPvkJz3AzANRfN5oITx/X5a3aVfxMJ+5Cw\nDwn7kOivPtTU9PyqnsUaUjcBnaXAKcDiruwkhHAxyfT+Y8C7YozNXS0gxrgZ2NxufwBUV1f3yi/n\nSPrrdQqdfUjYh0R/9GF7poGfPbcVgOPGDeNdr59FaQEeRvVvImEfEvYhYR8Sfd2H3gjAxXri1LPA\nhBDCIRckzD8fn19+WCGE84BfAUuBy2OMXT76Kmlw+/4jr9DQnAPgUxcUZkCVpGJXrCH1TpKTnK5p\nN35NfvxOgBBCeQhhTv4kp1YhhD8DfgOsBi6JMdb1fcmSBoJd+xr5rydeBeCYMUN56/zJR9hCktQd\nRTndH2N8PoTwPeDqEEI1yXT92cBVwC1troM6BVgB/BD4EEAI4RjgtySfXf0h8Oftrmu4Ncb4QH/8\nHJKKz388uob9jVkAPnH+TMpKi/X/9SWpsBVlSM37FLCO5Bui3kdy6anrga8fYbtjgVH5x9/oYPlD\ngCFV0mtsq6vn3x9NLs88pWYIbz91asoVSdLAVbQhNX+S0w35W2frrCX5Bqq2Y39sPyZJXXHT/Ss5\n0JQcRb3mTcdTUeZRVEnqK77DSlIXrNhcx0+eXQ8k3y71jgUeRZWkvmRIlaQuuOHeFbR898n1b57r\nGf2S1McMqZJ0BA+t3M4jL+8A4MI54zl71tiUK5Kkgc+QKkmHkc1FbrhnBQClJYG/v2xOyhVJ0uBg\nSJWkw/jpM+t5aWsGgCtPn8bxEwbv1ylKUn8ypEpSJ/Y1NHPTAysBGFZRyjVvOiHliiRp8DCkSlIn\nbnn4FbZnGgD4xAWzGFddmXJFkjR4GFIlqQMbdu/n/3v4FQAmjaziw2cfm3JFkjS4GFIlqZ0YI1/8\n5bLWC/f/3SWzGVJRmnJVkjS4GFIlqZ27ntvEwyu3A3DWzDG8/dQpKVckSYOPIVWS2ti5t4F//PUL\nAFSWlXDjO04mBC/cL0n9zZAqSW189Z4V7N7fBMDnLjqBY8YMS7kiSRqcDKmSlPfQyu38cvFGAOZN\nHsFfnePJUpKUFkOqJJFcE/WLv1gKJN8s9bV3nkJZqW+RkpQW34ElCfiXB1aysfYAAB8591hOmjIy\n5YokaXAzpEoa9Bat282tj60BYProoVzzRr9ZSpLSZkiVNKjtOdDE1T9eTC4mz298x8leE1WSCoAh\nVdKgFWPkCz9bwobdyTT/X555DGfPGptyVZIkMKRKGsT+64lXue+FLQCcNGUEX3zz3JQrkiS1MKRK\nGpSWbdzDV3+zAoDhlWV8+z0LqCxzml+SCoUhVdKgk6lv4lO3L6IxmwPghneczIyxXrRfkgqJIVXS\noBJj5Iu/XMbanfsBeM8Z03nr/MkpVyVJas+QKmlQ+fFT6/n185sAmDOxmi9dfmLKFUmSOmJIlTRo\nPPryDv7XXcsAGFpRyrffu4Cqcj+HKkmFyJAqaVB4cUsdH//RszTnL4j6z+88hVnjh6dclSSpM4ZU\nSQPe1rp6Pnzr02QamgH4u0tm+zlUSSpwhlRJA9rehmauuvVpNu2pB+A9Z0zjE+fPTLkqSdKRGFIl\nDVhN2RyfvG0RyzfXAXDeCeP4yv84iRBCypVJko7EkCppQIox8r/uWsZDK7cDMG/yCP7f+xZQVurb\nniQVA9+tJQ04uVzkH+5axo+fWg/A5JFV/MeHTmd4ZVnKlUmSusp3bEkDSjYXue4XS/jJMxsAqBla\nzq1XncGEEVUpVyZJOhqGVEkDRjbCP9zzMve+kEzxjxlWwW1//WfMnlidcmWSpKNlSJU0IDRlc/zn\nyyU8tzMJqOOrK7n9r/+MWeMNqJJUjAypkopeQ3OWv/vVSzy3M/mY/aSRVdz+16/n2LHDUq5MktRd\nhlRJRW1bpp6P/dezLFpXC8DkkZXc+TdnMm300JQrkyT1hCFVUtFasqGWj/7ns2ypSy7UP7Yq8u/v\nPdmAKkkDgCFVUlG667mNfP5nS2hozgFwxjEjedu4nUwaWZlyZZKk3uB1UiUVlWwu8rX7XuQzdzzX\nGlA/dNYM/u2KeQwrT7k4SVKv8UiqpKKxec8B/u6nS3h01Q4AyksDX33bSVxx+nRqa2tTrk6S1JsM\nqZIKXoyRXy7eyJfufoFMfTMAY4dX8N33L+S0GaNTrk6S1BcMqZIK2s69DVz/y2Xc98KW1rGzZo7h\n/7xrPpNrhqRYmSSpLxlSJRWkGCP3L9/K9b9cyo69jQBUlpXw95fN4YNnzqCkJKRcoSSpLxlSJRWc\nlVszfOU3y3nk5R2tY/On1fAv757PzHHDU6xMktRfDKmSCsaufY383wdWcvtT68jmIgBlJYHPvPF4\nPn7+TMpKvSCJJA0WhlRJqatvynLbk+v41wdXUpc/MQrgwjnj+eKfz2XWeI+eStJgY0iVlJq9Dc3c\n9sSrfP/RNWzPNLSOzxo/nH94y4mcd8K4FKuTJKXJkCqp3+3a18gPHlvDDx5fe8iR05qh5XzuohN4\n7xnTndqXpEHOkCqp3yzdsIcfP72OXy7ayIGmbOv46GEV/NU5x/L+1x/DyCF+bZQkyZAqqY/V1Tdx\n13ObuOOpdbywqe6QZZNHVvHRNxzHFadPZ0hFaUoVSpIKkSFVUq+rb8ry8Mrt3Lt0M/e9sIX6ptwh\ny+dMrObD5xzL2143hYoyp/UlSa9lSJXUK/Y1NPPHl7Zz77LN/OHFbexvzB6yfFhFKW993WSuOH06\n86eOJAQvxi9J6pwhVVK35HKRFzbV8eiqHTy6ajtPr91NY3PuNeudOr2GK06bxlvmT2Z4pW85kqSu\n8V8MSV3SlM2xYnMdi9fV8tTaXTy+age79ze9Zr0Q4PRjRnPZyRO5ZN5EJtcMSaFaSVKxM6RKeo1s\nLvLqzn2s2JxhyYZaFq3bzZINe2jo4EgpJFP5Z84cw/mzx3PxvAmMr67q54olSQNN0YbUEEIp8HfA\nR4BpwHrg+8A3YozZw22b3/4k4OvAOfmhR4HPxxiX9U3FUuHJ5SKb9hzgle37eGX7Xl7ammH55gwr\nt2QOuURUe6UlgddNq+GcWWM55/ixvG5aDeVe11SS1IuKNqQC3wI+DtwKPA6cDdxIElg/ebgNQwjH\nk4TSXcCX8sNXA4+EEM6IMb7cV0VL/a2uvomNuw+wcfcBNuzez8baA6zfdYA1O/axZue+Dj9H2t7Y\n4RWcOn0Up06vYcH0UZwydSRDK4r57UOSVOiK8l+ZEMLJwMeAb8YYP5Mf/n4IoQ74dAjhuzHGpYfZ\nxY0kP/t5Mcb1+X3+DFgB3AC8q++ql3quvinLzn2N7NrbyLptu3l6e2DdUxvJNG9ma1092+oa2Jqp\nZ3tdA5mG5iPvsI3po4cyd1I1cyaOYO6kEcybPIKpo4Z4Nr4kqV8VZUgFrgQCcHO78ZtJjoheAXQY\nUkMIw4HLgTtaAipAjHF9COHnwBUhhGExxn19UrkGraZsjvqmLAeastQ35tjf1My+hiwHGrPsa2xm\nf2Mzexuy7K1vZm9DE3vrm8nUN1NX38SeAwdvtfubOvhsaCmsWtvlWoaUl3Ls2GEcO24Yx40dxnHj\nhnHs2OHMGj/cM/AlSQWhWP81Og3YGmNc03YwxrgmhLAtv7wzJwMVwJ86WPYE8MH8Ok/0Uq29rq6+\nmf3NyX040Obs6vjadWNHg0CMr90kxoPPYrv1XrOvNtsf3Fds3Sa22V/r8pis03b5we3bjkMuxkPX\nzz/OxWS7XIS6TIbVdTB83R6G7sy2jmdjzG8fyeXyz3ORbIxkc8n+srnkcTZGmnPJ8uZcJJvLJffZ\nlueRplyOpuZIcy5HUzbSnM3RlE0eN2ZzNDYnzxubczRmczQ0tdxnaWjO0dCc40BTlmyu499Fbysv\nDYyvrmLCiEomjKhiwogqpo4awpSaIUwZNYSpo4Yyami5R0YlSQWtWEPqZGBjJ8s2AlOOsG3Leh1t\nyxG2ByCEMAmY1G54DkAmk6G2tvZIu+i28//1SXKxDJ5+ss9eo3iUwQsD91y3spJAdWUp1VVljKgq\nY+SQstbHo4aUM2poOUNCM9s3rOH0U+ZyzIQaRlaVHT6ANu1nz57++xn6SyaTOeR+MLMXCfuQsA8J\n+5Dorz70xv6LNaQOBTr76euBEUfYFqChk20BunJhx7/h4ElXh3j22Wf7NKTGWEryaQelIRApDVBW\nQnLf9nEJlJckY+UlsfV521tFSbKsohQqS6CylNbHVaWRqlKoKoOq0mQ/Ibz2WqQA5IC9ycOakVD7\n6nJqX+23NhSsRYsWpV1CwbAXCfuQsA8J+5Do6z6sXr26x/so1pC6H6jsZFkVcOAI29LJ9i0Xdzzc\n9i1uAe5uNzYHuG3hwoXMnz+/C7vonivrV7J1y1bGTxhPRUXFIcs6OoIWDlne8XhHK7TfLrQfz68b\n2mzWuk6bZS0PQn78kPUDBA4dKwmh9fVa9lMSknFC8jgQaGyoZ92rrzLj2BkMHVJFIFBakqyX3A7u\nq7QkGSsNUFKSLGsZK2tZVpIcuSzN38ryt9KSQHlpSfK8NFm3kGQyGRYtWsSCBQuorq5Ou5zU2IeD\n7EXCPiTsQ8I+JPqrDzU1NT3eR7GG1E1AZylwCrD4CNu2rNfRttD5RwlaxRg3A5vbjrUEqurq6l75\n5XTmC5ecwEMPbea882b36esUutraWh46sJbzTps+qPvQoq//7oqFfTjIXiTsQ8I+JOxDoq/70BsB\nuFivvv0sMCGEcGzbwfzz8fnlnVkKNAJndrDs9fllA/dDjpIkSUWgWEPqnSQngl/Tbvya/PidACGE\n8hDCnPxJTgDEGPcCvwHeGUKY2jIeQpgGvBP4TX4dSZIkpaQop/tjjM+HEL4HXB1CqAYeI/nGqauA\nW2KMS/KrTiG5QP8PgQ+12cUXgTcBD4cQvpkfuxrI5pdJkiQpRUUZUvM+BawDPgK8j+RzpNcDXz/S\nhjHGl0II5wJfA76SH34U+EKM8aW+KVeSJEldVbQhNcbYTPIVpjccZp21dHISe/5o62V9UpwkSZJ6\npFg/kypJkqQBzJAqSZKkgmNIlSRJUsExpEqSJKngGFIlSZJUcAypkiRJKjiGVEmSJBUcQ6okSZIK\nTtFezL9AVQGsWLGiT18kk8mwevVqampqqK6u7tPXKmT2IWEfEvbhIHuRsA8J+5CwD4n+6kObLFTV\n3X2EGGPvVCNCCO8Fbku7DkmSpALxvhjj7d3Z0JDai0IIY4BLgLVAfR++1BySMPw+4MU+fJ1CZx8S\n9iFhHw6yFwn7kLAPCfuQ6K8+VAEzgN/FGHd2ZwdO9/ei/C+hW/+3cDRCCC0PX4wxLurr1ytU9iFh\nHxL24SB7kbAPCfuQsA+Jfu7D4z3Z2BOnJEmSVHAMqZIkSSo4hlRJkiQVHENqcdoM/GP+fjCzDwn7\nkLAPB9mLhH1I2IeEfUgUTR88u1+SJEkFxyOpkiRJKjiGVEmSJBUcQ6okSZIKjiFVkiRJBceQKkmS\npIJjSJUkSVLBMaQWmBDCxSGE74UQng0hNIYQYghhxmHWPymEcG8IoS5/uzeEcNJRvF5pCOG6EMKq\nEEJD/v66EEJpb/w8vSWEMCPfi85uTT3cx/f74+foDSGEHxzm55jaxX0Uxe+9MyGEoSGEj+X/3jeE\nEPaHEJaHEL4eQqjp4j6K6u+hp7+znr5XFIIQwmkhhJtDCEtCCJkQwpYQwu9DCG/q4vY9/m+nEPTG\n3+4A+Xs43O8zhhCu78H2Bfn3EEIYHkL4cgjh1yGEzflaf9DJuj1+n0/776Ssv15IXfZe4D3AUuAl\noNM/hhDC8cCjwC7gS/nhq4FHQghnxBhf7sLrfQv4OHAr8DhwNnAjMA34ZDd/hr6wHfhAB+PTgBuA\n3x7Fvu4CftZubFU360rTXwK5dmO7urhtsfzeO3Mc8G/AI/n7bcBC4LPA20MIC2OMdV3cV7H8PXT7\nd9ZL7xWF4DrgPODnwLeB4cBVwAMhhE/EGL/Txf305L+dQtKtv90B9PdwC/BgB+OfAU6j6/8uFNPf\nw1iS39lm4BngLYdZt0fv8wXxdxJj9FZAN2DK/9/evYZcVpUBHP8/NeqMppWJqIOopJDBTARaaVGG\nOEKkpWYaliMFfhAxEYIyIQIhjCKNLtqnCZRSk7xiKJkJUpgWWiEUmpc0p7Q0J2+pTx/Wfu145pz3\n7HP2eeesd/P/wea8s2+z9l7PWufZ1wPs0vx9IZDAgWPm/QmwDdh/YNz+zbirW/xfGygN85Kh8Zc0\n4zcsen+02IYLmn10Yot5D2zmvXDR5e64zVua7Vgz4/J9qPe9gI0jxn+22Tfn9SkeutZZ176iloHy\nJbvL0Lh1lAP6f05qE13bTi1D19jtSzyM2bZdgX8D97WYd9XFA7ALsL75e01T/i0j5uvcz9cQJ17u\nr0xmPpaZL06aLyLeBBwHXJOZjw4s/yjlLMNxEbHbhNWcCgRw8dD4i5vxp0xT9gU5HXgKuHGahSJi\nXUSsW5ki7TAREXtExLTteNXXe2Y+mZn3jZh0dfP5zmnWtwriYeY6m1NfUYXMvHO4f8zM5ynt/63A\nPi1XNWvbqc60sduneBjjBGB34IdTLLNq4iEzX8zMx1rM2qmfryVOqq8QjbUB2Bn41Yhpv6YcbW2Y\nsI7DgK2Z+ZfBkc2//95Mr1ZEHAkcAvwoM1+aYtHPA88Bz0XEnyPirBUp4Mp7CngG2BYR10TE21su\nt6rrfYL9ms9/TLHMaoiHLnU2j76idvsBLwNPt5x/1rZTm1lit+/xsJkSC5dPsUxf4mFQ136+ijjx\nntTVa+nLeNQR1dK49S3WMe6I7LEWyy/a5uaz7RHzq8DPgZ8Cj1C2/0zguxFxUGZ+Yf5FXBFPAN8E\n7gFeAo4EzgY+GBGHZebDE5Zf7fW+nC9TLn/9uMW8qykeutTZPPqKakXEocCJwPWZuW3C7F3bTi26\nxG5v4yEi1gNHAzdn5tYWi/QlHkbp2s9XEScmqSskIoJypNHGq1OeCYRy3w3AqFsDXmg+J10C2hV4\ndsy0F4A9pixTK/PYNxGxFvgk8MfMvLvNijLzEeB1TwE3T8L+EjgvIi7NzAdalquzWfdDZn5xaNo1\nEXEr5SGBrwJnTFjXQkBQVoQAAAXQSURBVOp9nHm1lYg4k/Jw3cWZee+kFdUWDxN0qbN59BVViog3\nUy49Pg+cN2n+ObSdKnSM3d7GA6X9v4Fyr+lEfYmHMbr281XEiZf7V84BlI6zzXDLDOt/rvkc9eW+\ntvl8vsU6xiUHa1ssP6t57Jvjgbcw3X1H28nMV4CLKG3h6C7rmsHcYiQzfwb8FtjU4v9dVL2P03k/\nRMTHKU/53wTMfAZ0wfGwnC51No++ojrNfZg3UN70cMKsZ72mbDvVmiJ2exkPjdMpD9DdMOsK+hIP\ndO/nq4gTz6SunCcpr0Zp44kZ1v948znqdPvSuEk3Vz8OvGvMtPXA72YoVxvz2DebgVeY7r6jcZa+\n3Paaw7qmMe8YeZh29wgtqt7H6bQfImIT5fL+ncDJmflyx/IsKh6W06XO5tFXVCUidqZc6j4C+ERm\n/qLjKtu2ndq1id3exQNARBwOHAp8r83DxxP0IR669vNVxIlJ6gpp7o3asoL/xe8p99AcAVw6NO19\nzbQ/TFjHPcCm5h6m126ujoiDgL2b6XPXdd9ExD7AscAtmfm3ORTp4OazzT1Mc7MCMXIw7bZhIfU+\nTpf9EBEfAq6ltIfjmie9u1pIPEzQpc7m0VdUIyLWAFcBxwCnZ+Z1c1ht27ZTuzax26t4GDDtMwrL\n6UM8dO3nq4gTL/evUs0X+43ASYO/jBER+wMnATcOPkQQEftGxDsiYqeB1VxJecjk3KHVn9uMv3Kl\nyt/RacAbWSaxGbW9EbH3iPnWUd61+l9mu+1ih4qI3Ua99iMiTqEc+d80NL5P9f46EfFeSht4ADg2\nl3l5fw/ioVWdRcROzXbuuzTDtH1FzZpXBF0OfAw4KzOvGDPfdvth2rZTs7ax2/d4WNKcWf8UcH9m\n3jVieq/jYYzW/XzNceKZ1MpExEbK/ZYAH2g+z46Ip4GnM/M7A7OfT7l5/o6I+HYz7hzKZfDzh1b9\nNcqR5kHAQwCZeW9E/AA4JyJ2p1wufT/l0utlY95DWYPNlFfNLHcGZbvtBS6LiLcBtwF/pTy9uJly\nT9uXBt8FV7FDgNsi4krKC8yXjnRPo1yi+srQ/H2q99dExAGUhxvWUs6cfKQ8f/WarZl568C/V3U8\nTFFn64H7KfvkjIFVTNNX1OwblPc73gH8JyI+PTT91uap7lH7Ydq2U7O2sdv3eFjyUWBP4Otjpvcq\nHiLibMozGUsnGjdGxAXN39dn5n1T9vP1xsmO+MUAh/ZDEyA5ZnhoxPwbKV/WzzbDzYz+JZ4tjPj1\nKsqByvnAg5Sn+B5s/l3lL3AA72624/sT5ttue4HPUb7ctlLONvyL8hqX4xe9XVNs/z7AFcCfKL/6\n8SLlZxC/BezV13ofsV1HLdNOEri9b/HQps74/y8RbRmxfKu+ouYBuH1CvR81bj9M23ZqHtrGbt/j\nYWBbrqMkTvuNmd6reKAcaI9rA2cMzNeqn685TqIphCRJklQN70mVJElSdUxSJUmSVB2TVEmSJFXH\nJFWSJEnVMUmVJElSdUxSJUmSVB2TVEmSJFXHJFWSJEnVMUmVJElSdUxSJUmSVB2TVEmSJFXHJFWS\nJEnVMUmVJElSdUxSJUmSVB2TVEnqgYjYMyJymeHURZdRkqaxZtEFkCTNRQKfGRq3DriIckLizh1e\nIknqIDJz0WWQJM1ZRKwDrgPeA2zKzLsWXCRJmoqX+yWpZ0xQJfWBl/slqUeGEtRjMvM3Cy6SJM3E\nM6mS1BMmqJL6xCRVknpgIEE9HBNUST3g5X5JWuVGJKh3L7hIktSZT/dL0ioXEVcBJwOXAMMJ6rbM\nvHbHl0qSujFJlaRVLCICeAbYfcwst2fmh3dgkSRpLkxSJUmSVB0fnJIkSVJ1TFIlSZJUHZNUSZIk\nVcckVZIkSdUxSZUkSVJ1TFIlSZJUHZNUSZIkVcckVZIkSdUxSZUkSVJ1TFIlSZJUHZNUSZIkVcck\nVZIkSdUxSZUkSVJ1TFIlSZJUHZNUSZIkVed/JoYZl8RpMoIAAAAASUVORK5CYII=\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "z = np.linspace(-10, 10, 100)\n", "plot.xlabel('$ z $'), plot.ylabel('$ \\hat{y} $')\n", "plot.plot(z, 1 / (1 + np.exp(-z)))\n", "plot.grid(True)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Note, that $ z $ is essentially a result of matrix multiplication of two column vectors of weights $ w $ and features $ x $ plus bias $ b $: \n", "\n", "$$ z = w_1 x_1 + w_2 x_2 + \\ldots + w_n x_n + b = w^T x + b $$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Column vectors $ x $ of each example can also be stacked into a matrix (each computation can be performed in parallel):\n", "\n", "$$\n", "z =\n", "w^T\n", "\\begin{bmatrix}\n", " x_{1}^{(1)} & x_{1}^{(2)} & \\dots & x_{1}^{(m)} \\\\\n", " x_{2}^{(1)} & x_{2}^{(2)} & \\dots & x_{2}^{(m)} \\\\\n", " \\vdots & \\vdots & \\ddots & \\vdots \\\\\n", " x_{n}^{(1)} & x_{n}^{(2)} & \\dots & x_{n}^{(m)}\n", "\\end{bmatrix} = \\\\\n", "= [(w^T x^{(1)} + b), (w^T x^{(2)} + b), \\ldots, (w^T x^{(m)} + b)]\n", "$$" ] }, { "cell_type": "code", "execution_count": 70, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "12.2 ms ± 262 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n", "2.87 µs ± 76.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n" ] } ], "source": [ "v1 = np.random.rand(10000, 1)\n", "v2 = np.random.rand(10000, 1)\n", "\n", "# computation happens in Python interpreter\n", "%timeit sum(a * b for a, b in zip(v1, v2))\n", "\n", "# computation happens in numpy\n", "%timeit np.dot(v1.T, v2)" ] }, { "cell_type": "code", "execution_count": 71, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "def initialize_weights(n):\n", " # the simplest way is to initialize to zeros, but random\n", " # initialization is also ok\n", " \n", " w = np.zeros((n, 1))\n", " b = 0.0\n", "\n", " return w, b" ] }, { "cell_type": "code", "execution_count": 72, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "def hypothesis(w, b, x):\n", " z = np.dot(w.T, x) + b\n", "\n", " return 1. / (1. + np.exp(-z))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Logistic regression: training\n", "\n", "**Training** is a process of finding such values of model parameters $ w $ and $ b $, which give the best **performance** on the training set.\n", "\n", "But how do we measure performance?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Logistic regression: cost function\n", "\n", "**Cost function** is a measure of how close model predictions $ \\hat{y} $ are to true labels $ y $: \n", "\n", "$$ J(w, b) = - \\frac{1}{m} \\sum_{i=1}^{m} \\big( y_i \\ln{\\hat{y_i}} + (1 - y_i) \\ln{(1 - \\hat{y_i})} \\big) $$\n", "\n", "There are many different cost functions for ML algorithms, this one is called **logistic loss**." ] }, { "cell_type": "code", "execution_count": 82, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAApIAAAG0CAYAAACBlcfQAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAATOQAAEzkBj8JWAQAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4wLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvpW3flQAAIABJREFUeJzs3XeYXFdhx/3vmbZ1dme1K626ZFm2\nJFu2bMkNNxkwpvdmiAMYHByHACEEXhISHEqA4EB4IW+wKcEUk4QSWmxijDEyBlu2tbYkF/VedqUt\nszu7s2XKef+4d8r22TJN+/s8z33unXvvzJzdI8s/nXaNtRYRERERkanyFLsAIiIiIlKeFCRFRERE\nZFoUJEVERERkWhQkRURERGRaFCRFREREZFoUJEVERERkWhQkRURERGRaFCRFREREZFoUJEVERERk\nWhQkRURERGRaFCRFREREZFoUJEVERERkWhQkRURERGRaFCRFREREZFp8xS5AoRljGoGXAoeAgeKW\nRkRERKRoKoGVwP3W2o7pfMCcC5I4IfKeYhdCREREpET8CfCD6bxxLgbJQwDf//73WbduXV6/KBKJ\nsG3bNjZt2kQwGMzrd8n0qI7Kg+qpPKieSp/qqDwUqp6ef/55brrpJnCz0XTMxSA5ALBu3To2btyY\n1y8Kh8OEw2E2bNhAKBTK63fJ9KiOyoPqqTyonkqf6qg8FKGepj3UT5NtRERERGRaFCRFREREZFoU\nJEVERERkWhQkRURERGRaFCRFREREZFoUJEVERERkWhQkRURERGRaFCRFREREZFpKPkgaY7zGmI8Z\nY/YZYwbd/ceMMd5il01ERERkLiuHJ9t8FbgN+DbwR+Aq4HPAMuB9RSyXiIiIyJxW0kHSGHMB8OfA\nV6y1H3RPf9MY0wO83xhzp7V2Z/FKKCIiIjJ3lXrX9o2AAb484vyX3fNvLXiJRERERAQo8RZJ4BKg\nzVp7MPuktfagMeaUe700HXkMX/sxmiJ78baGILYQAjXuVgtef7FLKCIiIkVkraU/lqBvMEF0KJ7e\nn+rs5ukOwwXRGKFQsUs5sVIPkouB4+NcOw4smejNxphFwKIRp9cCRCIRwuHwjAs4nprffp7aQw9x\nFcC+0detN4D1V4O/BhuowfprRr8OVGP9teDuM+drRtxXA/5qMKXewFx6IpHIsL2UJtVTeVA9lT7V\n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\nkBQRERERX/4fNqnNTJH5R1MAAAAASUVORK5CYII=\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "y_h = np.linspace(0.000001, 0.999999, 100)\n", "plot.plot(y_h, np.log(y_h)), plot.plot(y_h, np.log(1 - y_h))\n", "plot.legend(['$ ln(\\hat{y}) $', '$ ln(1 - \\hat{y}) $'])\n", "plot.grid(True)" ] }, { "cell_type": "code", "execution_count": 83, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "def cost(w, b, x, y):\n", " m = x.shape[1]\n", " y_h = hypothesis(w, b, x)\n", "\n", " return - np.sum(y * np.log(y_h) + (1 - y) * np.log(1 - y_h)) / m" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Logistic regression: gradient descent\n", "\n", "**Gradient descent** is an iterative function optimization algorithm, that takes steps proportional to the negative of the *gradient* to find the local minimum:\n", "\n", "$$ w^{i + 1} = w^{i} - \\alpha \\frac{\\partial J}{\\partial w} $$\n", "\n", "$$ b^{i + 1} = b^{i} - \\alpha \\frac{\\partial J}{\\partial b} $$\n", "\n", "where:\n", "\n", "* $ \\alpha $ - is a *hyperparameter* called **learning rate**, which effectively defines the size of gradient descent steps" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Gradient descent\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Logistic regression: gradient descent\n", "\n", "$$ \n", " \\frac{\\partial J}{\\partial z} = \\frac{\\partial J}{\\partial \\hat{y}} \\frac{\\partial \\hat{y}}{\\partial z} =\n", " \\hat{y} - y \n", "$$\n", "\n", "$$ \n", " \\frac{\\partial J}{\\partial w} =\n", " \\frac{\\partial J}{\\partial \\hat{y}} \\frac{\\partial \\hat{y}}{\\partial z} \\frac{\\partial z}{\\partial w} =\n", " \\frac{1}{m} X (\\hat{y} - y)^T\n", "$$\n", "\n", "$$\n", " \\frac{\\partial J}{\\partial b} =\n", " \\frac{\\partial J}{\\partial \\hat{y}} \\frac{\\partial \\hat{y}}{\\partial z} \\frac{\\partial z}{\\partial b} =\n", " \\frac{1}{m} \\sum_{i=1}^{m} (\\hat{y}_i - y_i)\n", "$$\n", "\n", "The process of changing the weights is sometimes called **backward propagation of errors** (as we use the difference between predictions $ \\hat{y} $ and true labels $ y $ in order to modify the weights of inputs)." ] }, { "cell_type": "code", "execution_count": 75, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "def update_weights(w, b, x, y_h, y, learning_rate):\n", " m = x.shape[1]\n", "\n", " # calculate the values of partial derivatives\n", " dz = y_h - y\n", " dw = np.dot(x, dz.T) / m\n", " db = np.sum(dz) / m\n", "\n", " # update the weights for the next iteration\n", " w = w - learning_rate * dw\n", " b = b - learning_rate * db\n", "\n", " return w, b" ] }, { "cell_type": "code", "execution_count": 76, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "def logistic_regression(train_set, learning_rate=0.001, iterations=100, batch_size=64, callback=None):\n", " # stack training examples as columns into a (n, m) matrix\n", " x = np.column_stack(x[0] for x in train_set)\n", " y = np.array([x[1] for x in train_set], dtype=np.float64).reshape(1, len(train_set))\n", "\n", " # split the whole training set into batches of equal size\n", " n, m = x.shape\n", " num_batches = m // batch_size + (1 if m % batch_size > 0 else 0)\n", " x_batches = np.array_split(x, num_batches, axis=1)\n", " y_batches = np.array_split(y, num_batches, axis=1)\n", "\n", " # run the gradient descent to learn w and b\n", " w, b = initialize_weights(n)\n", " for iteration in range(iterations):\n", " j = 0\n", "\n", " for x_batch, y_batch in zip(x_batches, y_batches):\n", " y_hat = hypothesis(w, b, x_batch)\n", " w, b = update_weights(w, b, x_batch, y_hat, y_batch, learning_rate)\n", "\n", " j += cost(w, b, x_batch, y_batch) / num_batches\n", "\n", " if callback is not None:\n", " callback(iteration=iteration, w=w, b=b, cost=j)\n", "\n", " return w, b" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Model performance evaluation\n", "\n", "It's important that we test the trained model on a separate set of examples it **has not seen before**, so that we ensure it generalizes well and does not **overfit** the training set.\n", "\n", "Training and test set examples should come from the same distribution, so that the model is trained on the same kind of data it will be used to make predictions on later.\n", "\n", "The performance metric we will use is **accuracy**, i.e. the percentage of correct predictions on a given data set." ] }, { "cell_type": "code", "execution_count": 77, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "def predict(w, b, x, threshold=0.5):\n", " y_h = hypothesis(w, b, x)\n", "\n", " return y_h >= threshold" ] }, { "cell_type": "code", "execution_count": 78, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "def accuracy(w, b, data):\n", " # stack examples as columns into a (n, m) matrix\n", " x = np.column_stack(x[0] for x in data)\n", " y = np.array([x[1] for x in data]).reshape(1, x.shape[1])\n", "\n", " # calculate the accuracy value as a percentage of correct predictions\n", " correct_predictions = np.count_nonzero((y == predict(w, b, x)))\n", " total_predictions = x.shape[1]\n", "\n", " return correct_predictions / total_predictions" ] }, { "cell_type": "code", "execution_count": 85, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "def main(path, iterations=100, max_examples=25000, train_ratio=0.9):\n", " # load examples and make sure they are uniformly distributed\n", " examples = load_examples(path)\n", " random.shuffle(examples)\n", "\n", " # split all the examples into train and test sets\n", " m_train = int(max_examples * train_ratio)\n", " train_set = examples[:m_train]\n", " test_set = examples[m_train:]\n", " \n", " # monitor the progress of training\n", " def progress(iteration, cost, w, b):\n", " print('Iteration %d' % iteration)\n", " print('\\tCost: %f' % cost)\n", " if iteration % 10 == 0:\n", " print('\\tTrain set accuracy: %s' % accuracy(w, b, train_set))\n", " print('\\tTest set accuracy: %s' % accuracy(w, b, test_set)) \n", "\n", " # run the training process to learn model parameters\n", " w, b = logistic_regression(train_set, iterations=iterations, callback=progress)\n", " print('\\tFinal train set accuracy: %s' % accuracy(w, b, train_set))\n", " print('\\tFinal test set accuracy: %s' % accuracy(w, b, test_set)) " ] }, { "cell_type": "code", "execution_count": 86, "metadata": { "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Iteration 0\n", "\tCost: 0.671012\n", "\tTrain set accuracy: 0.5730222222222222\n", "\tTest set accuracy: 0.5704\n", "Iteration 1\n", "\tCost: 0.661474\n", "Iteration 2\n", "\tCost: 0.657053\n", "Iteration 3\n", "\tCost: 0.654155\n", "Iteration 4\n", "\tCost: 0.651971\n", "Iteration 5\n", "\tCost: 0.650178\n", "Iteration 6\n", "\tCost: 0.648624\n", "Iteration 7\n", "\tCost: 0.647228\n", "Iteration 8\n", "\tCost: 0.645945\n", "Iteration 9\n", "\tCost: 0.644749\n", "Iteration 10\n", "\tCost: 0.643624\n", "\tTrain set accuracy: 0.6156444444444444\n", "\tTest set accuracy: 0.6032\n", "Iteration 11\n", "\tCost: 0.642558\n", "Iteration 12\n", "\tCost: 0.641543\n", "Iteration 13\n", "\tCost: 0.640573\n", "Iteration 14\n", "\tCost: 0.639644\n", "Iteration 15\n", "\tCost: 0.638753\n", "Iteration 16\n", "\tCost: 0.637895\n", "Iteration 17\n", "\tCost: 0.637070\n", "Iteration 18\n", "\tCost: 0.636274\n", "Iteration 19\n", "\tCost: 0.635505\n", "Iteration 20\n", "\tCost: 0.634762\n", "\tTrain set accuracy: 0.6285333333333334\n", "\tTest set accuracy: 0.6108\n", "Iteration 21\n", "\tCost: 0.634043\n", "Iteration 22\n", "\tCost: 0.633347\n", "Iteration 23\n", "\tCost: 0.632671\n", "Iteration 24\n", "\tCost: 0.632016\n", "Iteration 25\n", "\tCost: 0.631379\n", "Iteration 26\n", "\tCost: 0.630760\n", "Iteration 27\n", "\tCost: 0.630158\n", "Iteration 28\n", "\tCost: 0.629572\n", "Iteration 29\n", "\tCost: 0.629001\n", "Iteration 30\n", "\tCost: 0.628444\n", "\tTrain set accuracy: 0.6368444444444444\n", "\tTest set accuracy: 0.6152\n", "Iteration 31\n", "\tCost: 0.627900\n", "Iteration 32\n", "\tCost: 0.627369\n", "Iteration 33\n", "\tCost: 0.626851\n", "Iteration 34\n", "\tCost: 0.626344\n", "Iteration 35\n", "\tCost: 0.625848\n", "Iteration 36\n", "\tCost: 0.625363\n", "Iteration 37\n", "\tCost: 0.624888\n", "Iteration 38\n", "\tCost: 0.624422\n", "Iteration 39\n", "\tCost: 0.623966\n", "Iteration 40\n", "\tCost: 0.623518\n", "\tTrain set accuracy: 0.6437777777777778\n", "\tTest set accuracy: 0.6204\n", "Iteration 41\n", "\tCost: 0.623079\n", "Iteration 42\n", "\tCost: 0.622647\n", "Iteration 43\n", "\tCost: 0.622224\n", "Iteration 44\n", "\tCost: 0.621808\n", "Iteration 45\n", "\tCost: 0.621398\n", "Iteration 46\n", "\tCost: 0.620996\n", "Iteration 47\n", "\tCost: 0.620600\n", "Iteration 48\n", "\tCost: 0.620211\n", "Iteration 49\n", "\tCost: 0.619827\n", "Iteration 50\n", "\tCost: 0.619450\n", "\tTrain set accuracy: 0.6501777777777777\n", "\tTest set accuracy: 0.6184\n", "Iteration 51\n", "\tCost: 0.619078\n", "Iteration 52\n", "\tCost: 0.618711\n", "Iteration 53\n", "\tCost: 0.618350\n", "Iteration 54\n", "\tCost: 0.617993\n", "Iteration 55\n", "\tCost: 0.617642\n", "Iteration 56\n", "\tCost: 0.617295\n", "Iteration 57\n", "\tCost: 0.616953\n", "Iteration 58\n", "\tCost: 0.616615\n", "Iteration 59\n", "\tCost: 0.616281\n", "Iteration 60\n", "\tCost: 0.615951\n", "\tTrain set accuracy: 0.6545777777777778\n", "\tTest set accuracy: 0.6216\n", "Iteration 61\n", "\tCost: 0.615625\n", "Iteration 62\n", "\tCost: 0.615304\n", "Iteration 63\n", "\tCost: 0.614986\n", "Iteration 64\n", "\tCost: 0.614671\n", "Iteration 65\n", "\tCost: 0.614360\n", "Iteration 66\n", "\tCost: 0.614052\n", "Iteration 67\n", "\tCost: 0.613748\n", "Iteration 68\n", "\tCost: 0.613447\n", "Iteration 69\n", "\tCost: 0.613149\n", "Iteration 70\n", "\tCost: 0.612854\n", "\tTrain set accuracy: 0.6580444444444444\n", "\tTest set accuracy: 0.6224\n", "Iteration 71\n", "\tCost: 0.612562\n", "Iteration 72\n", "\tCost: 0.612273\n", "Iteration 73\n", "\tCost: 0.611986\n", "Iteration 74\n", "\tCost: 0.611703\n", "Iteration 75\n", "\tCost: 0.611422\n", "Iteration 76\n", "\tCost: 0.611143\n", "Iteration 77\n", "\tCost: 0.610867\n", "Iteration 78\n", "\tCost: 0.610594\n", "Iteration 79\n", "\tCost: 0.610323\n", "Iteration 80\n", "\tCost: 0.610054\n", "\tTrain set accuracy: 0.6606666666666666\n", "\tTest set accuracy: 0.624\n", "Iteration 81\n", "\tCost: 0.609788\n", "Iteration 82\n", "\tCost: 0.609524\n", "Iteration 83\n", "\tCost: 0.609262\n", "Iteration 84\n", "\tCost: 0.609002\n", "Iteration 85\n", "\tCost: 0.608744\n", "Iteration 86\n", "\tCost: 0.608489\n", "Iteration 87\n", "\tCost: 0.608235\n", "Iteration 88\n", "\tCost: 0.607983\n", "Iteration 89\n", "\tCost: 0.607733\n", "Iteration 90\n", "\tCost: 0.607485\n", "\tTrain set accuracy: 0.6634222222222222\n", "\tTest set accuracy: 0.6228\n", "Iteration 91\n", "\tCost: 0.607239\n", "Iteration 92\n", "\tCost: 0.606995\n", "Iteration 93\n", "\tCost: 0.606752\n", "Iteration 94\n", "\tCost: 0.606512\n", "Iteration 95\n", "\tCost: 0.606272\n", "Iteration 96\n", "\tCost: 0.606035\n", "Iteration 97\n", "\tCost: 0.605799\n", "Iteration 98\n", "\tCost: 0.605565\n", "Iteration 99\n", "\tCost: 0.605332\n", "\tFinal train set accuracy: 0.6658222222222222\n", "\tFinal test set accuracy: 0.6244\n" ] } ], "source": [ "main(\"train\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Summary\n", "\n", "* logistic regression is a basic model, that does not generalize well for this task and only achieves ~63% accuracy on the test set (e.g. the leader in this Kaggle competition achieved ~98.6%)\n", "\n", "* there are more sophisticated ML algorithms like **convolutional neural networks**, that perform better at image classification tasks\n", "\n", "* concepts like backward propagation of errors and gradient descent are used in other algorithms as well" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Summary (continued)\n", "\n", "* we did not have to explain a computer how to distinguish a cat from a dog - we just had to show it a lot of labeled examples\n", "\n", "* ML algorithms are generic - you can use the very same logistic regression implementation for many different problems - just provide a different data set!" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Links\n", "\n", "Andrew Ng:\n", "\n", "* Introduction to ML: https://www.coursera.org/learn/machine-learning\n", "\n", "* Deep Learning specialization: https://www.coursera.org/specializations/deep-learning\n", "\n", "Machine Learning and Data Analysis specialization (Yandex):\n", "\n", "* https://www.coursera.org/specializations/machine-learning-data-analysis" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Thanks!\n", "\n", "\n", "\n", "twitter: @rpodoliaka
\n", "email: roman.podoliaka@gmail.com
\n", "blog: http://podoliaka.org
\n", "slides: http://podoliaka.org/talks/" ] } ], "metadata": { "celltoolbar": "Slideshow", "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.6.3" } }, "nbformat": 4, "nbformat_minor": 2 }