├── .gitignore
├── Adaline.ipynb
├── Backpropagation.ipynb
├── Funções de Ativação.ipynb
├── LICENSE
├── Neurônio Sigmoid.ipynb
├── Perceptron.ipynb
├── Perceptron_Intuicao.ipynb
├── README.md
├── Rede Neural.ipynb
├── Rede Neural_Intuição.ipynb
├── data
├── anuncios.csv
├── medidas.csv
└── notas.csv
├── images
├── backprop_example_1.png
├── backpropagation_padroes.png
├── bias_truque.jpg
├── circuito_2.png
├── circuito_2_back.png
├── circuito_3.png
├── circuito_3_back.png
├── circuito_3_forward.png
├── classificador_linear.png
├── comparacao_camadas.jpeg
├── comparacao_perceptron_adaline.png
├── comparacao_regularizacao.jpeg
├── derivada.gif
├── funcao_de_ativacao_elu.png
├── funcao_de_ativacao_gaussian.png
├── funcao_de_ativacao_leaky_relu.png
├── funcao_de_ativacao_linear.png
├── funcao_de_ativacao_relu.png
├── funcao_de_ativacao_sigmoid.png
├── funcao_de_ativacao_tanh.png
├── funcoes_de_ativacao.png
├── hiperplanos_perceptron_adaline.png
├── lr_decay_exponential_1.png
├── lr_decay_exponential_2.png
├── lr_decay_exponential_3.png
├── lr_decay_staircase_1.png
├── lr_decay_staircase_2.png
├── lr_decay_staircase_3.png
├── lr_decay_time_based_1.png
├── lr_decay_time_based_2.png
├── lr_decay_time_based_3.png
├── nn_arquitetura.png
├── perceptron.png
├── pesos_glorot_normal.png
├── pesos_glorot_uniform.png
├── pesos_normal.png
├── pesos_ones.png
├── pesos_uniform.png
├── pesos_zeros.png
├── porta_multiplicacao.png
├── pre_processamento.png
├── pre_processamento_pca_whitening.png
└── udemy_logo.png
└── utils
├── __init__.py
├── grad_check.py
├── plot.py
└── samples_generator.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | env/
12 | build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | wheels/
24 | *.egg-info/
25 | .installed.cfg
26 | *.egg
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | nosetests.xml
45 | coverage.xml
46 | *.cover
47 | .hypothesis/
48 |
49 | # Translations
50 | *.mo
51 | *.pot
52 |
53 | # Django stuff:
54 | *.log
55 | local_settings.py
56 |
57 | # Flask stuff:
58 | instance/
59 | .webassets-cache
60 |
61 | # Scrapy stuff:
62 | .scrapy
63 |
64 | # Sphinx documentation
65 | docs/_build/
66 |
67 | # PyBuilder
68 | target/
69 |
70 | # Jupyter Notebook
71 | .ipynb_checkpoints
72 |
73 | # pyenv
74 | .python-version
75 |
76 | # celery beat schedule file
77 | celerybeat-schedule
78 |
79 | # SageMath parsed files
80 | *.sage.py
81 |
82 | # dotenv
83 | .env
84 |
85 | # virtualenv
86 | .venv
87 | venv/
88 | ENV/
89 |
90 | # Spyder project settings
91 | .spyderproject
92 | .spyproject
93 |
94 | # Rope project settings
95 | .ropeproject
96 |
97 | # mkdocs documentation
98 | /site
99 |
100 | # mypy
101 | .mypy_cache/
102 |
--------------------------------------------------------------------------------
/Adaline.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "No notebook anterior, nós aprendemos sobre o Perceptron. Vimos como ele aprende e como pode ser utilizado tanto para classificação binária quanto para regressão linear. Nesse notebook, nós veremos um algoritmo muito parecido com o Perceptron, mais conhecido como __Adaline__, que foi uma proposta de melhoria ao algoritmo original do Perceptron. Veremos as semelhanças e diferenças entre os dois algoritmos e iremos implementá-lo utilizando python e numpy. Por fim, vamos aplicar nos mesmos problemas de classificação do notebook do Perceptron para entender de fato suas diferenças. __O código para utilizar o Adaline em problemas de regressão é exatamente o mesmo do perceptron__.\n",
8 | "\n",
9 | "__Objetivos__:\n",
10 | "\n",
11 | "- Entender as diferenças entre os algoritmos do Perceptron e Adaline.\n",
12 | "- Implementar o Adaline e seu modelo de aprendizado em Python puro e Numpy\n",
13 | "- Utilizar o Adaline para classificação e regressão."
14 | ]
15 | },
16 | {
17 | "cell_type": "markdown",
18 | "metadata": {
19 | "heading_collapsed": true
20 | },
21 | "source": [
22 | "# Sumário"
23 | ]
24 | },
25 | {
26 | "cell_type": "markdown",
27 | "metadata": {
28 | "hidden": true
29 | },
30 | "source": [
31 | "[Introdução](#Introdução)\n",
32 | "\n",
33 | "[Regra de Aprendizado do Adaline](#Regra-de-Aprendizado-do-Adaline)\n",
34 | "\n",
35 | "[Classificação](#Classificação)\n",
36 | "- [Porta AND/OR](#Porta-AND/OR)\n",
37 | "- [Exercício de Classificação](#Exerc%C3%ADcio-de-Classificação)"
38 | ]
39 | },
40 | {
41 | "cell_type": "markdown",
42 | "metadata": {},
43 | "source": [
44 | "# Imports e Configurações"
45 | ]
46 | },
47 | {
48 | "cell_type": "code",
49 | "execution_count": null,
50 | "metadata": {
51 | "ExecuteTime": {
52 | "end_time": "2017-09-20T12:53:30.345746Z",
53 | "start_time": "2017-09-20T12:52:48.057739Z"
54 | }
55 | },
56 | "outputs": [],
57 | "source": [
58 | "import numpy as np\n",
59 | "import pandas as pd\n",
60 | "import matplotlib.pyplot as plt\n",
61 | "from random import random\n",
62 | "from sklearn.linear_model import LinearRegression\n",
63 | "from sklearn.preprocessing import MinMaxScaler\n",
64 | "from sklearn.datasets import make_blobs\n",
65 | "\n",
66 | "%matplotlib inline"
67 | ]
68 | },
69 | {
70 | "cell_type": "markdown",
71 | "metadata": {
72 | "heading_collapsed": true
73 | },
74 | "source": [
75 | "# Introdução"
76 | ]
77 | },
78 | {
79 | "cell_type": "markdown",
80 | "metadata": {},
81 | "source": [
82 | "Poucos meses após a publicação do teorema da convergência do Perceptron por Rosenblatt, os engenheiros da Universidade de Stanford, Bernard Widrow e Marcian Hoff, publicaram um trabalho descrevendo uma rede neural muito parecida com o Perceptron, a __Adaline__ (do inglês _ADAptive LINear Element_). Porém, ao invés de utilizar a função _step_ como função de ativação, a __Adaline utiliza função de ativação linear e tem uma nova regra de aprendizado supervisionado__, conhecida como __regra de Widrow-Hoff__ (ou __regra delta__, ou ainda __regra LMS__). \n",
83 | "\n",
84 | "De fato, tanto o Perceptron quanto o Adaline possuem muitas características semelhantes e __é comum ver o pessoal confundindo o Perceptron com o Adaline__. Entre as principais semelhanças, podemos destacar:\n",
85 | "- Ambos possuem __apenas um neurônio de N entradas e apenas uma saída. Não há camadas escondidas__.\n",
86 | "- Ambos são __classificadores lineares binários__ por definição, mas podemos adaptá-los para efetuar __regressão linear__, da mesma forma como vimos no notebook sobre o Perceptron. __Na verdade, o código para treinar um Adaline para regressão é o mesmo de um Perceptron__.\n",
87 | "- Ambos tem o **método de aprendizagem _online_**. Isto é, a atualização dos pesos é efetuada amostra por amostra.\n",
88 | "- Ambos tem uma **função _step_ para classificação**. Porém, ao contrário do Perceptron, __na Adaline ela não é utilizada na atualização dos pesos__. Nós veremos por que a seguir.\n",
89 | "\n",
90 | "Porém, a principal diferença entre o Perceptron e a Adaline é que o Perceptron utiliza os labels das classes para fazer a atualização dos pesos, enquanto __a Adaline utiliza o resultado da função de ativação (linear) como valor contínuo de predição__. Isto é, ao invés da saída ser discreta como no Perceptron (0 ou 1), __na Adaline a saída pode ser qualquer valor contínuo__. Essa diferença fica mais clara quando vemos a figura a seguir:\n",
91 | "\n",
92 | "
\n",
93 | "[Fonte](https://www.quora.com/What-is-the-difference-between-a-Perceptron-Adaline-and-neural-network-model)\n",
94 | "\n",
95 | "Repare, como dito, que ambos têm a função _step_. No Perceptron, ela é utilizada como função de ativação. No Adaline, por sua vez, a função de ativação é linear e a funcão _step_ é utilizada para gerar a predição. \n",
96 | "\n",
97 | "Por calcular a saída como um valor contínuo, __muitos consideram o Adaline mais poderoso__, uma vez que a diferença entre a saída desejada e o valor predito ($y_i - \\widehat{y}_i$) nos diz agora \"o quanto estamos certos ou errados\". __Na prática, isso faz com o que o Adaline tente encontrar a \"melhor solução\" para o problema, ao invés de somente uma \"solução adequada\"__. Tomando como exemplo a figura abaixo, o Perceptron pode encontrar diversas retas que separam as classes, enquanto o Adaline tenta encontrar a melhor reta que separa as classes.\n",
98 | "\n",
99 | "
\n",
100 | "\n",
101 | "[Fonte](http://www.barbon.com.br/wp-content/uploads/2013/08/RNA_Aula4.pdf)\n",
102 | "\n",
103 | "Ok, mas como isso muda o aprendizado? É o que veremos a seguir."
104 | ]
105 | },
106 | {
107 | "cell_type": "markdown",
108 | "metadata": {
109 | "hidden": true
110 | },
111 | "source": [
112 | "## Regra de Aprendizado do Adaline"
113 | ]
114 | },
115 | {
116 | "cell_type": "markdown",
117 | "metadata": {
118 | "hidden": true
119 | },
120 | "source": [
121 | "A atualização dos pesos do Adaline é dada pela mesma fórmula do Perceptron:\n",
122 | "\n",
123 | "$$w_i = w_i + \\lambda(y_i - \\widehat{y}_i)x_i$$\n",
124 | "\n",
125 | "Onde $\\lambda$ é a __taxa de aprendizagem__.\n",
126 | "\n",
127 | "Mas você já imaginou da onde vem essa fórmula? Em primeiro lugar, o método de atualização dos pesos é baseado na __Regra Delta__ (*Delta Rule*). Sendo $\\overrightarrow{w} = \\{w_1, w_2, ..., w_D\\}$, a atualização dos pesos é dada por:\n",
128 | "\n",
129 | "$$\\overrightarrow{w} = \\overrightarrow{w} - \\Delta{\\overrightarrow{w}}$$\n",
130 | "\n",
131 | "em que:\n",
132 | "\n",
133 | "$$\\Delta{\\overrightarrow{w}} = \\lambda\\nabla E(\\overrightarrow{w})$$\n",
134 | "\n",
135 | "Sendo $\\nabla E(\\overrightarrow{w})$ o gradiente de uma função que depende de $\\overrightarrow{w}$ e que queremos minimizar.\n",
136 | "\n",
137 | "No caso do Adaline, __a função de custo é dada pela soma dos erros quadrados__:\n",
138 | "\n",
139 | "$$J(w) = \\frac{1}{2}\\sum_{i}^N (y_i - \\widehat{y}_i)^2$$\n",
140 | "\n",
141 | "Onde $N$ é a quantidade de amostras nos dados, e as demais variáveis representam as mesmas vistas anteriormente. Repare que a função de custo é quase uma _Mean Squared Error (MSE)_, só que ao invés de dividir por $N$, estamos dividindo por 2 o resultado do somatório. O por quê disso será entendido mais a frente na demonstração.\n",
142 | "\n",
143 | "Queremos encontrar, então, o vetor $\\overrightarrow{w}$ que minimiza a função $J$. Assim, temos:\n",
144 | "\n",
145 | "$$\\frac{\\partial J}{\\partial w_i} = \\frac{\\partial}{\\partial w_i}\\frac{1}{2}\\sum_i^N (y_i - \\widehat{y}_i)^2$$\n",
146 | "\n",
147 | "Como a derivada do somatório é igual ao somatório das derivadas:\n",
148 | "\n",
149 | "$$= \\frac{1}{2}\\sum_i^N \\frac{\\partial}{\\partial w_i}(y_i - \\widehat{y}_i)^2$$\n",
150 | "\n",
151 | "Aplicando a regra da cadeia:\n",
152 | "\n",
153 | "$$= \\sum_i^N (y_i - \\widehat{y}_i)\\frac{\\partial}{\\partial w_i}(y_i - \\widehat{y}_i)$$\n",
154 | "\n",
155 | "Repare que, quando derivamos $(y_i - \\widehat{y}_i)^2$, o expoente 2, ao sair do somatório, foi multiplicado por $\\frac{1}{2}$, tornando-o 1. Isso é o que os matemáticos denominam de \"conveniência matemática\". \n",
156 | "\n",
157 | "Como $\\widehat{y}_i = x_iw_i + b$ é uma função que depende de $w$, e sua derivada em relação a $w_i$ é apenas $x_i$, temos que:\n",
158 | "\n",
159 | "$$\\frac{\\partial J}{\\partial w_i} = \\sum_i^N (y_i - \\widehat{y}_i)(-x_i)$$\n",
160 | "$$\\frac{\\partial J}{\\partial w_i} = -\\sum_i^N (y_i - \\widehat{y}_i)x_i$$\n",
161 | "\n",
162 | "$$\\frac{\\partial J}{\\partial \\overrightarrow{w}} = -(\\overrightarrow{y} - \\overrightarrow{\\widehat{y}_i})\\overrightarrow{x}$$\n",
163 | "\n",
164 | "De maneira análoga, podemos calcular que a derivada de $J$ em relação a $b_i$ é:\n",
165 | "\n",
166 | "$$\\frac{\\partial J}{\\partial b_i} = -\\sum_i^N (y_i - \\widehat{y}_i)*1.0$$\n",
167 | "\n",
168 | "Já que a derivada de $\\widehat{y}_i$ em relação a $b_i$ ($\\frac{\\partial J}{\\partial b_i}$) é igual a 1.0. Logo, a atualização dos bias será dada por:\n",
169 | "\n",
170 | "$$b_i = b_i + \\lambda(y_i - \\widehat{y}_i)$$"
171 | ]
172 | },
173 | {
174 | "cell_type": "markdown",
175 | "metadata": {},
176 | "source": [
177 | "# Regressão"
178 | ]
179 | },
180 | {
181 | "cell_type": "code",
182 | "execution_count": null,
183 | "metadata": {},
184 | "outputs": [],
185 | "source": [
186 | "df = pd.read_csv('data/notas.csv')\n",
187 | "\n",
188 | "print(df.shape)\n",
189 | "df.head(10)"
190 | ]
191 | },
192 | {
193 | "cell_type": "code",
194 | "execution_count": null,
195 | "metadata": {},
196 | "outputs": [],
197 | "source": [
198 | "x = df[['prova1', 'prova2', 'prova3']].values\n",
199 | "y = df['final'].values.reshape(-1, 1)\n",
200 | "\n",
201 | "print(x.shape, y.shape)"
202 | ]
203 | },
204 | {
205 | "cell_type": "code",
206 | "execution_count": null,
207 | "metadata": {},
208 | "outputs": [],
209 | "source": [
210 | "minmax = MinMaxScaler(feature_range=(-1,1))\n",
211 | "x = minmax.fit_transform(x.astype(np.float64))"
212 | ]
213 | },
214 | {
215 | "cell_type": "code",
216 | "execution_count": null,
217 | "metadata": {},
218 | "outputs": [],
219 | "source": [
220 | "D = x.shape[1]\n",
221 | "w = [2*random() - 1 for i in range(D)]\n",
222 | "b = 2*random() - 1\n",
223 | "\n",
224 | "learning_rate = 1e-2\n",
225 | "\n",
226 | "for step in range(2001):\n",
227 | " cost = 0\n",
228 | " for x_n, y_n in zip(x, y):\n",
229 | " y_pred = sum([x_i*w_i for x_i, w_i in zip(x_n, w)]) + b\n",
230 | " error = y_n - y_pred\n",
231 | " w = [w_i + learning_rate*error*x_i for x_i, w_i in zip(x_n, w)]\n",
232 | " b = b + learning_rate*error\n",
233 | " cost += error**2\n",
234 | " \n",
235 | " if step%200 == 0:\n",
236 | " print('step {0}: {1}'.format(step, cost))\n",
237 | "\n",
238 | "print('w: ', w)\n",
239 | "print('b: ', b)"
240 | ]
241 | },
242 | {
243 | "cell_type": "markdown",
244 | "metadata": {},
245 | "source": [
246 | "# Classificação"
247 | ]
248 | },
249 | {
250 | "cell_type": "markdown",
251 | "metadata": {},
252 | "source": [
253 | "## Porta AND/OR"
254 | ]
255 | },
256 | {
257 | "cell_type": "code",
258 | "execution_count": null,
259 | "metadata": {
260 | "ExecuteTime": {
261 | "end_time": "2017-09-15T11:11:37.370366Z",
262 | "start_time": "2017-09-15T11:11:37.359356Z"
263 | }
264 | },
265 | "outputs": [],
266 | "source": [
267 | "x = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])\n",
268 | "# y = np.array([[0, 1, 1, 1]]).T # porta OR\n",
269 | "y = np.array([0, 0, 0, 1]).T # porta AND\n",
270 | "\n",
271 | "print(x.shape, y.shape)"
272 | ]
273 | },
274 | {
275 | "cell_type": "markdown",
276 | "metadata": {
277 | "heading_collapsed": true
278 | },
279 | "source": [
280 | "### Python"
281 | ]
282 | },
283 | {
284 | "cell_type": "code",
285 | "execution_count": null,
286 | "metadata": {
287 | "ExecuteTime": {
288 | "end_time": "2017-09-15T11:21:18.798586Z",
289 | "start_time": "2017-09-15T11:21:18.667487Z"
290 | },
291 | "hidden": true
292 | },
293 | "outputs": [],
294 | "source": [
295 | "D = x.shape[1]\n",
296 | "w = [2*random() - 1 for i in range(D)]\n",
297 | "b = 2*random() - 1\n",
298 | "\n",
299 | "learning_rate = 1.0 # <- tente estimar a learning_rate\n",
300 | "\n",
301 | "for step in range(101):\n",
302 | " cost = 0\n",
303 | " for x_n, y_n in zip(x, y):\n",
304 | " # qual linha devemos remover para transformar o Perceptron num Adaline?\n",
305 | " y_pred = sum([x_i*w_i for x_i, w_i in zip(x_n, w)]) + b\n",
306 | " y_pred = 1 if y_pred > 0 else 0\n",
307 | " error = y_n - y_pred\n",
308 | " w = [w_i + learning_rate*error*x_i for x_i, w_i in zip(x_n, w)]\n",
309 | " b = b + learning_rate*error\n",
310 | " cost += error**2\n",
311 | " \n",
312 | " if step%10 == 0:\n",
313 | " print('step {0}: {1}'.format(step, cost))\n",
314 | "\n",
315 | "print('w: ', w)\n",
316 | "print('b: ', b)"
317 | ]
318 | },
319 | {
320 | "cell_type": "markdown",
321 | "metadata": {
322 | "heading_collapsed": true
323 | },
324 | "source": [
325 | "### Numpy"
326 | ]
327 | },
328 | {
329 | "cell_type": "code",
330 | "execution_count": null,
331 | "metadata": {
332 | "ExecuteTime": {
333 | "end_time": "2017-09-15T12:21:02.603975Z",
334 | "start_time": "2017-09-15T12:21:02.555936Z"
335 | },
336 | "hidden": true
337 | },
338 | "outputs": [],
339 | "source": [
340 | "D = x.shape[1]\n",
341 | "w = 2*np.random.random(size=D)-1\n",
342 | "b = 2*np.random.random()-1 \n",
343 | "\n",
344 | "learning_rate = 1.0 # <- use a mesma learning rate do python\n",
345 | "\n",
346 | "for step in range(101):\n",
347 | " cost = 0\n",
348 | " for x_n, y_n in zip(x, y):\n",
349 | " # qual linha devemos remover para transformar o Perceptron num Adaline?\n",
350 | " y_pred = np.dot(x_n, w) + b \n",
351 | " y_pred = np.where(y_pred > 0, 1, 0)\n",
352 | " error = y_n - y_pred\n",
353 | " w = w + learning_rate*np.dot(error, x_n)\n",
354 | " b = b + learning_rate*error\n",
355 | " cost += error**2\n",
356 | " \n",
357 | " if step%10 == 0:\n",
358 | " print('step {0}: {1}'.format(step, cost))\n",
359 | " \n",
360 | "print('w: ', w)\n",
361 | "print('b: ', b)\n",
362 | "print('y_pred: {0}'.format(np.dot(x, w)+b))"
363 | ]
364 | },
365 | {
366 | "cell_type": "markdown",
367 | "metadata": {
368 | "collapsed": true
369 | },
370 | "source": [
371 | "## Exercício de Classificação"
372 | ]
373 | },
374 | {
375 | "cell_type": "code",
376 | "execution_count": null,
377 | "metadata": {},
378 | "outputs": [],
379 | "source": [
380 | "x, y = make_blobs(n_samples=100, n_features=2, centers=2, random_state=1234)\n",
381 | "\n",
382 | "print(x.shape, y.shape)\n",
383 | "plt.scatter(x[:,0], x[:,1], c=y.ravel(), cmap='bwr')"
384 | ]
385 | },
386 | {
387 | "cell_type": "code",
388 | "execution_count": null,
389 | "metadata": {},
390 | "outputs": [],
391 | "source": [
392 | "def plot_linear_classifier(x, y, w, b):\n",
393 | " x1_min, x1_max = x[:,0].min(), x[:,0].max()\n",
394 | " x2_min, x2_max = x[:,1].min(), x[:,1].max()\n",
395 | "\n",
396 | " x1, x2 = np.meshgrid(np.linspace(x1_min-1, x1_max+1,100), np.linspace(x2_min-1, x2_max+1, 100))\n",
397 | " x_mesh = np.array([x1.ravel(), x2.ravel()]).T\n",
398 | "\n",
399 | " plt.scatter(x[:,0], x[:,1], c=y.ravel(), cmap='bwr')\n",
400 | "\n",
401 | " y_mesh = np.dot(x_mesh, np.array(w).reshape(1, -1).T) + b\n",
402 | " y_mesh = np.where(y_mesh < 0.5, 0, 1)\n",
403 | "\n",
404 | " plt.contourf(x1, x2, y_mesh.reshape(x1.shape), cmap='bwr', alpha=0.5)\n",
405 | " plt.xlim(x1_min-1, x1_max+1)\n",
406 | " plt.ylim(x2_min-1, x2_max+1)"
407 | ]
408 | },
409 | {
410 | "cell_type": "markdown",
411 | "metadata": {},
412 | "source": [
413 | "### Python"
414 | ]
415 | },
416 | {
417 | "cell_type": "code",
418 | "execution_count": null,
419 | "metadata": {
420 | "scrolled": false
421 | },
422 | "outputs": [],
423 | "source": [
424 | "D = x.shape[1]\n",
425 | "w = [2*random() - 1 for i in range(D)]\n",
426 | "b = 2*random() - 1\n",
427 | "\n",
428 | "learning_rate = 1.0 # <- tente estimar a learning_rate\n",
429 | "\n",
430 | "for step in range(1): # <- tente estimar a #epochs\n",
431 | " cost = 0\n",
432 | " for x_n, y_n in zip(x, y):\n",
433 | " y_pred = sum([x_i*w_i for x_i, w_i in zip(x_n, w)]) + b\n",
434 | " error = y_n - y_pred\n",
435 | " w = [w_i + learning_rate*error*x_i for x_i, w_i in zip(x_n, w)]\n",
436 | " b = b + learning_rate*error\n",
437 | " cost += error**2\n",
438 | " \n",
439 | " if step%100 == 0:\n",
440 | " print('step {0}: {1}'.format(step, cost))\n",
441 | "\n",
442 | "print('w: ', w)\n",
443 | "print('b: ', b)\n",
444 | "\n",
445 | "plot_linear_classifier(x, y, w, b)"
446 | ]
447 | },
448 | {
449 | "cell_type": "markdown",
450 | "metadata": {},
451 | "source": [
452 | "### Numpy"
453 | ]
454 | },
455 | {
456 | "cell_type": "code",
457 | "execution_count": null,
458 | "metadata": {},
459 | "outputs": [],
460 | "source": [
461 | "D = x.shape[1]\n",
462 | "w = 2*np.random.random(size=D)-1\n",
463 | "b = 2*np.random.random()-1 \n",
464 | "\n",
465 | "learning_rate = 1.0 # <- use a mesma learning rate do python\n",
466 | "\n",
467 | "for step in range(1): # <- use a mesma #epochs do python\n",
468 | " cost = 0\n",
469 | " for x_n, y_n in zip(x, y):\n",
470 | " y_pred = np.dot(x_n, w) + b \n",
471 | " error = y_n - y_pred\n",
472 | " w = w + learning_rate*np.dot(error, x_n)\n",
473 | " b = b + learning_rate*error\n",
474 | " cost += error**2\n",
475 | " \n",
476 | " if step%100 == 0:\n",
477 | " print('step {0}: {1}'.format(step, cost))\n",
478 | " \n",
479 | "print('w: ', w)\n",
480 | "print('b: ', b)\n",
481 | "\n",
482 | "plot_linear_classifier(x, y, w, b)"
483 | ]
484 | },
485 | {
486 | "cell_type": "markdown",
487 | "metadata": {
488 | "collapsed": true
489 | },
490 | "source": [
491 | "# Referências"
492 | ]
493 | },
494 | {
495 | "cell_type": "markdown",
496 | "metadata": {},
497 | "source": [
498 | "- [http://sisne.org/Disciplinas/PosGrad/PsicoConex/aula6.pdf](http://sisne.org/Disciplinas/PosGrad/PsicoConex/aula6.pdf)\n",
499 | "- [What is the difference between a Perceptron, Adaline, and neural network model?](https://www.quora.com/What-is-the-difference-between-a-Perceptron-Adaline-and-neural-network-model)\n",
500 | "- [RNA – Adaline e Regra do Delta](http://www.barbon.com.br/wp-content/uploads/2013/08/RNA_Aula4.pdf)"
501 | ]
502 | }
503 | ],
504 | "metadata": {
505 | "kernelspec": {
506 | "display_name": "Python 3 (ipykernel)",
507 | "language": "python",
508 | "name": "python3"
509 | },
510 | "language_info": {
511 | "codemirror_mode": {
512 | "name": "ipython",
513 | "version": 3
514 | },
515 | "file_extension": ".py",
516 | "mimetype": "text/x-python",
517 | "name": "python",
518 | "nbconvert_exporter": "python",
519 | "pygments_lexer": "ipython3",
520 | "version": "3.11.3"
521 | }
522 | },
523 | "nbformat": 4,
524 | "nbformat_minor": 2
525 | }
526 |
--------------------------------------------------------------------------------
/Backpropagation.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "__Objetivos__: \n",
8 | "\n",
9 | "- entender os conceitos de derivada e gradiente\n",
10 | "- entender a diferença entre gradiente analítico e numérico\n",
11 | "- aprender a calcular a backpropagação de qualquer rede neural."
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "metadata": {},
17 | "source": [
18 | "# Sumário"
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {},
24 | "source": [
25 | "[0. Imports and Configurações](#0.-Imports-and-Configurações)\n",
26 | "\n",
27 | "[1. Introdução](#1.-Introdução)\n",
28 | "- [O Objetivo](#O-Objetivo)\n",
29 | "- [Estratégia 1: Busca Aleatória](#Estratégia-1:-Busca-Aleatória)\n",
30 | "- [Estratégia 2: Busca Aleatória Local](#Estratégia-2:-Busca-Aleatória-Local)\n",
31 | "- [Estratégia 3: Gradiente Numérico](#Estratégia-3:-Gradiente-Numérico)\n",
32 | "- [Estratégia 4: Gradiente Analítico](#Estratégia-4:-Gradiente-Anal%C3%ADtico)\n",
33 | "- [Caso Recursivo: Múltiplas Portas](#Caso-Recursivo:-Múltiplas-Portas)\n",
34 | "- [Checagem do gradiente numérico](#Checagem-do-gradiente-numérico)\n",
35 | "- [Neurônio Sigmóide](#Neurônio-Sigmóide)\n",
36 | "\n",
37 | "[2. Backpropagation](#2.-Backpropagation)\n",
38 | "- [Se tornando um Ninja em Backpropagation!](#Se-tornando-um-Ninja-em-Backpropagation!)\n",
39 | "- [Resumo dos Padrões na Backpropagation](#Resumo-dos-Padrões-na-Backpropagation)\n",
40 | "- [Exemplo 1](#Exemplo-1)\n",
41 | "- [Exemplo 2](#Exemplo-2)"
42 | ]
43 | },
44 | {
45 | "cell_type": "markdown",
46 | "metadata": {},
47 | "source": [
48 | "# 0. Imports and Configurações"
49 | ]
50 | },
51 | {
52 | "cell_type": "code",
53 | "execution_count": null,
54 | "metadata": {
55 | "ExecuteTime": {
56 | "end_time": "2017-09-12T19:39:25.803460Z",
57 | "start_time": "2017-09-12T19:39:18.946627Z"
58 | }
59 | },
60 | "outputs": [],
61 | "source": [
62 | "import numpy as np\n",
63 | "import matplotlib.pyplot as plt\n",
64 | "\n",
65 | "%matplotlib inline"
66 | ]
67 | },
68 | {
69 | "cell_type": "markdown",
70 | "metadata": {},
71 | "source": [
72 | "# 1. Introdução"
73 | ]
74 | },
75 | {
76 | "cell_type": "markdown",
77 | "metadata": {},
78 | "source": [
79 | "A melhor maneira de pensar em redes neurais é como circuitos de valores reais. Mas, ao invés de valores booleanos, valores reais e, ao invés de portas lógicas como **and** ou **or**, portas binárias (dois operandos) como $*$ (multiplicação), + (adição), max, exp, etc. Além disso, também teremos **gradientes** fluindo pelo circuito, mas na direção oposta.\n",
80 | "\n",
81 | "
"
82 | ]
83 | },
84 | {
85 | "cell_type": "code",
86 | "execution_count": null,
87 | "metadata": {
88 | "ExecuteTime": {
89 | "end_time": "2017-09-12T19:39:25.821474Z",
90 | "start_time": "2017-09-12T19:39:25.807463Z"
91 | }
92 | },
93 | "outputs": [],
94 | "source": []
95 | },
96 | {
97 | "cell_type": "markdown",
98 | "metadata": {},
99 | "source": [
100 | "De forma matemática, a gente pode considerar que essa porta implementa a seguinte função:\n",
101 | "\n",
102 | "$$f(x,y)=x*y$$"
103 | ]
104 | },
105 | {
106 | "cell_type": "markdown",
107 | "metadata": {},
108 | "source": [
109 | "## O Objetivo"
110 | ]
111 | },
112 | {
113 | "cell_type": "markdown",
114 | "metadata": {},
115 | "source": [
116 | "Vamos imaginar que temos o seguinte problema:\n",
117 | "1. Nós vamos providenciar a um circuito valores específicos como entrada (x=-2, y=3)\n",
118 | "2. O circuito vai calcular o valor de saída (-6)\n",
119 | "3. A questão é: *Quanto mudar a entrada para levemente **aumentar** a saída?*\n",
120 | "\n",
121 | "No nosso caso, em que direção devemos mudar x,y para conseguir um número maior que -6? Note que, pro nosso exemplo, se x = -1.99 e y = 2.99, x$*$y = -5.95 que é maior que -6. **-5.95 é melhor (maior) que 6**, e obtivemos uma melhora de 0.05."
122 | ]
123 | },
124 | {
125 | "cell_type": "markdown",
126 | "metadata": {},
127 | "source": [
128 | "## Estratégia 1: Busca Aleatória"
129 | ]
130 | },
131 | {
132 | "cell_type": "markdown",
133 | "metadata": {},
134 | "source": [
135 | "Ok. Isso não é trivial? A gente pode simplesmente gerar valores aleatórios, calcular a saída e guardar o melhor resultado."
136 | ]
137 | },
138 | {
139 | "cell_type": "code",
140 | "execution_count": null,
141 | "metadata": {
142 | "ExecuteTime": {
143 | "end_time": "2017-09-12T19:39:25.998751Z",
144 | "start_time": "2017-09-12T19:39:25.827478Z"
145 | }
146 | },
147 | "outputs": [],
148 | "source": [
149 | "x, y = -2, 3\n",
150 | "melhor_saida = forwardMultiplyGate(x,y)\n",
151 | "melhor_x, melhor_y = 0, 0\n",
152 | "\n",
153 | "for k in range(0,100):\n",
154 | " x_try = 5*np.random.random() - 5\n",
155 | " y_try = 5*np.random.random() - 5\n",
156 | " out = forwardMultiplyGate(x_try, y_try)\n",
157 | " \n",
158 | " if out > melhor_saida:\n",
159 | " melhor_saida = out\n",
160 | " melhor_x, melhor_y = x_try, y_try\n",
161 | "\n",
162 | "print(melhor_x, melhor_y, forwardMultiplyGate(melhor_x, melhor_y))"
163 | ]
164 | },
165 | {
166 | "cell_type": "markdown",
167 | "metadata": {},
168 | "source": [
169 | "Ok, foi bem melhor. Mas, e se tivermos milhões de entradas? É claro que essa estratégia não funcionará. Vamos tentar algo mais aprimorado."
170 | ]
171 | },
172 | {
173 | "cell_type": "markdown",
174 | "metadata": {},
175 | "source": [
176 | "## Estratégia 2: Busca Aleatória Local"
177 | ]
178 | },
179 | {
180 | "cell_type": "code",
181 | "execution_count": null,
182 | "metadata": {
183 | "ExecuteTime": {
184 | "end_time": "2017-09-12T19:39:26.158036Z",
185 | "start_time": "2017-09-12T19:39:26.003755Z"
186 | }
187 | },
188 | "outputs": [],
189 | "source": [
190 | "x, y = -2, 3\n",
191 | "passo = 0.01\n",
192 | "melhor_saida = forwardMultiplyGate(x,y)\n",
193 | "melhor_x, melhor_y = 0, 0\n",
194 | "\n",
195 | "for k in range(0,100):\n",
196 | " x_try = x + passo * (2*np.random.random() - 1)\n",
197 | " y_try = y + passo * (2*np.random.random() - 1) \n",
198 | " out = forwardMultiplyGate(x_try, y_try)\n",
199 | " \n",
200 | " if out > melhor_saida:\n",
201 | " melhor_saida = out\n",
202 | " melhor_x, melhor_y = x_try, y_try\n",
203 | "\n",
204 | "print(melhor_x, melhor_y, forwardMultiplyGate(melhor_x, melhor_y))"
205 | ]
206 | },
207 | {
208 | "cell_type": "markdown",
209 | "metadata": {
210 | "collapsed": true
211 | },
212 | "source": [
213 | "## Estratégia 3: Gradiente Numérico"
214 | ]
215 | },
216 | {
217 | "cell_type": "markdown",
218 | "metadata": {},
219 | "source": [
220 | "Imagine agora que a gente pega as entradas de um circuito e puxa-as para uma direção positiva. Essa força puxando $x$ e $y$ vai nos dizer como $x$ e $y$ devem mudar para aumentar a saída. Não entendeu? Vamos explicar:\n",
221 | "\n",
222 | "Se olharmos para as entradas, a gente pode intuitivamente ver que a força em $x$ deveria sempre ser positiva, porque tornando $x$ um pouquinho maior de $x=-2$ para $x=-1$ aumenta a saída do circuito para $-3$, o que é bem maior que $-6$. Por outro lado, se a força em $y$ for negativa, tornando-o menor, como de $y=3$ para $y=2$, também aumenta a saída: $-2\\times2 = -4$, de novo maior que $-6$.\n",
223 | "\n",
224 | "E como calcular essa força? Usando **derivadas**.\n",
225 | "\n",
226 | "> *A derivada pode ser pensada como a força que a gente aplica em cada entrada para aumentar a saída*\n",
227 | "\n",
228 | "
\n",
229 | "\n",
230 | "E como exatamente a gente vai fazer isso? Em vez de olhar para o valor de saída, como fizemos anteriormente, nós vamos iterar sobre as cada entrada individualmente, aumentando-as bem devagar e vendo o que acontece com a saída. **A quantidade que a saída muda é a resposta da derivada**.\n",
231 | "\n",
232 | "Vamos para definição matemática. A derivada em relação a $x$ pode ser definida como:\n",
233 | "\n",
234 | "$$\\frac{\\partial f(x,y)}{\\partial x} = \\frac{f(x+h,y) - f(x,y)}{h}$$\n",
235 | "\n",
236 | "Onde $h$ é pequeno. Nós vamos, então, calcular a saída inicial $f(x,y)$ e aumentar $x$ por um valor pequeno $h$ e calcular a nova saída $f(x+h,y)$. Então, nós subtraimos esse valores para ver a diferença e dividimos por $f(x+h,y)$ para normalizar essa mudança pelo valor (arbitrário) que nós usamos.\n",
237 | "\n",
238 | "Em termos de código, teremos:"
239 | ]
240 | },
241 | {
242 | "cell_type": "code",
243 | "execution_count": null,
244 | "metadata": {
245 | "ExecuteTime": {
246 | "end_time": "2017-09-12T19:39:26.300444Z",
247 | "start_time": "2017-09-12T19:39:26.165041Z"
248 | }
249 | },
250 | "outputs": [],
251 | "source": [
252 | "x, y = -2, 3\n",
253 | "out = forwardMultiplyGate(x,y)\n",
254 | "h = 0.0001\n",
255 | "\n",
256 | "# derivada em relação a x\n",
257 | "\n",
258 | "\n",
259 | "# derivada em relação a y\n"
260 | ]
261 | },
262 | {
263 | "cell_type": "markdown",
264 | "metadata": {},
265 | "source": [
266 | "Como a gente pode ver, a derivada em relação a $x$ é igual a $+3$. O sinal positivo indica que alterando o valor de $x$ pelo passo $h$, a saída se torna maior. O valor $3$ pode ser considerado como o valor da força que puxa $x$. O inverso acontece com $y$.\n",
267 | "\n",
268 | "> *A derivada em relação a alguma entrada pode ser calculada ajustando levemente aquela entrada e observando a mudança no valor da saída*\n",
269 | "\n",
270 | "A derivada é calculada sobre cada entrada, enquanto o **gradiente** representa todas as derivadas sobre as entradas concatenadas em um vetor."
271 | ]
272 | },
273 | {
274 | "cell_type": "code",
275 | "execution_count": null,
276 | "metadata": {
277 | "ExecuteTime": {
278 | "end_time": "2017-09-12T19:39:26.440557Z",
279 | "start_time": "2017-09-12T19:39:26.304947Z"
280 | }
281 | },
282 | "outputs": [],
283 | "source": []
284 | },
285 | {
286 | "cell_type": "markdown",
287 | "metadata": {},
288 | "source": [
289 | "Como a gente pode perceber $-5.87 > -6$. Apenas 3 avaliações foram necessárias para aumentar o valor da saída (ao invés de centenas) e conseguimos um melhor resultado.\n",
290 | "\n",
291 | "**Passo maior nem sempre é melhor**: É importante destacar que qualquer valor de passo maior que 0.01 ia sempre funcionar melhor (por exemplo, passo = 1 gera a saída = 1). No entanto, à medida que os circuitos vão ficando mais complexos (como em redes neurais completas), a função vai ser tornando mais caótica e complexa. O gradiente garante que se você tem um passo muito pequeno (o ideal seria infinitesimal), então você definitivamente aumenta a saída seguindo aquela direção. O passo que estamos utilizando (0.01) ainda é muito grande, mas como nosso circuito é simples, podemos esperar pelo melhor resultado. Lembre-se da analogia do **escalador cego**."
292 | ]
293 | },
294 | {
295 | "cell_type": "markdown",
296 | "metadata": {},
297 | "source": [
298 | "## Estratégia 4: Gradiente Analítico"
299 | ]
300 | },
301 | {
302 | "cell_type": "markdown",
303 | "metadata": {},
304 | "source": [
305 | "A estratégia que utilizamos até agora de ajustar levemente a entrada e ver o que acontece com a saída pode não ser muito cômoda na prática quando temos milhares de entradas para ajustar. Então, a gente precisa de algo melhor.\n",
306 | "\n",
307 | "Felizmente, existe uma estratégia mais fácil e muito mais rápida para calcular o gradiente: podemos usar cálculo para derivar diretamente a nossa função. Chamamos isso de **gradiente analítico** e dessa forma não precisamos ajustar levemente nada. \n",
308 | "\n",
309 | "> *O gradiente analítico evita o leve ajustamento das entradas. O circuito pode ser derivado usando cálculo.*\n",
310 | "\n",
311 | "É muito fácil calcular derivadas parciais para funções simples como $x*y$. Se você não lembra da definição, aqui está o cálculo da derivada parcial em relação a $x$ da nossa função $f(x,y)$:\n",
312 | "\n",
313 | "$$\\frac{\\partial f(x,y)}{\\partial x} = \\frac{f(x+h,y) - f(x,y)}{h}\n",
314 | "= \\frac{(x+h)y - xy}{h}\n",
315 | "= \\frac{xy + hy - xy}{h}\n",
316 | "= \\frac{hy}{h}\n",
317 | "= y$$\n",
318 | "\n",
319 | "A derivada parcial em relação em $x$ da nossa $f(x,y)$ é igual $y$. Você reparou na coincidência de $\\partial x = 3.0$, que é exatamente o valor de $y$? E que o mesmo aconteceu para $x$? **Então, a gente não precisa ajustar nada!** E nosso código fica assim:"
320 | ]
321 | },
322 | {
323 | "cell_type": "code",
324 | "execution_count": null,
325 | "metadata": {
326 | "ExecuteTime": {
327 | "end_time": "2017-09-12T19:39:26.571650Z",
328 | "start_time": "2017-09-12T19:39:26.444559Z"
329 | }
330 | },
331 | "outputs": [],
332 | "source": [
333 | "x, y = -2, 3\n",
334 | "out = forwardMultiplyGate(x,y)\n",
335 | "\n",
336 | "# insira seu código aqui!"
337 | ]
338 | },
339 | {
340 | "cell_type": "markdown",
341 | "metadata": {},
342 | "source": [
343 | "É importante destacar que a Estratégia #3 reduziu a #2 para uma única vez. Porém, a #3 nos dá somente uma aproximação do gradiente, enquanto a Estratégia #4 nos dá o valor exato. Sem aproximações. O único lado negativo é que temos de saber derivar a nossa funcão.\n",
344 | "\n",
345 | "Recapitulando o que vimos até aqui:\n",
346 | "- __Estratégia 1__: definimos valores aleatórios em todas as iterações. Não funciona para muitas entradas.\n",
347 | "- __Estratégia 2__: pequenos ajustes aleatórios nas entradas e vemos qual funciona melhor. Tão ruim quando a #1.\n",
348 | "- __Estratégia 3__: muito melhor através do cálculo do gradiente. Independentemente de quão complicado é o circuito, o **gradiente numérico** é muito simples de se calcular (mas um pouco caro).\n",
349 | "- __Estratégia 4__: no final, vimos que a forma melhor, mais inteligente e mais rápida é calcular o **gradiente analítico**. O resultado é idêntico ao gradiente numérico, porém mais rápido e não precisa de ajustes."
350 | ]
351 | },
352 | {
353 | "cell_type": "markdown",
354 | "metadata": {},
355 | "source": [
356 | "## Caso Recursivo: Múltiplas Portas"
357 | ]
358 | },
359 | {
360 | "cell_type": "markdown",
361 | "metadata": {},
362 | "source": [
363 | "Calcular o gradiente para o nosso circuito foi trivial. Mas, e em circuitos mais complexos? Como a gente vai ver agora, cada porta pode ser tratada individualmente e a gente pode calcular derivadas locais como a gente fez anteriormente. Vamos considerar nossa função agora como a seguinte:\n",
364 | "\n",
365 | "$$f(x,y,z) = (x+y)*z$$\n",
366 | "\n",
367 | "
\n",
368 | "\n"
369 | ]
370 | },
371 | {
372 | "cell_type": "code",
373 | "execution_count": null,
374 | "metadata": {
375 | "ExecuteTime": {
376 | "end_time": "2017-09-12T19:39:26.747159Z",
377 | "start_time": "2017-09-12T19:39:26.575653Z"
378 | }
379 | },
380 | "outputs": [],
381 | "source": []
382 | },
383 | {
384 | "cell_type": "markdown",
385 | "metadata": {},
386 | "source": [
387 | "Como vamos calcular agora a nossa derivada? Primeiramente, vamos esquecer da porta de soma e fingir que temos apenas duas entradas no nosso circuito: **q** e **z**. Como já vimos, as nossas derivadas parciais podem ser definidas da seguinte maneira:\n",
388 | "\n",
389 | "$$f(q,z) = q z \\hspace{0.5in} \\implies \\hspace{0.5in} \\frac{\\partial f(q,z)}{\\partial q} = z, \\hspace{1in} \\frac{\\partial f(q,z)}{\\partial z} = q$$\n",
390 | "\n",
391 | "Ok, mas e em relação a $x$ e $y$? Como $q$ é calculado em função de $x$ e $y$ (pela adição em nosso exemplo), nós também podemos calcular suas derivadas parciais:\n",
392 | "\n",
393 | "$$q(x,y) = x + y \\hspace{0.5in} \\implies \\hspace{0.5in} \\frac{\\partial q(x,y)}{\\partial x} = 1, \\hspace{1in} \\frac{\\partial q(x,y)}{\\partial y} = 1$$\n",
394 | "\n",
395 | "Correto! As derivadas parciais são 1, independentemente dos valores de $x$ e $y$. Isso faz sentido se pensarmos que para aumentar A saída de uma porta de adição, a gente espera uma força positiva tanto em $x$ quanto em $y$, independente dos seus valores.\n",
396 | "\n",
397 | "Com as fórmulas acima, nós sabemos calcular o gradiente da saída em relação a $q$ e $z$, e o gradiente de $q$ em relação a $x$ e $y$. Para calcular o gradiente do nosso circuito em relação a $x$, $y$ e $z$, nós vamos utilizar a **Regra da Cadeia**, que vai nos dizer como combinar esses gradientes. A derivada final em relação a $x$, será dada por:\n",
398 | "\n",
399 | "$$\\frac{\\partial f(q,z)}{\\partial x} = \\frac{\\partial q(x,y)}{\\partial x} \\frac{\\partial f(q,z)}{\\partial q}$$\n",
400 | "\n",
401 | "Pode parecer complicado à primeira vista, mas a verdade é que isso vai ser simplificado a somente duas multiplicações:"
402 | ]
403 | },
404 | {
405 | "cell_type": "code",
406 | "execution_count": null,
407 | "metadata": {
408 | "ExecuteTime": {
409 | "end_time": "2017-09-12T19:39:26.889072Z",
410 | "start_time": "2017-09-12T19:39:26.753160Z"
411 | }
412 | },
413 | "outputs": [],
414 | "source": [
415 | "\n",
416 | "\n",
417 | "# Derivada da porta de multiplicação\n",
418 | " \n",
419 | "\n",
420 | "# Derivada da porta de adição\n",
421 | "\n",
422 | "\n",
423 | "# Regra da cadeia\n",
424 | "\n"
425 | ]
426 | },
427 | {
428 | "cell_type": "markdown",
429 | "metadata": {},
430 | "source": [
431 | "
\n",
432 | "\n",
433 | "É isso! Vamos agora fazer nossas entradas responderem ao gradiente. Lembrando que queremos um valor maior que -12."
434 | ]
435 | },
436 | {
437 | "cell_type": "code",
438 | "execution_count": null,
439 | "metadata": {
440 | "ExecuteTime": {
441 | "end_time": "2017-09-12T19:39:27.023174Z",
442 | "start_time": "2017-09-12T19:39:26.893080Z"
443 | }
444 | },
445 | "outputs": [],
446 | "source": []
447 | },
448 | {
449 | "cell_type": "markdown",
450 | "metadata": {},
451 | "source": [
452 | "Vamos agora analisar os resultados separadamente. Analisando primeiramente $q$ e $z$, vemos que o circuito quer que $z$ aumente (der_f_rel_z = +3) e o valor de $q$ diminua (der_f_rel_q = -4) com uma força maior (4 contra 3).\n",
453 | "\n",
454 | "Em relação a porta de soma, como vimos, o padrão é que aumentando as entradas a saída também aumenta. Porém, o circuito quer que $q$ diminua (der_f_rel_q = -4). Esse é o **ponto crucial**: em vez de aplicarmos uma força de +1 as entradas da porta de soma como normalmente faríamos (derivada local), o circuito quer que os gradientes em $x$ e $y$ se tornem 1x-4=-4. Isso faz sentido: o circuito quer $x$ e $y$ pequeno para que $q$ seja pequeno também, o que vai aumentar $f$.\n",
455 | "\n",
456 | "> *Se isso fez sentido, você entendeu backpropagation.*\n",
457 | "\n",
458 | "**Recapitulando:**\n",
459 | "- Vimos que, para uma simples porta (or simples expressão), podemos derivar o gradiente analítico usando cálculo simples. Nós interpretamos o gradiente como uma força que puxa as entradas na direção necessária para fazer a saída aumentar.\n",
460 | "- No caso de múltiplas portas, cada porta é tratada individualmente até que o circuito seja tratado como um todo. A *única* diferença é que agora o circuito diz como a saída de outras portas devem se comportar (como da porta de adição), que é o gradiente final do circuito em relação a saída da porta. É como o circuito pedindo aquela porta maior ou menor valor de saída, e com alguma força. A porta simplesmente pega essa força e multiplica em relação a todas as forças calculadas para suas entradas anteriores (regra da cadeia) - repare como a força de q (-4) é multiplicada as forças de x e y. Isso pode ter dois efeitos desejados:\n",
461 | " - Se a porta tem uma força positiva de saída, essa força também é multiplicada nas suas entradas, escalonada pelo valor da força das entradas.\n",
462 | " - Se a porta tem uma força negativa de saída, isso significa que o circuito quer que a saída decresça, então essa força é multiplicada pelas entradas para diminuir o valor de saída.\n",
463 | "\n",
464 | "> *Tenha em mente que a força da saída do circuito vai puxando as outras forças na direção desejada por todo o circuito até as entradas.*"
465 | ]
466 | },
467 | {
468 | "cell_type": "markdown",
469 | "metadata": {},
470 | "source": [
471 | "## Checagem do gradiente numérico"
472 | ]
473 | },
474 | {
475 | "cell_type": "markdown",
476 | "metadata": {},
477 | "source": [
478 | "Vamos verificar se os gradientes analíticos que calculamos por backpropagation estão corretos. Lembre-se que podemos fazer isso através do gradiente numérico e esperamos que o resultado seja [-4, -4, 4] para $x,y,z$."
479 | ]
480 | },
481 | {
482 | "cell_type": "code",
483 | "execution_count": null,
484 | "metadata": {
485 | "ExecuteTime": {
486 | "end_time": "2017-09-12T19:39:27.209310Z",
487 | "start_time": "2017-09-12T19:39:27.027170Z"
488 | }
489 | },
490 | "outputs": [],
491 | "source": [
492 | "x,y,z = -2,5,-4\n",
493 | "h = 0.0001\n",
494 | "\n",
495 | "#insira seu código aqui"
496 | ]
497 | },
498 | {
499 | "cell_type": "markdown",
500 | "metadata": {
501 | "collapsed": true
502 | },
503 | "source": [
504 | "## Neurônio Sigmóide"
505 | ]
506 | },
507 | {
508 | "cell_type": "markdown",
509 | "metadata": {},
510 | "source": [
511 | "Qualquer função diferenciável pode atuar como uma porta, como também podemos agrupar múltiplas portas para formar uma simples porta, ou decompor um função em múltiplas portas quando for conveniente. Para exemplificar, vamos utilizar a função de ativação *sigmoid* com entradas **x** e pesos **w**:\n",
512 | "\n",
513 | "$$f(w,x) = \\frac{1}{1+e^{-(w_0x_0 + w_1x_1 + w_2)}}$$\n",
514 | "\n",
515 | "Como dito, a função acima nada mais é que a função sigmoid $\\sigma(x)$. Sabendo, então, que a derivada da função sigmoid é:\n",
516 | "\n",
517 | "$$\\sigma(x)=\\frac{1}{1+e^{-x}}=(1-\\sigma(x))\\sigma(x)$$\n",
518 | "\n",
519 | "Vamos calcular a gradiente em relação as entradas:"
520 | ]
521 | },
522 | {
523 | "cell_type": "code",
524 | "execution_count": null,
525 | "metadata": {
526 | "ExecuteTime": {
527 | "end_time": "2017-09-12T19:39:27.342454Z",
528 | "start_time": "2017-09-12T19:39:27.217305Z"
529 | }
530 | },
531 | "outputs": [],
532 | "source": [
533 | "w0, w1, w2 = 2, -3, -3\n",
534 | "x0, x1 = -1, -2\n",
535 | "\n",
536 | "# forward pass\n",
537 | "\n",
538 | "\n",
539 | "# backward pass\n",
540 | "\n",
541 | "\n",
542 | "# Nova saida\n"
543 | ]
544 | },
545 | {
546 | "cell_type": "markdown",
547 | "metadata": {},
548 | "source": [
549 | "Vamos supor agora que não sabemos a derivada da função $\\sigma(x)$ muito menos de $f(w,x)$. O que podemos fazer?.\n",
550 | "\n",
551 | "**Decompor essa função em circuito com múltiplas portas!** Dessa forma:\n",
552 | "\n",
553 | "
\n",
554 | "\n",
555 | "Calculando a saída para cada porta, temos:\n",
556 | "\n",
557 | "
\n",
558 | "\n",
559 | "Onde sabemos as seguintes derivadas:\n",
560 | "\n",
561 | "$$f(x) = \\frac{1}{x} \\rightarrow \\frac{df}{dx} = -1/x^2 \n",
562 | "\\\\\\\\\n",
563 | "f_c(x) = c + x \\rightarrow \\frac{df}{dx} = 1 \n",
564 | "\\\\\\\\\n",
565 | "f(x) = e^x \\rightarrow \\frac{df}{dx} = e^x\n",
566 | "\\\\\\\\\n",
567 | "f_a(x) = ax \\rightarrow \\frac{df}{dx} = a$$\n",
568 | "\n",
569 | "Onde as funções $f_c(x)$ e $f_a(x)$ transladam a entrada por uma constante $c$ e escala por uma contante $a$, respectivamente. Na verdade, são apenas casos especias de adição e multiplicação, mas que foram introduzidos como portas unárias.\n",
570 | "\n",
571 | "Como podemos calcular a derivada em relação as entradas agora? **Usando Backpropagation!!**"
572 | ]
573 | },
574 | {
575 | "cell_type": "markdown",
576 | "metadata": {},
577 | "source": [
578 | "# 2. Backpropagation"
579 | ]
580 | },
581 | {
582 | "cell_type": "markdown",
583 | "metadata": {},
584 | "source": [
585 | "## Se tornando um Ninja em Backpropagation!"
586 | ]
587 | },
588 | {
589 | "cell_type": "markdown",
590 | "metadata": {},
591 | "source": [
592 | "Antes de resolver o circuito acima, vamos praticar um pouco de backpropagation com alguns exemplos. Vamos esquecer funções por enquanto e trabalhar só com 4 variáveis: $a$, $b$, $c$, e $x$. Vamos também nos referir as seus gradientes como $da$, $db$, $dc$, e $dx$. Além disso, vamos assumir que $dx$ é dado (ou é +1 como nos casos acima). Nosso primeiro exemplo é a porta $*$, que já conhecemos:\n",
593 | "\n",
594 | "$$x = a * b$$\n",
595 | "\n",
596 | "$$da = b * dx$$\n",
597 | "$$db = a * dx$$\n",
598 | "\n",
599 | "Se você reparar bem, vai perceber que a porta $*$ atua como um *switcher* durante a backpropagation, ou seja, o gradiente de cada entrada é o valor da outra multiplicado pelo gradiente da anterior (regra da cadeia). Por outro lado, vamos analisar a porta +:\n",
600 | "\n",
601 | "$$x = a + b$$\n",
602 | "\n",
603 | "$$da = 1.0 * dx$$\n",
604 | "$$db = 1.0 * dx$$\n",
605 | "\n",
606 | "Nesse caso, 1.0 é o gradiente local e a multiplicação é a nossa regra da cadeia. **E se fosse a adição de 3 números?**:\n",
607 | "\n",
608 | "$$q = a + b$$\n",
609 | "$$x = q + c$$\n",
610 | "\n",
611 | "$$dc = 1.0 * dx$$\n",
612 | "$$dq = 1.0 * dx$$\n",
613 | "$$da = 1.0 * dq$$\n",
614 | "$$db = 1.0 * dq$$\n",
615 | "\n",
616 | "Você percebe o que está acontecendo? Se você olhar nos diagramas dos circuitos que já resolvemos, vai perceber que a porta + simplesmente pega o gradiente atual e roteia igualmente para todas as entradas (porque os gradientes locais são sempre 1.0 para todas as entradas, independente dos seus valores atuais). Então, podemos fazer bem mais rápido:\n",
617 | "\n",
618 | "$$x = a + b + c$$\n",
619 | "\n",
620 | "$$da = 1.0 * dx$$\n",
621 | "$$db = 1.0 * dx$$\n",
622 | "$$dc = 1.0 * dx$$\n",
623 | "\n",
624 | "Okay. Mas, e se combinarmos portas?\n",
625 | "\n",
626 | "$$x = a*b + c$$\n",
627 | "\n",
628 | "$$da = b * dx$$\n",
629 | "$$db = a * dx$$\n",
630 | "$$dc = 1.0 * dx$$\n",
631 | "\n",
632 | "Se você não percebeu o que aconteceu, introduza uma variável temporária $q = a * b$ e então calcula $x = q + c$ para se convencer. E quanto a este exemplo:\n",
633 | "\n",
634 | "$$x = a * a$$\n",
635 | "$$da = 2 * a * dx$$\n",
636 | "\n",
637 | "Outro exemplo:\n",
638 | "\n",
639 | "$$x = a*a + b*b + c*c$$\n",
640 | "$$da = 2 * a * dx$$\n",
641 | "$$db = 2 * b * dx$$\n",
642 | "$$dc = 2 * c * dx$$\n",
643 | "\n",
644 | "Ok. Agora mais complexo:\n",
645 | "\n",
646 | "$$x = (a * b + c) * d)^2$$\n",
647 | "\n",
648 | "Quando casos mais complexos como esse acontecem, eu gosto de dividir a expressão em partes gerenciáveis que são quase sempre compostas de simples expressões onde eu posso aplicar a regra da cadeia:\n",
649 | "\n",
650 | "$$x1 = a * b + c$$\n",
651 | "$$x2 = x1 * d$$\n",
652 | "$$x = x2 * x2$$\n",
653 | "\n",
654 | "$$dx2 = 2 * x2 * dx$$\n",
655 | "$$dx1 = d * dx2$$\n",
656 | "$$dd = x1 * dx2$$\n",
657 | "$$da = b * dx1$$\n",
658 | "$$db = a * dx1$$\n",
659 | "$$dc = 1 * dx1$$\n",
660 | "\n",
661 | "Não foi tão difícil! Essas são as equações para toda a expressão, e nós fizemos dividindo peça por peça e aplicando backpropagation a todas as variáveis. Note que **toda variável durante a fase forward tem uma variável equivalente na backpropagação que contém o gradiente em relação a saída do circuito.**. Mais um exemplo útil de função e seu gradiente local:\n",
662 | "\n",
663 | "$$x = 1.0/a$$\n",
664 | "$$da = 1.0/(a*a) * dx$$\n",
665 | "\n",
666 | "E como ela pode ser aplicada na prática:\n",
667 | "\n",
668 | "$$x = (a+b)/(c+d)$$\n",
669 | "\n",
670 | "$$x1 = a + b$$\n",
671 | "$$x2 = c + d$$\n",
672 | "$$x3 = 1.0 / x2$$\n",
673 | "$$x = x1 * x3$$\n",
674 | "\n",
675 | "$$dx1 = x3 * dx$$\n",
676 | "$$dx3 = x1 * dx$$\n",
677 | "$$dx2 = (1.0/(x2 * x2)) * dx3$$\n",
678 | "$$dc = 1 * dx2$$\n",
679 | "$$dd = 1 * dx2$$\n",
680 | "$$da = 1 * dx1$$\n",
681 | "$$db = 1 * dx1$$\n",
682 | "\n",
683 | "E mais uma:\n",
684 | "\n",
685 | "$$x = math.max(a, b)$$\n",
686 | "$$da = x == a\\ ?\\ 1.0 * dx\\ :\\ 0.0$$\n",
687 | "$$db = x == b\\ ?\\ 1.0 * dx\\ :\\ 0.0$$\n",
688 | "\n",
689 | "No caso acima é mais difícil de entender. A função **max** passa o valor para a maior entrada e ignora as outras. Na fase de backpropagation, a porta __max__ simplesmente pega o gradiente atual e roteia para a entrada que teve o maior valor durante a fase de forward. A porta age como um simples switch baseado na entrada com o maior valor durante a forward. As outras entradas terão gradiente zero.\n",
690 | "\n",
691 | "Agora, vamos dar uma olhada na porta **ReLU (*Rectified Linear Unit)***, muita usada em redes neurais no lugar da função sigmoid. Ela é simplesmente um threshold com zero:\n",
692 | "\n",
693 | "$$x = max(a, 0)$$\n",
694 | "$$da = a > 0\\ ?\\ 1.0 * dx\\ :\\ 0.0$$\n",
695 | "\n",
696 | "Em outras palavras, essa porta simplesmente passa o valor adiante se ele é maior que zero, ou interrompe o fluxo e seta o valor para zero. Na backpropagação, a porta vai passar o gradiente atual se ele foi ativado durante a forward. Se a entrada original foi menor que zero, ela vai interromper o fluxo de gradiente.\n",
697 | "\n",
698 | "Finalmente, vamos ver como calcular o gradiente em operações vetorizadas que vamos utilizar muito em redes neurais:\n",
699 | "\n",
700 | "$$W = np.random.randn(5,10)$$\n",
701 | "$$X = np.random.randn(3,10)$$\n",
702 | "$$Y = X.dot(W^T)$$\n",
703 | "\n",
704 | "Supondo que o gradiente de Y é dado como a seguir:\n",
705 | "$$dY = np.random.randn(*Y.shape)$$\n",
706 | "$$dW = dY^T.dot(X)$$\n",
707 | "$$dX = dY.dot(W)$$\n",
708 | "\n",
709 | "Espero que tenha entendido como calcular expressões inteiras (que são feitas de muitas portas) e como calcular a backpropagação para cada uma delas."
710 | ]
711 | },
712 | {
713 | "cell_type": "markdown",
714 | "metadata": {},
715 | "source": [
716 | "## Resumo dos Padrões na Backpropagation"
717 | ]
718 | },
719 | {
720 | "cell_type": "markdown",
721 | "metadata": {},
722 | "source": [
723 | "Para resumir os padrões no fluxo da backpropagation considere esse circuito:\n",
724 | "\n",
725 | "
\n",
726 | "\n",
727 | "A **porta de soma** simplesmente pega o gradiente na saída e distribui igualmente para entrada, independente dos valores durante a etapa de forward. Isso vem do fato que o gradiente local para a operação de adicionar é simplesmente +1.0, então os gradientes em todas as entradas vão ser exatamente iguais ao gradiente da saída porque ele vai ser multiplicado por 1.0 (e continua o mesmo). No circuito acima, repare como a porta + roteou o gradiente 2.0 para ambas as entradas, igualmente e sem alteração.\n",
728 | "\n",
729 | "A **porta max** roteia o gradiente. Diferente da porta de soma que distribui o gradiente para todas as entradas, distribui o gradiente (sem alteração) para exatamente uma das entradas (a que tinha o maior valor durante a etapa de forward). Isso acontece por que o gradiente local é 1.0 para o maior valor e 0.0 para os outros valores. No circuito acima, a operação max roteou o gradiente de 2.0 para a variável $z$, que tinha um valor maior que $w$, e o gradiente de $w$ continua zero.\n",
730 | "\n",
731 | "A **porta de multiplicação** é um pouquinho mais difícil de interpretar. Os gradientes locais são os valores das entradas (cambiados) e multiplicados pelo gradiente da saída durante a regra da cadeia. No exemplo acima, o gradiente em $x$ é -8.00, pois é igual a -4.00x2.00.\n",
732 | "\n",
733 | "*Efeitos não inutuitivos e suas consequências*. Note que se uma das entradas na porta de multiplicação é muito pequena e a outra é muito grande, então a porta de multiplicação vai fazer algo intuitivo: ela vai atribuir um gradiente muito alto para a menor entrada e um muito pequeno para a maior entrada. Perceba que no caso de classificadores lineares, onde os pesos são multiplicados com as entradas $w^Tx_i$, isso implica que a escala dos dados tem um efeito na magnitude do gradiente para os pesos. Por exemplo, se você multiplicar todos os dados de entrada **$x_i$** por 1000 durante pré-processamento, então o gradiente dos pesos vão ser 1000x maior, e você terá de usar baixas taxas de aprendizagem para compensar o fator. Por isso que o pré-processamento é tão importante e o conhecimento intuitivo sobre os gradientes podem ajudar a debugar alguns desses casos."
734 | ]
735 | },
736 | {
737 | "cell_type": "markdown",
738 | "metadata": {},
739 | "source": [
740 | "## Exemplo 1"
741 | ]
742 | },
743 | {
744 | "cell_type": "markdown",
745 | "metadata": {},
746 | "source": [
747 | "Implementando o nosso neurônio\n",
748 | "\n",
749 | "
"
750 | ]
751 | },
752 | {
753 | "cell_type": "code",
754 | "execution_count": null,
755 | "metadata": {
756 | "ExecuteTime": {
757 | "end_time": "2017-09-12T19:39:27.492474Z",
758 | "start_time": "2017-09-12T19:39:27.347458Z"
759 | }
760 | },
761 | "outputs": [],
762 | "source": [
763 | "w0, w1, w2 = 2, -3, -3\n",
764 | "x0, x1 = -1, -2\n",
765 | "\n",
766 | "# forward pass\n",
767 | "\n",
768 | "\n",
769 | "# backward pass\n",
770 | "\n"
771 | ]
772 | },
773 | {
774 | "cell_type": "markdown",
775 | "metadata": {},
776 | "source": [
777 | "## Exemplo 2"
778 | ]
779 | },
780 | {
781 | "cell_type": "markdown",
782 | "metadata": {},
783 | "source": [
784 | "Vamos ver outro exemplo. Suponha que temos a seguinte função:\n",
785 | "\n",
786 | "$$f(x,y) = \\frac{x + \\sigma(y)}{\\sigma(x) + (x+y)^2}$$\n",
787 | "\n",
788 | "Só para deixar claro, essa função é completamente inútil, mas um bom exemplo de backpropagation na prática. Também é importante destacar que ela é bem difícil de derivar em relação a $x$ e $y$. No entanto, como vimos, saber derivar uma função é completamente desnecessário por que não precisamos saber derivar a função inteira para calcular os gradientes. Só precisamos saber como calcular os gradientes locais. Aqui está a resolução:"
789 | ]
790 | },
791 | {
792 | "cell_type": "code",
793 | "execution_count": null,
794 | "metadata": {
795 | "ExecuteTime": {
796 | "end_time": "2017-09-12T19:39:27.640572Z",
797 | "start_time": "2017-09-12T19:39:27.500477Z"
798 | }
799 | },
800 | "outputs": [],
801 | "source": [
802 | "x, y = 3, -4\n",
803 | "\n",
804 | "# forward pass\n",
805 | "\n",
806 | "\n",
807 | "# backward pass\n",
808 | "\n"
809 | ]
810 | },
811 | {
812 | "cell_type": "markdown",
813 | "metadata": {},
814 | "source": [
815 | "Repare em algumas coisas importantes:\n",
816 | "\n",
817 | "**Variáveis temporárias para armazenar resultados**. Para calcular a backpropagation, é importante ter algumas (se não todas) das variáveis calculadas na etapa de forward. Na prática, é bom estruturar seu código de maneira a guardar esses valores para a backprop. Em último caso, você pode recalculá-las.\n",
818 | "\n",
819 | "**Gradientes adicionados**. A etapa de forward envolveu as variáveis $x$ e $y$ muitas vezes, então quando fazemos a backprop temos de ter cuidados de acumular o gradiente nessas variáveis (+=). Isso segue a **regra da cadeia multivariável** em cálculo."
820 | ]
821 | },
822 | {
823 | "cell_type": "markdown",
824 | "metadata": {},
825 | "source": [
826 | "# Referências "
827 | ]
828 | },
829 | {
830 | "cell_type": "markdown",
831 | "metadata": {},
832 | "source": [
833 | "1. [CS231n - Optimization: Stochastic Gradient Descent](http://cs231n.github.io/optimization-1/) \n",
834 | "2. [CS231n - Backpropagation, Intuitions](http://cs231n.github.io/optimization-2/)\n",
835 | "3. [Hacker's guide to Neural Networks](http://karpathy.github.io/neuralnets/)"
836 | ]
837 | }
838 | ],
839 | "metadata": {
840 | "anaconda-cloud": {},
841 | "kernelspec": {
842 | "display_name": "Python 3",
843 | "language": "python",
844 | "name": "python3"
845 | },
846 | "language_info": {
847 | "codemirror_mode": {
848 | "name": "ipython",
849 | "version": 3
850 | },
851 | "file_extension": ".py",
852 | "mimetype": "text/x-python",
853 | "name": "python",
854 | "nbconvert_exporter": "python",
855 | "pygments_lexer": "ipython3",
856 | "version": "3.6.5"
857 | },
858 | "toc": {
859 | "nav_menu": {},
860 | "number_sections": false,
861 | "sideBar": true,
862 | "skip_h1_title": false,
863 | "toc_cell": false,
864 | "toc_position": {},
865 | "toc_section_display": "block",
866 | "toc_window_display": false
867 | }
868 | },
869 | "nbformat": 4,
870 | "nbformat_minor": 1
871 | }
872 |
--------------------------------------------------------------------------------
/Funções de Ativação.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "__Objetivos__:\n",
8 | "\n",
9 | "- Implementar as principais funções de ativação\n",
10 | "- Entender intuitivamente como $w$ e $b$ influenciam nas funções de ativação"
11 | ]
12 | },
13 | {
14 | "cell_type": "markdown",
15 | "metadata": {},
16 | "source": [
17 | "# Sumário"
18 | ]
19 | },
20 | {
21 | "cell_type": "markdown",
22 | "metadata": {},
23 | "source": [
24 | "- [Linear](#Linear)\n",
25 | "- [Sigmoid](#Sigmoid)\n",
26 | "- [Tanh](#Tanh)\n",
27 | "- [Rectified Linear Unit (ReLU)](#Rectified-Linear-Unit-(ReLU))\n",
28 | "- [Leaky ReLU](#Leaky-ReLU)\n",
29 | "- [Exponential Linear Unit (eLU)](#Exponential-Linear-Unit-(eLU))\n",
30 | "- [Tabela das Funções de Ativação](#Tabela-das-Funções-de-Ativação)\n",
31 | "- [Referências](#Referências)"
32 | ]
33 | },
34 | {
35 | "cell_type": "code",
36 | "execution_count": null,
37 | "metadata": {},
38 | "outputs": [],
39 | "source": [
40 | "import numpy as np\n",
41 | "import matplotlib.pyplot as plt\n",
42 | "import ipywidgets as wg\n",
43 | "from ipywidgets import interactive, fixed\n",
44 | "\n",
45 | "%matplotlib inline"
46 | ]
47 | },
48 | {
49 | "cell_type": "code",
50 | "execution_count": null,
51 | "metadata": {},
52 | "outputs": [],
53 | "source": [
54 | "def plot_interactive(w, b, func, ylim=fixed((0, 1)), show_der=False):\n",
55 | " plt.figure(0)\n",
56 | " \n",
57 | " x = np.linspace(-10, 10, num=1000)\n",
58 | " z = w*x + b\n",
59 | " y = func(z)\n",
60 | " \n",
61 | " plt.plot(x, y, color='blue')\n",
62 | " if show_der:\n",
63 | " der = func(z, derivative=True)\n",
64 | " y_der_z = der\n",
65 | " y_der_x = w*der\n",
66 | " plt.plot(x, y_der_z, color='red')\n",
67 | " plt.plot(x, y_der_x, color='green')\n",
68 | " plt.xlim(-10, 10)\n",
69 | " plt.ylim(ylim[0], ylim[1])\n",
70 | " plt.show()"
71 | ]
72 | },
73 | {
74 | "cell_type": "markdown",
75 | "metadata": {},
76 | "source": [
77 | "# Linear"
78 | ]
79 | },
80 | {
81 | "cell_type": "markdown",
82 | "metadata": {},
83 | "source": [
84 | "$$y=x$$\n",
85 | "\n",
86 | "$$y^\\prime = 1$$"
87 | ]
88 | },
89 | {
90 | "cell_type": "code",
91 | "execution_count": null,
92 | "metadata": {},
93 | "outputs": [],
94 | "source": []
95 | },
96 | {
97 | "cell_type": "code",
98 | "execution_count": null,
99 | "metadata": {},
100 | "outputs": [],
101 | "source": [
102 | "interactive_plot = interactive(plot_interactive, w=(-2.0, 2.0), b=(-3, 3, 0.5), func=fixed(linear), ylim=fixed((-10, 10)))\n",
103 | "interactive_plot"
104 | ]
105 | },
106 | {
107 | "cell_type": "markdown",
108 | "metadata": {},
109 | "source": [
110 | "# Sigmoid "
111 | ]
112 | },
113 | {
114 | "cell_type": "markdown",
115 | "metadata": {},
116 | "source": [
117 | "$$y = \\frac{1}{1+e^{-x}}$$\n",
118 | "\n",
119 | "$$y^\\prime = y(1-y)$$"
120 | ]
121 | },
122 | {
123 | "cell_type": "code",
124 | "execution_count": null,
125 | "metadata": {},
126 | "outputs": [],
127 | "source": []
128 | },
129 | {
130 | "cell_type": "code",
131 | "execution_count": null,
132 | "metadata": {},
133 | "outputs": [],
134 | "source": [
135 | "interactive_plot = interactive(plot_interactive, w=(-2.0, 2.0), b=(-3, 3, 0.5), func=fixed(sigmoid))\n",
136 | "interactive_plot"
137 | ]
138 | },
139 | {
140 | "cell_type": "markdown",
141 | "metadata": {},
142 | "source": [
143 | "# Tanh"
144 | ]
145 | },
146 | {
147 | "cell_type": "markdown",
148 | "metadata": {},
149 | "source": [
150 | "$$y = \\frac{e^x - e^{-x}}{e^x+e^{-x}}$$\n",
151 | "\n",
152 | "$$y^\\prime = 1 - y^2$$"
153 | ]
154 | },
155 | {
156 | "cell_type": "code",
157 | "execution_count": null,
158 | "metadata": {},
159 | "outputs": [],
160 | "source": []
161 | },
162 | {
163 | "cell_type": "code",
164 | "execution_count": null,
165 | "metadata": {},
166 | "outputs": [],
167 | "source": [
168 | "interactive_plot = interactive(plot_interactive, w=(-2.0, 2.0), b=(-3, 3, 0.5), func=fixed(tanh), ylim=fixed((-2, 2)))\n",
169 | "interactive_plot"
170 | ]
171 | },
172 | {
173 | "cell_type": "markdown",
174 | "metadata": {},
175 | "source": [
176 | "# Rectified Linear Unit (ReLU)"
177 | ]
178 | },
179 | {
180 | "cell_type": "markdown",
181 | "metadata": {},
182 | "source": [
183 | "$$y = max(0, x)$$\n",
184 | "\n",
185 | "$$\\frac{\\partial y}{\\partial x} = \\begin{cases}0 &,\\ x \\leq 0\\\\1 &,\\ x > 0\\end{cases}$$\n",
186 | "\n",
187 | "__Obs.__: Lembrando que a derivada da ReLU quando x = 0 não existe matematicamente, mas é convencionalmente definida como 0."
188 | ]
189 | },
190 | {
191 | "cell_type": "code",
192 | "execution_count": null,
193 | "metadata": {},
194 | "outputs": [],
195 | "source": []
196 | },
197 | {
198 | "cell_type": "code",
199 | "execution_count": null,
200 | "metadata": {},
201 | "outputs": [],
202 | "source": [
203 | "interactive_plot = interactive(plot_interactive, w=(-2.0, 2.0), b=(-3, 3, 0.5), func=fixed(relu), ylim=fixed((-1, 10)))\n",
204 | "interactive_plot"
205 | ]
206 | },
207 | {
208 | "cell_type": "markdown",
209 | "metadata": {},
210 | "source": [
211 | "# Leaky ReLU "
212 | ]
213 | },
214 | {
215 | "cell_type": "markdown",
216 | "metadata": {},
217 | "source": [
218 | "$$y = \\begin{cases}\\alpha x &,\\ x \\leq 0\\\\x &,\\ x > 0\\end{cases}$$\n",
219 | "\n",
220 | "$$\\frac{\\partial y}{\\partial x} = \\begin{cases}\\alpha &,\\ x \\leq 0\\\\1 &,\\ x > 0\\end{cases}$$"
221 | ]
222 | },
223 | {
224 | "cell_type": "code",
225 | "execution_count": null,
226 | "metadata": {},
227 | "outputs": [],
228 | "source": []
229 | },
230 | {
231 | "cell_type": "code",
232 | "execution_count": null,
233 | "metadata": {},
234 | "outputs": [],
235 | "source": [
236 | "interactive_plot = interactive(plot_interactive, w=(-2.0, 2.0), b=(-3, 3, 0.5), func=fixed(leaky_relu), ylim=fixed((-1, 10)))\n",
237 | "interactive_plot"
238 | ]
239 | },
240 | {
241 | "cell_type": "markdown",
242 | "metadata": {},
243 | "source": [
244 | "# Exponential Linear Unit (eLU) "
245 | ]
246 | },
247 | {
248 | "cell_type": "markdown",
249 | "metadata": {},
250 | "source": [
251 | "$$y = \\begin{cases}\\alpha(e^x -1) &,\\ x \\leq 0\\\\x &,\\ x > 0\\end{cases}$$\n",
252 | "\n",
253 | "$$\\frac{\\partial y}{\\partial x} = \\begin{cases}y + \\alpha &,\\ x \\leq 0\\\\1 &,\\ x > 0\\end{cases}$$"
254 | ]
255 | },
256 | {
257 | "cell_type": "code",
258 | "execution_count": null,
259 | "metadata": {},
260 | "outputs": [],
261 | "source": []
262 | },
263 | {
264 | "cell_type": "code",
265 | "execution_count": null,
266 | "metadata": {},
267 | "outputs": [],
268 | "source": [
269 | "interactive_plot = interactive(plot_interactive, w=(-2.0, 2.0), b=(-3, 3, 0.5), func=fixed(elu), ylim=fixed((-2, 10)))\n",
270 | "interactive_plot"
271 | ]
272 | },
273 | {
274 | "cell_type": "markdown",
275 | "metadata": {},
276 | "source": [
277 | "# Tabela das Funções de Ativação"
278 | ]
279 | },
280 | {
281 | "cell_type": "markdown",
282 | "metadata": {},
283 | "source": [
284 | "
"
285 | ]
286 | },
287 | {
288 | "cell_type": "markdown",
289 | "metadata": {},
290 | "source": [
291 | "# Referências"
292 | ]
293 | },
294 | {
295 | "cell_type": "markdown",
296 | "metadata": {},
297 | "source": [
298 | "- [Tabela das funções de ativação](https://en.wikipedia.org/wiki/Activation_function)\n",
299 | "- [Towards Data Science](https://medium.com/towards-data-science/activation-functions-neural-networks-1cbd9f8d91d6)\n",
300 | "- [Stack Exchange](https://stats.stackexchange.com/questions/115258/comprehensive-list-of-activation-functions-in-neural-networks-with-pros-cons)"
301 | ]
302 | }
303 | ],
304 | "metadata": {
305 | "kernelspec": {
306 | "display_name": "Python 3",
307 | "language": "python",
308 | "name": "python3"
309 | },
310 | "language_info": {
311 | "codemirror_mode": {
312 | "name": "ipython",
313 | "version": 3
314 | },
315 | "file_extension": ".py",
316 | "mimetype": "text/x-python",
317 | "name": "python",
318 | "nbconvert_exporter": "python",
319 | "pygments_lexer": "ipython3",
320 | "version": "3.6.5"
321 | },
322 | "widgets": {
323 | "state": {
324 | "568cf18b31b04b14b5b59379918b64e2": {
325 | "views": [
326 | {
327 | "cell_index": 6
328 | }
329 | ]
330 | },
331 | "58032045773043aeb5dab953be590b44": {
332 | "views": [
333 | {
334 | "cell_index": 30
335 | }
336 | ]
337 | },
338 | "743ccf7c641c485e9250b2558be149d1": {
339 | "views": [
340 | {
341 | "cell_index": 22
342 | }
343 | ]
344 | },
345 | "a41e4be364004b0d924d05e304ee3bcb": {
346 | "views": [
347 | {
348 | "cell_index": 26
349 | }
350 | ]
351 | },
352 | "bbf702b6ba494528a2233c691e2bd6d9": {
353 | "views": [
354 | {
355 | "cell_index": 14
356 | }
357 | ]
358 | },
359 | "c259af61fd66413783ae3ed1e32ece47": {
360 | "views": [
361 | {
362 | "cell_index": 10
363 | }
364 | ]
365 | },
366 | "c7f3128cf6d8492795e406ed70fa7e07": {
367 | "views": [
368 | {
369 | "cell_index": 18
370 | }
371 | ]
372 | }
373 | },
374 | "version": "1.2.0"
375 | }
376 | },
377 | "nbformat": 4,
378 | "nbformat_minor": 2
379 | }
380 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Arnaldo Gualberto
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Neurônio Sigmoid.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": []
7 | },
8 | {
9 | "cell_type": "markdown",
10 | "metadata": {},
11 | "source": [
12 | "# Sumário"
13 | ]
14 | },
15 | {
16 | "cell_type": "markdown",
17 | "metadata": {},
18 | "source": [
19 | "[Introdução](#Introdução)\n",
20 | "\n",
21 | "[Função de Custo](#Função-de-Custo)\n",
22 | "\n",
23 | "[Regressão Logística](#Regressão-Log%C3%ADstica)\n",
24 | "\n",
25 | "[Exercícios](#Exercícios)\n",
26 | "\n",
27 | "[Referências](#Referências)"
28 | ]
29 | },
30 | {
31 | "cell_type": "markdown",
32 | "metadata": {},
33 | "source": [
34 | "# Imports e Configurações"
35 | ]
36 | },
37 | {
38 | "cell_type": "code",
39 | "execution_count": null,
40 | "metadata": {},
41 | "outputs": [],
42 | "source": [
43 | "import numpy as np\n",
44 | "import pandas as pd\n",
45 | "import matplotlib.pyplot as plt\n",
46 | "from sklearn.linear_model import LogisticRegression\n",
47 | "from sklearn.preprocessing import MinMaxScaler\n",
48 | "from sklearn.metrics import accuracy_score\n",
49 | "from mpl_toolkits.mplot3d import Axes3D\n",
50 | "\n",
51 | "%matplotlib inline"
52 | ]
53 | },
54 | {
55 | "cell_type": "markdown",
56 | "metadata": {},
57 | "source": [
58 | "# Introdução"
59 | ]
60 | },
61 | {
62 | "cell_type": "markdown",
63 | "metadata": {},
64 | "source": [
65 | "A __Regressão Logística__, apesar do nome, é uma técnica utilizada para fazer __classificação binária__. Nesse caso, ao invés de prever um valor contínuo, a nossa __saída é composta de apenas dois valores: 0 ou 1__, em geral. Para fazer a regressão logística, utilizamos como função de ativação a função conhecida como __sigmoid__. Tal função, é descrita pela seguinte fórmula:\n",
66 | "\n",
67 | "$$\\widehat{y} = \\frac{1}{1+e^{-z}} = \\frac{e^z}{1+e^z}$$\n",
68 | "\n",
69 | "No caso de redes neurais, em geral consideramos $z(w,b) = xw^T + b$."
70 | ]
71 | },
72 | {
73 | "cell_type": "markdown",
74 | "metadata": {},
75 | "source": [
76 | "# Função de Custo"
77 | ]
78 | },
79 | {
80 | "cell_type": "markdown",
81 | "metadata": {},
82 | "source": [
83 | "A função de custo da regressão logística é chamada de __entropia cruzada__ (do inglês, __cross-entropy__) e é definida pela seguinte fórmula:\n",
84 | "\n",
85 | "$$J(z) = -\\frac{1}{N}\\sum_{i}^N y_i\\log(\\widehat{y}_i) + (1-y_i)\\log(1-\\widehat{y}_i)$$\n",
86 | "\n",
87 | "Onde $N$ é quantidade de amostras e $y_i$ representa o valor da $i$-ésima amostra (0 ou 1). Lembrando que $\\widehat{y}_i$ é agora calculada agora utilizando a função ___sigmoid___, como mostrado na seção anterior.\n",
88 | "\n",
89 | "Repare também que:\n",
90 | "\n",
91 | "- quando $y_i = 0$, o primeiro termo anula-se (pois $y_i = 0$). Logo, vamos considerar os dois casos extremos para $\\widehat{y}_i = 0$ no segundo termo da equação ($(1-y_i)\\log(1-\\widehat{y}_i)$):\n",
92 | " - quando $\\widehat{y}_i = 0$, temos que o $\\log(1-\\widehat{y}_i) = \\log(1) = 0$. Logo, o nosso custo $J = 0$. Repare que isso faz todo sentido, pois $y_i = 0$ e $\\widehat{y}_i = 0$. \n",
93 | " - quando $\\widehat{y}_i = 1$, temos que o $\\log(1-\\widehat{y}_i) = \\log(0) = \\infty$. Agora, o nosso custo $J = \\infty$. Ou seja, quanto mais diferente são $y_i$ e $\\widehat{y}_i$, maior o nosso custo.\n",
94 | "- quando $y_i = 1$, o segundo termo anula-se (pois $(1-y_i) = 0$). Novamente, vamos considerar os dois casos extremos para $\\widehat{y}_i = 0$, só que agora no primeiro termo da equação ($y_i\\log(\\widehat{y}_i)$):\n",
95 | " - quando $\\widehat{y}_i = 0$, temos que o $\\log(\\widehat{y}_i) = \\infty$. Logo, o nosso custo $J = \\infty$. Novamente, como $y_i$ e $\\widehat{y}_i$ são bem diferentes, o custo tende a aumentar.\n",
96 | " - quando $\\widehat{y}_i = 1$, temos que $\\log(\\widehat{y}_i) = \\log(1) = 0$. Agora, o nosso custo $J = 0$. Novamente, isso faz todo sentido, pois $y_i = 1$ e $\\widehat{y}_i = 1$.\n"
97 | ]
98 | },
99 | {
100 | "cell_type": "markdown",
101 | "metadata": {},
102 | "source": [
103 | "## Derivada da Cross-Entropy"
104 | ]
105 | },
106 | {
107 | "cell_type": "markdown",
108 | "metadata": {},
109 | "source": [
110 | "Para calcular a derivada da nossa função de custo $J(z)$, primeiramente vamos calcular $\\log(\\widehat{y}_i)$:\n",
111 | "\n",
112 | "$$\\log(\\widehat{y}_i) = log\\frac{1}{1+e^{-z}} = log(1) - log(1+e^{-z}) = -log(1+e^{-z})$$\n",
113 | "\n",
114 | "E $\\log(1-\\widehat{y}_i)$:\n",
115 | "\n",
116 | "$$\\log(1-\\widehat{y}_i) = log \\left(1-\\frac{1}{1+e^{-z}}\\right) = log(e^{-z}) - log(1+e^{-z}) = -z -log(1+e^{-z})$$\n",
117 | "\n",
118 | "Substituindo as duas equações anteriores na fórmula da função de custo, temos:\n",
119 | "\n",
120 | "$$J(z) = -\\frac{1}{N}\\sum_{i}^N \\left[-y_i\\log(1+e^{-z}) + (1-y_i)(-z -\\log(1+e^{-z}))\\right]$$\n",
121 | "\n",
122 | "Efetuando as distribuições, podemos simplificar a equação acima para:\n",
123 | "\n",
124 | "$$J(z) = -\\frac{1}{N}\\sum_{i}^N \\left[y_iz -z -\\log(1+e^{-z})\\right]$$\n",
125 | "\n",
126 | "Uma vez que:\n",
127 | "\n",
128 | "$$-z -\\log(1+e^{-z}) = -\\left[\\log e^{z} + log(1+e^{-z})\\right] = -log(1+e^z)$$\n",
129 | "\n",
130 | "Temos:\n",
131 | "\n",
132 | "$$J(z) = -\\frac{1}{N}\\sum_{i}^N \\left[y_iz -\\log(1+e^z)\\right]$$\n",
133 | "\n",
134 | "Como a derivada da diferença é igual a diferença das derivadas, podemos calcular cada derivada individualmente em relação a $w$:\n",
135 | "\n",
136 | "$$\\frac{\\partial}{\\partial w_i}y_iz = y_ix_i,\\quad \\frac{\\partial}{\\partial w_i}\\log(1+e^z) = \\frac{x_ie^z}{1+e^z} = x_i \\widehat{y}_i$$\n",
137 | "\n",
138 | "e em relação à $b$:\n",
139 | "\n",
140 | "$$\\frac{\\partial}{\\partial b}y_iz = y_i,\\quad \\frac{\\partial}{\\partial b}\\log(1+e^z) = \\frac{e^z}{1+e^z} = \\widehat{y}_i$$\n",
141 | "\n",
142 | "Assim, a derivada da nossa função de custo $J(z)$ é:\n",
143 | "\n",
144 | "$$\\frac{\\partial}{\\partial w_i}J(z) = \\sum_i^N (y_i - \\widehat{y}_i)x_i$$\n",
145 | "\n",
146 | "$$\\frac{\\partial}{\\partial b}J(z) = \\sum_i^N (y_i - \\widehat{y}_i)$$\n",
147 | "\n",
148 | "Por fim, repare que o __gradiente de J ($\\nabla J$) é exatamente o mesmo que o gradiente da função de custo do [Perceptron Linear](Perceptron.ipynb#Como-o-Perceptron-Aprende?)__. Portanto, os pesos serão atualizados da mesma maneira. O que muda é a forma como calculamos $\\widehat{y}$ (agora usando a função _sigmoid_) e a função de custo $J$."
149 | ]
150 | },
151 | {
152 | "cell_type": "markdown",
153 | "metadata": {},
154 | "source": [
155 | "# Regressão Logística"
156 | ]
157 | },
158 | {
159 | "cell_type": "code",
160 | "execution_count": null,
161 | "metadata": {},
162 | "outputs": [],
163 | "source": [
164 | "df = pd.read_csv('data/anuncios.csv')\n",
165 | "print(df.shape)\n",
166 | "df.head()"
167 | ]
168 | },
169 | {
170 | "cell_type": "code",
171 | "execution_count": null,
172 | "metadata": {},
173 | "outputs": [],
174 | "source": [
175 | "x, y = df.idade.values.reshape(-1,1), df.comprou.values.reshape(-1,1)\n",
176 | "\n",
177 | "print(x.shape, y.shape)"
178 | ]
179 | },
180 | {
181 | "cell_type": "code",
182 | "execution_count": null,
183 | "metadata": {},
184 | "outputs": [],
185 | "source": [
186 | "plt.scatter(x, y, c=y, cmap='bwr')\n",
187 | "plt.xlabel('idade')\n",
188 | "plt.ylabel('comprou?')"
189 | ]
190 | },
191 | {
192 | "cell_type": "code",
193 | "execution_count": null,
194 | "metadata": {},
195 | "outputs": [],
196 | "source": [
197 | "minmax = MinMaxScaler(feature_range=(-1,1))\n",
198 | "x = minmax.fit_transform(x.astype(np.float64))\n",
199 | "\n",
200 | "print(x.min(), x.max())"
201 | ]
202 | },
203 | {
204 | "cell_type": "markdown",
205 | "metadata": {},
206 | "source": [
207 | "Vamos utilizar o _sklearn_ como gabarito para nossa implementação. Entretanto, como a Regressão Logística do _sklearn_ faz uma __regularização L2__ automaticamente, temos de definir $C=10^{15}$ para \"anular\" a regularização. O parâmetro $C$ define a inversa da força da regularização (ver [documentação](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html)). __Logo, quanto menor for o $C$, maior será a regularização e menores serão os valores dos pesos e bias.__"
208 | ]
209 | },
210 | {
211 | "cell_type": "code",
212 | "execution_count": null,
213 | "metadata": {},
214 | "outputs": [],
215 | "source": [
216 | "clf_sk = LogisticRegression(C=1e15)\n",
217 | "clf_sk.fit(x, y.ravel())\n",
218 | "\n",
219 | "print(clf_sk.coef_, clf_sk.intercept_)\n",
220 | "print(clf_sk.score(x, y))"
221 | ]
222 | },
223 | {
224 | "cell_type": "code",
225 | "execution_count": null,
226 | "metadata": {},
227 | "outputs": [],
228 | "source": [
229 | "x_test = np.linspace(x.min(), x.max(), 100).reshape(-1,1)\n",
230 | "y_sk = clf_sk.predict_proba(x_test)\n",
231 | "\n",
232 | "plt.scatter(x, y, c=y, cmap='bwr')\n",
233 | "plt.plot(x_test, y_sk[:,1], color='black')\n",
234 | "plt.xlabel('idade')\n",
235 | "plt.ylabel('comprou?')"
236 | ]
237 | },
238 | {
239 | "cell_type": "code",
240 | "execution_count": null,
241 | "metadata": {},
242 | "outputs": [],
243 | "source": [
244 | "# implemente a função sigmoid aqui\n"
245 | ]
246 | },
247 | {
248 | "cell_type": "markdown",
249 | "metadata": {},
250 | "source": [
251 | "## Numpy "
252 | ]
253 | },
254 | {
255 | "cell_type": "code",
256 | "execution_count": null,
257 | "metadata": {},
258 | "outputs": [],
259 | "source": [
260 | "# implemente o neurônio sigmoid aqui\n"
261 | ]
262 | },
263 | {
264 | "cell_type": "code",
265 | "execution_count": null,
266 | "metadata": {},
267 | "outputs": [],
268 | "source": [
269 | "x_test = np.linspace(x.min(), x.max(), 100).reshape(-1,1)\n",
270 | "y_sk = clf_sk.predict_proba(x_test)\n",
271 | "y_pred = sigmoid(np.dot(x_test, w.T) + b)\n",
272 | "\n",
273 | "plt.scatter(x, y, c=y, cmap='bwr')\n",
274 | "plt.plot(x_test, y_sk[:,1], color='black', linewidth=7.0)\n",
275 | "plt.plot(x_test, y_pred, color='yellow')\n",
276 | "plt.xlabel('idade')\n",
277 | "plt.ylabel('comprou?')"
278 | ]
279 | },
280 | {
281 | "cell_type": "code",
282 | "execution_count": null,
283 | "metadata": {},
284 | "outputs": [],
285 | "source": [
286 | "print('Acurácia pelo Scikit-learn: {:.2f}%'.format(clf_sk.score(x, y)*100))\n",
287 | "\n",
288 | "y_pred = np.round(sigmoid(np.dot(x, w.T) + b))\n",
289 | "print('Acurária pela nossa implementação: {:.2f}%'.format(accuracy_score(y, y_pred)*100))"
290 | ]
291 | },
292 | {
293 | "cell_type": "markdown",
294 | "metadata": {},
295 | "source": [
296 | "# Exercícios"
297 | ]
298 | },
299 | {
300 | "cell_type": "code",
301 | "execution_count": null,
302 | "metadata": {},
303 | "outputs": [],
304 | "source": [
305 | "x, y = df[['idade', 'salario']].values, df.comprou.values.reshape(-1,1)\n",
306 | "\n",
307 | "print(x.shape, y.shape)"
308 | ]
309 | },
310 | {
311 | "cell_type": "code",
312 | "execution_count": null,
313 | "metadata": {},
314 | "outputs": [],
315 | "source": [
316 | "fig = plt.figure(figsize=(8,6))\n",
317 | "ax = fig.add_subplot(111, projection='3d')\n",
318 | "ax.scatter3D(x[:,0], x[:,1], y, c=y.ravel())"
319 | ]
320 | },
321 | {
322 | "cell_type": "code",
323 | "execution_count": null,
324 | "metadata": {},
325 | "outputs": [],
326 | "source": [
327 | "minmax = MinMaxScaler(feature_range=(-1,1))\n",
328 | "x = minmax.fit_transform(x.astype(np.float64))\n",
329 | "\n",
330 | "print(x.min(), x.max())"
331 | ]
332 | },
333 | {
334 | "cell_type": "code",
335 | "execution_count": null,
336 | "metadata": {},
337 | "outputs": [],
338 | "source": [
339 | "clf_sk = LogisticRegression(C=1e15)\n",
340 | "clf_sk.fit(x, y.ravel())\n",
341 | "\n",
342 | "print(clf_sk.coef_, clf_sk.intercept_)\n",
343 | "print(clf_sk.score(x, y))"
344 | ]
345 | },
346 | {
347 | "cell_type": "markdown",
348 | "metadata": {},
349 | "source": [
350 | "## Numpy"
351 | ]
352 | },
353 | {
354 | "cell_type": "code",
355 | "execution_count": null,
356 | "metadata": {},
357 | "outputs": [],
358 | "source": [
359 | "D = x.shape[1]\n",
360 | "w = 2*np.random.random((1, D))-1 # [1x2]\n",
361 | "b = 2*np.random.random()-1 # [1x1]\n",
362 | "\n",
363 | "learning_rate = 1.0 # <- tente estimar a learning rate\n",
364 | "\n",
365 | "for step in range(1): # <- tente estimar a #epochs\n",
366 | " # calcule a saida do neuronio sigmoid\n",
367 | " z = \n",
368 | " y_pred =\n",
369 | " \n",
370 | " error = y - y_pred # [400x1]\n",
371 | " \n",
372 | " w = w + learning_rate*np.dot(error.T, x)\n",
373 | " b = b + learning_rate*error.sum()\n",
374 | " \n",
375 | " if step%100 == 0:\n",
376 | " # implemente a entropia cruzada (1 linhas)\n",
377 | " cost = \n",
378 | " print('step {0}: {1}'.format(step, cost))\n",
379 | "\n",
380 | "print('w: ', w)\n",
381 | "print('b: ', b)"
382 | ]
383 | },
384 | {
385 | "cell_type": "code",
386 | "execution_count": null,
387 | "metadata": {},
388 | "outputs": [],
389 | "source": [
390 | "x1 = np.linspace(x[:, 0].min(), x[:, 0].max())\n",
391 | "x2 = np.linspace(x[:, 1].min(), x[:, 1].max())\n",
392 | "x1_mesh, x2_mesh = np.meshgrid(x1, x2)\n",
393 | "x1_mesh = x1_mesh.reshape(-1, 1)\n",
394 | "x2_mesh = x2_mesh.reshape(-1, 1)\n",
395 | "\n",
396 | "x_mesh = np.hstack((x1_mesh, x2_mesh))\n",
397 | "y_pred = sigmoid(np.dot(x_mesh, w.T) + b)\n",
398 | "\n",
399 | "fig = plt.figure(figsize=(8, 6))\n",
400 | "ax = fig.add_subplot(111, projection='3d')\n",
401 | "ax.scatter3D(x[:,0], x[:,1], y, c=y.ravel())\n",
402 | "ax.plot_trisurf(x1_mesh.ravel(), x2_mesh.ravel(), y_pred.ravel(), alpha=0.3, shade=False)"
403 | ]
404 | },
405 | {
406 | "cell_type": "code",
407 | "execution_count": null,
408 | "metadata": {},
409 | "outputs": [],
410 | "source": [
411 | "print('Acurácia pelo Scikit-learn: {:.2f}%'.format(clf_sk.score(x, y)*100))\n",
412 | "\n",
413 | "y_pred = np.round(sigmoid(np.dot(x, w.T) + b))\n",
414 | "print('Acurária pela nossa implementação: {:.2f}%'.format(accuracy_score(y, y_pred)*100))"
415 | ]
416 | },
417 | {
418 | "cell_type": "markdown",
419 | "metadata": {},
420 | "source": [
421 | "# Referências"
422 | ]
423 | },
424 | {
425 | "cell_type": "markdown",
426 | "metadata": {},
427 | "source": [
428 | "1. [Logistic Regression from Scratch in Python](https://beckernick.github.io/logistic-regression-from-scratch/)\n",
429 | "2. [Derivative of cost function for logistic Regression](https://math.stackexchange.com/questions/477207/derivative-of-cost-function-for-logistic-regression)"
430 | ]
431 | }
432 | ],
433 | "metadata": {
434 | "kernelspec": {
435 | "display_name": "Python 3",
436 | "language": "python",
437 | "name": "python3"
438 | },
439 | "language_info": {
440 | "codemirror_mode": {
441 | "name": "ipython",
442 | "version": 3
443 | },
444 | "file_extension": ".py",
445 | "mimetype": "text/x-python",
446 | "name": "python",
447 | "nbconvert_exporter": "python",
448 | "pygments_lexer": "ipython3",
449 | "version": "3.6.5"
450 | }
451 | },
452 | "nbformat": 4,
453 | "nbformat_minor": 2
454 | }
455 |
--------------------------------------------------------------------------------
/Perceptron.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "No notebook anterior, nós aprendemos intuitivamente como o perceptron aprende. De maneira geral, nós vamos atualizando os pesos e o bias sempre buscando diminuir uma função de custo. Nesse notebook, nós vamos ver como esse aprendizado realmente acontence, tanto na teoria quanto na prática. Também utilizaremos o Perceptron para resolver problemas de classificação e regressão.\n",
8 | "\n",
9 | "__Objetivos__:\n",
10 | "\n",
11 | "- Implementar o perceptron e seu modelo de aprendizado em Python puro e Numpy\n",
12 | "- Utilizar o perceptron para regressão e classificação"
13 | ]
14 | },
15 | {
16 | "cell_type": "markdown",
17 | "metadata": {
18 | "heading_collapsed": true
19 | },
20 | "source": [
21 | "# Sumário"
22 | ]
23 | },
24 | {
25 | "cell_type": "markdown",
26 | "metadata": {
27 | "hidden": true
28 | },
29 | "source": [
30 | "[Introdução](#Introdução)\n",
31 | "- [Regra de Aprendizado do Perceptron](#Regra-de-Aprendizado-do-Perceptron)\n",
32 | "- [Pseudo-algoritmo do Perceptron](#Pseudo-algoritmo-do-Perceptron)\n",
33 | "\n",
34 | "[Classificação](#Classificação)\n",
35 | "- [Porta AND/OR](#Porta-AND/OR)\n",
36 | "- [Exercício de Classificação](#Exerc%C3%ADcio-de-Classificação)\n",
37 | "\n",
38 | "[Regressão](#Regressão)\n",
39 | "- [Exercício de Regressão](#Exerc%C3%ADcio-de-Regressão)\n",
40 | "\n",
41 | "[Referências](#Referências)"
42 | ]
43 | },
44 | {
45 | "cell_type": "markdown",
46 | "metadata": {},
47 | "source": [
48 | "# Imports e Configurações"
49 | ]
50 | },
51 | {
52 | "cell_type": "code",
53 | "execution_count": null,
54 | "metadata": {
55 | "ExecuteTime": {
56 | "end_time": "2017-09-20T12:53:30.345746Z",
57 | "start_time": "2017-09-20T12:52:48.057739Z"
58 | }
59 | },
60 | "outputs": [],
61 | "source": [
62 | "import numpy as np\n",
63 | "import pandas as pd\n",
64 | "import matplotlib.pyplot as plt\n",
65 | "from random import random\n",
66 | "from sklearn.linear_model import LinearRegression\n",
67 | "from sklearn.preprocessing import MinMaxScaler\n",
68 | "from sklearn.datasets import make_blobs\n",
69 | "\n",
70 | "%matplotlib inline"
71 | ]
72 | },
73 | {
74 | "cell_type": "markdown",
75 | "metadata": {
76 | "heading_collapsed": true
77 | },
78 | "source": [
79 | "# Introdução"
80 | ]
81 | },
82 | {
83 | "cell_type": "markdown",
84 | "metadata": {
85 | "hidden": true
86 | },
87 | "source": [
88 | "O tipo mais básico de Rede Neural Artificial é formada por apenas um neurônio, o __Perceptron__. Inicialmente, o Perceptron foi projetado para ser um __classificador binário linear__ responsável por mapear uma ou mais entradas em uma saída desejada. Porém, também podemos utilizá-lo para resolver problemas de __regressão linear__. Ele foi projetado em 1957 por Frank Rosenblatt.\n",
89 | "\n",
90 | "O perceptron é formado por:\n",
91 | "\n",
92 | "
\n",
93 | "\n",
94 | "- __entradas__ $x_1,...,x_D$: representam os atributos dos seus dados com dimensionalidade $D$. O Perceptron aceita qualquer tamanho de entrada, porém a saída é sempre apenas um valor.\n",
95 | "- __junção aditiva__ $\\sum$: também chamada de _função agregadora_, nada mais é que a soma ponderada das entradas com os __pesos__ ($w_1,...,w_D)$. Em geral, o resultado é somado com um __bias__ $b$, responsável por deslocar o resultado do somatório. A junção aditiva é descrita pela seguinte fórmula:\n",
96 | "\n",
97 | "$$\\sum_i^D{x_iw_i} + b$$\n",
98 | "\n",
99 | "- __função de ativação__ $f$: utilizada para mapear o resultado da junção aditiva em uma saída esperada. Mais detalhes abaixo.\n",
100 | "\n",
101 | "Logo, o Perceptron é representado pela seguinte fórmula matemática:\n",
102 | "\n",
103 | "$$\\widehat{y}_i = f(\\sum_i^D{x_iw_i} + b)$$\n",
104 | "\n",
105 | "Onde:\n",
106 | "\n",
107 | "- $D$: representa a dimensionalidade das amostras, ou seja, a quantidade de atributos de cada amostra.\n",
108 | "- $x_i$: representam os atributos de uma amostra que servem de entrada para o Perceptron.\n",
109 | "- $w_i$: representam os __pesos sinápticos__ que ponderam as entradas.\n",
110 | "- $b$: representa o __bias__, responsável por deslocar a fronteira de decisão além da origem e não depende de nenhum valor de entrada. Repare que o bias encontra-se fora do somatório.\n",
111 | "- $f$: __função de ativação__. Quando a função de ativação é linear, ou seja, nenhuma transformação é aplicada no resultado da junção aditiva, o Perceptron atua como um __Regressor Linear__. Se precisamos efetuar uma __Classificação binária__, devemos utilizar a função _step_ (também conhecida como _função degrau_) para mapear a saída em um valor discreto (0 ou 1):\n",
112 | "\n",
113 | "$$f = \\begin{cases}1 & se \\ wx+b > 0\\\\0 & caso \\ contr\\acute ario\\end{cases}$$\n",
114 | "\n",
115 | "- $\\widehat{y}$: representa a saída do Perceptron (o valor predito).\n",
116 | "\n",
117 | "__Observações importantes__:\n",
118 | "\n",
119 | "- O Perceptron não faz __Classificação Multiclasse__.\n",
120 | "- __A atualização dos pesos é *online*, ou seja, efetuada amostra a amostra__ utilizando uma fórmula pré-definida que veremos na seção a seguir."
121 | ]
122 | },
123 | {
124 | "cell_type": "markdown",
125 | "metadata": {},
126 | "source": [
127 | "## Regra de Aprendizado do Perceptron"
128 | ]
129 | },
130 | {
131 | "cell_type": "markdown",
132 | "metadata": {},
133 | "source": [
134 | "O Perceptron tem sua própria forma de aprendizado conforme definido no seu artigo original. Na verdade, a fórmula para atualização dos pesos e bias é bem simples:\n",
135 | "\n",
136 | "$$w_i = w_i + \\lambda(y_i - \\widehat{y}_i)x_i$$\n",
137 | "
\n",
138 | "$$b_i = b_i + \\lambda(y_i - \\widehat{y}_i)$$\n",
139 | "\n",
140 | "Onde $\\lambda$ é a __taxa de aprendizagem__ (___learning rate___).\n",
141 | "\n",
142 | "Repare que $y_i - \\widehat{y}_i$ significa calcular a diferença entre o valor esperado ($y_i$) e o valor predito ($\\widehat{y}_i$). Supondo que estamos fazendo __classificação binária__ de uma amostra $(x_i, y_i)$. Nesse caso, teremos duas possibilidades:\n",
143 | "- __O valor esperado é $y_i = \\widehat{y}_i$__, ou seja, a saída do Perceptron (após a função de ativação _step_) é __igual__ a saída esperada. Nesse caso, __a diferença $y_i - \\widehat{y}_i = 0$ e não haverá atualização de pesos__.\n",
144 | "- __O valor esperado é $y_i \\neq \\widehat{y}_i$__, ou seja, a saída do Perceptron (após a função de ativação _step_) é __diferente__ da saída esperada. Nesse caso, __a atualização dos pesos será dada pela diferença $y_i - \\widehat{y}_i$__. Repare que:\n",
145 | " - quando essa diferença é __negativa__ (ou seja, $y_i = 0$ e $\\widehat{y}_i = 1$), __os pesos tendem a diminuir__.\n",
146 | " - quando essa diferença é __positiva__ (ou seja, $y_i = 1$ e $\\widehat{y}_i = 0$), __os pesos tendem a aumentar__."
147 | ]
148 | },
149 | {
150 | "cell_type": "markdown",
151 | "metadata": {},
152 | "source": [
153 | "## Pseudo-algoritmo do Perceptron"
154 | ]
155 | },
156 | {
157 | "cell_type": "markdown",
158 | "metadata": {},
159 | "source": [
160 | "1. Inicialize os pesos $w$ e o bias $b$\n",
161 | "2. Para cada amostra $(x_n, y_n)$ do nosso banco:\n",
162 | " 1. Calcule $\\widehat{y} = f(\\sum_i^D{x_iw_i} + b)$, onde $f$ é a __função _step_ para classificação__ e __linear no caso da regressão__\n",
163 | " 2. Calcule o $erro = y_n - \\widehat{y}$\n",
164 | " 3. Atualize os pesos $w_i = w_i + \\lambda*erro*x_i$\n",
165 | " 4. Atualize o bias $b_i = b_i + \\lambda*erro$\n",
166 | "3. Repita o passo 2 por N vezes ou até que alguma medida de custo para o $erro$ seja menor que um valor pré-determinado.\n",
167 | " \n",
168 | "Repare, como dito lá em cima, que __a atualização dos pesos e bias é feito a cada amostra__, e não somente após ver todas as amostras do banco."
169 | ]
170 | },
171 | {
172 | "cell_type": "markdown",
173 | "metadata": {},
174 | "source": [
175 | "# Classificação"
176 | ]
177 | },
178 | {
179 | "cell_type": "markdown",
180 | "metadata": {},
181 | "source": [
182 | "## Porta AND/OR"
183 | ]
184 | },
185 | {
186 | "cell_type": "code",
187 | "execution_count": null,
188 | "metadata": {
189 | "ExecuteTime": {
190 | "end_time": "2017-09-15T11:11:37.370366Z",
191 | "start_time": "2017-09-15T11:11:37.359356Z"
192 | }
193 | },
194 | "outputs": [],
195 | "source": [
196 | "x = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])\n",
197 | "#y = np.array([0, 1, 1, 1]) # porta OR\n",
198 | "y = np.array([0, 0, 0, 1]).T # porta AND\n",
199 | "\n",
200 | "print(x.shape, y.shape)"
201 | ]
202 | },
203 | {
204 | "cell_type": "markdown",
205 | "metadata": {
206 | "heading_collapsed": true
207 | },
208 | "source": [
209 | "### Python"
210 | ]
211 | },
212 | {
213 | "cell_type": "code",
214 | "execution_count": null,
215 | "metadata": {
216 | "ExecuteTime": {
217 | "end_time": "2017-09-15T11:21:18.798586Z",
218 | "start_time": "2017-09-15T11:21:18.667487Z"
219 | },
220 | "hidden": true
221 | },
222 | "outputs": [],
223 | "source": []
224 | },
225 | {
226 | "cell_type": "markdown",
227 | "metadata": {
228 | "heading_collapsed": true
229 | },
230 | "source": [
231 | "### Numpy"
232 | ]
233 | },
234 | {
235 | "cell_type": "code",
236 | "execution_count": null,
237 | "metadata": {
238 | "ExecuteTime": {
239 | "end_time": "2017-09-15T12:21:02.603975Z",
240 | "start_time": "2017-09-15T12:21:02.555936Z"
241 | },
242 | "hidden": true
243 | },
244 | "outputs": [],
245 | "source": []
246 | },
247 | {
248 | "cell_type": "markdown",
249 | "metadata": {
250 | "collapsed": true
251 | },
252 | "source": [
253 | "## Exercício de Classificação"
254 | ]
255 | },
256 | {
257 | "cell_type": "code",
258 | "execution_count": null,
259 | "metadata": {},
260 | "outputs": [],
261 | "source": [
262 | "x, y = make_blobs(n_samples=100, n_features=2, centers=2, random_state=1234)\n",
263 | "\n",
264 | "print(x.shape, y.shape)\n",
265 | "plt.scatter(x[:,0], x[:,1], c=y.ravel(), cmap='bwr')"
266 | ]
267 | },
268 | {
269 | "cell_type": "code",
270 | "execution_count": null,
271 | "metadata": {},
272 | "outputs": [],
273 | "source": [
274 | "def plot_linear_classifier(x, y, w, b):\n",
275 | " x1_min, x1_max = x[:,0].min(), x[:,0].max()\n",
276 | " x2_min, x2_max = x[:,1].min(), x[:,1].max()\n",
277 | "\n",
278 | " x1, x2 = np.meshgrid(np.linspace(x1_min-1, x1_max+1,100), np.linspace(x2_min-1, x2_max+1, 100))\n",
279 | " x_mesh = np.array([x1.ravel(), x2.ravel()]).T\n",
280 | "\n",
281 | " plt.scatter(x[:,0], x[:,1], c=y.ravel(), cmap='bwr')\n",
282 | "\n",
283 | " y_mesh = np.dot(x_mesh, np.array(w).reshape(1, -1).T) + b\n",
284 | " y_mesh = np.where(y_mesh <= 0, 0, 1)\n",
285 | "\n",
286 | " plt.contourf(x1, x2, y_mesh.reshape(x1.shape), cmap='bwr', alpha=0.5)\n",
287 | " plt.xlim(x1_min-1, x1_max+1)\n",
288 | " plt.ylim(x2_min-1, x2_max+1)"
289 | ]
290 | },
291 | {
292 | "cell_type": "markdown",
293 | "metadata": {},
294 | "source": [
295 | "### Python"
296 | ]
297 | },
298 | {
299 | "cell_type": "code",
300 | "execution_count": null,
301 | "metadata": {},
302 | "outputs": [],
303 | "source": []
304 | },
305 | {
306 | "cell_type": "markdown",
307 | "metadata": {},
308 | "source": [
309 | "### Numpy"
310 | ]
311 | },
312 | {
313 | "cell_type": "code",
314 | "execution_count": null,
315 | "metadata": {},
316 | "outputs": [],
317 | "source": []
318 | },
319 | {
320 | "cell_type": "markdown",
321 | "metadata": {
322 | "heading_collapsed": true
323 | },
324 | "source": [
325 | "# Regressão "
326 | ]
327 | },
328 | {
329 | "cell_type": "markdown",
330 | "metadata": {
331 | "collapsed": true
332 | },
333 | "source": [
334 | "Para transformar o Perceptron em um __regressor linear__, só o que temos de fazer é __remover a função de ativação _step___, transformando-a em uma função de ativação linear.\n",
335 | "\n",
336 | "Apesar dessa modificação, __a fórmula de atualização dos pesos não sofre nenhuma alteração__. \n",
337 | "\n",
338 | "Vamos, então, implementar nosso perceptron para classificação em Python, Numpy, Keras e TensorFlow:"
339 | ]
340 | },
341 | {
342 | "cell_type": "code",
343 | "execution_count": null,
344 | "metadata": {
345 | "ExecuteTime": {
346 | "end_time": "2017-09-14T19:21:04.802972Z",
347 | "start_time": "2017-09-14T19:21:04.773952Z"
348 | },
349 | "hidden": true
350 | },
351 | "outputs": [],
352 | "source": [
353 | "df = pd.read_csv('data/medidas.csv')\n",
354 | "print(df.shape)\n",
355 | "df.head(10)"
356 | ]
357 | },
358 | {
359 | "cell_type": "code",
360 | "execution_count": null,
361 | "metadata": {
362 | "ExecuteTime": {
363 | "end_time": "2017-09-14T19:21:08.765341Z",
364 | "start_time": "2017-09-14T19:21:08.441110Z"
365 | },
366 | "hidden": true
367 | },
368 | "outputs": [],
369 | "source": [
370 | "x = df.Altura.values\n",
371 | "y = df.Peso.values\n",
372 | "\n",
373 | "plt.figure()\n",
374 | "plt.scatter(x, y)\n",
375 | "plt.xlabel('Altura')\n",
376 | "plt.ylabel('Peso')"
377 | ]
378 | },
379 | {
380 | "cell_type": "code",
381 | "execution_count": null,
382 | "metadata": {
383 | "ExecuteTime": {
384 | "end_time": "2017-09-14T19:21:10.893855Z",
385 | "start_time": "2017-09-14T19:21:10.883847Z"
386 | },
387 | "hidden": true
388 | },
389 | "outputs": [],
390 | "source": [
391 | "print(x.shape, y.shape)"
392 | ]
393 | },
394 | {
395 | "cell_type": "code",
396 | "execution_count": null,
397 | "metadata": {
398 | "ExecuteTime": {
399 | "end_time": "2017-09-14T19:21:11.535313Z",
400 | "start_time": "2017-09-14T19:21:11.527304Z"
401 | },
402 | "hidden": true
403 | },
404 | "outputs": [],
405 | "source": [
406 | "x = x.reshape(-1, 1)\n",
407 | "\n",
408 | "print(x.shape, y.shape)"
409 | ]
410 | },
411 | {
412 | "cell_type": "markdown",
413 | "metadata": {
414 | "heading_collapsed": true,
415 | "hidden": true
416 | },
417 | "source": [
418 | "### Python"
419 | ]
420 | },
421 | {
422 | "cell_type": "markdown",
423 | "metadata": {
424 | "hidden": true
425 | },
426 | "source": [
427 | "__Exercício__: tentar estimar as learning_rates de **w** e __b__. Elas são diferentes por que nossos dados não estão na mesma escala!"
428 | ]
429 | },
430 | {
431 | "cell_type": "code",
432 | "execution_count": null,
433 | "metadata": {
434 | "ExecuteTime": {
435 | "end_time": "2017-09-14T19:21:38.253347Z",
436 | "start_time": "2017-09-14T19:21:16.413722Z"
437 | },
438 | "hidden": true
439 | },
440 | "outputs": [],
441 | "source": [
442 | "D = x.shape[1]\n",
443 | "w = [2*random() - 1 for i in range(D)]\n",
444 | "b = 2*random() - 1\n",
445 | "\n",
446 | "for step in range(10001):\n",
447 | " cost = 0\n",
448 | " for x_n, y_n in zip(x, y):\n",
449 | " # qual linha devemos remover para transformar o Perceptron num regressor?\n",
450 | " y_pred = sum([x_i*w_i for x_i, w_i in zip(x_n, w)]) + b\n",
451 | " y_pred = 1 if y_pred > 0 else 0\n",
452 | " error = y_n - y_pred\n",
453 | " w = [w_i + 1.0*error*x_i for x_i, w_i in zip(x_n, w)]\n",
454 | " b = b + 1.0*error\n",
455 | " cost += error**2\n",
456 | "\n",
457 | " if step%1000 == 0:\n",
458 | " print('step {0}: {1}'.format(step, cost))\n",
459 | "\n",
460 | "print('w: ', w)\n",
461 | "print('b: ', b)"
462 | ]
463 | },
464 | {
465 | "cell_type": "markdown",
466 | "metadata": {
467 | "hidden": true
468 | },
469 | "source": [
470 | "### Numpy "
471 | ]
472 | },
473 | {
474 | "cell_type": "code",
475 | "execution_count": null,
476 | "metadata": {
477 | "ExecuteTime": {
478 | "end_time": "2017-09-14T19:21:45.406815Z",
479 | "start_time": "2017-09-14T19:21:45.008532Z"
480 | },
481 | "hidden": true
482 | },
483 | "outputs": [],
484 | "source": [
485 | "D = x.shape[1]\n",
486 | "w = 2*np.random.random(size=D)-1\n",
487 | "b = 2*np.random.random()-1 \n",
488 | "\n",
489 | "for step in range(10001):\n",
490 | " cost = 0\n",
491 | " for x_n, y_n in zip(x, y):\n",
492 | " # qual linha devemos remover para transformar o Perceptron num regressor?\n",
493 | " y_pred = np.dot(x_n, w) + b \n",
494 | " y_pred = np.where(y_pred > 0, 1, 0)\n",
495 | " error = y_n - y_pred\n",
496 | " w = w + 1.0*np.dot(error, x_n)\n",
497 | " b = b + 1.0*error\n",
498 | " cost += error**2\n",
499 | " \n",
500 | " if step%1000 == 0:\n",
501 | " print('step {0}: {1}'.format(step, cost))\n",
502 | " \n",
503 | "print('w: ', w)\n",
504 | "print('b: ', b)"
505 | ]
506 | },
507 | {
508 | "cell_type": "markdown",
509 | "metadata": {
510 | "hidden": true
511 | },
512 | "source": [
513 | "### Numpy com Pré-processamento"
514 | ]
515 | },
516 | {
517 | "cell_type": "code",
518 | "execution_count": null,
519 | "metadata": {
520 | "ExecuteTime": {
521 | "end_time": "2017-09-14T19:22:08.568244Z",
522 | "start_time": "2017-09-14T19:22:08.561239Z"
523 | },
524 | "hidden": true
525 | },
526 | "outputs": [],
527 | "source": [
528 | "minmax = MinMaxScaler(feature_range=(-1,1))\n",
529 | "x = minmax.fit_transform(x.astype(np.float64))\n",
530 | "\n",
531 | "print(x.min(), x.max())"
532 | ]
533 | },
534 | {
535 | "cell_type": "code",
536 | "execution_count": null,
537 | "metadata": {},
538 | "outputs": [],
539 | "source": [
540 | "reg = LinearRegression()\n",
541 | "reg.fit(x,y)\n",
542 | "\n",
543 | "print('w: ', reg.coef_)\n",
544 | "print('b: ', reg.intercept_)"
545 | ]
546 | },
547 | {
548 | "cell_type": "code",
549 | "execution_count": null,
550 | "metadata": {
551 | "ExecuteTime": {
552 | "end_time": "2017-09-14T19:22:33.763665Z",
553 | "start_time": "2017-09-14T19:22:33.556518Z"
554 | },
555 | "hidden": true
556 | },
557 | "outputs": [],
558 | "source": [
559 | "D = x.shape[1]\n",
560 | "w = 2*np.random.random(size=D)-1\n",
561 | "b = 2*np.random.random()-1 \n",
562 | "\n",
563 | "learning_rate = 1.0 # <- tente estimar a learning_rate\n",
564 | "\n",
565 | "for step in range(1001):\n",
566 | " cost = 0\n",
567 | " for x_n, y_n in zip(x, y):\n",
568 | " y_pred = np.dot(x_n, w) + b \n",
569 | " error = y_n - y_pred\n",
570 | " w = w + learning_rate*np.dot(error, x_n)\n",
571 | " b = b + learning_rate*error\n",
572 | " cost += error**2\n",
573 | " \n",
574 | " if step%100 == 0:\n",
575 | " print('step {0}: {1}'.format(step, cost))\n",
576 | " \n",
577 | "print('w: ', w)\n",
578 | "print('b: ', b)"
579 | ]
580 | },
581 | {
582 | "cell_type": "markdown",
583 | "metadata": {
584 | "hidden": true
585 | },
586 | "source": [
587 | "## Exercício de Regressão"
588 | ]
589 | },
590 | {
591 | "cell_type": "code",
592 | "execution_count": null,
593 | "metadata": {
594 | "ExecuteTime": {
595 | "end_time": "2017-09-15T10:56:07.079178Z",
596 | "start_time": "2017-09-15T10:56:06.991114Z"
597 | },
598 | "hidden": true
599 | },
600 | "outputs": [],
601 | "source": [
602 | "df = pd.read_csv('data/notas.csv')\n",
603 | "\n",
604 | "print(df.shape)\n",
605 | "df.head(10)"
606 | ]
607 | },
608 | {
609 | "cell_type": "code",
610 | "execution_count": null,
611 | "metadata": {},
612 | "outputs": [],
613 | "source": [
614 | "plt.figure(figsize=(20, 4))\n",
615 | "\n",
616 | "plt.subplot(1, 3, 1)\n",
617 | "plt.scatter(df.prova1.values, df.final.values)\n",
618 | "plt.xlabel('Prova 1')\n",
619 | "plt.ylabel('Final')\n",
620 | "\n",
621 | "plt.subplot(1, 3, 2)\n",
622 | "plt.scatter(df.prova2.values, df.final.values)\n",
623 | "plt.xlabel('Prova 2')\n",
624 | "plt.ylabel('Final')\n",
625 | "\n",
626 | "plt.subplot(1, 3, 3)\n",
627 | "plt.scatter(df.prova3.values, df.final.values)\n",
628 | "plt.xlabel('Prova 3')\n",
629 | "plt.ylabel('Final')"
630 | ]
631 | },
632 | {
633 | "cell_type": "code",
634 | "execution_count": null,
635 | "metadata": {
636 | "ExecuteTime": {
637 | "end_time": "2017-09-15T10:56:14.202826Z",
638 | "start_time": "2017-09-15T10:56:14.189835Z"
639 | },
640 | "hidden": true
641 | },
642 | "outputs": [],
643 | "source": [
644 | "x = df[['prova1', 'prova2', 'prova3']].values\n",
645 | "y = df['final'].values\n",
646 | "\n",
647 | "print(x.shape, y.shape)"
648 | ]
649 | },
650 | {
651 | "cell_type": "code",
652 | "execution_count": null,
653 | "metadata": {
654 | "ExecuteTime": {
655 | "end_time": "2017-09-15T10:56:15.149753Z",
656 | "start_time": "2017-09-15T10:56:15.143751Z"
657 | },
658 | "hidden": true
659 | },
660 | "outputs": [],
661 | "source": [
662 | "minmax = MinMaxScaler(feature_range=(-1,1))\n",
663 | "x = minmax.fit_transform(x.astype(np.float64))"
664 | ]
665 | },
666 | {
667 | "cell_type": "code",
668 | "execution_count": null,
669 | "metadata": {
670 | "ExecuteTime": {
671 | "end_time": "2017-09-14T19:24:23.821886Z",
672 | "start_time": "2017-09-14T19:24:23.678784Z"
673 | },
674 | "hidden": true
675 | },
676 | "outputs": [],
677 | "source": [
678 | "reg = LinearRegression()\n",
679 | "reg.fit(x, y)\n",
680 | "\n",
681 | "print('w: ', reg.coef_)\n",
682 | "print('b: ', reg.intercept_)"
683 | ]
684 | },
685 | {
686 | "cell_type": "markdown",
687 | "metadata": {
688 | "heading_collapsed": true,
689 | "hidden": true
690 | },
691 | "source": [
692 | "### Python"
693 | ]
694 | },
695 | {
696 | "cell_type": "code",
697 | "execution_count": null,
698 | "metadata": {
699 | "ExecuteTime": {
700 | "end_time": "2017-09-14T19:24:36.348182Z",
701 | "start_time": "2017-09-14T19:24:33.850407Z"
702 | },
703 | "hidden": true
704 | },
705 | "outputs": [],
706 | "source": [
707 | "D = x.shape[1]\n",
708 | "w = [2*random() - 1 for i in range(D)]\n",
709 | "b = 2*random() - 1\n",
710 | "\n",
711 | "learning_rate = 1.0 # <- tente estimar a learning_rate\n",
712 | "\n",
713 | "for step in range(1): # <- tente estimar o número de passos\n",
714 | " cost = 0\n",
715 | " for x_n, y_n in zip(x, y):\n",
716 | " y_pred = sum([x_i*w_i for x_i, w_i in zip(x_n, w)]) + b\n",
717 | " error = y_n - y_pred\n",
718 | " w = [w_i + learning_rate*error*x_i for x_i, w_i in zip(x_n, w)]\n",
719 | " b = b + learning_rate*error\n",
720 | " cost += error**2\n",
721 | " \n",
722 | " if step%200 == 0:\n",
723 | " print('step {0}: {1}'.format(step, cost))\n",
724 | "\n",
725 | "print('w: ', w)\n",
726 | "print('b: ', b)"
727 | ]
728 | },
729 | {
730 | "cell_type": "markdown",
731 | "metadata": {
732 | "heading_collapsed": true,
733 | "hidden": true
734 | },
735 | "source": [
736 | "### Numpy"
737 | ]
738 | },
739 | {
740 | "cell_type": "code",
741 | "execution_count": null,
742 | "metadata": {
743 | "ExecuteTime": {
744 | "end_time": "2017-09-14T19:24:55.296538Z",
745 | "start_time": "2017-09-14T19:24:54.907259Z"
746 | },
747 | "hidden": true
748 | },
749 | "outputs": [],
750 | "source": [
751 | "D = x.shape[1]\n",
752 | "w = 2*np.random.random(size=D)-1\n",
753 | "b = 2*np.random.random()-1 \n",
754 | "\n",
755 | "learning_rate = 1.0 # <- tente estimar a learning_rate\n",
756 | "\n",
757 | "for step in range(1): # <- tente estimar o número de passos\n",
758 | " cost = 0\n",
759 | " for x_n, y_n in zip(x, y):\n",
760 | " y_pred = np.dot(x_n, w) + b \n",
761 | " error = y_n - y_pred\n",
762 | " w = w + learning_rate*np.dot(error, x_n)\n",
763 | " b = b + learning_rate*error\n",
764 | " cost += error**2\n",
765 | " \n",
766 | " if step%200 == 0:\n",
767 | " print('step {0}: {1}'.format(step, cost))\n",
768 | " \n",
769 | "print('w: ', w)\n",
770 | "print('b: ', b)"
771 | ]
772 | },
773 | {
774 | "cell_type": "markdown",
775 | "metadata": {},
776 | "source": [
777 | "# Referências"
778 | ]
779 | },
780 | {
781 | "cell_type": "markdown",
782 | "metadata": {},
783 | "source": [
784 | "- [Artigo original do Perceptron](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.335.3398&rep=rep1&type=pdf)"
785 | ]
786 | }
787 | ],
788 | "metadata": {
789 | "kernelspec": {
790 | "display_name": "Python 3",
791 | "language": "python",
792 | "name": "python3"
793 | },
794 | "language_info": {
795 | "codemirror_mode": {
796 | "name": "ipython",
797 | "version": 3
798 | },
799 | "file_extension": ".py",
800 | "mimetype": "text/x-python",
801 | "name": "python",
802 | "nbconvert_exporter": "python",
803 | "pygments_lexer": "ipython3",
804 | "version": "3.6.5"
805 | }
806 | },
807 | "nbformat": 4,
808 | "nbformat_minor": 2
809 | }
810 |
--------------------------------------------------------------------------------
/Perceptron_Intuicao.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "__Objetivos__: \n",
8 | "- entender como o perceptron funciona intuitivamente, tanto em regressão quanto em classificação."
9 | ]
10 | },
11 | {
12 | "cell_type": "markdown",
13 | "metadata": {},
14 | "source": [
15 | "# Sumário"
16 | ]
17 | },
18 | {
19 | "cell_type": "markdown",
20 | "metadata": {},
21 | "source": [
22 | "[Regressão](#Regressão)\n",
23 | "\n",
24 | "[Classificação](#Classificação)\n",
25 | "- [Porta AND](#Porta-AND)\n",
26 | "- [Porta OR](#Porta-OR)\n",
27 | "- [Porta XOR](#Porta-XOR)"
28 | ]
29 | },
30 | {
31 | "cell_type": "markdown",
32 | "metadata": {},
33 | "source": [
34 | "# Imports"
35 | ]
36 | },
37 | {
38 | "cell_type": "code",
39 | "execution_count": null,
40 | "metadata": {
41 | "ExecuteTime": {
42 | "end_time": "2017-09-12T12:19:56.559341Z",
43 | "start_time": "2017-09-12T12:19:55.344478Z"
44 | }
45 | },
46 | "outputs": [],
47 | "source": [
48 | "import numpy as np\n",
49 | "import pandas as pd\n",
50 | "import matplotlib.pyplot as plt\n",
51 | "import ipywidgets as wg\n",
52 | "from ipywidgets import interactive, fixed\n",
53 | "\n",
54 | "%matplotlib inline\n",
55 | "\n",
56 | "# jupyter nbextension enable --py widgetsnbextension --sys-prefix\n",
57 | "# restart jupyter notebook"
58 | ]
59 | },
60 | {
61 | "cell_type": "markdown",
62 | "metadata": {},
63 | "source": [
64 | "# Regressão "
65 | ]
66 | },
67 | {
68 | "cell_type": "code",
69 | "execution_count": null,
70 | "metadata": {
71 | "ExecuteTime": {
72 | "end_time": "2017-09-12T12:19:58.026525Z",
73 | "start_time": "2017-09-12T12:19:57.992499Z"
74 | }
75 | },
76 | "outputs": [],
77 | "source": [
78 | "df = pd.read_csv('data/medidas.csv')\n",
79 | "print(df.shape)\n",
80 | "df.head(10)"
81 | ]
82 | },
83 | {
84 | "cell_type": "code",
85 | "execution_count": null,
86 | "metadata": {
87 | "ExecuteTime": {
88 | "end_time": "2017-09-12T12:20:01.271158Z",
89 | "start_time": "2017-09-12T12:20:00.922905Z"
90 | }
91 | },
92 | "outputs": [],
93 | "source": [
94 | "x = df.Altura\n",
95 | "y = df.Peso\n",
96 | "\n",
97 | "plt.figure()\n",
98 | "plt.scatter(x, y)\n",
99 | "plt.xlabel('Altura')\n",
100 | "plt.ylabel('Peso')"
101 | ]
102 | },
103 | {
104 | "cell_type": "code",
105 | "execution_count": null,
106 | "metadata": {
107 | "ExecuteTime": {
108 | "end_time": "2017-09-12T12:20:55.215232Z",
109 | "start_time": "2017-09-12T12:20:55.145178Z"
110 | }
111 | },
112 | "outputs": [],
113 | "source": [
114 | "def plot_line(w, b):\n",
115 | " plt.figure(0, figsize=(20,4))\n",
116 | " plt.subplot(1,3,3)\n",
117 | " plt.scatter(x, y)\n",
118 | " y_pred = x*w + b\n",
119 | " plt.plot(x, y_pred, c='red')\n",
120 | " plt.xlim(140, 210)\n",
121 | " plt.ylim(40, 120)\n",
122 | " \n",
123 | " plt.subplot(1,3,2)\n",
124 | " x_ = np.array([0, x.max()])\n",
125 | " y_ = x_*w + b\n",
126 | " plt.scatter(x, y)\n",
127 | " plt.plot(x_, y_, c='red')\n",
128 | " plt.xlim(0, 210)\n",
129 | " plt.ylim(-160, 120)\n",
130 | " \n",
131 | " plt.subplot(1,3,1)\n",
132 | " mse = np.mean((y - y_pred)**2)\n",
133 | " loss.append(mse)\n",
134 | " plt.plot(loss)\n",
135 | " plt.title('Loss')\n",
136 | " \n",
137 | " plt.show()"
138 | ]
139 | },
140 | {
141 | "cell_type": "code",
142 | "execution_count": null,
143 | "metadata": {
144 | "ExecuteTime": {
145 | "end_time": "2017-09-12T12:20:56.782344Z",
146 | "start_time": "2017-09-12T12:20:55.705578Z"
147 | }
148 | },
149 | "outputs": [],
150 | "source": [
151 | "loss = []\n",
152 | "\n",
153 | "interactive_plot = interactive(plot_line, w=(1, 1.5, 0.01), b=(-200, 0, 1))\n",
154 | "output = interactive_plot.children[-1]\n",
155 | "output.layout_height = '350px'\n",
156 | "interactive_plot"
157 | ]
158 | },
159 | {
160 | "cell_type": "code",
161 | "execution_count": null,
162 | "metadata": {
163 | "ExecuteTime": {
164 | "end_time": "2017-09-12T12:22:03.437838Z",
165 | "start_time": "2017-09-12T12:21:50.268473Z"
166 | }
167 | },
168 | "outputs": [],
169 | "source": [
170 | "from sklearn.linear_model import LinearRegression\n",
171 | "\n",
172 | "reg = LinearRegression()\n",
173 | "reg.fit(x.values.reshape(-1,1), y)\n",
174 | "print(\"w: {:.2f} \\nb: {:.2f}\".format(reg.coef_[0], reg.intercept_))"
175 | ]
176 | },
177 | {
178 | "cell_type": "markdown",
179 | "metadata": {},
180 | "source": [
181 | "# Classificação"
182 | ]
183 | },
184 | {
185 | "cell_type": "code",
186 | "execution_count": null,
187 | "metadata": {
188 | "ExecuteTime": {
189 | "end_time": "2017-09-12T12:57:48.364600Z",
190 | "start_time": "2017-09-12T12:57:48.232507Z"
191 | }
192 | },
193 | "outputs": [],
194 | "source": [
195 | "def plot_line(w1, w2, b):\n",
196 | " x1, x2 = np.meshgrid(np.linspace(0,1,100), np.linspace(0,1,100))\n",
197 | " x_mesh = np.array([x1.ravel(), x2.ravel()]).T\n",
198 | " \n",
199 | " plt.figure(0, figsize=(10,4))\n",
200 | " plt.subplot(1,2,2)\n",
201 | " plt.scatter(x[:,0], x[:,1], c=y.ravel(), s=100, cmap='bwr')\n",
202 | " \n",
203 | " y_mesh = np.dot(x_mesh, np.array([w1, w2]).T) + b\n",
204 | " y_mesh = np.where(y_mesh <= 0, 0, 1)\n",
205 | "\n",
206 | " plt.contourf(x1, x2, y_mesh.reshape(x1.shape), cmap='bwr')\n",
207 | " \n",
208 | " y_pred = np.dot(x, np.array([w1, w2]).T) + b\n",
209 | " y_bin = np.where(y_pred <= 0, 0, 1)\n",
210 | " print('{0} => {1}'.format(y_pred, y_bin))\n",
211 | " \n",
212 | " plt.subplot(1,2,1)\n",
213 | " mse = np.mean((y.ravel() - y_bin)**2)\n",
214 | " loss.append(mse)\n",
215 | " plt.plot(loss)\n",
216 | " plt.title('Loss')\n",
217 | " \n",
218 | " plt.show()"
219 | ]
220 | },
221 | {
222 | "cell_type": "markdown",
223 | "metadata": {},
224 | "source": [
225 | "### Porta AND"
226 | ]
227 | },
228 | {
229 | "cell_type": "code",
230 | "execution_count": null,
231 | "metadata": {
232 | "ExecuteTime": {
233 | "end_time": "2017-09-12T12:22:17.785319Z",
234 | "start_time": "2017-09-12T12:22:17.770308Z"
235 | }
236 | },
237 | "outputs": [],
238 | "source": [
239 | "x = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])\n",
240 | "y = np.array([[0, 0, 0, 1]]).T\n",
241 | "\n",
242 | "print(x, y, sep='\\n')"
243 | ]
244 | },
245 | {
246 | "cell_type": "code",
247 | "execution_count": null,
248 | "metadata": {
249 | "ExecuteTime": {
250 | "end_time": "2017-09-12T12:22:20.966580Z",
251 | "start_time": "2017-09-12T12:22:20.670370Z"
252 | }
253 | },
254 | "outputs": [],
255 | "source": [
256 | "plt.scatter(x[:,0], x[:,1], c=y.ravel(), s=50, cmap='bwr')"
257 | ]
258 | },
259 | {
260 | "cell_type": "code",
261 | "execution_count": null,
262 | "metadata": {
263 | "ExecuteTime": {
264 | "end_time": "2017-09-12T12:57:49.470386Z",
265 | "start_time": "2017-09-12T12:57:48.796908Z"
266 | }
267 | },
268 | "outputs": [],
269 | "source": [
270 | "loss = []\n",
271 | "\n",
272 | "interactive_plot = interactive(plot_line, w1=(-1,1,0.01), w2=(-1,1,0.01), b=(-1.5, 1.5, 0.01))\n",
273 | "interactive_plot"
274 | ]
275 | },
276 | {
277 | "cell_type": "markdown",
278 | "metadata": {},
279 | "source": [
280 | "### Porta OR"
281 | ]
282 | },
283 | {
284 | "cell_type": "code",
285 | "execution_count": null,
286 | "metadata": {},
287 | "outputs": [],
288 | "source": [
289 | "x = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])\n",
290 | "y = np.array([[0, 1, 1, 1]]).T\n",
291 | "\n",
292 | "print(x, y, sep='\\n')"
293 | ]
294 | },
295 | {
296 | "cell_type": "code",
297 | "execution_count": null,
298 | "metadata": {},
299 | "outputs": [],
300 | "source": [
301 | "plt.scatter(x[:,0], x[:,1], c=y.ravel(), s=50, cmap='bwr')"
302 | ]
303 | },
304 | {
305 | "cell_type": "code",
306 | "execution_count": null,
307 | "metadata": {},
308 | "outputs": [],
309 | "source": [
310 | "loss = []\n",
311 | "\n",
312 | "interactive_plot = interactive(plot_line, w1=(-1,1,0.01), w2=(-1,1,0.01), b=(-1.5, 1.5, 0.01))\n",
313 | "interactive_plot"
314 | ]
315 | },
316 | {
317 | "cell_type": "markdown",
318 | "metadata": {},
319 | "source": [
320 | "### Porta XOR"
321 | ]
322 | },
323 | {
324 | "cell_type": "code",
325 | "execution_count": null,
326 | "metadata": {},
327 | "outputs": [],
328 | "source": [
329 | "x = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])\n",
330 | "y = np.array([[0, 1, 1, 0]]).T\n",
331 | "\n",
332 | "print(x, y, sep='\\n')"
333 | ]
334 | },
335 | {
336 | "cell_type": "code",
337 | "execution_count": null,
338 | "metadata": {},
339 | "outputs": [],
340 | "source": [
341 | "plt.scatter(x[:,0], x[:,1], c=y.ravel(), s=50, cmap='bwr')"
342 | ]
343 | },
344 | {
345 | "cell_type": "code",
346 | "execution_count": null,
347 | "metadata": {},
348 | "outputs": [],
349 | "source": [
350 | "loss = []\n",
351 | "\n",
352 | "interactive_plot = interactive(plot_line, w1=(-1,1,0.01), w2=(-1,1,0.01), b=(-1.5, 1.5, 0.01))\n",
353 | "interactive_plot"
354 | ]
355 | }
356 | ],
357 | "metadata": {
358 | "anaconda-cloud": {},
359 | "kernelspec": {
360 | "display_name": "Python 3",
361 | "language": "python",
362 | "name": "python3"
363 | },
364 | "language_info": {
365 | "codemirror_mode": {
366 | "name": "ipython",
367 | "version": 3
368 | },
369 | "file_extension": ".py",
370 | "mimetype": "text/x-python",
371 | "name": "python",
372 | "nbconvert_exporter": "python",
373 | "pygments_lexer": "ipython3",
374 | "version": "3.6.5"
375 | },
376 | "widgets": {
377 | "state": {
378 | "ad801d6429424cc183bd50005dba0cc5": {
379 | "views": [
380 | {
381 | "cell_index": 9
382 | }
383 | ]
384 | },
385 | "d48f520c0c534642ba50d4079c3ceead": {
386 | "views": [
387 | {
388 | "cell_index": 21
389 | }
390 | ]
391 | },
392 | "f4b33603eeec488391bdb5d73d9c16a3": {
393 | "views": [
394 | {
395 | "cell_index": 16
396 | }
397 | ]
398 | }
399 | },
400 | "version": "1.2.0"
401 | }
402 | },
403 | "nbformat": 4,
404 | "nbformat_minor": 1
405 | }
406 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Este repositório contém todo o código-fonte do curso __Manual Prático do Deep Learning__ na Udemy.
2 |
3 | ### [Link para o curso](https://www.udemy.com/course/redes-neurais/?referralCode=34C61CFBEACD87D2FD37)
4 |
5 | ### [Link para os slides](https://www.icloud.com/keynote/0LZvPsaugs7uCqr4TS-keRh-g#Manual)
6 |
7 | # Instalação
8 | 1. Baixe ou clone o repositório.
9 | 2. Baixe e instale o [Miniconda](https://conda.io/miniconda.html). (__Windows__: marque a opção de adicionar o conda às variáveis de ambiente (_$PATH_))
10 | 3. Abra o terminal e digite o seguinte comando para instalar o ambiente:
11 | ```sh
12 | $ conda create -n mpdl python numpy=1.24.3 pandas=2.0.3 matplotlib=3.7.1 scikit-learn=1.2.2 jupyter=1.0.0
13 | ```
14 |
15 | # Uso do ambiente
16 |
17 | > __Nota: É obrigatório seguir as ordens da seção "Instalação" antes de utilizar o ambiente__.
18 |
19 | Siga os passos abaixo sempre que quiser executar os códigos desse repositório.
20 | 1. Abra o terminal e digite:
21 |
22 | - __Windows__:
23 | ```sh
24 | $ activate mpdl
25 | ```
26 | - __Linux/Mac__:
27 | ```sh
28 | $ source activate mpdl
29 | ```
30 | 2. Execute o Jupyter Notebook:
31 | ```sh
32 | $ jupyter notebook
33 | ```
34 |
35 | # Dúvidas ou sugestões?
36 |
37 | Sinta-se à vontade para sanar qualquer dúvida diretamente com o professor do curso utilizando o contato mais abaixo. Porém, de preferência a fazer perguntas no fórum do curso ou aqui mesmo no Github. Se possível, siga as orientações abaixo de acordo com o tipo da sua dúvida:
38 |
39 | - __Conteúdo teórico__: faça a pergunta dentro do próprio vídeo do udemy referente a pergunta ou utilize a seção FAQ do curso.
40 | - __Código__: abra uma issue aqui no repositório.
41 |
42 | > __Lembre-se que a sua dúvida pode acabar ajudando outras pessoas com a mesma dúvida!__
43 |
44 | # Contato
45 |
46 | :bust_in_silhouette: __Arnaldo Gualberto__:
47 |
48 | * arnaldo.g12@gmail.com
49 | * [Github](https://github.com/arnaldog12)
50 | * [Site Pessoal](http://arnaldogualberto.com)
51 | * [LinkedIn](https://www.linkedin.com/in/arnaldo-gualberto/)
52 |
--------------------------------------------------------------------------------
/Rede Neural.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Sumário"
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "[Funções de Ativação](#Funções-de-Ativação)\n",
15 | "\n",
16 | "[Funções Auxiliares](#Funções-Auxiliares)\n",
17 | "\n",
18 | "[Funções de Custo](#Funções-de-Custo)\n",
19 | "\n",
20 | "[Inicialização de Pesos](#Inicialização-de-Pesos)\n",
21 | "\n",
22 | "[Regularização](#Regularização)\n",
23 | "\n",
24 | "[Learning Rate Decay](#Learning-Rate-Decay)\n",
25 | "\n",
26 | "[Batch Normalization](#Batch-Normalization)\n",
27 | "\n",
28 | "[Batch Generator](#Batch-Generator)\n",
29 | "\n",
30 | "[Implementação](#Implementação)\n",
31 | "\n",
32 | "[Testes da Implementação](#Testes-da-Implementação)\n",
33 | "\n",
34 | "- [Exemplos do Notebook da Intuição](#Exemplos-do-Notebook-da-Intuição)\n",
35 | "\n",
36 | "- [Regressão](#Regressão)\n",
37 | " - [Regressão Linear Simples](#Regressão-Linear-Simples---Exemplo-do-Perceptron)\n",
38 | " - [Regressão Linear Multivariada](#Regressão-Linear-Multivariada---Exerc%C3%ADcio-de-Regressão-do-Perceptron)\n",
39 | " - [Regressão Quadrática](#Regressão-Quadrática)\n",
40 | " - [Regressão Cúbica](#Regressão-Cúbica)\n",
41 | " - [Regressão Logarítimica](#Regressão-Logar%C3%ADtimica)\n",
42 | " - [Regressão Exponencial](#Regressão-Exponencial)\n",
43 | "\n",
44 | "- [Classificação Binária](#Classificação-Binária)\n",
45 | " - [Porta AND/OR](#Porta-AND/OR)\n",
46 | " - [Porta XOR](#Porta-XOR)\n",
47 | " - [2 Clusters](#2-Clusters)\n",
48 | " - [4 Clusters](#4-Clusters)\n",
49 | " - [Círculos](#C%C3%ADrculos)\n",
50 | " - [Moons](#Moons)\n",
51 | " - [Espiral](#Espiral)\n",
52 | " \n",
53 | "- [Classificação Multiclasse](#Classificação-Multiclasse)\n",
54 | " - [3 Clusters Multiclasse](#3-Clusters-Multiclasse)\n",
55 | " - [4 Clusters Multiclasse](#4-Clusters-Multiclasse)\n",
56 | " - [Espiral - 5 Classes](#Espiral---5-Classes)\n",
57 | " - [Make Classification - 4 Classes](#Make-Classification---4-Classes)\n",
58 | " - [Iris Dataset](#Iris-Dataset)\n",
59 | "\n",
60 | "[Referências](#Referências)"
61 | ]
62 | },
63 | {
64 | "cell_type": "markdown",
65 | "metadata": {},
66 | "source": [
67 | "# Imports and Configurações"
68 | ]
69 | },
70 | {
71 | "cell_type": "code",
72 | "execution_count": null,
73 | "metadata": {},
74 | "outputs": [],
75 | "source": [
76 | "import numpy as np\n",
77 | "import _pickle as pkl\n",
78 | "import matplotlib.pyplot as plt\n",
79 | "from sklearn.datasets import load_iris\n",
80 | "from sklearn.datasets import make_blobs, make_circles, make_moons, make_classification\n",
81 | "from sklearn.metrics import accuracy_score\n",
82 | "from sklearn.preprocessing import MinMaxScaler, OneHotEncoder\n",
83 | "from utils import plot\n",
84 | "from utils.samples_generator import make_spiral, make_square, make_cubic, make_exp, make_log10\n",
85 | "\n",
86 | "%matplotlib inline"
87 | ]
88 | },
89 | {
90 | "cell_type": "markdown",
91 | "metadata": {},
92 | "source": [
93 | "# Funções de Ativação"
94 | ]
95 | },
96 | {
97 | "cell_type": "code",
98 | "execution_count": null,
99 | "metadata": {},
100 | "outputs": [],
101 | "source": [
102 | "def linear(x, derivative=False):\n",
103 | " return np.ones_like(x) if derivative else x\n",
104 | "\n",
105 | "def sigmoid(x, derivative=False):\n",
106 | " if derivative:\n",
107 | " y = sigmoid(x)\n",
108 | " return y*(1 - y)\n",
109 | " return 1.0/(1.0 + np.exp(-x))\n",
110 | "\n",
111 | "def tanh(x, derivative=False):\n",
112 | " if derivative:\n",
113 | " y = tanh(x)\n",
114 | " return 1 - y**2\n",
115 | " return (np.exp(x) - np.exp(-x))/(np.exp(x) + np.exp(-x))\n",
116 | "\n",
117 | "def relu(x, derivative=False):\n",
118 | " if derivative:\n",
119 | " return np.where(x <= 0, 0, 1)\n",
120 | " return np.maximum(0, x)\n",
121 | "\n",
122 | "def leaky_relu(x, derivative=False):\n",
123 | " alpha = 0.1\n",
124 | " if derivative:\n",
125 | " return np.where(x <= 0, alpha, 1)\n",
126 | " return np.where(x <= 0, alpha*x, x)\n",
127 | "\n",
128 | "def elu(x, derivative=False):\n",
129 | " alpha = 1.0\n",
130 | " if derivative:\n",
131 | " y = elu(x)\n",
132 | " return np.where(x <= 0, y + alpha, 1)\n",
133 | " return np.where(x <= 0, alpha*(np.exp(x) - 1), x)"
134 | ]
135 | },
136 | {
137 | "cell_type": "markdown",
138 | "metadata": {},
139 | "source": [
140 | "# Funções Auxiliares"
141 | ]
142 | },
143 | {
144 | "cell_type": "code",
145 | "execution_count": null,
146 | "metadata": {},
147 | "outputs": [],
148 | "source": [
149 | "def softmax(x, y_oh=None, derivative=False):\n",
150 | " if derivative:\n",
151 | " y_pred = softmax(x)\n",
152 | " k = np.nonzero(y_pred * y_oh)\n",
153 | " pk = y_pred[k]\n",
154 | " y_pred[k] = pk * (1.0 - pk)\n",
155 | " return y_pred\n",
156 | " exp = np.exp(x)\n",
157 | " return exp / np.sum(exp, axis=1, keepdims=True)"
158 | ]
159 | },
160 | {
161 | "cell_type": "markdown",
162 | "metadata": {},
163 | "source": [
164 | "# Funções de Custo"
165 | ]
166 | },
167 | {
168 | "cell_type": "markdown",
169 | "metadata": {},
170 | "source": [
171 | "###### Para Regressão"
172 | ]
173 | },
174 | {
175 | "cell_type": "code",
176 | "execution_count": null,
177 | "metadata": {},
178 | "outputs": [],
179 | "source": []
180 | },
181 | {
182 | "cell_type": "markdown",
183 | "metadata": {},
184 | "source": [
185 | "###### Para Classificação Binária"
186 | ]
187 | },
188 | {
189 | "cell_type": "code",
190 | "execution_count": null,
191 | "metadata": {},
192 | "outputs": [],
193 | "source": []
194 | },
195 | {
196 | "cell_type": "markdown",
197 | "metadata": {},
198 | "source": [
199 | "###### Para Classificação Multiclasse"
200 | ]
201 | },
202 | {
203 | "cell_type": "code",
204 | "execution_count": null,
205 | "metadata": {},
206 | "outputs": [],
207 | "source": [
208 | "def neg_log_likelihood(y_oh, y_pred, derivative=False):\n",
209 | " k = np.nonzero(y_pred * y_oh)\n",
210 | " pk = y_pred[k]\n",
211 | " if derivative:\n",
212 | " y_pred[k] = (-1.0 / pk)\n",
213 | " return y_pred\n",
214 | " return np.mean(-np.log(pk))\n",
215 | "\n",
216 | "def softmax_neg_log_likelihood(y_oh, y_pred, derivative=False):\n",
217 | " y_softmax = softmax(y_pred)\n",
218 | " if derivative:\n",
219 | " return -(y_oh - y_softmax) / y_oh.shape[0] \n",
220 | " return neg_log_likelihood(y_oh, y_softmax)"
221 | ]
222 | },
223 | {
224 | "cell_type": "markdown",
225 | "metadata": {},
226 | "source": [
227 | "# Inicialização de Pesos"
228 | ]
229 | },
230 | {
231 | "cell_type": "code",
232 | "execution_count": null,
233 | "metadata": {},
234 | "outputs": [],
235 | "source": []
236 | },
237 | {
238 | "cell_type": "markdown",
239 | "metadata": {},
240 | "source": [
241 | "# Regularização"
242 | ]
243 | },
244 | {
245 | "cell_type": "code",
246 | "execution_count": null,
247 | "metadata": {},
248 | "outputs": [],
249 | "source": []
250 | },
251 | {
252 | "cell_type": "markdown",
253 | "metadata": {},
254 | "source": [
255 | "# Batch Generator"
256 | ]
257 | },
258 | {
259 | "cell_type": "code",
260 | "execution_count": null,
261 | "metadata": {},
262 | "outputs": [],
263 | "source": []
264 | },
265 | {
266 | "cell_type": "markdown",
267 | "metadata": {},
268 | "source": [
269 | "# Learning Rate Decay"
270 | ]
271 | },
272 | {
273 | "cell_type": "code",
274 | "execution_count": null,
275 | "metadata": {},
276 | "outputs": [],
277 | "source": []
278 | },
279 | {
280 | "cell_type": "markdown",
281 | "metadata": {},
282 | "source": [
283 | "# Batch Normalization "
284 | ]
285 | },
286 | {
287 | "cell_type": "code",
288 | "execution_count": null,
289 | "metadata": {},
290 | "outputs": [],
291 | "source": []
292 | },
293 | {
294 | "cell_type": "markdown",
295 | "metadata": {},
296 | "source": [
297 | "# Implementação "
298 | ]
299 | },
300 | {
301 | "cell_type": "code",
302 | "execution_count": null,
303 | "metadata": {},
304 | "outputs": [],
305 | "source": []
306 | },
307 | {
308 | "cell_type": "markdown",
309 | "metadata": {},
310 | "source": [
311 | "## Exemplos do Notebook da Intuição"
312 | ]
313 | },
314 | {
315 | "cell_type": "markdown",
316 | "metadata": {},
317 | "source": [
318 | "### Exemplo 1"
319 | ]
320 | },
321 | {
322 | "cell_type": "code",
323 | "execution_count": null,
324 | "metadata": {},
325 | "outputs": [],
326 | "source": [
327 | "x = np.array([[0.05, 0.10]])\n",
328 | "y = np.array([[0.01, 0.99]])\n",
329 | "\n",
330 | "w1 = np.array([[0.15, 0.20], [0.25, 0.30]])\n",
331 | "b1 = np.array([[0.35]]) \n",
332 | "w2 = np.array([[0.40, 0.45], [0.50, 0.55]])\n",
333 | "b2 = np.array([[0.60]])\n",
334 | "\n",
335 | "# insira sua rede aqui!"
336 | ]
337 | },
338 | {
339 | "cell_type": "markdown",
340 | "metadata": {},
341 | "source": [
342 | "### Exemplo 2"
343 | ]
344 | },
345 | {
346 | "cell_type": "code",
347 | "execution_count": null,
348 | "metadata": {},
349 | "outputs": [],
350 | "source": [
351 | "x = np.array([[0.1, 0.2, 0.7]])\n",
352 | "y = np.array([[1, 0, 0]])\n",
353 | "D_in, D_out = x.shape[1], y.shape[1]\n",
354 | "\n",
355 | "w1 = np.array([[0.1, 0.2, 0.3], [0.3, 0.2, 0.7], [0.4, 0.3, 0.9]])\n",
356 | "b1 = np.ones((1,3))\n",
357 | "w2 = np.array([[0.2, 0.3, 0.5], [0.3, 0.5, 0.7], [0.6, 0.4, 0.8]])\n",
358 | "b2 = np.ones((1,3))\n",
359 | "w3 = np.array([[0.1, 0.4, 0.8], [0.3, 0.7, 0.2], [0.5, 0.2, 0.9]])\n",
360 | "b3 = np.ones((1,3))\n",
361 | "\n",
362 | "# insira sua rede aqui!"
363 | ]
364 | },
365 | {
366 | "cell_type": "markdown",
367 | "metadata": {
368 | "collapsed": true
369 | },
370 | "source": [
371 | "## Gradient Checking"
372 | ]
373 | },
374 | {
375 | "cell_type": "code",
376 | "execution_count": null,
377 | "metadata": {},
378 | "outputs": [],
379 | "source": []
380 | },
381 | {
382 | "cell_type": "code",
383 | "execution_count": null,
384 | "metadata": {},
385 | "outputs": [],
386 | "source": []
387 | },
388 | {
389 | "cell_type": "code",
390 | "execution_count": null,
391 | "metadata": {},
392 | "outputs": [],
393 | "source": []
394 | },
395 | {
396 | "cell_type": "code",
397 | "execution_count": null,
398 | "metadata": {},
399 | "outputs": [],
400 | "source": []
401 | },
402 | {
403 | "cell_type": "markdown",
404 | "metadata": {},
405 | "source": [
406 | "## Regressão"
407 | ]
408 | },
409 | {
410 | "cell_type": "markdown",
411 | "metadata": {},
412 | "source": [
413 | "### Regressão Linear Simples - Exemplo do Perceptron"
414 | ]
415 | },
416 | {
417 | "cell_type": "code",
418 | "execution_count": null,
419 | "metadata": {},
420 | "outputs": [],
421 | "source": [
422 | "data = np.loadtxt('data/medidas.csv', delimiter=',', skiprows=1)\n",
423 | "print(data.shape)\n",
424 | "\n",
425 | "x, y = data[:,0].reshape(-1,1), data[:,1].reshape(-1,1)\n",
426 | "print(x.shape, y.shape)\n",
427 | "plt.scatter(x, y)"
428 | ]
429 | },
430 | {
431 | "cell_type": "code",
432 | "execution_count": null,
433 | "metadata": {},
434 | "outputs": [],
435 | "source": [
436 | "minmax = MinMaxScaler(feature_range=(-1, 1))\n",
437 | "x = minmax.fit_transform(x.astype(np.float64))\n",
438 | "\n",
439 | "print(x.min(), x.max())\n",
440 | "plt.scatter(x, y)"
441 | ]
442 | },
443 | {
444 | "cell_type": "code",
445 | "execution_count": null,
446 | "metadata": {},
447 | "outputs": [],
448 | "source": [
449 | "input_dim, output_dim = x.shape[1], y.shape[1]\n",
450 | "\n",
451 | "# insira sua rede aqui!\n",
452 | "\n",
453 | "plt.figure(figsize=(12, 6))\n",
454 | "plt.subplot(1, 2, 1)\n",
455 | "plt.scatter(x, y)\n",
456 | "plt.plot(x, nn.predict(x), c='green')"
457 | ]
458 | },
459 | {
460 | "cell_type": "markdown",
461 | "metadata": {},
462 | "source": [
463 | "### Regressão Linear Multivariada - Exercício de Regressão do Perceptron"
464 | ]
465 | },
466 | {
467 | "cell_type": "code",
468 | "execution_count": null,
469 | "metadata": {},
470 | "outputs": [],
471 | "source": [
472 | "data = np.loadtxt('data/notas.csv', delimiter=',', skiprows=1)\n",
473 | "print(data.shape)\n",
474 | "\n",
475 | "x, y = data[:,:-1], data[:,-1].reshape(-1,1)\n",
476 | "print(x.shape, y.shape)"
477 | ]
478 | },
479 | {
480 | "cell_type": "code",
481 | "execution_count": null,
482 | "metadata": {},
483 | "outputs": [],
484 | "source": [
485 | "minmax = MinMaxScaler(feature_range=(-1, 1))\n",
486 | "x = minmax.fit_transform(x.astype(np.float64))\n",
487 | "\n",
488 | "print(x.min(axis=0), x.max(axis=0))\n",
489 | "plt.scatter(x, y)"
490 | ]
491 | },
492 | {
493 | "cell_type": "code",
494 | "execution_count": null,
495 | "metadata": {},
496 | "outputs": [],
497 | "source": [
498 | "input_dim, output_dim = x.shape[1], y.shape[1]\n",
499 | "\n",
500 | "# insira sua rede aqui!"
501 | ]
502 | },
503 | {
504 | "cell_type": "markdown",
505 | "metadata": {},
506 | "source": [
507 | "### Regressão Quadrática"
508 | ]
509 | },
510 | {
511 | "cell_type": "code",
512 | "execution_count": null,
513 | "metadata": {},
514 | "outputs": [],
515 | "source": [
516 | "x, y = make_square(n_samples=100, x_min=-10, x_max=10, a=1, b=1, c=1, noise=10)\n",
517 | "\n",
518 | "print(x.shape, y.shape)\n",
519 | "plt.scatter(x, y)"
520 | ]
521 | },
522 | {
523 | "cell_type": "code",
524 | "execution_count": null,
525 | "metadata": {},
526 | "outputs": [],
527 | "source": [
528 | "minmax = MinMaxScaler(feature_range=(-1, 1))\n",
529 | "x = minmax.fit_transform(x.astype(np.float64))\n",
530 | "\n",
531 | "print(x.min(axis=0), x.max(axis=0))"
532 | ]
533 | },
534 | {
535 | "cell_type": "code",
536 | "execution_count": null,
537 | "metadata": {},
538 | "outputs": [],
539 | "source": [
540 | "input_dim, output_dim = x.shape[1], y.shape[1]\n",
541 | "\n",
542 | "# insira sua rede aqui!\n",
543 | "\n",
544 | "plt.figure(figsize=(12, 6))\n",
545 | "plt.subplot(1, 2, 1)\n",
546 | "plt.scatter(x, y)\n",
547 | "plt.plot(x, nn.predict(x), c='green')"
548 | ]
549 | },
550 | {
551 | "cell_type": "markdown",
552 | "metadata": {},
553 | "source": [
554 | "### Regressão Cúbica"
555 | ]
556 | },
557 | {
558 | "cell_type": "code",
559 | "execution_count": null,
560 | "metadata": {},
561 | "outputs": [],
562 | "source": [
563 | "x, y = make_cubic(n_samples=100, x_min=-4, x_max=4, a=1, b=0, c=-10, d=0, noise=3)\n",
564 | "\n",
565 | "print(x.shape, y.shape)\n",
566 | "plt.scatter(x, y)"
567 | ]
568 | },
569 | {
570 | "cell_type": "code",
571 | "execution_count": null,
572 | "metadata": {},
573 | "outputs": [],
574 | "source": [
575 | "minmax = MinMaxScaler(feature_range=(-1, 1))\n",
576 | "x = minmax.fit_transform(x.astype(np.float64))\n",
577 | "\n",
578 | "print(x.min(axis=0), x.max(axis=0))"
579 | ]
580 | },
581 | {
582 | "cell_type": "code",
583 | "execution_count": null,
584 | "metadata": {},
585 | "outputs": [],
586 | "source": [
587 | "input_dim, output_dim = x.shape[1], y.shape[1]\n",
588 | "\n",
589 | "# insira sua rede aqui!\n",
590 | "\n",
591 | "plt.figure(figsize=(12, 6))\n",
592 | "plt.subplot(1, 2, 1)\n",
593 | "plt.scatter(x, y)\n",
594 | "plt.plot(x, nn.predict(x), c='green')"
595 | ]
596 | },
597 | {
598 | "cell_type": "markdown",
599 | "metadata": {},
600 | "source": [
601 | "### Regressão Logarítimica"
602 | ]
603 | },
604 | {
605 | "cell_type": "code",
606 | "execution_count": null,
607 | "metadata": {},
608 | "outputs": [],
609 | "source": [
610 | "x, y = make_log10(n_samples=100, x_min=1, x_max=100, noise=0.3)\n",
611 | "\n",
612 | "print(x.shape, y.shape)\n",
613 | "plt.scatter(x, y)"
614 | ]
615 | },
616 | {
617 | "cell_type": "code",
618 | "execution_count": null,
619 | "metadata": {},
620 | "outputs": [],
621 | "source": [
622 | "minmax = MinMaxScaler(feature_range=(-1, 1))\n",
623 | "x = minmax.fit_transform(x.astype(np.float64))\n",
624 | "\n",
625 | "print(x.min(axis=0), x.max(axis=0))"
626 | ]
627 | },
628 | {
629 | "cell_type": "code",
630 | "execution_count": null,
631 | "metadata": {},
632 | "outputs": [],
633 | "source": [
634 | "input_dim, output_dim = x.shape[1], y.shape[1]\n",
635 | "\n",
636 | "# insira sua rede aqui!\n",
637 | "\n",
638 | "plt.figure(figsize=(12, 6))\n",
639 | "plt.subplot(1, 2, 1)\n",
640 | "plt.scatter(x, y)\n",
641 | "plt.plot(x, nn.predict(x), c='green')"
642 | ]
643 | },
644 | {
645 | "cell_type": "markdown",
646 | "metadata": {},
647 | "source": [
648 | "### Regressão Exponencial"
649 | ]
650 | },
651 | {
652 | "cell_type": "code",
653 | "execution_count": null,
654 | "metadata": {},
655 | "outputs": [],
656 | "source": [
657 | "x, y = make_exp(n_samples=100, x_min=0, x_max=5, noise=10)\n",
658 | "\n",
659 | "print(x.shape, y.shape)\n",
660 | "plt.scatter(x, y)"
661 | ]
662 | },
663 | {
664 | "cell_type": "code",
665 | "execution_count": null,
666 | "metadata": {},
667 | "outputs": [],
668 | "source": [
669 | "minmax = MinMaxScaler(feature_range=(-1, 1))\n",
670 | "x = minmax.fit_transform(x.astype(np.float64))\n",
671 | "\n",
672 | "print(x.min(axis=0), x.max(axis=0))"
673 | ]
674 | },
675 | {
676 | "cell_type": "code",
677 | "execution_count": null,
678 | "metadata": {},
679 | "outputs": [],
680 | "source": [
681 | "input_dim, output_dim = x.shape[1], y.shape[1]\n",
682 | "\n",
683 | "# insira sua rede aqui!\n",
684 | "\n",
685 | "plt.figure(figsize=(12, 6))\n",
686 | "plt.subplot(1, 2, 1)\n",
687 | "plt.scatter(x, y)\n",
688 | "plt.plot(x, nn.predict(x), c='green')"
689 | ]
690 | },
691 | {
692 | "cell_type": "markdown",
693 | "metadata": {},
694 | "source": [
695 | "## Classificação Binária"
696 | ]
697 | },
698 | {
699 | "cell_type": "markdown",
700 | "metadata": {},
701 | "source": [
702 | "### Porta AND/OR"
703 | ]
704 | },
705 | {
706 | "cell_type": "code",
707 | "execution_count": null,
708 | "metadata": {},
709 | "outputs": [],
710 | "source": [
711 | "x = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])\n",
712 | "y = np.array([0, 0, 0, 1]).reshape(-1, 1)\n",
713 | "\n",
714 | "print(x.shape, y.shape)\n",
715 | "plt.scatter(x[:,0], x[:,1], c=list(np.array(y).ravel()), s=15, cmap='bwr')"
716 | ]
717 | },
718 | {
719 | "cell_type": "code",
720 | "execution_count": null,
721 | "metadata": {},
722 | "outputs": [],
723 | "source": [
724 | "input_dim, output_dim = x.shape[1], y.shape[1]\n",
725 | "\n",
726 | "# insira sua rede aqui!\n",
727 | "\n",
728 | "y_pred = nn.predict(x)\n",
729 | "print('Predições:', y_pred, sep='\\n')\n",
730 | "print('Acurácia: {:.2f}%'.format(100*accuracy_score(y, y_pred > 0.5)))\n",
731 | "\n",
732 | "plot.classification_predictions(x, y, is_binary=True, nn=nn, cmap='bwr')"
733 | ]
734 | },
735 | {
736 | "cell_type": "markdown",
737 | "metadata": {},
738 | "source": [
739 | "### Porta XOR"
740 | ]
741 | },
742 | {
743 | "cell_type": "code",
744 | "execution_count": null,
745 | "metadata": {},
746 | "outputs": [],
747 | "source": [
748 | "x = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])\n",
749 | "y = np.array([0, 1, 1, 0]).reshape(-1, 1)\n",
750 | "\n",
751 | "print(x.shape, y.shape)\n",
752 | "plt.scatter(x[:,0], x[:,1], c=list(np.array(y).ravel()), s=15, cmap='bwr')"
753 | ]
754 | },
755 | {
756 | "cell_type": "code",
757 | "execution_count": null,
758 | "metadata": {},
759 | "outputs": [],
760 | "source": [
761 | "input_dim, output_dim = x.shape[1], y.shape[1]\n",
762 | "\n",
763 | "# insira sua rede aqui!\n",
764 | "\n",
765 | "y_pred = nn.predict(x)\n",
766 | "print('Predições:', y_pred, sep='\\n')\n",
767 | "print('Acurácia: {:.2f}%'.format(100*accuracy_score(y, y_pred > 0.5)))\n",
768 | "\n",
769 | "plot.classification_predictions(x, y, is_binary=True, nn=nn, cmap='bwr')"
770 | ]
771 | },
772 | {
773 | "cell_type": "markdown",
774 | "metadata": {},
775 | "source": [
776 | "### 2 Clusters"
777 | ]
778 | },
779 | {
780 | "cell_type": "code",
781 | "execution_count": null,
782 | "metadata": {},
783 | "outputs": [],
784 | "source": [
785 | "x, y = make_blobs(n_samples=100, n_features=2, centers=2, random_state=1234)\n",
786 | "y = y.reshape(-1, 1)\n",
787 | "\n",
788 | "print(x.shape, y.shape)\n",
789 | "plt.scatter(x[:,0], x[:,1], c=list(np.array(y).ravel()), s=15, cmap='bwr')"
790 | ]
791 | },
792 | {
793 | "cell_type": "code",
794 | "execution_count": null,
795 | "metadata": {},
796 | "outputs": [],
797 | "source": [
798 | "input_dim, output_dim = x.shape[1], y.shape[1]\n",
799 | "\n",
800 | "# insira sua rede aqui!\n",
801 | "\n",
802 | "y_pred = nn.predict(x)\n",
803 | "\n",
804 | "threshold = 0 if nn.layers[-1].activation == linear else 0.5\n",
805 | "print('Acurácia: {:.2f}%'.format(100*accuracy_score(y, y_pred >= threshold)))\n",
806 | "plot.classification_predictions(x, y, is_binary=True, nn=nn, threshold=threshold, cmap='bwr')"
807 | ]
808 | },
809 | {
810 | "cell_type": "markdown",
811 | "metadata": {},
812 | "source": [
813 | "### 4 Clusters"
814 | ]
815 | },
816 | {
817 | "cell_type": "code",
818 | "execution_count": null,
819 | "metadata": {},
820 | "outputs": [],
821 | "source": [
822 | "x, y = make_blobs(n_samples=500, n_features=2, cluster_std=0.9, centers=[(-3, -3), (3, 3), (-3, 3), (3, -3)], random_state=1234)\n",
823 | "y = y.reshape(-1, 1)\n",
824 | "y = np.where(y >= 2, 1, 0)\n",
825 | "\n",
826 | "print(x.shape, y.shape)\n",
827 | "plt.scatter(x[:,0], x[:,1], c=list(np.array(y).ravel()), s=15, cmap='bwr')"
828 | ]
829 | },
830 | {
831 | "cell_type": "code",
832 | "execution_count": null,
833 | "metadata": {},
834 | "outputs": [],
835 | "source": [
836 | "input_dim, output_dim = x.shape[1], y.shape[1]\n",
837 | "\n",
838 | "# insira sua rede aqui!\n",
839 | "\n",
840 | "y_pred = nn.predict(x)\n",
841 | "print('Acurácia: {:.2f}%'.format(100*accuracy_score(y, y_pred > 0.5)))\n",
842 | "\n",
843 | "plot.classification_predictions(x, y, is_binary=True, nn=nn, threshold=0.5, cmap='bwr')"
844 | ]
845 | },
846 | {
847 | "cell_type": "markdown",
848 | "metadata": {},
849 | "source": [
850 | "### Círculos"
851 | ]
852 | },
853 | {
854 | "cell_type": "code",
855 | "execution_count": null,
856 | "metadata": {},
857 | "outputs": [],
858 | "source": [
859 | "x, y = make_circles(n_samples=500, noise=0.1, factor=0.4, random_state=1234)\n",
860 | "y = y.reshape(-1, 1)\n",
861 | "\n",
862 | "print(x.shape, y.shape)\n",
863 | "plt.scatter(x[:,0], x[:,1], c=list(np.array(y).ravel()), s=15, cmap='bwr')"
864 | ]
865 | },
866 | {
867 | "cell_type": "code",
868 | "execution_count": null,
869 | "metadata": {},
870 | "outputs": [],
871 | "source": [
872 | "input_dim, output_dim = x.shape[1], y.shape[1]\n",
873 | "\n",
874 | "# insira sua rede aqui!\n",
875 | "\n",
876 | "y_pred = nn.predict(x)\n",
877 | "print('Acurácia: {:.2f}%'.format(100*accuracy_score(y, y_pred > 0.5)))\n",
878 | "\n",
879 | "plot.classification_predictions(x, y, is_binary=True, nn=nn, threshold=0.5, cmap='bwr')"
880 | ]
881 | },
882 | {
883 | "cell_type": "markdown",
884 | "metadata": {},
885 | "source": [
886 | "### Moons"
887 | ]
888 | },
889 | {
890 | "cell_type": "code",
891 | "execution_count": null,
892 | "metadata": {},
893 | "outputs": [],
894 | "source": [
895 | "x, y = make_moons(200, noise=0.20)\n",
896 | "y = y.reshape(-1, 1)\n",
897 | "\n",
898 | "print(x.shape, y.shape)\n",
899 | "plt.scatter(x[:,0], x[:,1], c=list(np.array(y).ravel()), s=15, cmap='bwr')"
900 | ]
901 | },
902 | {
903 | "cell_type": "code",
904 | "execution_count": null,
905 | "metadata": {},
906 | "outputs": [],
907 | "source": [
908 | "input_dim, output_dim = x.shape[1], y.shape[1]\n",
909 | "\n",
910 | "# insira sua rede aqui!\n",
911 | "\n",
912 | "y_pred = nn.predict(x)\n",
913 | "print('Acurácia: {:.2f}%'.format(100*accuracy_score(y, y_pred > 0.5)))\n",
914 | "\n",
915 | "plot.classification_predictions(x, y, is_binary=True, nn=nn, threshold=0.5, cmap='bwr')"
916 | ]
917 | },
918 | {
919 | "cell_type": "markdown",
920 | "metadata": {},
921 | "source": [
922 | "### Espiral"
923 | ]
924 | },
925 | {
926 | "cell_type": "code",
927 | "execution_count": null,
928 | "metadata": {},
929 | "outputs": [],
930 | "source": [
931 | "x, y = make_spiral(n_samples=100, n_class=2, radius=5, laps=1.75)\n",
932 | "y = y.reshape(-1, 1)\n",
933 | "\n",
934 | "print(x.shape, y.shape)\n",
935 | "plt.scatter(x[:,0], x[:,1], c=list(np.array(y).ravel()), s=15, cmap='bwr')"
936 | ]
937 | },
938 | {
939 | "cell_type": "code",
940 | "execution_count": null,
941 | "metadata": {},
942 | "outputs": [],
943 | "source": [
944 | "input_dim, output_dim = x.shape[1], y.shape[1]\n",
945 | "\n",
946 | "# insira sua rede aqui!\n",
947 | "\n",
948 | "y_pred = nn.predict(x)\n",
949 | "print('Acurácia: {:.2f}%'.format(100*accuracy_score(y, y_pred > 0.5)))\n",
950 | "\n",
951 | "plot.classification_predictions(x, y, is_binary=True, nn=nn, threshold=0.5, cmap='bwr')"
952 | ]
953 | },
954 | {
955 | "cell_type": "markdown",
956 | "metadata": {},
957 | "source": [
958 | "## Classificação Multiclasse"
959 | ]
960 | },
961 | {
962 | "cell_type": "markdown",
963 | "metadata": {},
964 | "source": [
965 | "### 3 Clusters Multiclasse"
966 | ]
967 | },
968 | {
969 | "cell_type": "code",
970 | "execution_count": null,
971 | "metadata": {},
972 | "outputs": [],
973 | "source": [
974 | "x, y = make_blobs(n_samples=300, n_features=2, centers=[(0, -3), (-3, 3), (3, 3)], random_state=1234)\n",
975 | "y = y.reshape(-1, 1)\n",
976 | "\n",
977 | "print(x.shape, y.shape)\n",
978 | "plt.scatter(x[:,0], x[:,1], c=list(np.array(y).ravel()), s=15, cmap=plt.cm.viridis)"
979 | ]
980 | },
981 | {
982 | "cell_type": "code",
983 | "execution_count": null,
984 | "metadata": {},
985 | "outputs": [],
986 | "source": [
987 | "onehot = OneHotEncoder(sparse=False)\n",
988 | "y_onehot = onehot.fit_transform(y)\n",
989 | "print(y_onehot[::60])"
990 | ]
991 | },
992 | {
993 | "cell_type": "code",
994 | "execution_count": null,
995 | "metadata": {},
996 | "outputs": [],
997 | "source": [
998 | "input_dim, output_dim = x.shape[1], y.shape[1]\n",
999 | "\n",
1000 | "# insira sua rede aqui!\n",
1001 | " \n",
1002 | "y_pred = np.argmax(nn.predict(x), axis=1)\n",
1003 | "print('Acurácia: {:.2f}%'.format(100*accuracy_score(y, y_pred)))\n",
1004 | "\n",
1005 | "plot.classification_predictions(x, y, is_binary=False, nn=nn)"
1006 | ]
1007 | },
1008 | {
1009 | "cell_type": "markdown",
1010 | "metadata": {},
1011 | "source": [
1012 | "### 4 Clusters Multiclasse"
1013 | ]
1014 | },
1015 | {
1016 | "cell_type": "code",
1017 | "execution_count": null,
1018 | "metadata": {},
1019 | "outputs": [],
1020 | "source": [
1021 | "x, y = make_blobs(n_samples=400, n_features=2, centers=[(-3, 0), (3, 0), (0, 3), (0, -3)], random_state=1234)\n",
1022 | "y = y.reshape(-1, 1)\n",
1023 | "\n",
1024 | "print(x.shape, y.shape)\n",
1025 | "plt.scatter(x[:,0], x[:,1], c=list(np.array(y).ravel()), s=15, cmap=plt.cm.viridis)"
1026 | ]
1027 | },
1028 | {
1029 | "cell_type": "code",
1030 | "execution_count": null,
1031 | "metadata": {},
1032 | "outputs": [],
1033 | "source": [
1034 | "onehot = OneHotEncoder(sparse=False)\n",
1035 | "y_onehot = onehot.fit_transform(y)\n",
1036 | "print(y_onehot[::70])"
1037 | ]
1038 | },
1039 | {
1040 | "cell_type": "code",
1041 | "execution_count": null,
1042 | "metadata": {},
1043 | "outputs": [],
1044 | "source": [
1045 | "input_dim, output_dim = x.shape[1], y.shape[1]\n",
1046 | "\n",
1047 | "# insira sua rede aqui!\n",
1048 | "\n",
1049 | "y_pred = np.argmax(nn.predict(x), axis=1)\n",
1050 | "print('Acurácia: {:.2f}%'.format(100*accuracy_score(y, y_pred)))\n",
1051 | "\n",
1052 | "plot.classification_predictions(x, y, is_binary=False, nn=nn)"
1053 | ]
1054 | },
1055 | {
1056 | "cell_type": "markdown",
1057 | "metadata": {},
1058 | "source": [
1059 | "### Espiral - 5 Classes"
1060 | ]
1061 | },
1062 | {
1063 | "cell_type": "code",
1064 | "execution_count": null,
1065 | "metadata": {},
1066 | "outputs": [],
1067 | "source": [
1068 | "x, y = make_spiral(n_samples=100, n_class=5, radius=1, laps=0.5)\n",
1069 | "y = y.reshape(-1, 1)\n",
1070 | "\n",
1071 | "print(x.shape, y.shape)\n",
1072 | "plt.scatter(x[:,0], x[:,1], c=list(np.array(y).ravel()), s=15, cmap=plt.cm.viridis)"
1073 | ]
1074 | },
1075 | {
1076 | "cell_type": "code",
1077 | "execution_count": null,
1078 | "metadata": {
1079 | "scrolled": true
1080 | },
1081 | "outputs": [],
1082 | "source": [
1083 | "onehot = OneHotEncoder(sparse=False)\n",
1084 | "y_onehot = onehot.fit_transform(y)\n",
1085 | "print(y_onehot[::100])"
1086 | ]
1087 | },
1088 | {
1089 | "cell_type": "code",
1090 | "execution_count": null,
1091 | "metadata": {
1092 | "scrolled": false
1093 | },
1094 | "outputs": [],
1095 | "source": [
1096 | "input_dim, output_dim = x.shape[1], y.shape[1]\n",
1097 | "\n",
1098 | "# insira sua rede aqui!\n",
1099 | "\n",
1100 | "y_pred = np.argmax(nn.predict(x), axis=1)\n",
1101 | "print('Acurácia: {:.2f}%'.format(100*accuracy_score(y, y_pred)))\n",
1102 | "\n",
1103 | "plot.classification_predictions(x, y, is_binary=False, nn=nn)"
1104 | ]
1105 | },
1106 | {
1107 | "cell_type": "markdown",
1108 | "metadata": {},
1109 | "source": [
1110 | "### Make Classification - 4 Classes"
1111 | ]
1112 | },
1113 | {
1114 | "cell_type": "code",
1115 | "execution_count": null,
1116 | "metadata": {},
1117 | "outputs": [],
1118 | "source": [
1119 | "x, y = make_classification(n_samples=100, n_classes=4, n_features=2, n_clusters_per_class=1, n_redundant=0, n_repeated=0, random_state=1234)\n",
1120 | "y = y.reshape(-1, 1)\n",
1121 | "\n",
1122 | "print(x.shape, y.shape)\n",
1123 | "plt.scatter(x[:,0], x[:,1], c=list(np.array(y).ravel()), s=15, cmap=plt.cm.viridis)"
1124 | ]
1125 | },
1126 | {
1127 | "cell_type": "code",
1128 | "execution_count": null,
1129 | "metadata": {},
1130 | "outputs": [],
1131 | "source": [
1132 | "onehot = OneHotEncoder(sparse=False)\n",
1133 | "y_onehot = onehot.fit_transform(y)\n",
1134 | "print(y_onehot[::10])"
1135 | ]
1136 | },
1137 | {
1138 | "cell_type": "code",
1139 | "execution_count": null,
1140 | "metadata": {},
1141 | "outputs": [],
1142 | "source": [
1143 | "input_dim, output_dim = x.shape[1], y.shape[1]\n",
1144 | "\n",
1145 | "# insira sua rede aqui!\n",
1146 | "\n",
1147 | "y_pred = np.argmax(nn.predict(x), axis=1)\n",
1148 | "print('Acurácia: {:.2f}%'.format(100*accuracy_score(y, y_pred)))\n",
1149 | "\n",
1150 | "plot.classification_predictions(x, y, is_binary=False, nn=nn)"
1151 | ]
1152 | },
1153 | {
1154 | "cell_type": "markdown",
1155 | "metadata": {},
1156 | "source": [
1157 | "### Iris Dataset"
1158 | ]
1159 | },
1160 | {
1161 | "cell_type": "code",
1162 | "execution_count": null,
1163 | "metadata": {},
1164 | "outputs": [],
1165 | "source": [
1166 | "data = load_iris()\n",
1167 | "x, y = data.data[:, 2:], data.target.reshape(-1,1)\n",
1168 | "\n",
1169 | "print(data.feature_names)\n",
1170 | "print(data.target_names)\n",
1171 | "print(x.shape, y.shape)\n",
1172 | "plt.scatter(x[:,0], x[:,1], c=list(np.array(y).ravel()), s=15, cmap=plt.cm.viridis)"
1173 | ]
1174 | },
1175 | {
1176 | "cell_type": "code",
1177 | "execution_count": null,
1178 | "metadata": {},
1179 | "outputs": [],
1180 | "source": [
1181 | "onehot = OneHotEncoder(sparse=False)\n",
1182 | "y_onehot = onehot.fit_transform(y)\n",
1183 | "print(y_onehot[::20])"
1184 | ]
1185 | },
1186 | {
1187 | "cell_type": "code",
1188 | "execution_count": null,
1189 | "metadata": {},
1190 | "outputs": [],
1191 | "source": [
1192 | "input_dim, output_dim = x.shape[1], y.shape[1]\n",
1193 | "\n",
1194 | "# insira sua rede aqui!\n",
1195 | "\n",
1196 | "y_pred = np.argmax(nn.predict(x), axis=1)\n",
1197 | "print('Acurácia: {:.2f}%'.format(100*accuracy_score(y, y_pred)))\n",
1198 | "\n",
1199 | "plot.classification_predictions(x, y, is_binary=False, nn=nn)"
1200 | ]
1201 | },
1202 | {
1203 | "cell_type": "markdown",
1204 | "metadata": {},
1205 | "source": [
1206 | "# [Link para o Questionário](https://docs.google.com/forms/d/e/1FAIpQLSf1B3JKsPPPc1oYD_3FyX4UvNLpcXnTW2I177A_WE0_B56Elw/viewform?usp=sf_link)"
1207 | ]
1208 | },
1209 | {
1210 | "cell_type": "markdown",
1211 | "metadata": {},
1212 | "source": [
1213 | "# Referências"
1214 | ]
1215 | },
1216 | {
1217 | "cell_type": "markdown",
1218 | "metadata": {},
1219 | "source": [
1220 | "- [Tensorflow Playground](http://playground.tensorflow.org/#activation=tanh&batchSize=10&dataset=circle®Dataset=reg-plane&learningRate=0.03®ularizationRate=0&noise=0&networkShape=4,2&seed=0.94880&showTestData=false&discretize=false&percTrainData=50&x=true&y=true&xTimesY=false&xSquared=false&ySquared=false&cosX=false&sinX=false&cosY=false&sinY=false&collectStats=false&problem=classification&initZero=false&hideText=false)\n",
1221 | "\n",
1222 | "- [Linear Classification](http://cs231n.github.io/linear-classify/)\n",
1223 | "\n",
1224 | "__Regularization__:\n",
1225 | "- [Implementing Neural Network L1 Regularization](https://jamesmccaffrey.wordpress.com/2017/06/27/implementing-neural-network-l1-regularization/)\n",
1226 | "- [Implementing Neural Network L2 Regularization](https://jamesmccaffrey.wordpress.com/2017/06/29/implementing-neural-network-l2-regularization/)\n",
1227 | "- [Neural Network L2 Regularization Using Python](https://visualstudiomagazine.com/articles/2017/09/01/neural-network-l2.aspx)\n",
1228 | "\n",
1229 | "__Momentum__:\n",
1230 | "- [Neural Network Momentum Using Python](https://visualstudiomagazine.com/articles/2017/08/01/neural-network-momentum.aspx)\n",
1231 | "- [Beyond SGD: Gradient Descent with Momentum and Adaptive Learning Rate](https://wiseodd.github.io/techblog/2016/06/22/nn-optimization/)\n",
1232 | "\n",
1233 | "__Learning Rate Decay__:\n",
1234 | "- [Using Learning Rate Schedules for Deep Learning Models in Python with Keras](https://machinelearningmastery.com/using-learning-rate-schedules-deep-learning-models-python-keras/)\n",
1235 | "- [Learning Rate Schedules and Adaptive Learning Rate Methods for Deep Learning](https://towardsdatascience.com/learning-rate-schedules-and-adaptive-learning-rate-methods-for-deep-learning-2c8f433990d1)\n",
1236 | "- [Tensorflow Exponential Decay Documentation](https://www.tensorflow.org/api_docs/python/tf/train/exponential_decay)\n",
1237 | "\n",
1238 | "__Batch Normalization__:\n",
1239 | "- [Understanding the backward pass through Batch Normalization Layer](https://kratzert.github.io/2016/02/12/understanding-the-gradient-flow-through-the-batch-normalization-layer.html)\n",
1240 | "- [Deriving the Gradient for the Backward Pass of Batch Normalization](https://kevinzakka.github.io/2016/09/14/batch_normalization/)\n",
1241 | "- [Implementing BatchNorm in Neural Net](https://wiseodd.github.io/techblog/2016/07/04/batchnorm/)\n",
1242 | "- [What does the gradient flowing through batch normalization looks like ?](http://cthorey.github.io./backpropagation/)\n",
1243 | "- [GRADIENTS, BATCH NORMALIZATION AND LAYER NORMALIZATION](https://theneuralperspective.com/2016/10/27/gradient-topics/)\n",
1244 | "\n",
1245 | "__Gradient Checking__:\n",
1246 | "- [cs231n](https://github.com/cs231n/cs231n.github.io/blob/master/neural-networks-3.md#gradcheck)\n",
1247 | "- [Gradient checking and advanced optimization](http://ufldl.stanford.edu/wiki/index.php/Gradient_checking_and_advanced_optimization)\n",
1248 | "- [BatchNormalization fails gradient checking](https://github.com/torch/nn/issues/744)"
1249 | ]
1250 | }
1251 | ],
1252 | "metadata": {
1253 | "kernelspec": {
1254 | "display_name": "Python 3 (ipykernel)",
1255 | "language": "python",
1256 | "name": "python3"
1257 | },
1258 | "language_info": {
1259 | "codemirror_mode": {
1260 | "name": "ipython",
1261 | "version": 3
1262 | },
1263 | "file_extension": ".py",
1264 | "mimetype": "text/x-python",
1265 | "name": "python",
1266 | "nbconvert_exporter": "python",
1267 | "pygments_lexer": "ipython3",
1268 | "version": "3.11.3"
1269 | }
1270 | },
1271 | "nbformat": 4,
1272 | "nbformat_minor": 2
1273 | }
1274 |
--------------------------------------------------------------------------------
/Rede Neural_Intuição.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "Neste notebook, vamos codificar Redes Neurais de forma manual para tentar entender intuitivamente como elas são implementadas na prática."
8 | ]
9 | },
10 | {
11 | "cell_type": "markdown",
12 | "metadata": {},
13 | "source": [
14 | "# Sumário"
15 | ]
16 | },
17 | {
18 | "cell_type": "markdown",
19 | "metadata": {},
20 | "source": [
21 | "- [Exemplo 1](#Exemplo-1)\n",
22 | "- [Exemplo 2](#Exemplo-2)\n",
23 | "- [O que precisamos para implementar uma Rede Neural?](#O-que-precisamos-para-implementar-uma-Rede-Neural?)\n",
24 | "- [Referências](#Referências)"
25 | ]
26 | },
27 | {
28 | "cell_type": "markdown",
29 | "metadata": {},
30 | "source": [
31 | "# Imports e Configurações"
32 | ]
33 | },
34 | {
35 | "cell_type": "code",
36 | "execution_count": null,
37 | "metadata": {},
38 | "outputs": [],
39 | "source": [
40 | "import numpy as np"
41 | ]
42 | },
43 | {
44 | "cell_type": "markdown",
45 | "metadata": {},
46 | "source": [
47 | "# Exemplo 1"
48 | ]
49 | },
50 | {
51 | "cell_type": "markdown",
52 | "metadata": {},
53 | "source": [
54 | "
"
55 | ]
56 | },
57 | {
58 | "cell_type": "code",
59 | "execution_count": null,
60 | "metadata": {},
61 | "outputs": [],
62 | "source": []
63 | },
64 | {
65 | "cell_type": "code",
66 | "execution_count": null,
67 | "metadata": {},
68 | "outputs": [],
69 | "source": []
70 | },
71 | {
72 | "cell_type": "markdown",
73 | "metadata": {},
74 | "source": [
75 | "# Exemplo 2"
76 | ]
77 | },
78 | {
79 | "cell_type": "code",
80 | "execution_count": null,
81 | "metadata": {},
82 | "outputs": [],
83 | "source": [
84 | "def linear(x, derivative=False):\n",
85 | " return np.ones_like(x) if derivative else x\n",
86 | "\n",
87 | "def relu(x, derivative=False):\n",
88 | " if derivative:\n",
89 | " x = np.where(x <= 0, 0, 1)\n",
90 | " return np.maximum(0, x)"
91 | ]
92 | },
93 | {
94 | "cell_type": "code",
95 | "execution_count": null,
96 | "metadata": {},
97 | "outputs": [],
98 | "source": [
99 | "x = np.array([[0.1, 0.2, 0.7]])\n",
100 | "y = np.array([[1, 0, 0]])\n",
101 | "w1 = np.array([[0.1, 0.2, 0.3], [0.3, 0.2, 0.7], [0.4, 0.3, 0.9]])\n",
102 | "b1 = np.ones((1,3))\n",
103 | "w2 = np.array([[0.2, 0.3, 0.5], [0.3, 0.5, 0.7], [0.6, 0.4, 0.8]])\n",
104 | "b2 = np.ones((1,3))\n",
105 | "w3 = np.array([[0.1, 0.4, 0.8], [0.3, 0.7, 0.2], [0.5, 0.2, 0.9]])\n",
106 | "b3 = np.ones((1,3))\n",
107 | "\n",
108 | "learning_rate = 0.01\n",
109 | "\n",
110 | "for i in range(301):\n",
111 | " # feedforward\n",
112 | " # 1a camada\n",
113 | "\n",
114 | " \n",
115 | " # 2a camada\n",
116 | "\n",
117 | " \n",
118 | " # 3a camada\n",
119 | "\n",
120 | " \n",
121 | " # backpropagation\n",
122 | " # insira seu código aqui!\n",
123 | " \n",
124 | "\n",
125 | "for w in [w1, w2, w3]:\n",
126 | " print(w)"
127 | ]
128 | },
129 | {
130 | "cell_type": "markdown",
131 | "metadata": {},
132 | "source": [
133 | "# O que precisamos para implementar uma Rede Neural?"
134 | ]
135 | },
136 | {
137 | "cell_type": "markdown",
138 | "metadata": {},
139 | "source": []
140 | },
141 | {
142 | "cell_type": "markdown",
143 | "metadata": {},
144 | "source": [
145 | "# Referências"
146 | ]
147 | },
148 | {
149 | "cell_type": "markdown",
150 | "metadata": {},
151 | "source": [
152 | "- [Neural Network from Scratch](https://beckernick.github.io/neural-network-scratch/)\n",
153 | "- [Backpropagation Algorithm](https://theclevermachine.wordpress.com/tag/backpropagation-algorithm/)\n",
154 | "- [Back-Propagation is very simple. Who made it Complicated ?](https://becominghuman.ai/back-propagation-is-very-simple-who-made-it-complicated-97b794c97e5c)\n",
155 | "- [A Step by Step Backpropagation Example](https://mattmazur.com/2015/03/17/a-step-by-step-backpropagation-example/)\n",
156 | "- [Understanding softmax and the negative log-likelihood](https://ljvmiranda921.github.io/notebook/2017/08/13/softmax-and-the-negative-log-likelihood/)"
157 | ]
158 | }
159 | ],
160 | "metadata": {
161 | "kernelspec": {
162 | "display_name": "Python 3",
163 | "language": "python",
164 | "name": "python3"
165 | },
166 | "language_info": {
167 | "codemirror_mode": {
168 | "name": "ipython",
169 | "version": 3
170 | },
171 | "file_extension": ".py",
172 | "mimetype": "text/x-python",
173 | "name": "python",
174 | "nbconvert_exporter": "python",
175 | "pygments_lexer": "ipython3",
176 | "version": "3.6.5"
177 | }
178 | },
179 | "nbformat": 4,
180 | "nbformat_minor": 2
181 | }
182 |
--------------------------------------------------------------------------------
/data/anuncios.csv:
--------------------------------------------------------------------------------
1 | idade,salario,comprou
2 | 19,19000,0
3 | 35,20000,0
4 | 26,43000,0
5 | 27,57000,0
6 | 19,76000,0
7 | 27,58000,0
8 | 27,84000,0
9 | 32,150000,1
10 | 25,33000,0
11 | 35,65000,0
12 | 26,80000,0
13 | 26,52000,0
14 | 20,86000,0
15 | 32,18000,0
16 | 18,82000,0
17 | 29,80000,0
18 | 47,25000,1
19 | 45,26000,1
20 | 46,28000,1
21 | 48,29000,1
22 | 45,22000,1
23 | 47,49000,1
24 | 48,41000,1
25 | 45,22000,1
26 | 46,23000,1
27 | 47,20000,1
28 | 49,28000,1
29 | 47,30000,1
30 | 29,43000,0
31 | 31,18000,0
32 | 31,74000,0
33 | 27,137000,1
34 | 21,16000,0
35 | 28,44000,0
36 | 27,90000,0
37 | 35,27000,0
38 | 33,28000,0
39 | 30,49000,0
40 | 26,72000,0
41 | 27,31000,0
42 | 27,17000,0
43 | 33,51000,0
44 | 35,108000,0
45 | 30,15000,0
46 | 28,84000,0
47 | 23,20000,0
48 | 25,79000,0
49 | 27,54000,0
50 | 30,135000,1
51 | 31,89000,0
52 | 24,32000,0
53 | 18,44000,0
54 | 29,83000,0
55 | 35,23000,0
56 | 27,58000,0
57 | 24,55000,0
58 | 23,48000,0
59 | 28,79000,0
60 | 22,18000,0
61 | 32,117000,0
62 | 27,20000,0
63 | 25,87000,0
64 | 23,66000,0
65 | 32,120000,1
66 | 59,83000,0
67 | 24,58000,0
68 | 24,19000,0
69 | 23,82000,0
70 | 22,63000,0
71 | 31,68000,0
72 | 25,80000,0
73 | 24,27000,0
74 | 20,23000,0
75 | 33,113000,0
76 | 32,18000,0
77 | 34,112000,1
78 | 18,52000,0
79 | 22,27000,0
80 | 28,87000,0
81 | 26,17000,0
82 | 30,80000,0
83 | 39,42000,0
84 | 20,49000,0
85 | 35,88000,0
86 | 30,62000,0
87 | 31,118000,1
88 | 24,55000,0
89 | 28,85000,0
90 | 26,81000,0
91 | 35,50000,0
92 | 22,81000,0
93 | 30,116000,0
94 | 26,15000,0
95 | 29,28000,0
96 | 29,83000,0
97 | 35,44000,0
98 | 35,25000,0
99 | 28,123000,1
100 | 35,73000,0
101 | 28,37000,0
102 | 27,88000,0
103 | 28,59000,0
104 | 32,86000,0
105 | 33,149000,1
106 | 19,21000,0
107 | 21,72000,0
108 | 26,35000,0
109 | 27,89000,0
110 | 26,86000,0
111 | 38,80000,0
112 | 39,71000,0
113 | 37,71000,0
114 | 38,61000,0
115 | 37,55000,0
116 | 42,80000,0
117 | 40,57000,0
118 | 35,75000,0
119 | 36,52000,0
120 | 40,59000,0
121 | 41,59000,0
122 | 36,75000,0
123 | 37,72000,0
124 | 40,75000,0
125 | 35,53000,0
126 | 41,51000,0
127 | 39,61000,0
128 | 42,65000,0
129 | 26,32000,0
130 | 30,17000,0
131 | 26,84000,0
132 | 31,58000,0
133 | 33,31000,0
134 | 30,87000,0
135 | 21,68000,0
136 | 28,55000,0
137 | 23,63000,0
138 | 20,82000,0
139 | 30,107000,1
140 | 28,59000,0
141 | 19,25000,0
142 | 19,85000,0
143 | 18,68000,0
144 | 35,59000,0
145 | 30,89000,0
146 | 34,25000,0
147 | 24,89000,0
148 | 27,96000,1
149 | 41,30000,0
150 | 29,61000,0
151 | 20,74000,0
152 | 26,15000,0
153 | 41,45000,0
154 | 31,76000,0
155 | 36,50000,0
156 | 40,47000,0
157 | 31,15000,0
158 | 46,59000,0
159 | 29,75000,0
160 | 26,30000,0
161 | 32,135000,1
162 | 32,100000,1
163 | 25,90000,0
164 | 37,33000,0
165 | 35,38000,0
166 | 33,69000,0
167 | 18,86000,0
168 | 22,55000,0
169 | 35,71000,0
170 | 29,148000,1
171 | 29,47000,0
172 | 21,88000,0
173 | 34,115000,0
174 | 26,118000,0
175 | 34,43000,0
176 | 34,72000,0
177 | 23,28000,0
178 | 35,47000,0
179 | 25,22000,0
180 | 24,23000,0
181 | 31,34000,0
182 | 26,16000,0
183 | 31,71000,0
184 | 32,117000,1
185 | 33,43000,0
186 | 33,60000,0
187 | 31,66000,0
188 | 20,82000,0
189 | 33,41000,0
190 | 35,72000,0
191 | 28,32000,0
192 | 24,84000,0
193 | 19,26000,0
194 | 29,43000,0
195 | 19,70000,0
196 | 28,89000,0
197 | 34,43000,0
198 | 30,79000,0
199 | 20,36000,0
200 | 26,80000,0
201 | 35,22000,0
202 | 35,39000,0
203 | 49,74000,0
204 | 39,134000,1
205 | 41,71000,0
206 | 58,101000,1
207 | 47,47000,0
208 | 55,130000,1
209 | 52,114000,0
210 | 40,142000,1
211 | 46,22000,0
212 | 48,96000,1
213 | 52,150000,1
214 | 59,42000,0
215 | 35,58000,0
216 | 47,43000,0
217 | 60,108000,1
218 | 49,65000,0
219 | 40,78000,0
220 | 46,96000,0
221 | 59,143000,1
222 | 41,80000,0
223 | 35,91000,1
224 | 37,144000,1
225 | 60,102000,1
226 | 35,60000,0
227 | 37,53000,0
228 | 36,126000,1
229 | 56,133000,1
230 | 40,72000,0
231 | 42,80000,1
232 | 35,147000,1
233 | 39,42000,0
234 | 40,107000,1
235 | 49,86000,1
236 | 38,112000,0
237 | 46,79000,1
238 | 40,57000,0
239 | 37,80000,0
240 | 46,82000,0
241 | 53,143000,1
242 | 42,149000,1
243 | 38,59000,0
244 | 50,88000,1
245 | 56,104000,1
246 | 41,72000,0
247 | 51,146000,1
248 | 35,50000,0
249 | 57,122000,1
250 | 41,52000,0
251 | 35,97000,1
252 | 44,39000,0
253 | 37,52000,0
254 | 48,134000,1
255 | 37,146000,1
256 | 50,44000,0
257 | 52,90000,1
258 | 41,72000,0
259 | 40,57000,0
260 | 58,95000,1
261 | 45,131000,1
262 | 35,77000,0
263 | 36,144000,1
264 | 55,125000,1
265 | 35,72000,0
266 | 48,90000,1
267 | 42,108000,1
268 | 40,75000,0
269 | 37,74000,0
270 | 47,144000,1
271 | 40,61000,0
272 | 43,133000,0
273 | 59,76000,1
274 | 60,42000,1
275 | 39,106000,1
276 | 57,26000,1
277 | 57,74000,1
278 | 38,71000,0
279 | 49,88000,1
280 | 52,38000,1
281 | 50,36000,1
282 | 59,88000,1
283 | 35,61000,0
284 | 37,70000,1
285 | 52,21000,1
286 | 48,141000,0
287 | 37,93000,1
288 | 37,62000,0
289 | 48,138000,1
290 | 41,79000,0
291 | 37,78000,1
292 | 39,134000,1
293 | 49,89000,1
294 | 55,39000,1
295 | 37,77000,0
296 | 35,57000,0
297 | 36,63000,0
298 | 42,73000,1
299 | 43,112000,1
300 | 45,79000,0
301 | 46,117000,1
302 | 58,38000,1
303 | 48,74000,1
304 | 37,137000,1
305 | 37,79000,1
306 | 40,60000,0
307 | 42,54000,0
308 | 51,134000,0
309 | 47,113000,1
310 | 36,125000,1
311 | 38,50000,0
312 | 42,70000,0
313 | 39,96000,1
314 | 38,50000,0
315 | 49,141000,1
316 | 39,79000,0
317 | 39,75000,1
318 | 54,104000,1
319 | 35,55000,0
320 | 45,32000,1
321 | 36,60000,0
322 | 52,138000,1
323 | 53,82000,1
324 | 41,52000,0
325 | 48,30000,1
326 | 48,131000,1
327 | 41,60000,0
328 | 41,72000,0
329 | 42,75000,0
330 | 36,118000,1
331 | 47,107000,1
332 | 38,51000,0
333 | 48,119000,1
334 | 42,65000,0
335 | 40,65000,0
336 | 57,60000,1
337 | 36,54000,0
338 | 58,144000,1
339 | 35,79000,0
340 | 38,55000,0
341 | 39,122000,1
342 | 53,104000,1
343 | 35,75000,0
344 | 38,65000,0
345 | 47,51000,1
346 | 47,105000,1
347 | 41,63000,0
348 | 53,72000,1
349 | 54,108000,1
350 | 39,77000,0
351 | 38,61000,0
352 | 38,113000,1
353 | 37,75000,0
354 | 42,90000,1
355 | 37,57000,0
356 | 36,99000,1
357 | 60,34000,1
358 | 54,70000,1
359 | 41,72000,0
360 | 40,71000,1
361 | 42,54000,0
362 | 43,129000,1
363 | 53,34000,1
364 | 47,50000,1
365 | 42,79000,0
366 | 42,104000,1
367 | 59,29000,1
368 | 58,47000,1
369 | 46,88000,1
370 | 38,71000,0
371 | 54,26000,1
372 | 60,46000,1
373 | 60,83000,1
374 | 39,73000,0
375 | 59,130000,1
376 | 37,80000,0
377 | 46,32000,1
378 | 46,74000,0
379 | 42,53000,0
380 | 41,87000,1
381 | 58,23000,1
382 | 42,64000,0
383 | 48,33000,1
384 | 44,139000,1
385 | 49,28000,1
386 | 57,33000,1
387 | 56,60000,1
388 | 49,39000,1
389 | 39,71000,0
390 | 47,34000,1
391 | 48,35000,1
392 | 48,33000,1
393 | 47,23000,1
394 | 45,45000,1
395 | 60,42000,1
396 | 39,59000,0
397 | 46,41000,1
398 | 51,23000,1
399 | 50,20000,1
400 | 36,33000,0
401 | 49,36000,1
402 |
--------------------------------------------------------------------------------
/data/medidas.csv:
--------------------------------------------------------------------------------
1 | Altura,Peso
2 | 187,109.720
3 | 177,91.090
4 | 180,88.930
5 | 177,89.390
6 | 177,92.020
7 | 183,94.700
8 | 178,83.570
9 | 177,85.190
10 | 183,92.960
11 | 188,108.210
12 | 168,71.340
13 | 178,90.000
14 | 164,71.220
15 | 173,85.340
16 | 176,85.080
17 | 172,77.490
18 | 170,76.840
19 | 182,92.730
20 | 179,89.820
21 | 173,87.290
22 | 175,85.820
23 | 169,79.330
24 | 183,89.990
25 | 161,70.970
26 | 177,84.850
27 | 155,55.650
28 | 171,70.840
29 | 185,97.840
30 | 186,92.310
31 | 162,69.800
32 | 172,86.140
33 | 176,86.980
34 | 177,84.250
35 | 168,74.190
36 | 180,93.330
37 | 184,84.920
38 | 161,69.910
39 | 166,71.990
40 | 188,95.380
41 | 179,91.290
42 | 174,80.780
43 | 170,82.990
44 | 180,87.920
45 | 191,100.130
46 | 194,108.720
47 | 176,92.010
48 | 174,93.670
49 | 171,80.990
50 | 174,76.910
51 | 187,99.330
52 | 149,46.310
53 | 162,66.790
54 | 156,59.430
55 | 145,48.350
56 | 152,51.440
57 | 166,65.110
58 | 171,77.390
59 | 162,65.490
60 | 168,72.820
61 | 154,52.070
62 | 165,63.500
63 | 158,61.180
64 | 162,63.250
65 | 159,55.820
66 | 154,48.660
67 | 176,82.380
68 | 164,61.590
69 | 154,59.260
70 | 161,60.800
71 | 161,54.800
72 | 159,64.770
73 | 169,73.750
74 | 153,52.350
75 | 150,47.170
76 | 179,81.670
77 | 163,58.600
78 | 177,75.890
79 | 170,75.070
80 | 164,57.350
81 | 168,72.920
82 | 156,53.760
83 | 163,57.440
84 | 169,72.340
85 | 178,76.000
86 | 163,61.230
87 | 157,56.930
88 | 162,66.010
89 | 161,62.040
90 | 160,54.380
91 | 156,64.650
92 | 148,48.890
93 | 160,55.150
94 | 162,58.470
95 | 159,67.860
96 | 170,74.470
97 | 166,57.140
98 | 165,71.160
99 | 159,68.750
100 | 159,58.220
101 | 167,66.660
102 |
--------------------------------------------------------------------------------
/data/notas.csv:
--------------------------------------------------------------------------------
1 | prova1,prova2,prova3,final
2 | 73,80,75,152
3 | 93,88,93,185
4 | 89,91,90,180
5 | 96,98,100,196
6 | 73,66,70,142
7 | 53,46,55,101
8 | 69,74,77,149
9 | 47,56,60,115
10 | 87,79,90,175
11 | 79,70,88,164
12 | 69,70,73,141
13 | 70,65,74,141
14 | 93,95,91,184
15 | 79,80,73,152
16 | 70,73,78,148
17 | 93,89,96,192
18 | 78,75,68,147
19 | 81,90,93,183
20 | 88,92,86,177
21 | 78,83,77,159
22 | 82,86,90,177
23 | 86,82,89,175
24 | 78,83,85,175
25 | 76,83,71,149
26 | 96,93,95,192
27 |
--------------------------------------------------------------------------------
/images/backprop_example_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/backprop_example_1.png
--------------------------------------------------------------------------------
/images/backpropagation_padroes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/backpropagation_padroes.png
--------------------------------------------------------------------------------
/images/bias_truque.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/bias_truque.jpg
--------------------------------------------------------------------------------
/images/circuito_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/circuito_2.png
--------------------------------------------------------------------------------
/images/circuito_2_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/circuito_2_back.png
--------------------------------------------------------------------------------
/images/circuito_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/circuito_3.png
--------------------------------------------------------------------------------
/images/circuito_3_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/circuito_3_back.png
--------------------------------------------------------------------------------
/images/circuito_3_forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/circuito_3_forward.png
--------------------------------------------------------------------------------
/images/classificador_linear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/classificador_linear.png
--------------------------------------------------------------------------------
/images/comparacao_camadas.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/comparacao_camadas.jpeg
--------------------------------------------------------------------------------
/images/comparacao_perceptron_adaline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/comparacao_perceptron_adaline.png
--------------------------------------------------------------------------------
/images/comparacao_regularizacao.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/comparacao_regularizacao.jpeg
--------------------------------------------------------------------------------
/images/derivada.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/derivada.gif
--------------------------------------------------------------------------------
/images/funcao_de_ativacao_elu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/funcao_de_ativacao_elu.png
--------------------------------------------------------------------------------
/images/funcao_de_ativacao_gaussian.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/funcao_de_ativacao_gaussian.png
--------------------------------------------------------------------------------
/images/funcao_de_ativacao_leaky_relu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/funcao_de_ativacao_leaky_relu.png
--------------------------------------------------------------------------------
/images/funcao_de_ativacao_linear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/funcao_de_ativacao_linear.png
--------------------------------------------------------------------------------
/images/funcao_de_ativacao_relu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/funcao_de_ativacao_relu.png
--------------------------------------------------------------------------------
/images/funcao_de_ativacao_sigmoid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/funcao_de_ativacao_sigmoid.png
--------------------------------------------------------------------------------
/images/funcao_de_ativacao_tanh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/funcao_de_ativacao_tanh.png
--------------------------------------------------------------------------------
/images/funcoes_de_ativacao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/funcoes_de_ativacao.png
--------------------------------------------------------------------------------
/images/hiperplanos_perceptron_adaline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/hiperplanos_perceptron_adaline.png
--------------------------------------------------------------------------------
/images/lr_decay_exponential_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/lr_decay_exponential_1.png
--------------------------------------------------------------------------------
/images/lr_decay_exponential_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/lr_decay_exponential_2.png
--------------------------------------------------------------------------------
/images/lr_decay_exponential_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/lr_decay_exponential_3.png
--------------------------------------------------------------------------------
/images/lr_decay_staircase_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/lr_decay_staircase_1.png
--------------------------------------------------------------------------------
/images/lr_decay_staircase_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/lr_decay_staircase_2.png
--------------------------------------------------------------------------------
/images/lr_decay_staircase_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/lr_decay_staircase_3.png
--------------------------------------------------------------------------------
/images/lr_decay_time_based_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/lr_decay_time_based_1.png
--------------------------------------------------------------------------------
/images/lr_decay_time_based_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/lr_decay_time_based_2.png
--------------------------------------------------------------------------------
/images/lr_decay_time_based_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/lr_decay_time_based_3.png
--------------------------------------------------------------------------------
/images/nn_arquitetura.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/nn_arquitetura.png
--------------------------------------------------------------------------------
/images/perceptron.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/perceptron.png
--------------------------------------------------------------------------------
/images/pesos_glorot_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/pesos_glorot_normal.png
--------------------------------------------------------------------------------
/images/pesos_glorot_uniform.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/pesos_glorot_uniform.png
--------------------------------------------------------------------------------
/images/pesos_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/pesos_normal.png
--------------------------------------------------------------------------------
/images/pesos_ones.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/pesos_ones.png
--------------------------------------------------------------------------------
/images/pesos_uniform.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/pesos_uniform.png
--------------------------------------------------------------------------------
/images/pesos_zeros.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/pesos_zeros.png
--------------------------------------------------------------------------------
/images/porta_multiplicacao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/porta_multiplicacao.png
--------------------------------------------------------------------------------
/images/pre_processamento.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/pre_processamento.png
--------------------------------------------------------------------------------
/images/pre_processamento_pca_whitening.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/pre_processamento_pca_whitening.png
--------------------------------------------------------------------------------
/images/udemy_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/images/udemy_logo.png
--------------------------------------------------------------------------------
/utils/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/utils/__init__.py
--------------------------------------------------------------------------------
/utils/grad_check.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaldog12/Manual-Pratico-Deep-Learning/e7adf7443e57279a352aa1022906327fab627c60/utils/grad_check.py
--------------------------------------------------------------------------------
/utils/plot.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import matplotlib.pyplot as plt
3 |
4 | def __softmax(x):
5 | exp = np.exp(x)
6 | return exp / np.sum(exp, axis=1, keepdims=True)
7 |
8 | def __compute_meshgrid(x, y):
9 | x_min, x_max, y_min, y_max = x[:, 0].min(), x[:, 0].max(), x[:, 1].min(), x[:, 1].max()
10 | x1, x2 = np.meshgrid(np.linspace(x_min, x_max, 100), np.linspace(y_min, y_max, 100))
11 | x_mesh = np.array([x1.ravel(), x2.ravel()]).T
12 | return x1, x2, x_mesh
13 |
14 | def classification_predictions(x, y, is_binary, nn=None, threshold=0.0, figsize=(12,6), s=15, cmap=plt.cm.viridis):
15 | plt.figure(figsize=figsize)
16 | ax = plt.subplot(1, 2, 1)
17 | plt.scatter(x[:, 0], x[:, 1], c=list(np.array(y).ravel()), s=s, cmap=cmap)
18 |
19 | if nn is not None:
20 | plt.subplot(1, 2, 2, sharex=ax, sharey=ax)
21 |
22 | x1, x2, x_mesh = __compute_meshgrid(x, y)
23 | y_mesh = nn.predict(x_mesh)
24 | y_mesh = np.where(y_mesh <= threshold, 0, 1) if is_binary else np.argmax(__softmax(y_mesh), axis=1)
25 |
26 | plt.scatter(x[:, 0], x[:, 1], c=list(np.array(y).ravel()), s=s, cmap=cmap)
27 | plt.contourf(x1, x2, y_mesh.reshape(x1.shape), cmap=cmap, alpha=0.5)
--------------------------------------------------------------------------------
/utils/samples_generator.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | def make_cubic(n_samples, x_min, x_max, a=1, b=0, c=0, d=0, noise=0.0, random_state=None):
4 | np.random.seed(random_state)
5 | x = np.linspace(x_min, x_max, n_samples)
6 | y = a*x**3 + b*x**2 + c*x + d + (2*noise*np.random.random(n_samples) - noise)
7 | return x.reshape(-1,1), y.reshape(-1,1)
8 |
9 | def make_exp(n_samples, x_min, x_max, noise=0.0, random_state=None):
10 | np.random.seed(random_state)
11 | x = np.linspace(x_min, x_max, n_samples)
12 | y = np.exp(x) + 2*noise*np.random.random(n_samples) - noise
13 | return x.reshape(-1,1), y.reshape(-1,1)
14 |
15 | def make_log10(n_samples, x_min, x_max, noise=0.0, random_state=None):
16 | np.random.seed(random_state)
17 | x = np.logspace(np.log10(x_min), np.log10(x_max), n_samples)
18 | y = np.log10(x) + 2*noise*np.random.random(n_samples) - noise
19 | return x.reshape(-1,1), y.reshape(-1,1)
20 |
21 | def make_spiral(n_samples, n_class=2, radius=1, laps=1.0, noise=0.0, random_state=None):
22 | np.random.seed(random_state)
23 | x = np.zeros((n_samples * n_class, 2))
24 | y = np.zeros((n_samples * n_class))
25 |
26 | pi_2 = 2 * np.math.pi
27 | points = np.linspace(0, 1, n_samples)
28 | r = points * radius
29 | t = points * pi_2 * laps
30 | for label, delta_t in zip(range(n_class), np.arange(0, pi_2, pi_2/n_class)):
31 | random_noise = (2 * np.random.rand(n_samples) - 1) * noise
32 | index = np.arange(label*n_samples, (label+1)*n_samples)
33 | x[index] = np.c_[r * np.sin(t + delta_t) + random_noise,
34 | r * np.cos(t + delta_t) + random_noise]
35 | y[index] = label
36 | return x, y.reshape(-1, 1)
37 |
38 | def make_square(n_samples, x_min, x_max, a=1, b=0, c=0, noise=0.0, random_state=None):
39 | np.random.seed(random_state)
40 | x = np.linspace(x_min, x_max, n_samples)
41 | y = a*x**2 + b*x + c + (2*noise*np.random.random(n_samples) - noise)
42 | return x.reshape(-1,1), y.reshape(-1,1)
43 |
--------------------------------------------------------------------------------