{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Uczenie maszynowe\n",
"# 4. Sieci neuronowe – wprowadzenie"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"outputs": [],
"source": [
"# Przydatne importy\n",
"\n",
"import matplotlib\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"\n",
"%matplotlib inline"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## 4.1. Perceptron"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"https://www.youtube.com/watch?v=cNxadbrN_aI"
]
},
{
"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": "subslide"
}
},
"source": [
""
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Pierwszy perceptron liniowy\n",
"\n",
"* Frank Rosenblatt, 1957\n",
"* aparat fotograficzny podłączony do 400 fotokomórek (rozdzielczość obrazu: 20 x 20)\n",
"* wagi – potencjometry aktualizowane za pomocą silniczków"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Uczenie perceptronu\n",
"\n",
"Cykl uczenia perceptronu Rosenblatta:\n",
"\n",
"1. Sfotografuj planszę z kolejnym obiektem.\n",
"1. Zaobserwuj, która lampka zapaliła się na wyjściu.\n",
"1. Sprawdź, czy to jest właściwa lampka.\n",
"1. Wyślij sygnał „nagrody” lub „kary”."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Funkcja aktywacji\n",
"\n",
"Funkcja bipolarna:\n",
"\n",
"$$ g(z) = \\left\\{ \n",
"\\begin{array}{rl}\n",
"1 & \\textrm{gdy $z > \\theta_0$} \\\\\n",
"-1 & \\textrm{wpp.}\n",
"\\end{array}\n",
"\\right. $$\n",
"\n",
"gdzie $z = \\theta_0x_0 + \\ldots + \\theta_nx_n$,
\n",
"$\\theta_0$ to próg aktywacji,
\n",
"$x_0 = 1$. "
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"outputs": [],
"source": [
"def bipolar_plot():\n",
" matplotlib.rcParams.update({'font.size': 16})\n",
"\n",
" plt.figure(figsize=(8,5))\n",
" x = [-1,-.23,1] \n",
" y = [-1, -1, 1]\n",
" plt.ylim(-1.2,1.2)\n",
" plt.xlim(-1.2,1.2)\n",
" plt.plot([-2,2],[1,1], color='black', ls=\"dashed\")\n",
" plt.plot([-2,2],[-1,-1], color='black', ls=\"dashed\")\n",
" plt.step(x, y, lw=3)\n",
" ax = plt.gca()\n",
" ax.spines['right'].set_color('none')\n",
" ax.spines['top'].set_color('none')\n",
" ax.xaxis.set_ticks_position('bottom')\n",
" ax.spines['bottom'].set_position(('data',0))\n",
" ax.yaxis.set_ticks_position('left')\n",
" ax.spines['left'].set_position(('data',0))\n",
"\n",
" plt.annotate(r'$\\theta_0$',\n",
" xy=(-.23,0), xycoords='data',\n",
" xytext=(-50, +50), textcoords='offset points', fontsize=26,\n",
" arrowprops=dict(arrowstyle=\"->\"))\n",
"\n",
" plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"data": {
"image/png": "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TLiU+fPn67PPPtPbb7/t7FIANDMEJlyKl5eXli9frunTp+unn35ydjkAmhECEy7nzjvv1JAhQ/TEE084uxQAzQiBCZe0bNkyrV27Vv/5z3+cXQqAZoLAhEvq3LmzlixZoilTpqisrMzZ5QBoBghMuKw//vGPatGihVauXOnsUgA0AwQmXFaLFi30yiuvaMGCBTp16pSzywHQxBGYcGk33XSTHnjgAc2cOdPZpQBo4ghMuLzHH39cBw4c0DvvvGPXt3r1amVkZDihKgBNDYEJl9eqVSu9/PLLmjp1qi5evGjTl5+fr48++shJlQFoSghMNAnDhw9XSEiInn76aZv2zp078/kmgHpBYKLJeOmll7RixQp9/vnn1rZrr71W3377rROrAtBUEJhoMrp27arHH39cDz/8sAzDkHQlMDnDBFAfCEy4rLNnz+rw4cM2bdOmTdNPP/2kN954QxJvyQKoPwQmXFZ+fr5uu+02zZo1Sz/++KMkqWXLlkpOTtbcuXN19uxZ3pIFUG8ITLis0NBQffbZZzp79qz69OmjLVu2yDAM9evXTzExMXr00Ud1zTXX6PLlyyosLHR2uQBcHIEJl9apUyetWbNG69ev14IFCzRixAjl5+dr8eLFeuedd7R//3517tyZs0wAdUZgokkICwtTdna2brvtNoWGhurll1/W888/r8mTJ9fpc8wTJ05o9OjRatOmja655hqNGjVKX331lamxRUVFmjNnjrp06SJvb28NHDhQ7733Xq3qAOB8BCaaDA8PD82fP19ZWVn64IMP9OSTT6pNmzb64YcfanWGWVhYqPDwcH3xxRdau3at1q1bpyNHjuiOO+7QhQsXqh3/4IMPatWqVXryySe1bds2denSRb/73e+UnZ1dm6cHwMncnF0AUN8CAgK0bds2bd26VY888oi++eYbHTp0SFLfGj3OqlWrdOzYMeXl5alnz56SpJtvvlm9evVScnJylevX/uc//9HGjRv12muvaeLEiZKunAUHBQXp8ccfV3p6eq2fHwDn4AwTTZLFYtGoUaOUl5en4cOHy8vLq8aPkZ6ergEDBljDUroSxoMHD1ZaWlq1Y93d3RUTE2Ntc3Nz09ixY7V7924VFxfXuB4AzkVgoknz9fXV22+/rTlz5tR4bE5OjoKDg+3ag4KClJubW+3YgIAA+fj42I29dOmSjh49WuN6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97//bXh5eRm///3vjYyMDGP16tVGu3btjNGjRzf003Apc+fONTw9PY1ly5YZe/fuNaZMmWJYLBYjPT3dZrvw8HCjR48e1vsFBQXGkCFDjL///e/G7t27jfT0dGPixImGxWIxpkyZ0tBPw46zr8P86aefjB49ehjBwcHGW2+9ZaSlpRk333yzERAQYPz444/W7QoKCgxJxhNPPGEzPiYmxmjbtq2xatUqIyMjw7j33nsNT09PrimuQk32ecuWLW32+fPPP2/88Y9/NDZs2GDs3bvXWLNmjREcHGy4u7sb7733njOejssoP0ZPmTLFkGQsX77cSE1NNTIzM63btGzZ0njggQdsxpk99jSACjOx0QfmhAkTDF1Z09bu9vOLYcu3u9q+ffuMAQMGGJ6enkanTp2MP//5zzZBC3slJSXG4sWLje7duxseHh7GTTfdZKSmptptFxYWZlx//fXW+2fPnjWioqKM7t27G56enoaXl5fxq1/9yvjb3/5mczGzszg7MA3DMI4fP26MGjXKaN26teHr62tERUXZXdSdn59f4SIdhYWFxowZM4zOnTsbnp6exq233mrs3bu3wWp3VbXd5+np6cagQYOM9u3bG25uboafn58RGRlp/POf/2zYJ+CCKjtmh4WF2WwzYcIEm3Fmjz0NoMJMZPF1NBssvg7AJNdcfB0AgMaAwAQAwAQCEwAAEwhMAABMIDABADCBwAQAwAQCEwAAEwhMAABMIDABADCBwAQAwAQCEwAAEwhMAABMIDABADCBwAQAwAQCEwAAEwhMAABMIDABADCBwAQAwAQCEwAAEwhMAABMIDABADCBwAQAwAQCEwAAEwhMAABMIDABADCBwAQAwAQCEwAAEwhMAABMIDABADCBwAQAwAQCEwAAEwhMoBJlZWVKTEyUv7+/vLy8dMstt2jLli2mxsbFxclisdjd4uPjHVw1AEdxc3YBQGO1YMECLV26VE899ZT69eunN998U2PGjNG2bds0bNiwasd37NhR6enpNm1dunRxVLkAHIzABCpw+vRpLV26VPPmzdPs2bMlSXfccYeOHj2qefPmmQpMDw8PDRgwwNGlAmggvCULVGD37t26dOmSYmNjbdpjY2N16NAh5efnO6kyAM5CYAIVyMnJkaenp3r27GnTHhQUJEnKzc2t9jFOnz6tDh06yM3NTYGBgXr22WdV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\n",
"text/plain": [
"