From 1f39b264d98d4780563b49b60516b1c203fb244c Mon Sep 17 00:00:00 2001 From: aymericdamien Date: Thu, 7 Mar 2019 01:59:35 -0800 Subject: [PATCH 1/3] expanding examples to TensorFlow v2 --- .../0_Prerequisite/ml_introduction.ipynb | 50 +++++ .../0_Prerequisite/mnist_dataset_intro.ipynb | 96 +++++++++ .../1_Introduction/basic_operations.ipynb | 172 +++++++++++++++ .../notebooks/1_Introduction/helloworld.ipynb | 83 +++++++ .../2_BasicModels/linear_regression.ipynb | 204 ++++++++++++++++++ .../2_BasicModels/logistic_regression.ipynb | 131 +++++++++++ 6 files changed, 736 insertions(+) create mode 100644 tf2.0/notebooks/0_Prerequisite/ml_introduction.ipynb create mode 100644 tf2.0/notebooks/0_Prerequisite/mnist_dataset_intro.ipynb create mode 100644 tf2.0/notebooks/1_Introduction/basic_operations.ipynb create mode 100644 tf2.0/notebooks/1_Introduction/helloworld.ipynb create mode 100644 tf2.0/notebooks/2_BasicModels/linear_regression.ipynb create mode 100644 tf2.0/notebooks/2_BasicModels/logistic_regression.ipynb diff --git a/tf2.0/notebooks/0_Prerequisite/ml_introduction.ipynb b/tf2.0/notebooks/0_Prerequisite/ml_introduction.ipynb new file mode 100644 index 00000000..aa271e04 --- /dev/null +++ b/tf2.0/notebooks/0_Prerequisite/ml_introduction.ipynb @@ -0,0 +1,50 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Machine Learning\n", + "\n", + "Prior to start browsing the examples, it may be useful that you get familiar with machine learning, as TensorFlow is mostly used for machine learning tasks (especially Neural Networks). You can find below a list of useful links, that can give you the basic knowledge required for this TensorFlow Tutorial.\n", + "\n", + "## Machine Learning\n", + "\n", + "- [An Introduction to Machine Learning Theory and Its Applications: A Visual Tutorial with Examples](https://www.toptal.com/machine-learning/machine-learning-theory-an-introductory-primer)\n", + "- [A Gentle Guide to Machine Learning](https://blog.monkeylearn.com/a-gentle-guide-to-machine-learning/)\n", + "- [A Visual Introduction to Machine Learning](http://www.r2d3.us/visual-intro-to-machine-learning-part-1/)\n", + "- [Introduction to Machine Learning](http://alex.smola.org/drafts/thebook.pdf)\n", + "\n", + "## Deep Learning & Neural Networks\n", + "\n", + "- [An Introduction to Neural Networks](http://www.cs.stir.ac.uk/~lss/NNIntro/InvSlides.html)\n", + "- [An Introduction to Image Recognition with Deep Learning](https://medium.com/@ageitgey/machine-learning-is-fun-part-3-deep-learning-and-convolutional-neural-networks-f40359318721)\n", + "- [Neural Networks and Deep Learning](http://neuralnetworksanddeeplearning.com/index.html)\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "IPython (Python 2.7)", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.11" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/tf2.0/notebooks/0_Prerequisite/mnist_dataset_intro.ipynb b/tf2.0/notebooks/0_Prerequisite/mnist_dataset_intro.ipynb new file mode 100644 index 00000000..f1813c85 --- /dev/null +++ b/tf2.0/notebooks/0_Prerequisite/mnist_dataset_intro.ipynb @@ -0,0 +1,96 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "# MNIST Dataset Introduction\n", + "\n", + "Most examples are using MNIST dataset of handwritten digits. The dataset contains 60,000 examples for training and 10,000 examples for testing. The digits have been size-normalized and centered in a fixed-size image (28x28 pixels) with values from 0 to 1. For simplicity, each image has been flatten and converted to a 1-D numpy array of 784 features (28*28).\n", + "\n", + "## Overview\n", + "\n", + "![MNIST Digits](http://neuralnetworksanddeeplearning.com/images/mnist_100_digits.png)\n", + "\n", + "## Usage\n", + "In our examples, we are using TensorFlow [input_data.py](https://github.com/tensorflow/tensorflow/blob/r0.7/tensorflow/examples/tutorials/mnist/input_data.py) script to load that dataset.\n", + "It is quite useful for managing our data, and handle:\n", + "\n", + "- Dataset downloading\n", + "\n", + "- Loading the entire dataset into numpy array: \n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Import MNIST\n", + "from tensorflow.examples.tutorials.mnist import input_data\n", + "mnist = input_data.read_data_sets(\"/tmp/data/\", one_hot=True)\n", + "\n", + "# Load data\n", + "X_train = mnist.train.images\n", + "Y_train = mnist.train.labels\n", + "X_test = mnist.test.images\n", + "Y_test = mnist.test.labels" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- A `next_batch` function that can iterate over the whole dataset and return only the desired fraction of the dataset samples (in order to save memory and avoid to load the entire dataset)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Get the next 64 images array and labels\n", + "batch_X, batch_Y = mnist.train.next_batch(64)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Link: http://yann.lecun.com/exdb/mnist/" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/tf2.0/notebooks/1_Introduction/basic_operations.ipynb b/tf2.0/notebooks/1_Introduction/basic_operations.ipynb new file mode 100644 index 00000000..769cb600 --- /dev/null +++ b/tf2.0/notebooks/1_Introduction/basic_operations.ipynb @@ -0,0 +1,172 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Basic Tensor Operations\n", + "\n", + "Basic tensor operations using TensorFlow v2.\n", + "\n", + "- Author: Aymeric Damien\n", + "- Project: https://github.com/aymericdamien/TensorFlow-Examples/" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from __future__ import print_function\n", + "import tensorflow as tf" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Define tensor constants.\n", + "a = tf.constant(2)\n", + "b = tf.constant(3)\n", + "c = tf.constant(5)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "add = 5\n", + "sub = -1\n", + "mul = 6\n", + "div = 0.6666666666666666\n" + ] + } + ], + "source": [ + "# Various tensor operations.\n", + "# Note: Tensors also support python operators (+, *, ...)\n", + "add = tf.add(a, b)\n", + "sub = tf.subtract(a, b)\n", + "mul = tf.multiply(a, b)\n", + "div = tf.divide(a, b)\n", + "\n", + "# Access tensors value.\n", + "print(\"add =\", add.numpy())\n", + "print(\"sub =\", sub.numpy())\n", + "print(\"mul =\", mul.numpy())\n", + "print(\"div =\", div.numpy())" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "mean = 3\n", + "sum = 10\n" + ] + } + ], + "source": [ + "# Some more operations.\n", + "mean = tf.reduce_mean([a, b, c])\n", + "sum = tf.reduce_sum([a, b, c])\n", + "\n", + "# Access tensors value.\n", + "print(\"mean =\", mean.numpy())\n", + "print(\"sum =\", sum.numpy())" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Matrix multiplications.\n", + "matrix1 = tf.constant([[1., 2.], [3., 4.]])\n", + "matrix2 = tf.constant([[5., 6.], [7., 8.]])\n", + "\n", + "product = tf.matmul(matrix1, matrix2)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Display Tensor.\n", + "product" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[19., 22.],\n", + " [43., 50.]], dtype=float32)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Convert Tensor to Numpy.\n", + "product.numpy()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.15" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tf2.0/notebooks/1_Introduction/helloworld.ipynb b/tf2.0/notebooks/1_Introduction/helloworld.ipynb new file mode 100644 index 00000000..8a9479c0 --- /dev/null +++ b/tf2.0/notebooks/1_Introduction/helloworld.ipynb @@ -0,0 +1,83 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Hello World\n", + "\n", + "A very simple \"hello world\" using TensorFlow v2 tensors.\n", + "\n", + "- Author: Aymeric Damien\n", + "- Project: https://github.com/aymericdamien/TensorFlow-Examples/" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import tensorflow as tf" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tf.Tensor(hello world, shape=(), dtype=string)\n" + ] + } + ], + "source": [ + "# Create a Tensor.\n", + "hello = tf.constant(\"hello world\")\n", + "print hello" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "hello world\n" + ] + } + ], + "source": [ + "# To access a Tensor value, call numpy().\n", + "print hello.numpy()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.15" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tf2.0/notebooks/2_BasicModels/linear_regression.ipynb b/tf2.0/notebooks/2_BasicModels/linear_regression.ipynb new file mode 100644 index 00000000..17b57b8a --- /dev/null +++ b/tf2.0/notebooks/2_BasicModels/linear_regression.ipynb @@ -0,0 +1,204 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Linear Regression Example\n", + "\n", + "Linear regression implementation with TensorFlow v2 library.\n", + "\n", + "This example is using a low-level approach to better understand all mechanics behind the training process.\n", + "\n", + "- Author: Aymeric Damien\n", + "- Project: https://github.com/aymericdamien/TensorFlow-Examples/" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from __future__ import absolute_import, division, print_function" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import tensorflow as tf\n", + "import numpy as np\n", + "rng = np.random" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Parameters.\n", + "learning_rate = 0.01\n", + "training_steps = 1000\n", + "display_step = 50" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# Training Data.\n", + "X = np.array([3.3,4.4,5.5,6.71,6.93,4.168,9.779,6.182,7.59,2.167,\n", + " 7.042,10.791,5.313,7.997,5.654,9.27,3.1])\n", + "Y = np.array([1.7,2.76,2.09,3.19,1.694,1.573,3.366,2.596,2.53,1.221,\n", + " 2.827,3.465,1.65,2.904,2.42,2.94,1.3])\n", + "n_samples = X.shape[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Weight and Bias, initialized randomly.\n", + "W = tf.Variable(rng.randn(), name=\"weight\")\n", + "b = tf.Variable(rng.randn(), name=\"bias\")\n", + "\n", + "# Linear regression (Wx + b).\n", + "def linear_regression(x):\n", + " return W * x + b\n", + "\n", + "# Mean square error.\n", + "def mean_square(y_pred, y_true):\n", + " return tf.reduce_sum(tf.pow(y_pred-y_true, 2)) / (2 * n_samples)\n", + "\n", + "# Stochastic Gradient Descent Optimizer.\n", + "optimizer = tf.optimizers.SGD(learning_rate)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# Optimization process. \n", + "def run_optimization():\n", + " # Wrap computation inside a GradientTape for automatic differentiation.\n", + " with tf.GradientTape() as g:\n", + " pred = linear_regression(X)\n", + " loss = mean_square(pred, Y)\n", + "\n", + " # Compute gradients.\n", + " gradients = g.gradient(loss, [W, b])\n", + " \n", + " # Update W and b following gradients.\n", + " optimizer.apply_gradients(zip(gradients, [W, b]))" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "step: 50, loss: 0.210631, W: 0.458940, b: -0.670898\n", + "step: 100, loss: 0.195340, W: 0.446725, b: -0.584301\n", + "step: 150, loss: 0.181797, W: 0.435230, b: -0.502807\n", + "step: 200, loss: 0.169803, W: 0.424413, b: -0.426115\n", + "step: 250, loss: 0.159181, W: 0.414232, b: -0.353942\n", + "step: 300, loss: 0.149774, W: 0.404652, b: -0.286021\n", + "step: 350, loss: 0.141443, W: 0.395636, b: -0.222102\n", + "step: 400, loss: 0.134064, W: 0.387151, b: -0.161949\n", + "step: 450, loss: 0.127530, W: 0.379167, b: -0.105341\n", + "step: 500, loss: 0.121742, W: 0.371652, b: -0.052068\n", + "step: 550, loss: 0.116617, W: 0.364581, b: -0.001933\n", + "step: 600, loss: 0.112078, W: 0.357926, b: 0.045247\n", + "step: 650, loss: 0.108058, W: 0.351663, b: 0.089647\n", + "step: 700, loss: 0.104498, W: 0.345769, b: 0.131431\n", + "step: 750, loss: 0.101345, W: 0.340223, b: 0.170753\n", + "step: 800, loss: 0.098552, W: 0.335003, b: 0.207759\n", + "step: 850, loss: 0.096079, W: 0.330091, b: 0.242583\n", + "step: 900, loss: 0.093889, W: 0.325468, b: 0.275356\n", + "step: 950, loss: 0.091949, W: 0.321118, b: 0.306198\n", + "step: 1000, loss: 0.090231, W: 0.317024, b: 0.335223\n" + ] + } + ], + "source": [ + "# Run training for the given number of steps.\n", + "for step in range(1, training_steps + 1):\n", + " # Run the optimization to update W and b values.\n", + " run_optimization()\n", + " \n", + " if step % display_step == 0:\n", + " pred = linear_regression(X)\n", + " loss = mean_square(pred, Y)\n", + " print(\"step: %i, loss: %f, W: %f, b: %f\" % (step, loss, W.numpy(), b.numpy()))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Graphic display\n", + "plt.plot(X, Y, 'ro', label='Original data')\n", + "plt.plot(X, np.array(W * X + b), label='Fitted line')\n", + "plt.legend()\n", + "plt.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.15" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tf2.0/notebooks/2_BasicModels/logistic_regression.ipynb b/tf2.0/notebooks/2_BasicModels/logistic_regression.ipynb new file mode 100644 index 00000000..a1fff4ed --- /dev/null +++ b/tf2.0/notebooks/2_BasicModels/logistic_regression.ipynb @@ -0,0 +1,131 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Logistic Regression Example\n", + "\n", + "Logistic regression implementation with TensorFlow v2 library.\n", + "\n", + "This example is using a low-level approach to better understand all mechanics behind the training process.\n", + "\n", + "- Author: Aymeric Damien\n", + "- Project: https://github.com/aymericdamien/TensorFlow-Examples/" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## MNIST Dataset Overview\n", + "\n", + "This example is using MNIST handwritten digits. The dataset contains 60,000 examples for training and 10,000 examples for testing. The digits have been size-normalized and centered in a fixed-size image (28x28 pixels) with values from 0 to 1. For simplicity, each image has been flattened and converted to a 1-D numpy array of 784 features (28*28).\n", + "\n", + "![MNIST Dataset](http://neuralnetworksanddeeplearning.com/images/mnist_100_digits.png)\n", + "\n", + "More info: http://yann.lecun.com/exdb/mnist/" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from __future__ import absolute_import, division, print_function" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import tensorflow as tf\n", + "\n", + "# Import MINST data\n", + "from tensorflow.keras.datasets import mnist\n", + "(x_train, y_train), (x_test, y_test) = mnist.load_data()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Parameters\n", + "learning_rate = 0.01\n", + "training_steps = 500\n", + "batch_size = 128\n", + "display_step = 10" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Weight of shape [784, 10], the 28*28 image features,\n", + "# and the total number of classes.\n", + "W = tf.Variable(tf.zeros([784, 10]), name=\"weight\")\n", + "# Bias of shape [10], the total number of classes.\n", + "b = tf.Variable(tf.zeros([10]), name=\"bias\")\n", + "\n", + "# Logistic regression (Wx + b).\n", + "def logistic_regression(x):\n", + " return tf.nn.softmax(tf.matmul(x, W) + b)\n", + "\n", + "# Cross Entropy loss function.\n", + "def cross_entropy(y_pred, y_true):\n", + " return tf.reduce_mean(-tf.reduce_sum(y_true*tf.log(y_pred), reduction_indices=1))\n", + "\n", + "# Stochastic Gradient Descent Optimizer.\n", + "optimizer = tf.optimizers.SGD(learning_rate)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Optimization process. \n", + "def run_optimization(x, y):\n", + " # Wrap computation inside a GradientTape for automatic differentiation.\n", + " with tf.GradientTape() as g:\n", + " pred = logistic_regression(x)\n", + " loss = mean_square(pred, y)\n", + "\n", + " # Compute gradients.\n", + " gradients = g.gradient(loss, [W, b])\n", + " \n", + " # Update W and b following gradients.\n", + " optimizer.apply_gradients(zip(gradients, [W, b]))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.15" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 82f6003c27600de0f00162acae1ddf08968e5ebd Mon Sep 17 00:00:00 2001 From: aymericdamien Date: Thu, 7 Mar 2019 17:56:59 -0800 Subject: [PATCH 2/3] log reg --- .../2_BasicModels/logistic_regression.ipynb | 254 ++++++++++++++++-- 1 file changed, 231 insertions(+), 23 deletions(-) diff --git a/tf2.0/notebooks/2_BasicModels/logistic_regression.ipynb b/tf2.0/notebooks/2_BasicModels/logistic_regression.ipynb index a1fff4ed..ad6d705f 100644 --- a/tf2.0/notebooks/2_BasicModels/logistic_regression.ipynb +++ b/tf2.0/notebooks/2_BasicModels/logistic_regression.ipynb @@ -20,7 +20,9 @@ "source": [ "## MNIST Dataset Overview\n", "\n", - "This example is using MNIST handwritten digits. The dataset contains 60,000 examples for training and 10,000 examples for testing. The digits have been size-normalized and centered in a fixed-size image (28x28 pixels) with values from 0 to 1. For simplicity, each image has been flattened and converted to a 1-D numpy array of 784 features (28*28).\n", + "This example is using MNIST handwritten digits. The dataset contains 60,000 examples for training and 10,000 examples for testing. The digits have been size-normalized and centered in a fixed-size image (28x28 pixels) with values from 0 to 255. \n", + "\n", + "In this example, each image will be converted to float32, normalized to [0, 1] and flattened to a 1-D array of 784 features (28*28).\n", "\n", "![MNIST Dataset](http://neuralnetworksanddeeplearning.com/images/mnist_100_digits.png)\n", "\n", @@ -29,66 +31,94 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ - "from __future__ import absolute_import, division, print_function" + "from __future__ import absolute_import, division, print_function\n", + "\n", + "import tensorflow as tf\n", + "import numpy as np" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ - "import tensorflow as tf\n", + "# MNIST dataset parameters\n", + "num_classes = 10 # 0 to 9 digits\n", + "num_features = 784 # 28*28\n", "\n", - "# Import MINST data\n", + "# Training parameters\n", + "learning_rate = 0.1\n", + "training_steps = 500\n", + "batch_size = 256\n", + "display_step = 50" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Prepare MNIST data.\n", "from tensorflow.keras.datasets import mnist\n", - "(x_train, y_train), (x_test, y_test) = mnist.load_data()" + "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n", + "# Convert to float32\n", + "x_train, x_test = np.array(x_train, np.float32), np.array(x_test, np.float32)\n", + "# Flatten images to 1-D vector of 784 features (28*28).\n", + "x_train, x_test = x_train.reshape([-1, num_features]), x_test.reshape([-1, num_features])\n", + "# Normalize images value from [0, 255] to [0, 1].\n", + "x_train, x_test = x_train / 255., x_test / 255." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ - "# Parameters\n", - "learning_rate = 0.01\n", - "training_steps = 500\n", - "batch_size = 128\n", - "display_step = 10" + "# Use tf.data API to shuffle and batch data.\n", + "train_data = tf.data.Dataset.from_tensor_slices((x_train, y_train))\n", + "train_data = train_data.repeat().shuffle(5000).batch(batch_size).prefetch(1)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ - "# Weight of shape [784, 10], the 28*28 image features,\n", - "# and the total number of classes.\n", - "W = tf.Variable(tf.zeros([784, 10]), name=\"weight\")\n", + "# Weight of shape [784, 10], the 28*28 image features, and total number of classes.\n", + "W = tf.Variable(tf.zeros([num_features, num_classes]), name=\"weight\")\n", "# Bias of shape [10], the total number of classes.\n", - "b = tf.Variable(tf.zeros([10]), name=\"bias\")\n", + "b = tf.Variable(tf.zeros([num_classes]), name=\"bias\")\n", "\n", "# Logistic regression (Wx + b).\n", "def logistic_regression(x):\n", " return tf.nn.softmax(tf.matmul(x, W) + b)\n", "\n", - "# Cross Entropy loss function.\n", + "# Cross-Entropy loss function.\n", "def cross_entropy(y_pred, y_true):\n", - " return tf.reduce_mean(-tf.reduce_sum(y_true*tf.log(y_pred), reduction_indices=1))\n", + " y_true = tf.one_hot(y_true, depth=num_classes)\n", + " return tf.reduce_mean(-tf.reduce_sum(y_true*tf.math.log(y_pred), axis=1))\n", + "\n", + "# Accuracy metric.\n", + "def accuracy(y_pred, y_true):\n", + " # Predicted class is the index of prediction vector with highest score (i.e. argmax).\n", + " correct_prediction = tf.equal(tf.argmax(y_pred, 1), tf.cast(y_true, tf.int64))\n", + " return tf.reduce_mean(tf.cast(correct_prediction, tf.float32))\n", "\n", - "# Stochastic Gradient Descent Optimizer.\n", + "# Stochastic gradient descent optimizer.\n", "optimizer = tf.optimizers.SGD(learning_rate)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -97,7 +127,7 @@ " # Wrap computation inside a GradientTape for automatic differentiation.\n", " with tf.GradientTape() as g:\n", " pred = logistic_regression(x)\n", - " loss = mean_square(pred, y)\n", + " loss = cross_entropy(pred, y)\n", "\n", " # Compute gradients.\n", " gradients = g.gradient(loss, [W, b])\n", @@ -105,6 +135,184 @@ " # Update W and b following gradients.\n", " optimizer.apply_gradients(zip(gradients, [W, b]))" ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "step: 50, loss: 0.807478, accuracy: 0.847656\n", + "step: 100, loss: 0.582151, accuracy: 0.890625\n", + "step: 150, loss: 0.530786, accuracy: 0.867188\n", + "step: 200, loss: 0.478752, accuracy: 0.890625\n", + "step: 250, loss: 0.513769, accuracy: 0.859375\n", + "step: 300, loss: 0.422668, accuracy: 0.910156\n", + "step: 350, loss: 0.445952, accuracy: 0.875000\n", + "step: 400, loss: 0.428904, accuracy: 0.890625\n", + "step: 450, loss: 0.364081, accuracy: 0.917969\n", + "step: 500, loss: 0.386463, accuracy: 0.902344\n" + ] + } + ], + "source": [ + "# Run training for the given number of steps.\n", + "for step, (batch_x, batch_y) in enumerate(train_data.take(training_steps), 1):\n", + " # Run the optimization to update W and b values.\n", + " run_optimization(batch_x, batch_y)\n", + " \n", + " if step % display_step == 0:\n", + " pred = logistic_regression(batch_x)\n", + " loss = cross_entropy(pred, batch_y)\n", + " acc = accuracy(pred, batch_y)\n", + " print(\"step: %i, loss: %f, accuracy: %f\" % (step, loss, acc))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test Accuracy: 0.900000\n" + ] + } + ], + "source": [ + "# Test model on validation set.\n", + "pred = logistic_regression(x_test)\n", + "print(\"Test Accuracy: %f\" % accuracy(pred, y_test))" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# Visualize predictions.\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model prediction: 7\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model prediction: 2\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model prediction: 1\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model prediction: 0\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model prediction: 4\n" + ] + } + ], + "source": [ + "# Predict 5 images from validation set.\n", + "n_images = 5\n", + "test_images = x_test[:n_images]\n", + "predictions = logistic_regression(test_images)\n", + "\n", + "# Display image and model prediction.\n", + "for i in range(n_images):\n", + " plt.imshow(np.reshape(test_images[i], [28, 28]), cmap='gray')\n", + " plt.show()\n", + " print(\"Model prediction: %i\" % np.argmax(predictions.numpy()[i]))" + ] } ], "metadata": { From 0022029e2ed014c671800f24d44624bf4e0e8fc9 Mon Sep 17 00:00:00 2001 From: aymericdamien Date: Thu, 7 Mar 2019 23:51:34 -0800 Subject: [PATCH 3/3] add neural net and conv net --- .../2_BasicModels/logistic_regression.ipynb | 83 ++-- .../convolutional_network.ipynb | 429 ++++++++++++++++++ .../3_NeuralNetworks/neural_network.ipynb | 402 ++++++++++++++++ 3 files changed, 875 insertions(+), 39 deletions(-) create mode 100644 tf2.0/notebooks/3_NeuralNetworks/convolutional_network.ipynb create mode 100644 tf2.0/notebooks/3_NeuralNetworks/neural_network.ipynb diff --git a/tf2.0/notebooks/2_BasicModels/logistic_regression.ipynb b/tf2.0/notebooks/2_BasicModels/logistic_regression.ipynb index ad6d705f..c29c42b9 100644 --- a/tf2.0/notebooks/2_BasicModels/logistic_regression.ipynb +++ b/tf2.0/notebooks/2_BasicModels/logistic_regression.ipynb @@ -47,13 +47,13 @@ "metadata": {}, "outputs": [], "source": [ - "# MNIST dataset parameters\n", + "# MNIST dataset parameters.\n", "num_classes = 10 # 0 to 9 digits\n", "num_features = 784 # 28*28\n", "\n", - "# Training parameters\n", - "learning_rate = 0.1\n", - "training_steps = 500\n", + "# Training parameters.\n", + "learning_rate = 0.01\n", + "training_steps = 1000\n", "batch_size = 256\n", "display_step = 50" ] @@ -67,7 +67,7 @@ "# Prepare MNIST data.\n", "from tensorflow.keras.datasets import mnist\n", "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n", - "# Convert to float32\n", + "# Convert to float32.\n", "x_train, x_test = np.array(x_train, np.float32), np.array(x_test, np.float32)\n", "# Flatten images to 1-D vector of 784 features (28*28).\n", "x_train, x_test = x_train.reshape([-1, num_features]), x_test.reshape([-1, num_features])\n", @@ -93,22 +93,27 @@ "outputs": [], "source": [ "# Weight of shape [784, 10], the 28*28 image features, and total number of classes.\n", - "W = tf.Variable(tf.zeros([num_features, num_classes]), name=\"weight\")\n", + "W = tf.Variable(tf.ones([num_features, num_classes]), name=\"weight\")\n", "# Bias of shape [10], the total number of classes.\n", "b = tf.Variable(tf.zeros([num_classes]), name=\"bias\")\n", "\n", "# Logistic regression (Wx + b).\n", "def logistic_regression(x):\n", + " # Apply softmax to normalize the logits to a probability distribution.\n", " return tf.nn.softmax(tf.matmul(x, W) + b)\n", "\n", "# Cross-Entropy loss function.\n", "def cross_entropy(y_pred, y_true):\n", + " # Encode label to a one hot vector.\n", " y_true = tf.one_hot(y_true, depth=num_classes)\n", - " return tf.reduce_mean(-tf.reduce_sum(y_true*tf.math.log(y_pred), axis=1))\n", + " # Clip prediction values to avoid log(0) error.\n", + " y_pred = tf.clip_by_value(y_pred, 1e-9, 1.)\n", + " # Compute cross-entropy.\n", + " return tf.reduce_mean(-tf.reduce_sum(y_true * tf.math.log(y_pred)))\n", "\n", "# Accuracy metric.\n", "def accuracy(y_pred, y_true):\n", - " # Predicted class is the index of prediction vector with highest score (i.e. argmax).\n", + " # Predicted class is the index of highest score in prediction vector (i.e. argmax).\n", " correct_prediction = tf.equal(tf.argmax(y_pred, 1), tf.cast(y_true, tf.int64))\n", " return tf.reduce_mean(tf.cast(correct_prediction, tf.float32))\n", "\n", @@ -145,16 +150,26 @@ "name": "stdout", "output_type": "stream", "text": [ - "step: 50, loss: 0.807478, accuracy: 0.847656\n", - "step: 100, loss: 0.582151, accuracy: 0.890625\n", - "step: 150, loss: 0.530786, accuracy: 0.867188\n", - "step: 200, loss: 0.478752, accuracy: 0.890625\n", - "step: 250, loss: 0.513769, accuracy: 0.859375\n", - "step: 300, loss: 0.422668, accuracy: 0.910156\n", - "step: 350, loss: 0.445952, accuracy: 0.875000\n", - "step: 400, loss: 0.428904, accuracy: 0.890625\n", - "step: 450, loss: 0.364081, accuracy: 0.917969\n", - "step: 500, loss: 0.386463, accuracy: 0.902344\n" + "step: 50, loss: 608.584717, accuracy: 0.824219\n", + "step: 100, loss: 828.206482, accuracy: 0.765625\n", + "step: 150, loss: 716.329407, accuracy: 0.746094\n", + "step: 200, loss: 584.887634, accuracy: 0.820312\n", + "step: 250, loss: 472.098114, accuracy: 0.871094\n", + "step: 300, loss: 621.834595, accuracy: 0.832031\n", + "step: 350, loss: 567.288818, accuracy: 0.714844\n", + "step: 400, loss: 489.062988, accuracy: 0.847656\n", + "step: 450, loss: 496.466675, accuracy: 0.843750\n", + "step: 500, loss: 465.342224, accuracy: 0.875000\n", + "step: 550, loss: 586.347168, accuracy: 0.855469\n", + "step: 600, loss: 95.233109, accuracy: 0.906250\n", + "step: 650, loss: 88.136490, accuracy: 0.910156\n", + "step: 700, loss: 67.170349, accuracy: 0.937500\n", + "step: 750, loss: 79.673691, accuracy: 0.921875\n", + "step: 800, loss: 112.844872, accuracy: 0.914062\n", + "step: 850, loss: 92.789581, accuracy: 0.894531\n", + "step: 900, loss: 80.116165, accuracy: 0.921875\n", + "step: 950, loss: 45.706650, accuracy: 0.925781\n", + "step: 1000, loss: 72.986969, accuracy: 0.925781\n" ] } ], @@ -180,7 +195,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Test Accuracy: 0.900000\n" + "Test Accuracy: 0.915100\n" ] } ], @@ -207,14 +222,12 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] }, - "metadata": { - "needs_background": "light" - }, + "metadata": {}, "output_type": "display_data" }, { @@ -226,14 +239,12 @@ }, { "data": { - "image/png": "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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAP8AAAD8CAYAAAC4nHJkAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAADYNJREFUeJzt3X+oXPWZx/HPZ20CYouaFLMXYzc16rIqauUqiy2LSzW6S0wMWE3wjyy77O0fFbYYfxGECEuwLNvu7l+BFC9NtLVpuDHGWjYtsmoWTPAqGk2TtkauaTbX3A0pNkGkJnn2j3uy3MY7ZyYzZ+bMzfN+QZiZ88w552HI555z5pw5X0eEAOTzJ3U3AKAehB9IivADSRF+ICnCDyRF+IGkCD+QFOEHkiL8QFKf6+XKbHM5IdBlEeFW3tfRlt/2nbZ/Zfs92491siwAveV2r+23fZ6kX0u6XdJBSa9LWhERvyyZhy0/0GW92PLfLOm9iHg/Iv4g6ceSlnawPAA91En4L5X02ymvDxbT/ojtIdujtkc7WBeAinXyhd90uxaf2a2PiPWS1kvs9gP9pJMt/0FJl015PV/Soc7aAdArnYT/dUlX2v6y7dmSlkvaVk1bALqt7d3+iDhh+wFJ2yWdJ2k4IvZU1hmArmr7VF9bK+OYH+i6nlzkA2DmIvxAUoQfSIrwA0kRfiApwg8kRfiBpAg/kBThB5Ii/EBShB9IivADSRF+IKme3rob7XnooYdK6+eff37D2nXXXVc67z333NNWT6etW7eutP7aa681rD399NMdrRudYcsPJEX4gaQIP5AU4QeSIvxAUoQfSIrwA0lx994+sGnTptJ6p+fi67R///6Gtdtuu6103gMHDlTdTgrcvRdAKcIPJEX4gaQIP5AU4QeSIvxAUoQfSKqj3/PbHpN0TNJJSSciYrCKps41dZ7H37dvX2l9+/btpfXLL7+8tH7XXXeV1hcuXNiwdv/995fO++STT5bW0Zkqbubx1xFxpILlAOghdvuBpDoNf0j6ue03bA9V0RCA3uh0t/+rEXHI9iWSfmF7X0S8OvUNxR8F/jAAfaajLX9EHCoeJyQ9J+nmad6zPiIG+TIQ6C9th9/2Bba/cPq5pEWS3q2qMQDd1clu/zxJz9k+vZwfRcR/VtIVgK5rO/wR8b6k6yvsZcYaHCw/olm2bFlHy9+zZ09pfcmSJQ1rR46Un4U9fvx4aX327Nml9Z07d5bWr7++8X+RuXPnls6L7uJUH5AU4QeSIvxAUoQfSIrwA0kRfiAphuiuwMDAQGm9uBaioWan8u64447S+vj4eGm9E6tWrSqtX3311W0v+8UXX2x7XnSOLT+QFOEHkiL8QFKEH0iK8ANJEX4gKcIPJMV5/gq88MILpfUrrriitH7s2LHS+tGjR8+6p6osX768tD5r1qwedYKqseUHkiL8QFKEH0iK8ANJEX4gKcIPJEX4gaQ4z98DH3zwQd0tNPTwww+X1q+66qqOlr9r1662aug+tvxAUoQfSIrwA0kRfiApwg8kRfiBpAg/kJQjovwN9rCkxZImIuLaYtocSZskLZA0JuneiPhd05XZ5StD5RYvXlxa37x5c2m92RDdExMTpfWy+wG88sorpfOiPRFRPlBEoZUt/w8k3XnGtMckvRQRV0p6qXgNYAZpGv6IeFXSmbeSWSppQ/F8g6S7K+4LQJe1e8w/LyLGJal4vKS6lgD0Qtev7bc9JGmo2+sBcHba3fIftj0gScVjw299ImJ9RAxGxGCb6wLQBe2Gf5uklcXzlZKer6YdAL3SNPy2n5X0mqQ/t33Q9j9I+o6k223/RtLtxWsAM0jTY/6IWNGg9PWKe0EXDA6WH201O4/fzKZNm0rrnMvvX1zhByRF+IGkCD+QFOEHkiL8QFKEH0iKW3efA7Zu3dqwtmjRoo6WvXHjxtL6448/3tHyUR+2/EBShB9IivADSRF+ICnCDyRF+IGkCD+QVNNbd1e6Mm7d3ZaBgYHS+ttvv92wNnfu3NJ5jxw5Ulq/5ZZbSuv79+8vraP3qrx1N4BzEOEHkiL8QFKEH0iK8ANJEX4gKcIPJMXv+WeAkZGR0nqzc/llnnnmmdI65/HPXWz5gaQIP5AU4QeSIvxAUoQfSIrwA0kRfiCppuf5bQ9LWixpIiKuLaY9IekfJf1v8bbVEfGzbjV5rluyZElp/cYbb2x72S+//HJpfc2aNW0vGzNbK1v+H0i6c5rp/xYRNxT/CD4wwzQNf0S8KuloD3oB0EOdHPM/YHu37WHbF1fWEYCeaDf86yQtlHSDpHFJ3230RttDtkdtj7a5LgBd0Fb4I+JwRJyMiFOSvi/p5pL3ro+IwYgYbLdJANVrK/y2p95Odpmkd6tpB0CvtHKq71lJt0r6ou2DktZIutX2DZJC0pikb3axRwBd0DT8EbFimslPdaGXc1az39uvXr26tD5r1qy21/3WW2+V1o8fP972sjGzcYUfkBThB5Ii/EBShB9IivADSRF+IClu3d0Dq1atKq3fdNNNHS1/69atDWv8ZBeNsOUHkiL8QFKEH0iK8ANJEX4gKcIPJEX4gaQcEb1bmd27lfWRTz75pLTeyU92JWn+/PkNa+Pj4x0tGzNPRLiV97HlB5Ii/EBShB9IivADSRF+ICnCDyRF+IGk+D3/OWDOnDkNa59++mkPO/msjz76qGGtWW/Nrn+48MIL2+pJki666KLS+oMPPtj2sltx8uTJhrVHH320dN6PP/64kh7Y8gNJEX4gKcIPJEX4gaQIP5AU4QeSIvxAUk3P89u+TNJGSX8q6ZSk9RHxH7bnSNokaYGkMUn3RsTvutcqGtm9e3fdLTS0efPmhrVm9xqYN29eaf2+++5rq6d+9+GHH5bW165dW8l6Wtnyn5C0KiL+QtJfSvqW7aslPSbppYi4UtJLxWsAM0TT8EfEeES8WTw/JmmvpEslLZW0oXjbBkl3d6tJANU7q2N+2wskfUXSLknzImJcmvwDIemSqpsD0D0tX9tv+/OSRiR9OyJ+b7d0mzDZHpI01F57ALqlpS2/7VmaDP4PI2JLMfmw7YGiPiBpYrp5I2J9RAxGxGAVDQOoRtPwe3IT/5SkvRHxvSmlbZJWFs9XSnq++vYAdEvTW3fb/pqkHZLe0eSpPklarcnj/p9I+pKkA5K+ERFHmywr5a27t2zZUlpfunRpjzrJ5cSJEw1rp06dalhrxbZt20rro6OjbS97x44dpfWdO3eW1lu9dXfTY/6I+G9JjRb29VZWAqD/cIUfkBThB5Ii/EBShB9IivADSRF+ICmG6O4DjzzySGm90yG8y1xzzTWl9W7+bHZ4eLi0PjY21tHyR0ZGGtb27dvX0bL7GUN0AyhF+IGkCD+QFOEHkiL8QFKEH0iK8ANJcZ4fOMdwnh9AKcIPJEX4gaQIP5AU4QeSIvxAUoQfSIrwA0kRfiApwg8kRfiBpAg/kBThB5Ii/EBShB9Iqmn4bV9m+79s77W9x/Y/FdOfsP0/tt8q/v1t99sFUJWmN/OwPSBpICLetP0FSW9IulvSvZKOR8S/trwybuYBdF2rN/P4XAsLGpc0Xjw/ZnuvpEs7aw9A3c7qmN/2AklfkbSrmPSA7d22h21f3GCeIdujtkc76hRApVq+h5/tz0t6RdLaiNhie56kI5JC0j9r8tDg75ssg91+oMta3e1vKfy2Z0n6qaTtEfG9aeoLJP00Iq5tshzCD3RZZTfwtG1JT0naOzX4xReBpy2T9O7ZNgmgPq182/81STskvSPpVDF5taQVkm7Q5G7/mKRvFl8Oli2LLT/QZZXu9leF8APdx337AZQi/EBShB9IivADSRF+ICnCDyRF+IGkCD+QFOEHkiL8QFKEH0iK8ANJEX4gKcIPJNX0Bp4VOyLpgymvv1hM60f92lu/9iXRW7uq7O3PWn1jT3/P/5mV26MRMVhbAyX6tbd+7Uuit3bV1Ru7/UBShB9Iqu7wr695/WX6tbd+7Uuit3bV0lutx/wA6lP3lh9ATWoJv+07bf/K9nu2H6ujh0Zsj9l+pxh5uNYhxoph0CZsvztl2hzbv7D9m+Jx2mHSauqtL0ZuLhlZutbPrt9GvO75br/t8yT9WtLtkg5Kel3Sioj4ZU8bacD2mKTBiKj9nLDtv5J0XNLG06Mh2f4XSUcj4jvFH86LI+LRPuntCZ3lyM1d6q3RyNJ/pxo/uypHvK5CHVv+myW9FxHvR8QfJP1Y0tIa+uh7EfGqpKNnTF4qaUPxfIMm//P0XIPe+kJEjEfEm8XzY5JOjyxd62dX0lct6gj/pZJ+O+X1QfXXkN8h6ee237A9VHcz05h3emSk4vGSmvs5U9ORm3vpjJGl++aza2fE66rVEf7pRhPpp1MOX42IGyX9jaRvFbu3aM06SQs1OYzbuKTv1tlMMbL0iKRvR8Tv6+xlqmn6quVzqyP8ByVdNuX1fEmHauhjWhFxqHickPScJg9T+snh04OkFo8TNffz/yLicEScjIhTkr6vGj+7YmTpEUk/jIgtxeTaP7vp+qrrc6sj/K9LutL2l23PlrRc0rYa+vgM2xcUX8TI9gWSFqn/Rh/eJmll8XylpOdr7OWP9MvIzY1GllbNn12/jXhdy0U+xamMf5d0nqThiFjb8yamYftyTW7tpclfPP6ozt5sPyvpVk3+6uuwpDWStkr6iaQvSTog6RsR0fMv3hr0dqvOcuTmLvXWaGTpXarxs6tyxOtK+uEKPyAnrvADkiL8QFKEH0iK8ANJEX4gKcIPJEX4gaQIP5DU/wG6SwYLYCwMKQAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, - "metadata": { - "needs_background": "light" - }, + "metadata": {}, "output_type": "display_data" }, { @@ -245,14 +256,12 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] }, - "metadata": { - "needs_background": "light" - }, + "metadata": {}, "output_type": "display_data" }, { @@ -264,14 +273,12 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] }, - "metadata": { - "needs_background": "light" - }, + "metadata": {}, "output_type": "display_data" }, { @@ -283,14 +290,12 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] }, - "metadata": { - "needs_background": "light" - }, + "metadata": {}, "output_type": "display_data" }, { diff --git a/tf2.0/notebooks/3_NeuralNetworks/convolutional_network.ipynb b/tf2.0/notebooks/3_NeuralNetworks/convolutional_network.ipynb new file mode 100644 index 00000000..80adb3f0 --- /dev/null +++ b/tf2.0/notebooks/3_NeuralNetworks/convolutional_network.ipynb @@ -0,0 +1,429 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Convolutional Neural Network Example\n", + "\n", + "Build a convolutional neural network with TensorFlow v2.\n", + "\n", + "This example is using a low-level approach to better understand all mechanics behind building convolutional neural networks and the training process.\n", + "\n", + "- Author: Aymeric Damien\n", + "- Project: https://github.com/aymericdamien/TensorFlow-Examples/" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## CNN Overview\n", + "\n", + "![CNN](http://personal.ie.cuhk.edu.hk/~ccloy/project_target_code/images/fig3.png)\n", + "\n", + "## MNIST Dataset Overview\n", + "\n", + "This example is using MNIST handwritten digits. The dataset contains 60,000 examples for training and 10,000 examples for testing. The digits have been size-normalized and centered in a fixed-size image (28x28 pixels) with values from 0 to 255. \n", + "\n", + "In this example, each image will be converted to float32 and normalized to [0, 1].\n", + "\n", + "![MNIST Dataset](http://neuralnetworksanddeeplearning.com/images/mnist_100_digits.png)\n", + "\n", + "More info: http://yann.lecun.com/exdb/mnist/" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from __future__ import absolute_import, division, print_function\n", + "\n", + "import tensorflow as tf\n", + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# MNIST dataset parameters.\n", + "num_classes = 10 # total classes (0-9 digits).\n", + "\n", + "# Training parameters.\n", + "learning_rate = 0.001\n", + "training_steps = 200\n", + "batch_size = 128\n", + "display_step = 10\n", + "\n", + "# Network parameters.\n", + "conv1_filters = 32 # number of filters for 1st conv layer.\n", + "conv2_filters = 64 # number of filters for 2nd conv layer.\n", + "fc1_units = 1024 # number of neurons for 1st fully-connected layer." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Prepare MNIST data.\n", + "from tensorflow.keras.datasets import mnist\n", + "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n", + "# Convert to float32.\n", + "x_train, x_test = np.array(x_train, np.float32), np.array(x_test, np.float32)\n", + "# Normalize images value from [0, 255] to [0, 1].\n", + "x_train, x_test = x_train / 255., x_test / 255." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# Use tf.data API to shuffle and batch data.\n", + "train_data = tf.data.Dataset.from_tensor_slices((x_train, y_train))\n", + "train_data = train_data.repeat().shuffle(5000).batch(batch_size).prefetch(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Create some wrappers for simplicity.\n", + "def conv2d(x, W, b, strides=1):\n", + " # Conv2D wrapper, with bias and relu activation.\n", + " x = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME')\n", + " x = tf.nn.bias_add(x, b)\n", + " return tf.nn.relu(x)\n", + "\n", + "def maxpool2d(x, k=2):\n", + " # MaxPool2D wrapper.\n", + " return tf.nn.max_pool(x, ksize=[1, k, k, 1], strides=[1, k, k, 1], padding='SAME')" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# Store layers weight & bias\n", + "\n", + "# A random value generator to initialize weights.\n", + "random_normal = tf.initializers.RandomNormal()\n", + "\n", + "weights = {\n", + " # Conv Layer 1: 5x5 conv, 1 input, 32 filters (MNIST has 1 color channel only).\n", + " 'wc1': tf.Variable(random_normal([5, 5, 1, conv1_filters])),\n", + " # Conv Layer 2: 5x5 conv, 32 inputs, 64 filters.\n", + " 'wc2': tf.Variable(random_normal([5, 5, conv1_filters, conv2_filters])),\n", + " # FC Layer 1: 7*7*64 inputs, 1024 units.\n", + " 'wd1': tf.Variable(random_normal([7*7*64, fc1_units])),\n", + " # FC Out Layer: 1024 inputs, 10 units (total number of classes)\n", + " 'out': tf.Variable(random_normal([fc1_units, num_classes]))\n", + "}\n", + "\n", + "biases = {\n", + " 'bc1': tf.Variable(tf.zeros([conv1_filters])),\n", + " 'bc2': tf.Variable(tf.zeros([conv2_filters])),\n", + " 'bd1': tf.Variable(tf.zeros([fc1_units])),\n", + " 'out': tf.Variable(tf.zeros([num_classes]))\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# Create model\n", + "def conv_net(x):\n", + " \n", + " # Input shape: [-1, 28, 28, 1]. A batch of 28x28x1 (grayscale) images.\n", + " x = tf.reshape(x, [-1, 28, 28, 1])\n", + "\n", + " # Convolution Layer. Output shape: [-1, 28, 28, 32].\n", + " conv1 = conv2d(x, weights['wc1'], biases['bc1'])\n", + " \n", + " # Max Pooling (down-sampling). Output shape: [-1, 14, 14, 32].\n", + " conv1 = maxpool2d(conv1, k=2)\n", + "\n", + " # Convolution Layer. Output shape: [-1, 14, 14, 64].\n", + " conv2 = conv2d(conv1, weights['wc2'], biases['bc2'])\n", + " \n", + " # Max Pooling (down-sampling). Output shape: [-1, 7, 7, 64].\n", + " conv2 = maxpool2d(conv2, k=2)\n", + "\n", + " # Reshape conv2 output to fit fully connected layer input, Output shape: [-1, 7*7*64].\n", + " fc1 = tf.reshape(conv2, [-1, weights['wd1'].get_shape().as_list()[0]])\n", + " \n", + " # Fully connected layer, Output shape: [-1, 1024].\n", + " fc1 = tf.add(tf.matmul(fc1, weights['wd1']), biases['bd1'])\n", + " # Apply ReLU to fc1 output for non-linearity.\n", + " fc1 = tf.nn.relu(fc1)\n", + "\n", + " # Fully connected layer, Output shape: [-1, 10].\n", + " out = tf.add(tf.matmul(fc1, weights['out']), biases['out'])\n", + " # Apply softmax to normalize the logits to a probability distribution.\n", + " return tf.nn.softmax(out)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Cross-Entropy loss function.\n", + "def cross_entropy(y_pred, y_true):\n", + " # Encode label to a one hot vector.\n", + " y_true = tf.one_hot(y_true, depth=num_classes)\n", + " # Clip prediction values to avoid log(0) error.\n", + " y_pred = tf.clip_by_value(y_pred, 1e-9, 1.)\n", + " # Compute cross-entropy.\n", + " return tf.reduce_mean(-tf.reduce_sum(y_true * tf.math.log(y_pred)))\n", + "\n", + "# Accuracy metric.\n", + "def accuracy(y_pred, y_true):\n", + " # Predicted class is the index of highest score in prediction vector (i.e. argmax).\n", + " correct_prediction = tf.equal(tf.argmax(y_pred, 1), tf.cast(y_true, tf.int64))\n", + " return tf.reduce_mean(tf.cast(correct_prediction, tf.float32), axis=-1)\n", + "\n", + "# ADAM optimizer.\n", + "optimizer = tf.optimizers.Adam(learning_rate)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# Optimization process. \n", + "def run_optimization(x, y):\n", + " # Wrap computation inside a GradientTape for automatic differentiation.\n", + " with tf.GradientTape() as g:\n", + " pred = conv_net(x)\n", + " loss = cross_entropy(pred, y)\n", + " \n", + " # Variables to update, i.e. trainable variables.\n", + " trainable_variables = weights.values() + biases.values()\n", + "\n", + " # Compute gradients.\n", + " gradients = g.gradient(loss, trainable_variables)\n", + " \n", + " # Update W and b following gradients.\n", + " optimizer.apply_gradients(zip(gradients, trainable_variables))" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "step: 10, loss: 72.370056, accuracy: 0.851562\n", + "step: 20, loss: 53.936745, accuracy: 0.882812\n", + "step: 30, loss: 29.929554, accuracy: 0.921875\n", + "step: 40, loss: 28.075102, accuracy: 0.953125\n", + "step: 50, loss: 19.366310, accuracy: 0.960938\n", + "step: 60, loss: 20.398090, accuracy: 0.945312\n", + "step: 70, loss: 29.320951, accuracy: 0.960938\n", + "step: 80, loss: 9.121045, accuracy: 0.984375\n", + "step: 90, loss: 11.680668, accuracy: 0.976562\n", + "step: 100, loss: 12.413654, accuracy: 0.976562\n", + "step: 110, loss: 6.675493, accuracy: 0.984375\n", + "step: 120, loss: 8.730624, accuracy: 0.984375\n", + "step: 130, loss: 13.608270, accuracy: 0.960938\n", + "step: 140, loss: 12.859011, accuracy: 0.968750\n", + "step: 150, loss: 9.110849, accuracy: 0.976562\n", + "step: 160, loss: 5.832032, accuracy: 0.984375\n", + "step: 170, loss: 6.996647, accuracy: 0.968750\n", + "step: 180, loss: 5.325038, accuracy: 0.992188\n", + "step: 190, loss: 8.866342, accuracy: 0.984375\n", + "step: 200, loss: 2.626245, accuracy: 1.000000\n" + ] + } + ], + "source": [ + "# Run training for the given number of steps.\n", + "for step, (batch_x, batch_y) in enumerate(train_data.take(training_steps), 1):\n", + " # Run the optimization to update W and b values.\n", + " run_optimization(batch_x, batch_y)\n", + " \n", + " if step % display_step == 0:\n", + " pred = conv_net(batch_x)\n", + " loss = cross_entropy(pred, batch_y)\n", + " acc = accuracy(pred, batch_y)\n", + " print(\"step: %i, loss: %f, accuracy: %f\" % (step, loss, acc))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test Accuracy: 0.980000\n" + ] + } + ], + "source": [ + "# Test model on validation set.\n", + "pred = conv_net(x_test)\n", + "print(\"Test Accuracy: %f\" % accuracy(pred, y_test))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# Visualize predictions.\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model prediction: 7\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model prediction: 2\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAP8AAAD8CAYAAAC4nHJkAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAADCFJREFUeJzt3WGoXPWZx/Hvs1n7wrQvDDUarGu6RVdLxGS5iBBZXarFFSHmRaUKS2RL0xcNWNgXK76psBREtt1dfFFIaWgqrbVEs2pdbYsspguLGjVU21grcre9a8hVFGoVKSbPvrgn5VbvnLmZOTNnkuf7gTAz55kz52HI7/7PzDlz/pGZSKrnz/puQFI/DL9UlOGXijL8UlGGXyrK8EtFGX6pKMMvFWX4paL+fJobiwhPJ5QmLDNjNc8ba+SPiOsi4lcR8UpE3D7Oa0marhj13P6IWAO8DFwLLADPADdn5i9b1nHklyZsGiP/5cArmflqZv4B+AGwbYzXkzRF44T/POC3yx4vNMv+RETsjIiDEXFwjG1J6tg4X/ittGvxod36zNwN7AZ3+6VZMs7IvwCcv+zxJ4DXxmtH0rSME/5ngAsj4pMR8RHg88DD3bQladJG3u3PzPcjYhfwY2ANsCczf9FZZ5ImauRDfSNtzM/80sRN5SQfSacuwy8VZfilogy/VJThl4oy/FJRhl8qyvBLRRl+qSjDLxVl+KWiDL9UlOGXijL8UlGGXyrK8EtFGX6pKMMvFWX4paIMv1SU4ZeKmuoU3arnoosuGlh76aWXWte97bbbWuv33HPPSD1piSO/VJThl4oy/FJRhl8qyvBLRRl+qSjDLxU11nH+iJgH3gaOAe9n5lwXTen0sWXLloG148ePt667sLDQdTtapouTfP42M9/o4HUkTZG7/VJR44Y/gZ9ExLMRsbOLhiRNx7i7/Vsz87WIWA/8NCJeyswDy5/Q/FHwD4M0Y8Ya+TPzteZ2EdgPXL7Cc3Zn5pxfBkqzZeTwR8TaiPjYifvAZ4EXu2pM0mSNs9t/DrA/Ik68zvcz8/FOupI0cSOHPzNfBS7rsBedhjZv3jyw9s4777Suu3///q7b0TIe6pOKMvxSUYZfKsrwS0UZfqkowy8V5aW7NZZNmza11nft2jWwdu+993bdjk6CI79UlOGXijL8UlGGXyrK8EtFGX6pKMMvFeVxfo3l4osvbq2vXbt2YO3+++/vuh2dBEd+qSjDLxVl+KWiDL9UlOGXijL8UlGGXyoqMnN6G4uY3sY0FU8//XRr/eyzzx5YG3YtgGGX9tbKMjNW8zxHfqkowy8VZfilogy/VJThl4oy/FJRhl8qaujv+SNiD3ADsJiZm5pl64D7gY3APHBTZr41uTbVl40bN7bW5+bmWusvv/zywJrH8fu1mpH/O8B1H1h2O/BEZl4IPNE8lnQKGRr+zDwAvPmBxduAvc39vcCNHfclacJG/cx/TmYeAWhu13fXkqRpmPg1/CJiJ7Bz0tuRdHJGHfmPRsQGgOZ2cdATM3N3Zs5lZvs3Q5KmatTwPwzsaO7vAB7qph1J0zI0/BFxH/A/wF9FxEJEfAG4C7g2In4NXNs8lnQKGfqZPzNvHlD6TMe9aAZdddVVY63/+uuvd9SJuuYZflJRhl8qyvBLRRl+qSjDLxVl+KWinKJbrS699NKx1r/77rs76kRdc+SXijL8UlGGXyrK8EtFGX6pKMMvFWX4paKcoru4K664orX+6KOPttbn5+db61u3bh1Ye++991rX1WicoltSK8MvFWX4paIMv1SU4ZeKMvxSUYZfKsrf8xd3zTXXtNbXrVvXWn/88cdb6x7Ln12O/FJRhl8qyvBLRRl+qSjDLxVl+KWiDL9U1NDj/BGxB7gBWMzMTc2yO4EvAifmX74jM/9zUk1qci677LLW+rDrPezbt6/LdjRFqxn5vwNct8Lyf83Mzc0/gy+dYoaGPzMPAG9OoRdJUzTOZ/5dEfHziNgTEWd11pGkqRg1/N8EPgVsBo4AXx/0xIjYGREHI+LgiNuSNAEjhT8zj2bmscw8DnwLuLzlubszcy4z50ZtUlL3Rgp/RGxY9nA78GI37UialtUc6rsPuBr4eEQsAF8Fro6IzUAC88CXJtijpAnwuv2nuXPPPbe1fujQodb6W2+91Vq/5JJLTronTZbX7ZfUyvBLRRl+qSjDLxVl+KWiDL9UlJfuPs3deuutrfX169e31h977LEOu9EsceSXijL8UlGGXyrK8EtFGX6pKMMvFWX4paI8zn+au+CCC8Zaf9hPenXqcuSXijL8UlGGXyrK8EtFGX6pKMMvFWX4paI8zn+au+GGG8Za/5FHHumoE80aR36pKMMvFWX4paIMv1SU4ZeKMvxSUYZfKmrocf6IOB/4LnAucBzYnZn/HhHrgPuBjcA8cFNm+uPvHlx55ZUDa8Om6FZdqxn53wf+MTMvAa4AvhwRnwZuB57IzAuBJ5rHkk4RQ8OfmUcy87nm/tvAYeA8YBuwt3naXuDGSTUpqXsn9Zk/IjYCW4CngHMy8wgs/YEA2ud9kjRTVn1uf0R8FHgA+Epm/i4iVrveTmDnaO1JmpRVjfwRcQZLwf9eZj7YLD4aERua+gZgcaV1M3N3Zs5l5lwXDUvqxtDwx9IQ/23gcGZ+Y1npYWBHc38H8FD37UmalNXs9m8F/h54ISIONcvuAO4CfhgRXwB+A3xuMi1qmO3btw+srVmzpnXd559/vrV+4MCBkXrS7Bsa/sz8b2DQB/zPdNuOpGnxDD+pKMMvFWX4paIMv1SU4ZeKMvxSUV66+xRw5plnttavv/76kV973759rfVjx46N/NqabY78UlGGXyrK8EtFGX6pKMMvFWX4paIMv1RUZOb0NhYxvY2dRs4444zW+pNPPjmwtri44gWW/uiWW25prb/77rutdc2ezFzVNfYc+aWiDL9UlOGXijL8UlGGXyrK8EtFGX6pKI/zS6cZj/NLamX4paIMv1SU4ZeKMvxSUYZfKsrwS0UNDX9EnB8R/xURhyPiFxFxW7P8zoj4v4g41Pwb/eLxkqZu6Ek+EbEB2JCZz0XEx4BngRuBm4DfZ+a/rHpjnuQjTdxqT/IZOmNPZh4BjjT3346Iw8B547UnqW8n9Zk/IjYCW4CnmkW7IuLnEbEnIs4asM7OiDgYEQfH6lRSp1Z9bn9EfBR4EvhaZj4YEecAbwAJ/DNLHw3+YchruNsvTdhqd/tXFf6IOAP4EfDjzPzGCvWNwI8yc9OQ1zH80oR19sOeiAjg28Dh5cFvvgg8YTvw4sk2Kak/q/m2/0rgZ8ALwPFm8R3AzcBmlnb754EvNV8Otr2WI780YZ3u9nfF8EuT5+/5JbUy/FJRhl8qyvBLRRl+qSjDLxVl+KWiDL9UlOGXijL8UlGGXyrK8EtFGX6pKMMvFTX0Ap4dewP432WPP94sm0Wz2tus9gX2Nqoue7tgtU+c6u/5P7TxiIOZOddbAy1mtbdZ7QvsbVR99eZuv1SU4ZeK6jv8u3vefptZ7W1W+wJ7G1UvvfX6mV9Sf/oe+SX1pJfwR8R1EfGriHglIm7vo4dBImI+Il5oZh7udYqxZhq0xYh4cdmydRHx04j4dXO74jRpPfU2EzM3t8ws3et7N2szXk99tz8i1gAvA9cCC8AzwM2Z+cupNjJARMwDc5nZ+zHhiPgb4PfAd0/MhhQRdwNvZuZdzR/OszLzn2aktzs5yZmbJ9TboJmlb6XH967LGa+70MfIfznwSma+mpl/AH4AbOuhj5mXmQeANz+weBuwt7m/l6X/PFM3oLeZkJlHMvO55v7bwImZpXt971r66kUf4T8P+O2yxwvM1pTfCfwkIp6NiJ19N7OCc07MjNTcru+5nw8aOnPzNH1gZumZee9GmfG6a32Ef6XZRGbpkMPWzPxr4O+ALze7t1qdbwKfYmkatyPA1/tspplZ+gHgK5n5uz57WW6Fvnp53/oI/wJw/rLHnwBe66GPFWXma83tIrCfpY8ps+ToiUlSm9vFnvv5o8w8mpnHMvM48C16fO+amaUfAL6XmQ82i3t/71bqq6/3rY/wPwNcGBGfjIiPAJ8HHu6hjw+JiLXNFzFExFrgs8ze7MMPAzua+zuAh3rs5U/MyszNg2aWpuf3btZmvO7lJJ/mUMa/AWuAPZn5tak3sYKI+EuWRntY+sXj9/vsLSLuA65m6VdfR4GvAv8B/BD4C+A3wOcyc+pfvA3o7WpOcubmCfU2aGbpp+jxvetyxutO+vEMP6kmz/CTijL8UlGGXyrK8EtFGX6pKMMvFWX4paIMv1TU/wNPnZK3k8+kHgAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model prediction: 1\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model prediction: 0\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model prediction: 4\n" + ] + } + ], + "source": [ + "# Predict 5 images from validation set.\n", + "n_images = 5\n", + "test_images = x_test[:n_images]\n", + "predictions = conv_net(test_images)\n", + "\n", + "# Display image and model prediction.\n", + "for i in range(n_images):\n", + " plt.imshow(np.reshape(test_images[i], [28, 28]), cmap='gray')\n", + " plt.show()\n", + " print(\"Model prediction: %i\" % np.argmax(predictions.numpy()[i]))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.15" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tf2.0/notebooks/3_NeuralNetworks/neural_network.ipynb b/tf2.0/notebooks/3_NeuralNetworks/neural_network.ipynb new file mode 100644 index 00000000..bbec2f13 --- /dev/null +++ b/tf2.0/notebooks/3_NeuralNetworks/neural_network.ipynb @@ -0,0 +1,402 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Neural Network Example\n", + "\n", + "Build a 2-hidden layers fully connected neural network (a.k.a multilayer perceptron) with TensorFlow v2.\n", + "\n", + "This example is using a low-level approach to better understand all mechanics behind building neural networks and the training process.\n", + "\n", + "- Author: Aymeric Damien\n", + "- Project: https://github.com/aymericdamien/TensorFlow-Examples/" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Neural Network Overview\n", + "\n", + "\"nn\"\n", + "\n", + "## MNIST Dataset Overview\n", + "\n", + "This example is using MNIST handwritten digits. The dataset contains 60,000 examples for training and 10,000 examples for testing. The digits have been size-normalized and centered in a fixed-size image (28x28 pixels) with values from 0 to 255. \n", + "\n", + "In this example, each image will be converted to float32, normalized to [0, 1] and flattened to a 1-D array of 784 features (28*28).\n", + "\n", + "![MNIST Dataset](http://neuralnetworksanddeeplearning.com/images/mnist_100_digits.png)\n", + "\n", + "More info: http://yann.lecun.com/exdb/mnist/" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from __future__ import absolute_import, division, print_function\n", + "\n", + "import tensorflow as tf\n", + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# MNIST dataset parameters.\n", + "num_classes = 10 # total classes (0-9 digits).\n", + "num_features = 784 # data features (img shape: 28*28).\n", + "\n", + "# Training parameters.\n", + "learning_rate = 0.001\n", + "training_steps = 3000\n", + "batch_size = 256\n", + "display_step = 100\n", + "\n", + "# Network parameters.\n", + "n_hidden_1 = 128 # 1st layer number of neurons.\n", + "n_hidden_2 = 256 # 2nd layer number of neurons." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Prepare MNIST data.\n", + "from tensorflow.keras.datasets import mnist\n", + "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n", + "# Convert to float32.\n", + "x_train, x_test = np.array(x_train, np.float32), np.array(x_test, np.float32)\n", + "# Flatten images to 1-D vector of 784 features (28*28).\n", + "x_train, x_test = x_train.reshape([-1, num_features]), x_test.reshape([-1, num_features])\n", + "# Normalize images value from [0, 255] to [0, 1].\n", + "x_train, x_test = x_train / 255., x_test / 255." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# Use tf.data API to shuffle and batch data.\n", + "train_data = tf.data.Dataset.from_tensor_slices((x_train, y_train))\n", + "train_data = train_data.repeat().shuffle(5000).batch(batch_size).prefetch(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Store layers weight & bias\n", + "\n", + "# A random value generator to initialize weights.\n", + "random_normal = tf.initializers.RandomNormal()\n", + "\n", + "weights = {\n", + " 'h1': tf.Variable(random_normal([num_features, n_hidden_1])),\n", + " 'h2': tf.Variable(random_normal([n_hidden_1, n_hidden_2])),\n", + " 'out': tf.Variable(random_normal([n_hidden_2, num_classes]))\n", + "}\n", + "biases = {\n", + " 'b1': tf.Variable(tf.zeros([n_hidden_1])),\n", + " 'b2': tf.Variable(tf.zeros([n_hidden_2])),\n", + " 'out': tf.Variable(tf.zeros([num_classes]))\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# Create model.\n", + "def neural_net(x):\n", + " # Hidden fully connected layer with 128 neurons.\n", + " layer_1 = tf.add(tf.matmul(x, weights['h1']), biases['b1'])\n", + " # Apply sigmoid to layer_1 output for non-linearity.\n", + " layer_1 = tf.nn.sigmoid(layer_1)\n", + " \n", + " # Hidden fully connected layer with 256 neurons.\n", + " layer_2 = tf.add(tf.matmul(layer_1, weights['h2']), biases['b2'])\n", + " # Apply sigmoid to layer_2 output for non-linearity.\n", + " layer_2 = tf.nn.sigmoid(layer_2)\n", + " \n", + " # Output fully connected layer with a neuron for each class.\n", + " out_layer = tf.matmul(layer_2, weights['out']) + biases['out']\n", + " # Apply softmax to normalize the logits to a probability distribution.\n", + " return tf.nn.softmax(out_layer)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# Cross-Entropy loss function.\n", + "def cross_entropy(y_pred, y_true):\n", + " # Encode label to a one hot vector.\n", + " y_true = tf.one_hot(y_true, depth=num_classes)\n", + " # Clip prediction values to avoid log(0) error.\n", + " y_pred = tf.clip_by_value(y_pred, 1e-9, 1.)\n", + " # Compute cross-entropy.\n", + " return tf.reduce_mean(-tf.reduce_sum(y_true * tf.math.log(y_pred)))\n", + "\n", + "# Accuracy metric.\n", + "def accuracy(y_pred, y_true):\n", + " # Predicted class is the index of highest score in prediction vector (i.e. argmax).\n", + " correct_prediction = tf.equal(tf.argmax(y_pred, 1), tf.cast(y_true, tf.int64))\n", + " return tf.reduce_mean(tf.cast(correct_prediction, tf.float32), axis=-1)\n", + "\n", + "# Stochastic gradient descent optimizer.\n", + "optimizer = tf.optimizers.SGD(learning_rate)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Optimization process. \n", + "def run_optimization(x, y):\n", + " # Wrap computation inside a GradientTape for automatic differentiation.\n", + " with tf.GradientTape() as g:\n", + " pred = neural_net(x)\n", + " loss = cross_entropy(pred, y)\n", + " \n", + " # Variables to update, i.e. trainable variables.\n", + " trainable_variables = weights.values() + biases.values()\n", + "\n", + " # Compute gradients.\n", + " gradients = g.gradient(loss, trainable_variables)\n", + " \n", + " # Update W and b following gradients.\n", + " optimizer.apply_gradients(zip(gradients, trainable_variables))" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "step: 100, loss: 567.292969, accuracy: 0.136719\n", + "step: 200, loss: 398.614929, accuracy: 0.562500\n", + "step: 300, loss: 226.743774, accuracy: 0.753906\n", + "step: 400, loss: 193.384521, accuracy: 0.777344\n", + "step: 500, loss: 138.649963, accuracy: 0.886719\n", + "step: 600, loss: 109.713669, accuracy: 0.898438\n", + "step: 700, loss: 90.397217, accuracy: 0.906250\n", + "step: 800, loss: 104.545380, accuracy: 0.894531\n", + "step: 900, loss: 94.204697, accuracy: 0.890625\n", + "step: 1000, loss: 81.660645, accuracy: 0.906250\n", + "step: 1100, loss: 81.237137, accuracy: 0.902344\n", + "step: 1200, loss: 65.776703, accuracy: 0.925781\n", + "step: 1300, loss: 94.195862, accuracy: 0.910156\n", + "step: 1400, loss: 79.425507, accuracy: 0.917969\n", + "step: 1500, loss: 93.508163, accuracy: 0.914062\n", + "step: 1600, loss: 88.912506, accuracy: 0.917969\n", + "step: 1700, loss: 79.033607, accuracy: 0.929688\n", + "step: 1800, loss: 65.788315, accuracy: 0.898438\n", + "step: 1900, loss: 73.462387, accuracy: 0.937500\n", + "step: 2000, loss: 59.309540, accuracy: 0.917969\n", + "step: 2100, loss: 67.014008, accuracy: 0.917969\n", + "step: 2200, loss: 48.297115, accuracy: 0.949219\n", + "step: 2300, loss: 64.523148, accuracy: 0.910156\n", + "step: 2400, loss: 72.989517, accuracy: 0.925781\n", + "step: 2500, loss: 57.588585, accuracy: 0.929688\n", + "step: 2600, loss: 44.957100, accuracy: 0.960938\n", + "step: 2700, loss: 59.788242, accuracy: 0.937500\n", + "step: 2800, loss: 63.581337, accuracy: 0.937500\n", + "step: 2900, loss: 53.471252, accuracy: 0.941406\n", + "step: 3000, loss: 43.869728, accuracy: 0.949219\n" + ] + } + ], + "source": [ + "# Run training for the given number of steps.\n", + "for step, (batch_x, batch_y) in enumerate(train_data.take(training_steps), 1):\n", + " # Run the optimization to update W and b values.\n", + " run_optimization(batch_x, batch_y)\n", + " \n", + " if step % display_step == 0:\n", + " pred = neural_net(batch_x)\n", + " loss = cross_entropy(pred, batch_y)\n", + " acc = accuracy(pred, batch_y)\n", + " print(\"step: %i, loss: %f, accuracy: %f\" % (step, loss, acc))" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test Accuracy: 0.936800\n" + ] + } + ], + "source": [ + "# Test model on validation set.\n", + "pred = neural_net(x_test)\n", + "print(\"Test Accuracy: %f\" % accuracy(pred, y_test))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# Visualize predictions.\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model prediction: 7\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model prediction: 2\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model prediction: 1\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model prediction: 0\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model prediction: 4\n" + ] + } + ], + "source": [ + "# Predict 5 images from validation set.\n", + "n_images = 5\n", + "test_images = x_test[:n_images]\n", + "predictions = neural_net(test_images)\n", + "\n", + "# Display image and model prediction.\n", + "for i in range(n_images):\n", + " plt.imshow(np.reshape(test_images[i], [28, 28]), cmap='gray')\n", + " plt.show()\n", + " print(\"Model prediction: %i\" % np.argmax(predictions.numpy()[i]))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.15" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}