{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "\n", "*This notebook contains an excerpt from the [Deep Learning with Tensorflow 2.0](https://www.adhiraiyan.org/DeepLearningWithTensorflow.html) by Mukesh Mithrakumar. The code is released under the [MIT license](https://opensource.org/licenses/MIT) and is available for FREE [on GitHub](https://github.com/adhiraiyan/DeepLearningWithTF2.0).*\n", "\n", "*Open Source runs on love, laughter and a whole lot of coffee. Consider buying me [one](https://www.buymeacoffee.com/mmukesh) if you find this content useful!*\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "< [03.00 - Probability and Information Theory](03.00-Probability-and-Information-Theory.ipynb) | [Contents](Index.ipynb) |\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "DF-azaVjrT3v" }, "source": [ "# 04.00 - Numerical Computation" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "WCLFmnilZJC6" }, "source": [ "We now use computers for a wide range of reasons, from watching movies to reading books to playing games, but originally computers were designed and used to solve computational problems. \n", "\n", "Numerical analysis or scientific computing is defines as the study of approximation techniques for numerically solving mathematical problems. \n", "\n", "__Numerical Computation__ is necessary for problem solving in that very few mathematical problems have a closed form solution. If an equation solves a given problem in terms of functions and mathematical operations from a given generally-accepted set in a finite number of standard operations, it is said to be closed form. But since most of the problems we deal in real life are non closed form, we use numerical methods to solve it. \n", "\n", "Linear equations, linear programming, optimization and numerical partial differential equations are main branches of numerical computation. These may sound far off from what you deal with in daily life so let me give you few examples, you know how plane ticket prices seem to go up whenever they want, that is an optimization problem, Google's page rank that ranks web pages is an eigenvector of a matrix of order about 3 billion, all these problems are solved using numerical computation. We will look at some of those methods in this chapter.\n", "\n", "Optimization and solving systems of linear equations is at the heart of almost all machine learning and statistical techniques. These algorithms usually require a high amount of numerical computation. These evaluations can be difficult when the function involves real numbers, which can't be represented precisely using a finite amount of memory, which brings us to our first section." ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "colab": {}, "colab_type": "code", "id": "0x5dgEesF1XN" }, "outputs": [], "source": [ "\"\"\"\n", "At the moment of writing (06.06.2019) the only build that supports tensorflow probability is the tensorflow \n", "nightly build so we will use that to install tensorflow 2.0 and tensorflow probability.\n", "\"\"\"\n", "# Install tensorflow 2.0 and tensorflow probability from the nightly build\n", "!pip install --upgrade tf-nightly-2.0-preview tfp-nightly" ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "colab": {}, "colab_type": "code", "id": "05SSSlwwSW2f" }, "outputs": [], "source": [ "# Imports\n", "\n", "import tensorflow as tf\n", "import tensorflow_probability as tfp\n", "\n", "from matplotlib import pyplot as plt\n", "from mpl_toolkits.mplot3d import Axes3D\n", "\n", "import numpy as np\n", "\n", "# plt axis colors setup\n", "plt.rc_context({'axes.edgecolor':'orange', 'xtick.color':'red', 'ytick.color':'red', 'text.color':'orange'})" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "hQYa3NWorU1v" }, "source": [ "# 04.01 - Overflow and Underflow" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "TZIi9BksaDMc" }, "source": [ "Representing infinitely many real numbers with a finite number of bit patterns represents a fundamental difficulty in performing continuous math on a digital computer. This means that for almost all real numbers we incur some approximation error in the form of rounding error. Rounding error is problematic when it compounds across many operations, and can cause algorithms that work in theory to fail in practice if they are not designed to minimize the accumulation of rounding error.\n" ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 102 }, "colab_type": "code", "id": "vG3Nnyq_rVoC", "outputId": "6358e9d6-cd32-41e3-e2c7-aef8e7038a89" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x + y = 0.30000000000000004\n", "Rounded x + y: 0.3\n", "Check if .1 + .1 +.1 == .3: False\n", "What if we pre round before adding: False\n", "What if we post round after adding: True\n" ] } ], "source": [ "\"\"\"\n", "In the same way, no matter how many base 2 digits you’re willing to use, the decimal value 0.1 cannot be represented \n", "exactly as a base 2 fraction. In base 2, 1/10 is the infinitely repeating fraction\n", "\n", "0.0001100110011001100110011001100110011001100110011...\n", "\n", "One illusion may beget another. For example, since 0.1 is not exactly 1/10, summing three values of 0.1 may not \n", "yield exactly 0.3, either:\n", "\n", "Also, since the 0.1 cannot get any closer to the exact value of 1/10 and 0.3 cannot get any closer to the exact \n", "value of 3/10, then pre-rounding with round() function cannot help:\n", "\n", "Though the numbers cannot be made closer to their intended exact values, the round() function can be useful for \n", "post-rounding so that results with inexact values become comparable to one another:\n", "\n", "Binary floating-point arithmetic holds many surprises like this.\n", "\"\"\"\n", "\n", "x = 0.1\n", "y = 0.2\n", "\n", "print(\"x + y = {}\".format(x + y))\n", "print(\"Rounded x + y: {}\".format(round(x + y, 1)))\n", "print(\"Check if .1 + .1 +.1 == .3: {}\".format(1 + .1 + .1 == .3))\n", "print(\"What if we pre round before adding: {}\".format(round(.1, 1) + round(.1, 1) + round(.1, 1) == round(.3, 1)))\n", "print(\"What if we post round after adding: {}\".format(round(.1 + .1 + .1, 10) == round(.3, 10)))" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "0eH-1wLub-VN" }, "source": [ "__Underflow__: occurs when numbers near zero are rounded to zero. This can be particularly devastating, think of division by zero, some software environments will raise an exception but other will result with a placeholder not a number value.\n", "\n", "__Overflow__: occurs when numbers with large magnitude are approximated as $\\infty$ or $- \\infty$.\n", "\n", "One function that must be stabilized against underflow and overflow is the __softmax function__:\n", "\n", "$$\\color{orange}{\\text{softmax}(x)_i = \\frac{exp(x_j)}{\\sum_{j=1}^n exp(x_j)} \\tag{1}}$$" ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 119 }, "colab_type": "code", "id": "hoFPmxjob_AS", "outputId": "69e6d670-f8da-4bb0-abbc-66bd95f1b704" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Softmax Underflow [nan nan nan]\n", "Softmax Overflow [nan nan nan]\n", "Underflow Solved: [1. 0. 0.]\n", "Overflow Solved: [0. 0. 1.]\n", "Tensorflow Softmax Underflow: [1. 0. 0.] \n", "Tensorflow Softmax Overflow: [0. 0. 1.]\n" ] } ], "source": [ "def softmax(x, solve=False):\n", " \"\"\"Softmax implementation\"\"\"\n", " if solve:\n", " z = x-max(x)\n", " else:\n", " z = x\n", " numerator = tf.math.exp(z)\n", " denominator = tf.math.reduce_sum(numerator)\n", " \n", " return tf.divide(numerator, denominator)\n", "\n", "\n", "# Underflow example\n", "\"\"\"\n", "If c is very negative, exp(c) will underflow, meaning the denominator will become 0\n", "\"\"\"\n", "\n", "underflow = tf.constant([-12345, -67890, -99999999], dtype=tf.float32)\n", "print(\"Softmax Underflow {}\".format(softmax(underflow, solve=False)))\n", "\n", "# Overflow example\n", "\"\"\"\n", "When c is very large and positive, exp(c) will overflow and the expression ends up being undefined\n", "\"\"\"\n", "\n", "overflow = tf.constant([12345, 67890, 99999999], dtype=tf.float32)\n", "print(\"Softmax Overflow {}\".format(softmax(overflow, solve=False)))\n", "\n", "# Solution\n", "\"\"\"\n", "Both of these can be solved by evaluating softmax(z) where z = x - max_i x_i.\n", "This works because subtracting max results in the largest argument to exp being 0, getting rid of overflow\n", "and atleast one term in the denominator has a value of 1, which gets rid of underflow\n", "\n", "Compare the overflow and underflow examples\n", "\"\"\"\n", "\n", "underflow = tf.constant([-12345, -67890, -99999999], dtype=tf.float32)\n", "print(\"Underflow Solved: {}\".format(softmax(underflow, solve=True)))\n", "\n", "overflow = tf.constant([12345, 67890, 99999999], dtype=tf.float32)\n", "print(\"Overflow Solved: {}\".format(softmax(overflow, solve=True)))\n", "\n", "\n", "# compare the solution with the tensorflow softmax implementation\n", "underflow_softmax_tf = tf.nn.softmax(underflow, axis=None)\n", "overflow_softmax_tf = tf.nn.softmax(overflow, axis=None)\n", "\n", "print(\"Tensorflow Softmax Underflow: {} \\nTensorflow Softmax Overflow: {}\".format(underflow_softmax_tf, overflow_softmax_tf))" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "d3uIn1lPrZ6-" }, "source": [ "# 04.02 - Poor Conditioning" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "TSwxWe30iCyb" }, "source": [ "Conditioning refers to how rapidly a function changes with respect to small changes in its inputs. Functions that change rapidly when their inputs are perturbed slightly can be problematic for scientific computation because rounding errors in the inputs can result in large changes in the output.\n", "\n", "For example, the function $f(x) = A^{-1}x$. When $A \\in \\mathbb{R}^{n \\times n}$ has an eigenvalue decomposition, its __condition number__ is:\n", "\n", "$$\\color{orange}{max_{i, j} \\Biggr | \\frac{\\lambda_i}{\\lambda_j} \\Biggr | \\tag{2}}$$\n", "\n", "This is the ratio of the magnitude of the largest and smallest eigenvalue. When this number is large, matrix inversion is particularly sensitive to error in the input.\n", "\n", "This sensitivity is an intrinsic property of the matrix itself, not the result of rounding error during matrix inversion. Poorly conditioned matrices amplify pre-existing errors when we multiply by the true matrix inverse. In practice, the error will be compounded further by numerical errors in the inversion process itself." ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 255 }, "colab_type": "code", "id": "1UEpG4o-rapB", "outputId": "de8672b3-7b40-44d1-cf7d-a86e1841209b" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Matrix A: \n", "[[4.1 2.8]\n", " [9.7 6.6]]\n", "\n", "Value of x: \n", "[[ 1.0000000e+00]\n", " [-3.0517578e-05]]\n", "\n", "Solving for new x: \n", "[[0.3399811 ]\n", " [0.97002774]]\n", "We can see how the solution changes dramatically for a small increase in value\n", "\n", "Condition Number of A: 1623.00927734375\n" ] } ], "source": [ "A = tf.constant([[4.1, 2.8], [9.7, 6.6]], dtype=tf.float32)\n", "b = tf.constant([[4.1], [9.7]], dtype=tf.float32)\n", "print(\"Matrix A: \\n{}\\n\".format(A))\n", "\n", "# solve for x, from Ax=b, x = A^(-1) b\n", "x = tf.linalg.matmul(tf.linalg.inv(A), b)\n", "print(\"Value of x: \\n{}\\n\".format(x))\n", "\n", "# Now lets see what happens if we add 0.01 to the first component of b\n", "b2 = tf.constant([[4.11], [9.7]], dtype=tf.float32)\n", "\n", "# We can also use tf.linalg.solve to solve a systems of linear equations\n", "x_solve = tf.linalg.solve(A, b2)\n", "print(\"Solving for new x: \\n{}\".format(x_solve))\n", "print(\"We can see how the solution changes dramatically for a small increase in value\\n\")\n", "\n", "# let's now calculate the condition number for matrix A using ||A|| * ||A^-1||\n", "condition_A = tf.math.multiply(tf.norm(A), tf.norm(tf.linalg.inv(A)))\n", "print(\"Condition Number of A: {}\".format(condition_A))\n" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "o7BG2Q6_rbI2" }, "source": [ "# 04.03 - Gradient-Based Optimization" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "BFlhfprht5BQ" }, "source": [ "Most deep learning algorithms involve optimization of some sort. Optimization refers to the task of either minimizing or maximizing some function $f(x)$ by altering $x$. We usually phrase most optimization problems in terms of minimizing $f(x)$. Maximization may be accomplished via a minimization algorithm by minimizing $-f(x)$.\n", "\n", "The function we want to minimize or maximize is called the __objective function__ or __criterion__. When we are minimizing it, we may also call it the __cost function, loss function__, or __error function__.\n", "\n", "We often denote the value that minimizes or maximizes a function with a superscript *. For example we might say $x^* = arg \\ min \\ f(x)$.\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "3DO2wa2-vJ1T" }, "source": [ "Suppose we have a function $y = f(x)$, where both _x_ and _y_ are real numbers. The __derivative__ of this function is denoted as $f^{'}(x)$ or as $\\frac{dy}{dx}$. The derivative $f^{'}(x)$ gives the slope of $f(x)$ at the point _x_. In other words, it specifies how to scale a small change in the input to obtain the corresponding change in the output:\n", "\n", "$$\\color{orange}{f(x + \\epsilon) \\approx f(x) + \\epsilon f^{'}(x) \\tag{3}}$$" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "QyWiLUPEyPeY" }, "source": [ "__Gradient descent__ is the technique of moving in small steps with the opposite sign of the derivative to reduce $f(x)$.\n", "\n", "\n", "![Gradient descent](https://raw.githubusercontent.com/adhiraiyan/DeepLearningWithTF2.0/master/notebooks/figures/fig0403a.jpeg)\n" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "lKdh5_kZ3tMA" }, "source": [ "- When $f^{'}(x) = 0$, the derivative provides no information about which direction to move. These points are known as __critical points__, or __stationary points__.\n", "\n", "- A __local minimum__ is a points where $f(x)$ is lower than all neighboring points, so it is no longer possible to decrease $f(x)$ by making infinitesimal steps.\n", "\n", "- A __local maximum__ is a point where $f(x)$ is higher than all neighboring points, so it is not possible to increase $f(x)$ by making infinitesimal steps.\n", "\n", "- Some critical points are neither maxima or minima, these are knows as __saddle points__.\n", "\n", "- A point that obtains the absolute lowest value of $f(x)$ is a __global minimum__." ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 500 }, "colab_type": "code", "id": "8rP-VIP3r7OY", "outputId": "41d5568d-c644-4be6-8f05-deea5f5d97c3" }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "