{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/lukasheinrich/Code/iml_tutorial/_venv/lib/python3.9/site-packages/jax/_src/lib/__init__.py:33: UserWarning: JAX on Mac ARM machines is experimental and minimally tested. Please see https://github.com/google/jax/issues/5501 in the event of problems.\n", " warnings.warn(\"JAX on Mac ARM machines is experimental and minimally tested. \"\n" ] } ], "source": [ "import pyhf\n", "pyhf.set_backend('jax')\n", "import jax\n", "import jaxlib\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import jax.numpy as jnp" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## IML 2022-- Tutorial on Automatic Differentiation\n", "\n", "\n", "### Introduction\n", "\n", "Welcome to this tutorial on automatic differentiation. Automatic Differentiation is a method to compute exact derivatives of functions implements as **programs**. It's a widely applicable method and famously is used in\n", "many Machine learning optimization problems. E.g. neural networks, which are parametrized by weights $\\text{NN}(\\text{weights})$ are trained by (stocastic) **gradient** descent to find the minimum of the loss function $L$ where \n", "\n", "\n", "$$\\text{weights}_\\text{opt} = \\text{argmin}_\\text{weights} L(\\text{weights}) \\hspace{1cm} \\nabla L(\\text{weights}) = 0$$\n", "\n", "\n", "This means that efficient algorithms to compute derivatives are crucial.\n", "\n", "Aside from ML, many other use-cases require gradients: standard statistical analysis in HEP (fitting, hypothesis testing, ...) requires gradients. Uncertainty propagation (e.g. track parameters) uses gradients, etc..\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Other approaches to differentiation\n", "\n", "Before diving into automatic differentiation, let's review how my might otherwise compute derivatives\n", "\n", "\n", "\n", "#### Finite Differences\n", "\n", "\n", "A common appraoch to approximate gradients of a black-box function is to evaluate it\n", "at close-by points $x$ and $x+Δx$ and \n", "\n", "$\\frac{\\partial f}{\\partial x} \\approx \\frac{f(x) - f(x+\\Delta x}{\\Delta x}$ if $\\Delta x$ is sufficiently small\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "image/png": "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sccYMmQItWrVYtKkSSxevBh/f39++OEH6tevT1xcHPfeey8HDhwA4N133+XCCy8s/Rufhzb7nId3ft3PgVNpPD+mK/4+VneXo5RH2r17N/fffz87d+4kODiYd95555xlnn/+eSIiIoiKiuK3334jKiqK7OxsbrzxRmbNmsWWLVtYuXIl/v5/d8b4/vvveemll1i6dGmBwZ+WlkafPn3Yvn07gwcPzv1AufXWW3n55ZeJioqia9euPPvsszRv3pwnnniC++67j1dffZVOnTrlC36AqVOn0qdPH+bOncuMGTOKfM1paWn079+fLVu2cPHFFzNnzhwAHn74YQYPHsyWLVtyPwzLSo/8S2lvXArv/rqPMT0acXG7uu4uR6kKV9wRekVp2rQpAwcOBODmm2/mzTff5LHHHsu3zLx585g9ezY5OTnExMSwY8cORISGDRvSt29fAIKD/26WXb16NRERESxfvjzf9LwsFgs33nhj7n6vueYakpKSSExMZPDgwQDcdtttXH/99QDcddddzJ8/n/fee4/NmzeX6TX7+PgwevRoAHr37s2KFSty6/7ss88AsFqthISElGk/oEf+peJwGJ78fiuBvl783+hO7i5HKY92dvfFs58fPHiQmTNnsmrVKqKiohg1alSxfd1bt25NSkoKe/bsAcBut9OjRw969OjB1KlTS1TH2dLT0zl27BgAqampRS4L4OXlhcPhyH2et2Zvb+/c/VmtVnJycord3vnS8C+FrzccZcOhBJ4c2ZHwWr7uLkcpj3bkyBHWrl0LwJdffnnOydLk5GQCAwMJCQkhLi6On376CYD27dsTExPDhg0bAEhJSckN0ebNm/Pdd99x6623sn37dqxWK5s3b2bz5s1Mnz4dAIfDwbfffptvvyEhIYSFhfHHH38A8Pnnn+d+C3jiiSeYMGEC06dP5+677y72dbVo0YLNmzfjcDg4evQo69evL3adoUOH8u677wLOD6ykpKRi1ymOhn8JnUjO5MWfdtK/VW2u793E3eUo5fHat2/Pf//7Xzp27EhCQgL33Xdfvvndu3enZ8+edOjQgfHjx+c2Efn4+PDNN9/w0EMP0b17dy677LJ8R9cdOnRg7ty5XH/99ezfv/+c/QYGBrJ+/Xq6dOnC6tWrc78RfPrppzz++ON069aNzZs3M3XqVH777Tc2bNiQ+wHg4+PDxx9/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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "def black_box_func(x):\n", " return x**3\n", "\n", "def true_gradient_func(x):\n", " return 3*x**2\n", "\n", "\n", "def plot_gradients(nsteps,title):\n", " xi = np.linspace(-5,5,nsteps)\n", " yi = black_box_func(xi)\n", "\n", " approx_gradient = np.gradient(yi,xi)\n", " true_gradient = true_gradient_func(xi)\n", "\n", " plt.plot(xi,yi, label = 'black-box func')\n", " plt.scatter(xi,yi)\n", "\n", " plt.plot(xi,approx_gradient, label = 'finite diff grad')\n", " plt.scatter(xi,approx_gradient)\n", "\n", " plt.plot(xi,true_gradient, label = 'true grad')\n", " plt.scatter(xi,true_gradient)\n", "\n", " plt.legend()\n", " plt.title(title)\n", " plt.show()\n", " \n", " \n", "plot_gradients(11, title = 'it is pretty bad if Δx is too large')\n", "plot_gradients(41, title = 'it gets better at the cost of many evaluations') " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

\n", "while only approximate, finite differences is *simple*. I don't need to know \n", "anything about the function beyond having the ability \n", "to *evaluate* it\n", "

\n", "

\n", "This way I can compute gradients of functions encoded as a computer\n", "program, and it works in any programming language\n", "

\n", "\n", "

\n", "For multivariate (possibly vector-valued) functions $\\vec{f}(\\vec{x}) = f_i(x_1,x_2,\\dots,x_n)$ one needs to compute a finite difference\n", "gradient for each partial derivative $\\frac{\\partial f}{\\partial x}$ in order to get the\n", "full jacobian / total derivative $df_i = J_{ik} dx_k\\; J_{ik} = \\frac{\\partial f_i}{\\partial x_k}$\n", " \n", "In high dimensions, the number of required evaluations explodes!\n", "

\n", "\n", "\n", "**Finite Differences**:\n", "\n", "* Pro: easy to to, works in any language, no \"framework needed\"\n", "* Con: inaccurate unless one does a lot of evaluations\n", "* Con does not scale to large dimensions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Symbolic Differentiation in a CAS\n", "\n", "Computer Algebra Systems (CAS), such as Mathematica (or sympy)\n", "can manipulate functional *expressions* and know about differentiation rules (and many other things)\n", "\n", "If the function / the prograrm which we want to derive is available as such an expression the \n", "symbolic differentiation can produce **exact gradients**" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle x^{3}$" ], "text/plain": [ "x**3" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import sympy\n", "\n", "def function(x):\n", " return x**3\n", "\n", "def true_deriv(x):\n", " return 3*x**2\n", "\n", "symbolic_x = sympy.symbols('x')\n", "symbolic_func = function(symbolic_x)\n", "symbolic_func" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using `lambdify` we can turn it into a normal python function we can evaluate" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX8AAAD4CAYAAAAEhuazAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAAsTAAALEwEAmpwYAAAeGklEQVR4nO3deXhU5d3/8fc3GwQIhCWBEEBAMBAERCNgFyvViqIW8HFFrUsttk/tr7Z9aEFrfWrV9ida665oXepabAERrVFRW60igghhCwmbkLCEJUAg68z9/JGBBkiAkJk5s3xe18WVmXsmcz6D1/Xh9pz7nGPOOUREJL4keB1ARETCT+UvIhKHVP4iInFI5S8iEodU/iIicSjJ6wDHokuXLq53795exxARiSoLFy7c5pzLaOy1qCj/3r17s2DBAq9jiIhEFTNb39Rr2u0jIhKHVP4iInFI5S8iEodU/iIicUjlLyISh6JitY+ISLyZtaiEqfmFlJZX0j09lUmjcxg3LDton6/yFxGJMLMWlTBlRgGVtT4ASsormTKjACBo/wBot4+ISISZml94oPj3q6z1MTW/MGjbUPmLiESY0vLKZo0fD5W/iEiE6Z6e2qzx46HyFxGJMBcMyTpsLDU5kUmjc4K2DR3wFRGJIPtq6nhzySYy01qRlGBs2lWl1T4iIrHuT+8VUVJeyfSbzmB4n04h2452+4iIRIilJbv488druXJ4z5AWP6j8RUQigs/vmDKjgI5tUph83sCQb0+7fUREIsBzn6yjoGQXj0wYRoc2ySHfnmb+IiIeKymv5P53ChmVk8EFgw9f6RMKKn8REQ855/jNrKU4B78bdzJmFpbtqvxFRDz0j6WbmbtyK7849yR6dGwTtu2q/EVEPLKrspY7Zi/j5Oz2XPe13mHdtg74ioh45N63V7K9oppnrzudpMTwzsU18xcR8cCCdTt46bOvuOHrfTg5u0PYt6/yFxEJs5o6P1NmFJCdnsrPvnOSJxm020dEJMye/OdqirZW8Ox1p9O2lTc1rJm/iEgYrSmr4OEPirlgSBajBmR6liMo5W9mz5jZVjNb2mCsk5m9a2ZFgZ8dA+NmZg+ZWbGZLTGzU4ORQUQk0jnnuHVmAa2SErjjolxPswRr5v8ccN4hY5OBuc65/sDcwHOA84H+gT8TgceDlEFEJKK9tnAj89bsYMr5A8lMa+1plqCUv3PuX8COQ4bHAs8HHj8PjGsw/hdXbx6QbmbhOZ9ZRMQj2yqqueetFZzeuyNXnN7T6zgh3eff1Tm3KfB4M9A18Dgb2NDgfRsDYwcxs4lmtsDMFpSVlYUwpohI6N01Zzl7q+v4/cWDSUgIzyUcjiQsB3ydcw5wzfydac65POdcXkZGRoiSiYiE3r9WlTHry1J+dFY/+mWmeR0HCG35b9m/Oyfwc2tgvARo+P88PQJjIiIxp7LGx22zCuib0Zb/PutEr+McEMrynw1cG3h8LfB6g/HvBVb9jAR2Ndg9JCISUx6cW8SGHZXcM34wrZMTvY5zQFDOLjCzV4CzgC5mthG4A/gDMN3Mvg+sBy4LvP0tYAxQDOwDrg9GBhGRSLO8dDdPfbSGy/N6MrJvZ6/jHCQo5e+cu7KJl85u5L0O+HEwtisiEql8fseUmQV0bJPMlDEDvI5zGJ3hKyISAi98uo7FG8q5/cJc0tukeB3nMCp/EZEgKy2vZGp+IWeelMF3h3b3Ok6jVP4iIkF2x+xl+Jzj7jDelrG5VP4iIkH09tLNvLt8Cz875yR6dgrfbRmbS+UvIhIku6tquWP2UnKz2vP9b/TxOs4R6Xr+IiJBcl9+IWV7qpl2TV7Yb8vYXJGdTkQkSixcv5MX5q3n2q/1ZmjPdK/jHJXKX0SkhWp9fm6dUUBW+9b84twcr+McE+32ERFpoWn/WkPhlj08/b082nl0W8bm0sxfRKQF1m3by4NzixgzuBvn5HY9+i9ECJW/iMhxcs5x26wCWiUmcMdFg7yO0ywqfxGR4zTjixL+XbydX50/gK7tvb0tY3Op/EVEjsOOvTXc9eZyTjuhIxOG9/I6TrOp/EVEjsNdby6nIoJuy9hcKn8RkWb6d/E2ZnxRwk1nnshJXSPjtozNpfIXEWmGqloft84soE+Xttz87X5exzlu0bEgVUQkQjz8fhHrt+/j5RtHRNRtGZtLM38RkWO0cvNunvznGi45rQdf69fF6zgtovIXETkGfr9jyowC2qcmc9uYgV7HaTHt9hEROYJZi0qYml9ISXklAFeP6EXHtpF3W8bm0sxfRKQJsxaVMGVGwYHiB/jbwo3MWlTiYargUPmLiDRhan4hlbW+g8aq6vxMzS/0KFHwqPxFRJrQcMbfUGkT49FE5S8i0gjnXJOXZ+6enhrmNMGn8hcROYTf7/j1rKVUVNeReMilG1KTE5k0Ojpu2HIkKn8RkQZ8fsekvy3hpc++4kdnnch9lwwhOz0VA7LTU/n9xYMZNyzb65gtpqWeIiIBtT4/P/vrl8xZsomff+ckfvLtfpgZ40/t4XW0oFP5i4gA1XU+bn55Ee8u38JtYwbygzP7eh0ppFT+IhL3Kmt8THxhAR8VbeN3YwdxzRm9vY4Ucip/EYlrFdV13Pj853y2dgf3XjKEy/J6eh0pLEJe/ma2DtgD+IA651yemXUC/gr0BtYBlznndoY6i4hIQ7sqa7nu2fks2biLP11+CmNPif4DuccqXKt9RjnnTnHO5QWeTwbmOuf6A3MDz0VEwmbH3homPDWPpSW7eOyqU+Oq+MG7pZ5jgecDj58HxnmUQ0Ti0NY9VVwx7VOKt1bw1PfyGD2om9eRwi4c5e+Ad8xsoZlNDIx1dc5tCjzeDHQNQw4REUrLK7n8yXls3FnJs9efzlk5mV5H8kQ4Dvh+wzlXYmaZwLtmtrLhi845Z2bu0F8K/EMxEaBXr15hiCkisW7Djn1c+dQ8du2r5YXvD+e0Ezp5HckzIZ/5O+dKAj+3AjOB4cAWM8sCCPzc2sjvTXPO5Tnn8jIyMkIdU0Ri3OqyCi594lMqqut4+Qcj47r4IcTlb2ZtzSxt/2PgXGApMBu4NvC2a4HXQ5lDROLbys27ufzJT6nz+3nlByMZ3KOD15E8F+rdPl2BmWa2f1svO+feNrPPgelm9n1gPXBZiHOISJxaWrKLq//8Ga2SEnjpxpH0y2zndaSIENLyd86tAYY2Mr4dODuU2xYRWbh+J9c9O58Oqcm8fONIenVu43WkiKEzfEUkJn26ejvff/5zMtNa8fIPRsbENfiDSeUvIjHnw8Kt3PTCQnp1asNLN44gs31rryNFHJW/iMSU/GWbufnlL+ifmcaLN46gU9sUryNFJJW/iMSMNxaXcstfv2Rwdgeev344Hdokex0pYqn8RSQmvLZgA7/6+xLyenfimetOb/L+u1JPfzsiEvVe+HQdt7++jG/278K0a/JITUn0OlLEU/mLSFR7+qM13PXmCs4ZmMkjE06ldbKK/1io/EUkKjnneOT9Yu5/dxUXDM7igctPISXJqwsVRx+Vv4hEHeccU/MLeezD1Vw8LJt7LxlCUqKKvzlU/iISVZxz/PaN5Tz3yTomjOjFXWNPJiHBvI4VdVT+IhLxZi0qYWp+ISXllbRJSWRfjY/rv96b31yYS+DaYdJMKn8RiWizFpUwZUYBlbU+APbV+EhKMIZkd1Dxt4B2kolIRLv37ZUHin+/Or/jvndWeZQoNmjmLyIRyTnHeyu2UrqrqtHXS8srw5wotqj8RSSi+P2Od5Zv4aG5RSzftJvEBMPnP+xOr7pKZwup/EUkIvj9jreXbeahuUWs3LyH3p3bcN+lQzHg17OWHrTrJzU5kUmjc7wLGwNU/iLiKZ/f8VbBJh5+v4hVWyrom9GWBy4fykVDuh9Yu5+YYEzNL6S0vJLu6alMGp3DuGHZHiePbip/EfFEnc/PnCX1pb+6bC/9M9vx0JXDuGBwFomHrNsfNyxbZR9kKn8RCas6n5/XvyzlkQ+KWbttLzld03h0wqmcf3I3nawVRip/EQmLWp+fmYtKePSDYtZv38fArPY8cfWpnJur0veCyl9EQqqmzs/fv9jIox8Us3FnJSdnt2faNafxndyuOknLQyp/EQmJ6jofry3YyOMfrqakvJKhPTpw59hBjMrJVOlHAJW/iARVVa2P6Qs28PiHq9m0q4phvdK5e/zJfOukDJV+BFH5i0hQVNX6eGX+Vzzxz9Vs2V1N3gkdufeSIXyjXxeVfgRS+YtIi1TW+Hjps/U88c81bKuoZkSfTjxw+Smc0bezSj+CqfxF5Jjtv7RyaXkl3Tq05vTenfhk9Ta2VdTwtRM788iEYYzs29nrmHIMVP4ickwOvbTypl1VzF5cSk63NB6/+jRO793J44TSHCp/EWnSrspaVm7azYpNu7k3v/CwSysDVFTVqfijkMpfRPD5Heu272Xlpj2sCJT9ys17KDmGyybr0srRSeUvEmcazuZXbq4v+8Ite6iq9QP1F1E7MaMtp53QkatHnsCArDRys9oz/tF/N3ptfV1aOTqp/EWiTMODrke6wqXP71i/fS8rArP5lZt3s2LTwbP5jm2SGZjVnqtGnMCAbmkMzGpPv8x2tE5OPOzzfnnegIP2+YMurRzNPCt/MzsPeBBIBJ52zv3Bqywix+NYSzjY22xYwCXllUyZUcC+mjpOzGh3YCa/YvMeVm3ec+B9Tc3mM9NaHfNyzP3fTZdWjg3m3OF3yAn5Rs0SgVXAd4CNwOfAlc655Y29Py8vzy1YsCCMCSVaeFHA+7fb2Cz49xcPPur2nXPU+PzU+hw1dX5q6vzU+vxUN3hc46t/fOBnYPzON5ZTXll7xM/fP5sf0K09A7OOPJuX2GZmC51zeY295tXMfzhQ7JxbA2BmrwJjgUbLX6QxTc2CoX6WWtegYKt9vkbLtvaQcq1parzOT83+3/f5mPFFyWErXyprffzyb0t45t9rDyrugz+rvvhD4dnrT2/2bF7il1flnw1saPB8IzCi4RvMbCIwEaBXr17hSyYRr6bOT/HWCn77xrJGC/hnf/2Sn0//kkZu+9oiKUkJtEpMICUpgX01hy95BKjx+encNoWUpASSA+9NafAz+ZDnKUkJh7zXAj8TSd7/uMF7L39yHpt3H37QNTs9lVE5mcH9whLTIvaAr3NuGjAN6nf7eBxHPFK2p/qgpYcrNu2meGsFdUdodgfcPKrfQeWb3KC4kw8qXaPV/rJNsiaLOSnBDppNf/0P7ze6DDI7PZVnrx8eir8KACafr4OuEhxelX8J0LPB8x6BMYlT+2fz9StS/lP02ypqDrwnq0NrBnRL49sDMhmQ1Z675ixn657qwz4rOz2VX5wb2jKcNDrHkxLWQVcJFq/K/3Ogv5n1ob70rwAmeJRFgqA5B16PNptPSUogp2sao3Iy6w9cZqUxsFt7OrZNOehz/H7n2SzYyxLW/WwlGDwpf+dcnZndDORTv9TzGefcMi+ySMs1deC1zucnt3uHI87mu7VvzcCs/8zmc7PS6N25LUmJCUfdrtezYJWwRDNPlno2l5Z6Rram9n83tH82v/9EoqZm8yISPJG41FNiyJGK/6ErhzGwWxp9uhzbbF5EwkPlL8dt4fqdPDi3qMnXs9NT+e7Q7mFMJCLHSuUvzTZ/7Q4emlvEx8Xb6NQ2hQuHZPHe8i1U1f3n5CUtPxSJbCp/OWafrt7OQ3OL+HTNdrq0S+G2MQO5amQv2qQkeXaZBRE5Pip/OSLnHJ+s3s6Dc4uYv3YHGWmtuP3CXCYM70Vqyn+uFaOVLyLRReUvjXLO8VHRNh6cW8TC9Tvp2r4V/3tRLlcM76ULhInEAJW/HMQ5x4eFZTw4t4gvN5ST1aE1vxs7iEvzeqr0RWKIyl+A+tKfu2IrD71fxJKNu8hOT+We8YP5r9OyaZWk0heJNSr/OOf3O95dsYWH5haxrHQ3PTul8v//azDjh/UgJUnr8kVilco/Tvn9jreXbeahuUWs3LyH3p3bMPWSIYwblk2yTsYSiXkq/zjj8zveKtjEw+8XsWpLBX0z2vLA5UO5aEh3nYErEkdU/nHC53fMWVLKw+8XU7y1gn6Z7XjwilO4cEh3EhN01yeReKPyjzGHnmz18++chBk88n4xa7btJadrGo9MGMaYk7NIUOmLxC2Vfwxp7NLK//PaYhwwoFsaj191KqMHdVPpi4jKP5ZMzS887J62DujUNoW3/t83VfoicoCO8MWQpi6tvHNvjYpfRA6i8o8RtT4/qU2cgds9PTXMaUQk0qn8Y0B1nY+bX/6CylofSYfM8HVpZRFpjPb5R7mqWh8/fHEhHxaWccdFuXRsk6JLK4vIUan8o9je6jpufH4B89Zu557xg5kwoheAyl5EjkrlH6V2V9Vyw7Of88VXO/njZUMZP6yH15FEJIqo/KNQ+b4avvfMfJaX7uaRCacyZnCW15FEJMqo/KPMtopqrn76M9aU7eXJa07j7IFdvY4kIlFI5R9FNu+q4qqn51FSXsmfr8vjm/0zvI4kIlFK5R8lNuzYx1VPf8b2imr+csMIhvfp5HUkEYliKv8osHbbXq56ah4V1XW8eOMIhvXq6HUkEYlyKv8IV7RlDxOe/gyf3/HKxJEM6t7B60giEgNU/hFsWekurvnzfBITjL9OHEn/rmleRxKRGKHLO0SoRV/t5Mpp82idlMD0m85Q8YtIUGnmH4E+W7OdG577nM7tWvHyD0bQo2MbryOJSIwJ2czfzP7XzErM7MvAnzENXptiZsVmVmhmo0OVIRp9XLSNa5+dT7cOrZl+0xkqfhEJiVDP/B9wzt3XcMDMcoErgEFAd+A9MzvJOedr7APiydwVW/jRS1/Qt0tbXrxxBF3atfI6kojEKC/2+Y8FXnXOVTvn1gLFwHAPckSUN5ds4qYXFjKgWxqvThyp4heRkAp1+d9sZkvM7Bkz2784PRvY0OA9GwNjcWvmoo385JUvOKVnOi/eOIL0NileRxKRGNei8jez98xsaSN/xgKPAycCpwCbgPub+dkTzWyBmS0oKytrScyI9sr8r/j59MWM7NuZ528YTvvWyV5HEpE40KJ9/s65c47lfWb2FDAn8LQE6Nng5R6BsUM/exowDSAvL8+1JGekeubjtdw5ZzmjcjJ4/OrTaN3EbRhFRIItlKt9Gl5neDywNPB4NnCFmbUysz5Af2B+qHJEqsc+LObOOcs5b1A3nrwmT8UvImEVytU+95rZKYAD1gE3ATjnlpnZdGA5UAf8OJ5W+jjneODdVTz0fjFjT+nO/ZcOJSlR59qJSHiFrPydc9cc4bW7gbtDte1I5ZzjnrdW8NRHa7k8ryf3XDyYxENuuC4iEg46wzdM/H7HHbOX8cK89Vx7xgnccdEgElT8IuIRlX8Y+PyOyX9fwmsLN3LTmX2ZfP4AzFT8IuIdlX+I1fr8/Hz6Yt5YXMot5/Tnp2f3V/GLiOdU/iEwa1EJU/MLKSmvpHVyAlW1fiafP4AffutEr6OJiAAq/6CbtaiEKTMKqKytX8BUVesnOcHo1r61x8lERP5DawyDbGp+4YHi36/W75iaX+hRIhGRw6n8g6y0vLJZ4yIiXlD5B1m3Do3v3umenhrmJCIiTVP5B1n/zHaHjaUmJzJpdI4HaUREGqfyD6LFG8r5qHgb3+jXhez0VAzITk/l9xcPZtywuL5qtYhEGK32CZJan5/JMwrIaNeKx64+VZdmFpGIpvIPkmc+XsuKTbt5QsUvIlFAu32CYMOOfTzw3irOGdiV0YO6eR1HROSoVP4t5JzjtllLSTTjzrGDdOkGEYkKKv8Wmr24lH+tKmPS6Bwt5xSRqKHyb4HyfTXc+cZyhvZM55ozensdR0TkmOmAbwvc89YKyitreWG8bsoiItFFM//j9Onq7UxfsJEbv9mH3O7tvY4jItIsKv/jUFXr47aZBfTslMotZ5/kdRwRkWbTbp/j8NiHq1mzbS9/uWE4qSmJXscREWk2zfybqWjLHh7/sJhxp3TnzJMyvI4jInJcVP7N4Pc7bp1ZQNtWSfz6wlyv44iIHDeVfzO8+vkGPl+3k1vHDKRLu1ZexxEROW4q/2O0dXcVv//HCkb27cSlp/XwOo6ISIuo/I/Rb+csp7rOzz3jB+sSDiIS9VT+x+D9lVt4c8kmfjKqH30zDr9Zi4hItFH5H8Xe6jpun7WM/pntuOlbJ3odR0QkKLTO/yj++O4qSsor+dsPzyAlSf9WikhsUJsdQcHGXTz777VMGNGLvN6dvI4jIhI0Kv8m1Pn8TJ6xhM7tWvGr8wZ4HUdEJKi026cJz32yjmWlu3l0wql0SNVtGUUktrRo5m9ml5rZMjPzm1neIa9NMbNiMys0s9ENxs8LjBWb2eSWbD9UNuzYx/3vrOLsAZmMGazbMopI7Gnpbp+lwMXAvxoOmlkucAUwCDgPeMzMEs0sEXgUOB/IBa4MvDdiOOe4/fWlmMGd407Wmn4RiUkt2u3jnFsBNFaQY4FXnXPVwFozKwaGB14rds6tCfzeq4H3Lm9JjmCas2QTHxaWcfuFuWTrtowiEqNCdcA3G9jQ4PnGwFhT44cxs4lmtsDMFpSVlYUo5sF27avlt28sZ0iPDlz3td5h2aaIiBeOOvM3s/eAxnZ83+acez34keo556YB0wDy8vJcqLbT0B/eXsHOfTU8d/3pui2jiMS0o5a/c+6c4/jcEqBng+c9AmMcYdxT89fu4JX5G5h4Zl9Ozu7gdRwRkZAK1W6f2cAVZtbKzPoA/YH5wOdAfzPrY2Yp1B8Unh2iDMesus7HlBlLyE5P5ZZz+nsdR0Qk5Fp0wNfMxgMPAxnAm2b2pXNutHNumZlNp/5Abh3wY+ecL/A7NwP5QCLwjHNuWYu+QRA8/uFqVpft5dnrT6dNik59EJHY19LVPjOBmU28djdwdyPjbwFvtWS7wVS8tYLHPljNRUO7Myon0+s4IiJhEdeXd9h/W8bWyQn8RrdlFJE4Etfl/9rCDcxfu4PbLhhIRppuyygi8SNuy79sTzV3v7mC4X06cVlez6P/gohIDInb8v/dnOVU1eq2jCISn+Ky/D8o3MrsxaX896gT6Zep2zKKSPyJu/LfV1PHr2cu5cSMtvzoLN2WUUTiU9wtav/Te0WUlFcy/aYzaJWU6HUcERFPxNXMf2nJLv788VquHN6T4X10W0YRiV9xU/4+v2PKjAI6tklh8nkDvY4jIuKpuCn/5z5ZR0HJLu64KJcObXRbRhGJb3FR/iXlldz/TiFn5WRw4ZAsr+OIiHgupg/4zlpUwr1vr6R0VxUGfLN/F63pFxEhhmf+sxaVMGVGAaW7qgBwwH35q5i1KCJuHyAi4qmYLf+p+YVU1voOGqus9TE1v9CjRCIikSNmy7+0vLJZ4yIi8SRmy797emqzxkVE4knMlv+k0TmkJh98Bm9qciKTRud4lEhEJHLE7GqfccOygfp9/6XllXRPT2XS6JwD4yIi8Sxmyx/q/wFQ2YuIHC5md/uIiEjTVP4iInFI5S8iEodU/iIicUjlLyISh8w553WGozKzMmC91zmOQxdgm9chwkzfOT7oO0eHE5xzGY29EBXlH63MbIFzLs/rHOGk7xwf9J2jn3b7iIjEIZW/iEgcUvmH1jSvA3hA3zk+6DtHOe3zFxGJQ5r5i4jEIZW/iEgcUvmHiZn9wsycmXXxOkuomdlUM1tpZkvMbKaZpXudKRTM7DwzKzSzYjOb7HWeUDOznmb2gZktN7NlZvZTrzOFi5klmtkiM5vjdZZgUfmHgZn1BM4FvvI6S5i8C5zsnBsCrAKmeJwn6MwsEXgUOB/IBa40s1xvU4VcHfAL51wuMBL4cRx85/1+CqzwOkQwqfzD4wHgl0BcHF13zr3jnKsLPJ0H9PAyT4gMB4qdc2ucczXAq8BYjzOFlHNuk3Pui8DjPdSXYczfMMPMegAXAE97nSWYVP4hZmZjgRLn3GKvs3jkBuAfXocIgWxgQ4PnG4mDItzPzHoDw4DPPI4SDn+ifvLm9zhHUMX0nbzCxczeA7o18tJtwK3U7/KJKUf6zs651wPvuY36XQUvhTObhJaZtQP+DtzinNvtdZ5QMrMLga3OuYVmdpbHcYJK5R8EzrlzGhs3s8FAH2CxmUH97o8vzGy4c25zGCMGXVPfeT8zuw64EDjbxebJJCVAzwbPewTGYpqZJVNf/C8552Z4nScMvg5818zGAK2B9mb2onPuao9ztZhO8gojM1sH5Dnnou3KgM1iZucBfwS+5Zwr8zpPKJhZEvUHs8+mvvQ/ByY455Z5GiyErH4G8zywwzl3i8dxwi4w8/8f59yFHkcJCu3zl1B4BEgD3jWzL83sCa8DBVvggPbNQD71Bz6nx3LxB3wduAb4duC/65eBGbFEIc38RUTikGb+IiJxSOUvIhKHVP4iInFI5S8iEodU/iIicUjlLyISh1T+IiJx6P8A7KxutLC7f+IAAAAASUVORK5CYII=\n", "text/plain": [ "

" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "xi = np.linspace(-5,5,11)\n", "yi = sympy.lambdify(symbolic_x,symbolic_func)(xi)\n", "plt.plot(xi,yi)\n", "plt.scatter(xi,yi)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`symbolic_func` is now an experssion which we can differentiate *symbolically*" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle 3 x^{2}$" ], "text/plain": [ "3*x**2" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "symbolic_deriv = symbolic_func.diff(symbolic_x)\n", "symbolic_deriv" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "def plot_symbolic(nsteps,title):\n", " xi = np.linspace(-5,5,nsteps)\n", " yi = sympy.lambdify(symbolic_x,symbolic_func)(xi)\n", " plt.scatter(xi,yi)\n", " plt.plot(xi,yi, label = 'function')\n", "\n", "\n", "\n", " yi = true_deriv(xi)\n", " plt.plot(xi,yi)\n", " plt.scatter(xi,yi, label = 'true deriv')\n", "\n", " yi = sympy.lambdify(symbolic_x,symbolic_deriv)(xi)\n", " plt.plot(xi,yi)\n", " plt.scatter(xi,yi, label = 'symbolic deriv')\n", "\n", " plt.legend()\n", " plt.title(title)\n", " plt.show()\n", " \n", " \n", "plot_symbolic(11,title = 'the symbolid derivative is always exact')\n", "plot_symbolic(4, title = 'it does not matter where/how often you evaluate it') " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Chain Rule in CAS\n", "\n", "We can even handle function compositions" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\cos{\\left(x^{2} \\right)}$" ], "text/plain": [ "cos(x**2)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def f1(x):\n", " #standard operations are overloaded\n", " return x**2\n", "\n", "def f2(x):\n", " #note here we use a special cos function from sympy\n", " #instead of e.g. np.cos or math.cos\n", " return sympy.cos(x) \n", " \n", "\n", "composition = f2(f1(symbolic_x))\n", "\n", "composition" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle - 2 x \\sin{\\left(x^{2} \\right)}$" ], "text/plain": [ "-2*x*sin(x**2)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "composition.diff(symbolic_x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since `sympy` knows about the chain rule it can differentiate accordingly" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Problems with Symbolic Differentiation\n", "\n", "This looks great! We get exact derivatives. However,\n", "there are drawbacks\n", "\n", "1. Need to implement it in CAS\n", "\n", "Most functions we are interested in are not implemented \n", "e.g. Mathematica. Rather we have loads of C, C++, Python\n", "code that we are interested in. \n", "\n", "But ok, `sympy` alleviates this to some degree. The functions\n", "`f1` and `f2` are fairly generic since they use operator\n", "overloading. So a symbolic program and a \"normal\" program\n", "could only differ by a few import statements\n", "\n", "\n", "\n", "```python\n", "from sympy import cos\n", "\n", "def f1(x):\n", " return x**2\n", "\n", "def f2(x):\n", " return cos(x) \n", "```\n", "\n", "versus:\n", "\n", "```python\n", "from math import cos\n", "\n", "def f1(x):\n", " return x**2\n", "\n", "def f2(x):\n", " return cos(x) \n", "```\n", "\n", "\n", "Note the code is almost exactly the same\n", "\n", "But not all our functions are so simple!\n", "\n", "\n", "**Expression swell**\n", "\n", "Let's look at a quadratic map which is applied a few times" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle 243 x^{2} + 729 x + 81 \\left(x^{2} + 3 x + 4\\right)^{2} + 27 \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + 9 \\left(9 x^{2} + 27 x + 3 \\left(x^{2} + 3 x + 4\\right)^{2} + \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + 52\\right)^{2} + 3 \\left(27 x^{2} + 81 x + 9 \\left(x^{2} + 3 x + 4\\right)^{2} + 3 \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + \\left(9 x^{2} + 27 x + 3 \\left(x^{2} + 3 x + 4\\right)^{2} + \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + 52\\right)^{2} + 160\\right)^{2} + \\left(81 x^{2} + 243 x + 27 \\left(x^{2} + 3 x + 4\\right)^{2} + 9 \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + 3 \\left(9 x^{2} + 27 x + 3 \\left(x^{2} + 3 x + 4\\right)^{2} + \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + 52\\right)^{2} + \\left(27 x^{2} + 81 x + 9 \\left(x^{2} + 3 x + 4\\right)^{2} + 3 \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + \\left(9 x^{2} + 27 x + 3 \\left(x^{2} + 3 x + 4\\right)^{2} + \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + 52\\right)^{2} + 160\\right)^{2} + 484\\right)^{2} + 1456$" ], "text/plain": [ "243*x**2 + 729*x + 81*(x**2 + 3*x + 4)**2 + 27*(3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + 9*(9*x**2 + 27*x + 3*(x**2 + 3*x + 4)**2 + (3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + 52)**2 + 3*(27*x**2 + 81*x + 9*(x**2 + 3*x + 4)**2 + 3*(3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + (9*x**2 + 27*x + 3*(x**2 + 3*x + 4)**2 + (3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + 52)**2 + 160)**2 + (81*x**2 + 243*x + 27*(x**2 + 3*x + 4)**2 + 9*(3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + 3*(9*x**2 + 27*x + 3*(x**2 + 3*x + 4)**2 + (3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + 52)**2 + (27*x**2 + 81*x + 9*(x**2 + 3*x + 4)**2 + 3*(3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + (9*x**2 + 27*x + 3*(x**2 + 3*x + 4)**2 + (3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + 52)**2 + 160)**2 + 484)**2 + 1456" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def quadmap(x):\n", " return x**2 + 3*x + 4\n", "\n", "def func(x):\n", " for i in range(6):\n", " x = quadmap(x)\n", " return x\n", "\n", "quad_6_times = func(symbolic_x)\n", "quad_6_times" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This looks pretty intimidating. What happened? \n", "Symbolic programs run through the prgram and \n", "accumulate the full program into a single expression\n", "\n", "If we would just blindly differentiate this it would look like this" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle 486 x + 81 \\cdot \\left(4 x + 6\\right) \\left(x^{2} + 3 x + 4\\right) + 27 \\cdot \\left(12 x + 2 \\cdot \\left(4 x + 6\\right) \\left(x^{2} + 3 x + 4\\right) + 18\\right) \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right) + 9 \\cdot \\left(36 x + 6 \\cdot \\left(4 x + 6\\right) \\left(x^{2} + 3 x + 4\\right) + 2 \\cdot \\left(12 x + 2 \\cdot \\left(4 x + 6\\right) \\left(x^{2} + 3 x + 4\\right) + 18\\right) \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right) + 54\\right) \\left(9 x^{2} + 27 x + 3 \\left(x^{2} + 3 x + 4\\right)^{2} + \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + 52\\right) + 3 \\cdot \\left(108 x + 18 \\cdot \\left(4 x + 6\\right) \\left(x^{2} + 3 x + 4\\right) + 6 \\cdot \\left(12 x + 2 \\cdot \\left(4 x + 6\\right) \\left(x^{2} + 3 x + 4\\right) + 18\\right) \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right) + 2 \\cdot \\left(36 x + 6 \\cdot \\left(4 x + 6\\right) \\left(x^{2} + 3 x + 4\\right) + 2 \\cdot \\left(12 x + 2 \\cdot \\left(4 x + 6\\right) \\left(x^{2} + 3 x + 4\\right) + 18\\right) \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right) + 54\\right) \\left(9 x^{2} + 27 x + 3 \\left(x^{2} + 3 x + 4\\right)^{2} + \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + 52\\right) + 162\\right) \\left(27 x^{2} + 81 x + 9 \\left(x^{2} + 3 x + 4\\right)^{2} + 3 \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + \\left(9 x^{2} + 27 x + 3 \\left(x^{2} + 3 x + 4\\right)^{2} + \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + 52\\right)^{2} + 160\\right) + \\left(324 x + 54 \\cdot \\left(4 x + 6\\right) \\left(x^{2} + 3 x + 4\\right) + 18 \\cdot \\left(12 x + 2 \\cdot \\left(4 x + 6\\right) \\left(x^{2} + 3 x + 4\\right) + 18\\right) \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right) + 6 \\cdot \\left(36 x + 6 \\cdot \\left(4 x + 6\\right) \\left(x^{2} + 3 x + 4\\right) + 2 \\cdot \\left(12 x + 2 \\cdot \\left(4 x + 6\\right) \\left(x^{2} + 3 x + 4\\right) + 18\\right) \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right) + 54\\right) \\left(9 x^{2} + 27 x + 3 \\left(x^{2} + 3 x + 4\\right)^{2} + \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + 52\\right) + 2 \\cdot \\left(108 x + 18 \\cdot \\left(4 x + 6\\right) \\left(x^{2} + 3 x + 4\\right) + 6 \\cdot \\left(12 x + 2 \\cdot \\left(4 x + 6\\right) \\left(x^{2} + 3 x + 4\\right) + 18\\right) \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right) + 2 \\cdot \\left(36 x + 6 \\cdot \\left(4 x + 6\\right) \\left(x^{2} + 3 x + 4\\right) + 2 \\cdot \\left(12 x + 2 \\cdot \\left(4 x + 6\\right) \\left(x^{2} + 3 x + 4\\right) + 18\\right) \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right) + 54\\right) \\left(9 x^{2} + 27 x + 3 \\left(x^{2} + 3 x + 4\\right)^{2} + \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + 52\\right) + 162\\right) \\left(27 x^{2} + 81 x + 9 \\left(x^{2} + 3 x + 4\\right)^{2} + 3 \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + \\left(9 x^{2} + 27 x + 3 \\left(x^{2} + 3 x + 4\\right)^{2} + \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + 52\\right)^{2} + 160\\right) + 486\\right) \\left(81 x^{2} + 243 x + 27 \\left(x^{2} + 3 x + 4\\right)^{2} + 9 \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + 3 \\left(9 x^{2} + 27 x + 3 \\left(x^{2} + 3 x + 4\\right)^{2} + \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + 52\\right)^{2} + \\left(27 x^{2} + 81 x + 9 \\left(x^{2} + 3 x + 4\\right)^{2} + 3 \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + \\left(9 x^{2} + 27 x + 3 \\left(x^{2} + 3 x + 4\\right)^{2} + \\left(3 x^{2} + 9 x + \\left(x^{2} + 3 x + 4\\right)^{2} + 16\\right)^{2} + 52\\right)^{2} + 160\\right)^{2} + 484\\right) + 729$" ], "text/plain": [ "486*x + 81*(4*x + 6)*(x**2 + 3*x + 4) + 27*(12*x + 2*(4*x + 6)*(x**2 + 3*x + 4) + 18)*(3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16) + 9*(36*x + 6*(4*x + 6)*(x**2 + 3*x + 4) + 2*(12*x + 2*(4*x + 6)*(x**2 + 3*x + 4) + 18)*(3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16) + 54)*(9*x**2 + 27*x + 3*(x**2 + 3*x + 4)**2 + (3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + 52) + 3*(108*x + 18*(4*x + 6)*(x**2 + 3*x + 4) + 6*(12*x + 2*(4*x + 6)*(x**2 + 3*x + 4) + 18)*(3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16) + 2*(36*x + 6*(4*x + 6)*(x**2 + 3*x + 4) + 2*(12*x + 2*(4*x + 6)*(x**2 + 3*x + 4) + 18)*(3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16) + 54)*(9*x**2 + 27*x + 3*(x**2 + 3*x + 4)**2 + (3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + 52) + 162)*(27*x**2 + 81*x + 9*(x**2 + 3*x + 4)**2 + 3*(3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + (9*x**2 + 27*x + 3*(x**2 + 3*x + 4)**2 + (3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + 52)**2 + 160) + (324*x + 54*(4*x + 6)*(x**2 + 3*x + 4) + 18*(12*x + 2*(4*x + 6)*(x**2 + 3*x + 4) + 18)*(3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16) + 6*(36*x + 6*(4*x + 6)*(x**2 + 3*x + 4) + 2*(12*x + 2*(4*x + 6)*(x**2 + 3*x + 4) + 18)*(3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16) + 54)*(9*x**2 + 27*x + 3*(x**2 + 3*x + 4)**2 + (3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + 52) + 2*(108*x + 18*(4*x + 6)*(x**2 + 3*x + 4) + 6*(12*x + 2*(4*x + 6)*(x**2 + 3*x + 4) + 18)*(3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16) + 2*(36*x + 6*(4*x + 6)*(x**2 + 3*x + 4) + 2*(12*x + 2*(4*x + 6)*(x**2 + 3*x + 4) + 18)*(3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16) + 54)*(9*x**2 + 27*x + 3*(x**2 + 3*x + 4)**2 + (3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + 52) + 162)*(27*x**2 + 81*x + 9*(x**2 + 3*x + 4)**2 + 3*(3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + (9*x**2 + 27*x + 3*(x**2 + 3*x + 4)**2 + (3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + 52)**2 + 160) + 486)*(81*x**2 + 243*x + 27*(x**2 + 3*x + 4)**2 + 9*(3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + 3*(9*x**2 + 27*x + 3*(x**2 + 3*x + 4)**2 + (3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + 52)**2 + (27*x**2 + 81*x + 9*(x**2 + 3*x + 4)**2 + 3*(3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + (9*x**2 + 27*x + 3*(x**2 + 3*x + 4)**2 + (3*x**2 + 9*x + (x**2 + 3*x + 4)**2 + 16)**2 + 52)**2 + 160)**2 + 484) + 729" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "quad_6_times.diff(symbolic_x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This looks even worse!\n", "\n", "Also note that that if we just blindly substitute x for some value\n", "e.g. x=2, we would be computing a lot of the same terms\n", "manyt times. E.g. in the above expression $x^2+3x+4$ appears in a \n", "lot of places due to the \"structure' of the original progrm\n", "\n", "If you knew the structure of the program you likely could precompute\n", "some of these repeating terms. However once it got all expanded all\n", "this knowledge about the structure is gone!\n", "\n", "Modern CAS can recover some of this by finding \"common subexpressions\" (CSE)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "([(x0, x**2),\n", " (x1, (3*x + x0 + 4)**2),\n", " (x2, (9*x + 3*x0 + x1 + 16)**2),\n", " (x3, (27*x + 9*x0 + 3*x1 + x2 + 52)**2),\n", " (x4, (81*x + 27*x0 + 9*x1 + 3*x2 + x3 + 160)**2)],\n", " [729*x + 243*x0 + 81*x1 + 27*x2 + 9*x3 + 3*x4 + (243*x + 81*x0 + 27*x1 + 9*x2 + 3*x3 + x4 + 484)**2 + 1456])" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sympy.cse(quad_6_times)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But it's not as automatic and may note find all relevant subexpressions. In any case it's trying hard to recover some\n", "of the structure that is already implicitly present in the prograam we want to differentiate" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Control Flow**\n", "\n", "In addition to looping constucts like above, a lot of the functions we are interested in have \n", "control flow structures like if/else statements, while loops, etc..\n", "\n", "\n", "If we try to create a symbolic expression with conditionals we fail badly\n" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "cannot determine truth value of Relational", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "Input \u001b[0;32mIn [12]\u001b[0m, in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m x\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m3\u001b[39m\n\u001b[0;32m----> 7\u001b[0m symbolic_result \u001b[38;5;241m=\u001b[39m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43msymbolic_x\u001b[49m\u001b[43m)\u001b[49m\n", "Input \u001b[0;32mIn [12]\u001b[0m, in \u001b[0;36mfunc\u001b[0;34m(x)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mfunc\u001b[39m(x):\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m x \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m2\u001b[39m:\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m x\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m2\u001b[39m\n\u001b[1;32m 4\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n", "File \u001b[0;32m~/Code/iml_tutorial/_venv/lib/python3.9/site-packages/sympy/core/relational.py:511\u001b[0m, in \u001b[0;36mRelational.__bool__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 510\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__bool__\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m--> 511\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcannot determine truth value of Relational\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", "\u001b[0;31mTypeError\u001b[0m: cannot determine truth value of Relational" ] } ], "source": [ "def func(x):\n", " if x > 2:\n", " return x**2\n", " else:\n", " return x**3\n", " \n", "symbolic_result = func(symbolic_x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "That's too bad because this is a perfectly respectable functino *almost everywhere*" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "xi = np.linspace(-2,5,1001)\n", "yi = np.asarray([func(xx) for xx in xi])\n", "\n", "plt.plot(xi,yi)\n", "plt.scatter(xi,yi)\n", "plt.title(\"pretty smooth except at x=2\")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we could afford finite diffences it would compute gradients *just fine*." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "g = np.gradient(yi,xi)\n", "plt.plot(xi,g)\n", "plt.scatter(xi,g)\n", "plt.ylim(-2,10)\n", "plt.title('''\\\n", "parabolesque gradient in x^3 region,\n", "linear in x^2 region as expected''');" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In short: symbolic differentiation is not our saving grace.\n", "\n", "* Pro: Gradients are exact, if you can compute them\n", "* Con: Need to implement in CAS. Full-featured Cas not easily available in all languages\n", "* Con: lead to expression swell by losing any structure of the program (needs to be recovered separately0\n", "* Con: Cannot handle common control-flow structures like loops and conditionals easily" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## What we need\n", "\n", "To recap: \n", "\n", "Finite differences is\n", "* easy to implement in any language\n", "* handles arbitrary (halting) programs but\n", "* is inaccurate unless we're ready to pay a large computational overhead\n", "\n", "Symbolic differentiation is:\n", "* exact to machine precision\n", "* can lead to exccessive / inefficient computation if not careful\n", "* cannot handle complex programs with control flow structures\n", "\n", "\n", "

So what we need is a third approach!

\n", "\n", "One, that is \n", "* exact\n", "* efficient\n", "* can handle arbitrayr programs\n", "* that is easy to implement in many languages\n", "\n", "\n", "This third approach is 'Automatic' differentiation." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Short Interlude on Linear Transformations\n", "\n", "Before we start, let's first look at *linear transformations** from ℝᵐ → ℝⁿ:\n", "$$y(x) = Ax$$\n", "\n", "With a given basis, this is representable as a (rectangular0 matrix: \n", "$$y_i(x) = A_{ij}x_j$$\n", "\n", "\n", "For a given linear problem, there are few ways we can run this computation\n", "\n", "\n", "1. **full matrix computation**\n", "\n", " i.e. we store the full (dense) $nm$ elements of the rectangular matrix and \n", " compute an explicit matrix multiplication.\n", " \n", " The computation can be fully generic for any matrix\n", " \n", "```python\n", " def result(matrix, vector):\n", " return np.matmul(matrix,vector)\n", "```\n", "
\n", "\n", "2. **sparse matrix computation**\n", "\n", " If many $A_ij=0$, it might be wasteful to expend memory on them. We can just \n", " create a sparse matrix, by\n", " \n", " * storing only the non-zerro elements \n", " * storing a look-up table, where those elements are in the matrix\n", " \n", " The computation can be kept general\n", "\n", "```python\n", " def result(sparse_matrix, vector):\n", " return sparse_matmul(sparse_matrix,vector)\n", "```\n", "\n", "
\n", " \n", "3. **matrix-free computation**\n", "\n", " In many cases a linear program is not explicitly given by a Matrix, but it's\n", " given as *code* / a \"black-box\" function. As long as the computation in the body of \n", " keeps to (hard-coded) linear transformation the program is linear. The matrix elements\n", " are no longer explicitly enumerated and stored in a data structure\n", " but implicitly defined in the source code.\n", " \n", " This is not anymore a generic computation, but each linear transformation is its own\n", " program. At the same time this is also the most memory efficient representation. No\n", " lookup table is needed since all constants are hard-coded.\n", " \n", " \n", "```python\n", " def linear_program(vector):\n", " z1,z2 = 0,0\n", " z1 += A_11*x1\n", " z2 += A_12*x2\n", " z2 += A_22*x2\n", " return [z1,z2]\n", "```\n", "\n", "\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Recovering Matrix Elements from matrix-free computations\n", "\n", "\n", "#### Matrix-vector products\n", "\n", "In the matrix-free setting, the program does not give access to the matrix elements,\n", "but only computes \"matrix-vector\" products (MVP)\n", "\n", "We can use basis vectors to recover the matrix **one column at a time**\n", "\n", "\"A\n", "\n" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "M derived from matrix-vector products:\n", "[[2 0 0]\n", " [0 1 3]]\n" ] } ], "source": [ "def matrix_vector_product(x):\n", " x1,x2,x3 = x\n", " z1,z2 = 0,0\n", " z1 += 2*x1 #MVP statement 1\n", " z2 += 1*x2 #MVP statement 2\n", " z2 += 3*x3 #MVP statement 3\n", " return np.asarray([z1,z2])\n", "\n", "M = np.concatenate([\n", " matrix_vector_product(np.asarray([1,0,0])).reshape(-1,1),\n", " matrix_vector_product(np.asarray([0,1,0])).reshape(-1,1),\n", " matrix_vector_product(np.asarray([0,0,1])).reshape(-1,1),\n", "],axis=1)\n", "print(f'M derived from matrix-vector products:\\n{M}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Vector Matrix product (VMP)\n", "\n", "The same matrix induces a \"dual\" linear map: ℝⁿ → ℝᵐ \n", "$$ x_k = y_i A_{ik}$$\n", "\n", "i.e. instead of a Matrix-vector product it's now a *vector-Matrix* product (VMP)\n", "\n", "If one has access to a \"vector-Matrix\" program corresponding to a matrix $A$ one\n", "can again -- as in the MVP-case -- recover the matrix elements, by feeding in basis vectors.\n", "\n", "This time the matrix is built **one row at a time**\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\"A" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "M derived from vector-matix products:\n", "[[2 0 0]\n", " [0 1 3]]\n" ] } ], "source": [ "def vector_matrix_product(z):\n", " x1,x2,x3 = 0,0,0\n", " z1,z2 = z\n", "\n", " x3 += z2*3 #VMP version of statement 3\n", " x2 += z2*1 #VMP version of statement 2\n", " x1 += z1*2 #VMP version of statement 1\n", "\n", " return np.asarray([x1,x2,x3])\n", "\n", "\n", "M = np.concatenate([\n", " vector_matrix_product(np.asarray([1,0])).reshape(1,-1),\n", " vector_matrix_product(np.asarray([0,1])).reshape(1,-1),\n", "],axis=0)\n", "print(f'M derived from vector-matix products:\\n{M}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Short Recap:\n", "\n", "For a given linear transformation, characterized by a matrix $A_{ij}$ we have a forward (matrix-vector) and backward (vector-matrix) map $$y_i = A_{ij}x_k$$ $$x_j = y_i A_{ij}$$\n", "\n", "and we can use either to recover the full matrix $A_{ij}$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Wide versus Tall Transformation\n", "\n", "If you look at the code above, you'll notice that the number of calls necessary to the MVP or VMP program\n", "is related to the dimensions of matrix itself.\n", "\n", "For a $n\\times m$ matrix (for a map: ℝᵐ → ℝⁿ), you need as $m$ calls to the \"Matrix-vector\" program to \n", "built the full matrix one-column-at-a-time. Likewise you need $n$ calls to the \"vector-Matrix\" program\n", "to build the matrix one-row-at-a-time.\n", "\n", "This becomes relevant for very asymmetric maps: e.g. scalar maps from very high-dimensional spaces\n", "$\\mathbb{R}^{10000} \\to \\mathbb{R}$ the \"vector-Matrix\" appraoch is *vastly* more efficient than the\n", "\"Matrix-vector one. There's only one row, so only one call too the VMP program is needed to construct the full matrix!\n", "\n", "Similarly, functions mapping few variables into very high dimensional spaces $\\mathbb{R} \\to \\mathbb{R}^{10000}$\n", "it's the opposite: the \"Matrix-vector\" approach is much better suited than the \"vector-Matrix\" one (this time it's a single column!).\n", "\n", "\n", "## Function Compositions\n", "\n", "Of course copositions $(f\\circ g)(x) = f(g(x))$ of linear maps are also linear, so the above applies.\n", "\n", "\"A\n", "\n", "Depending on whether the \"Matrix-vector\" or \"vector-Matrix\" appraoch is used, the data is propagated **forwards** or **backwards**." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\"A\n", "\"A\n", "\n", "### From Matrices to Graphs\n", "\n", "The \"vector-Matrix\" or \"Matrix-vector\" picture can be generalized to arrbitrary directed acyclic graphs.\n", "\n", "* In the \"Matrix-vector\" picture the node value is the edge-weighted sum of the \"upstream nodes\".\n", "* In the \"vector-Matrix\" picture the node value is the edge-weighted sum of its \"downstream nodes\".\n", "\n", "(one could in principle always recove a rectangular/matrix-like version of a DAG by inserting trivial nodes)\n", "\n", "\n", "\"A\n", "\"A\n" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "def graph_like(x):\n", " x1,x2,x3 = x\n", " y1 = 2*x1+x2\n", " z1,z2 = y1+2*x3,x3-y1 #note that we reach \"over\" the \"ys\" and diectly touch x_n\n", " return np.asarray([z1,z2])\n", "\n", "def matrix_like(x):\n", " x1,x2,x3 = x\n", " y1 = 2*x1+x2\n", " y2 = x3 #can just introduce a dummy variable to make it matrix-like\n", " z1,z2 = y1+2*x3,y2-y1\n", " return np.asarray([z1,z2])\n" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "M derived from matrix like computation:\n", "[[ 2 1 2]\n", " [-2 -1 1]]\n", "M derived from graph-like products:\n", "[[ 2 1 2]\n", " [-2 -1 1]]\n" ] } ], "source": [ "M = np.concatenate([\n", " matrix_like(np.asarray([1,0,0])).reshape(-1,1),\n", " matrix_like(np.asarray([0,1,0])).reshape(-1,1),\n", " matrix_like(np.asarray([0,0,1])).reshape(-1,1),\n", "],axis=1)\n", "print(f'M derived from matrix like computation:\\n{M}')\n", "\n", "\n", "M = np.concatenate([\n", " graph_like(np.asarray([1,0,0])).reshape(-1,1),\n", " graph_like(np.asarray([0,1,0])).reshape(-1,1),\n", " graph_like(np.asarray([0,0,1])).reshape(-1,1),\n", "],axis=1)\n", "print(f'M derived from graph-like products:\\n{M}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Derivatives\n", "\n", "\n", "Why are we talking about linear transformations? After all lot of the code we write is non-linear! However, derivatives are always linear.\n", "\n", "And derivatives (the jacobian) of a composition $f\\circ g$ is the composition of linear derivatives (the jacobians\n", "of each map) i.e. the full jacobian Matrix is the result of multipying all Jacobians of the composition.\n", "$$J = J_0 J_1 J_2 J_3 \\dots J_n $$\n", "\n", "(This is just the chain rule)\n", "$$z = f(y) = f(g(x))\\hspace{1cm} \\frac{\\partial f_i}{\\partial x_j} = \\frac{\\partial f_i}{\\partial z_j}\\frac{\\partial z_j}{\\partial x_k}$$ \n", "\n", "\n", "I.e. finding derivatives, means characterizing the jacobian matrix. From the above discussion, we can use the \"Jacobian-vector product\" (JVP, builds Jacobians column-wise) or \"vector-Jacobian product\" (builds Jacobians row-wise) approach.\n", "\n", "In the language of automatic differentiation \n", "\n", "* Jacobian-vector products (JVP) = forward mode (forward propagation)\n", "\n", "$$ Jv_n = J_0 J_1 J_3 \\dots J_n v_n = J_0 J_1 J_2 J_3 v_3 = J_0 J_1 J_2 v_2 = J_0 J_1 v_1 = J_0 v_0 = \\text{col}$$\n", "\n", "* vector-Jacobian products (VJP) = reverse mode (reverse propagation)\n", "\n", "$$ v_0 J = v_0 J_0 J_1 J_3 \\dots J_n = v_1 J_1 J_2 J_3 \\dots J_n = v_2 J_2 J_3 \\dots J_n = v_3 J_3 \\dots J_n = \\dots = v_n J_n = \\text{row}$$\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Example\n", "\n", "Let's work this out on a very simple problem\n", "\n", "\n", "\"A" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the forward pass we use \"Matrix-vector\" products and need to do two evaluation\n", "\n", "\"A" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the backward pass we use \"vector-Matrix\" products and need to do only a single evaluation\n", "\n", "\"A" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Both approaches give the same result. Since this is a map from $\\mathbb{R}^2 \\to \\mathbb{R}^1$ the backward pass is more efficient than the forward pass\n", "\n", "\n", "Let's look at a real-life example\n", "\n", "$$z(x_1,x_2) = y + x_2 = x_1x_2 + x_2$$\n", "\n", "This is easy python code" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "12\n" ] } ], "source": [ "def mul_func(x1,x2):\n", " return x1*x2\n", "\n", "def sum_func(x1,x2):\n", " return x1+x2\n", "\n", "def function(x):\n", " x1,x2 = x\n", " y = mul_func(x1,x2)\n", " z = sum_func(y,x2)\n", " return z\n", "\n", "print(function([2,4]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the forward pass, an autodiff system needs to create a JVP implementation for each elementary operation " ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "def mul_jvp(x1,dx1,x2,dx2):\n", " y = mul_func(x1,x2)\n", " dy = x1*dx2 + x2*dx1\n", " return y, dy\n", "\n", "def sum_jvp(x1,dx1,x2,dx2):\n", " return sum_func(x1,x2), dx1 + dx2\n", "\n", "def function_jvp(x,dx):\n", " x1,x2 = x\n", " dx1,dx2 = dx\n", " y, dy = mul_jvp(x1,dx1,x2,dx2)\n", " z, dz = sum_jvp(y,dy, x2, dx2)\n", " return z,dz" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since in the forward pass we build \"column-at a time\" and our final jacobian is has shape (1x2), i.e. two columns we need two forward passes to get the full Jacobian. Not that for eacch forward pass we also get the fully computed functino value delivered on top!\n", "\n", "\n", "Also note that the \"JVP\" version of the functino has the same *structure* as the original function. For each call in the original program there is an equivalent call in the JVP program. However the JVP call does always two things at once\n", "\n", "1. compute the nominal result\n", "2. compute the differentials\n", "\n", "So it has roughly 2x the run-time as the original program (depending on the complexity of the derivatives). Said another way: computing the one-pass in the derivative has the same computational complexity as the function itself." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(12, 4)\n", "(12, 3)\n" ] } ], "source": [ "print(function_jvp([2,4],[1,0]))\n", "print(function_jvp([2,4],[0,1]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For the backward pass we build \"row-at-a-time'. For each elementary operation we need to build a VJP implementation" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "def mul_vjp(x1,x2,dx1,dx2,dout):\n", " dx2 += dout * x1\n", " dx1 += dout * x2\n", " return dx1,dx2\n", "\n", "def sum_vjp(x1,x2,dx1,dx2,dout):\n", " dx1 += dout * 1\n", " dx2 += dout * 1\n", " return dx1,dx2\n", "\n", "def function_vjp(x,dz):\n", " \n", " #run forward\n", " x1,x2 = x\n", " y = mul_func(x1,x2)\n", " z = sum_func(y,x2)\n", "\n", " #zero gradients\n", " dy = 0 \n", " dx1 = 0\n", " dx2 = 0\n", " \n", " #run backward\n", " dy,dx1 = sum_vjp(y,x1, dy, dx1, dz)\n", " dx1,dx2 = mul_vjp(x1,x2, dx1, dx2, dy)\n", " return z,[dx1,dx2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here, we see the power of backward propagation (or the reverse mode) we get all gradients of the single row ine oone go. Since this Jacobian only has one row, we're done! And we get the function value delivered on top of the gradients as well!" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(12, [5.0, 2.0])\n" ] } ], "source": [ "print(function_vjp([2,4],1.0))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Again, let's look at the \"VJP\" code. The forward pass is *exactly* the same as the original function. This just records the final result and all intermediate values, which we will need for the backward pass.\n", "\n", "Moving on to the backward pass, we see again, as in JVP, it has the same *structure* as the forward pass. For each call to a subroutine there is an equivalent call in the backward pass to compute the VJP. \n", "\n", "\n", "As in the JVP case, the computational complexity of one backward pass is roughly the same as the forward pass. Now unlike the JVP-case we only needed a single pass for **all the gradients** of this scalar function. So obtaining the **full gradient** of a function is only as expensive as the function itself." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Recap:\n", "\n", "Above we have built a *manual* autodiff system. Let's recap what we needed to do\n", "\n", "* define a set of operations we want to be differentiable\n", "* define sub-routines for nominal operations, JVP and VJP\n", "\n", "\n", "\n", "Once given a program, we had to do the following\n", "\n", "**In the forward mode**:\n", "\n", "* just replace the nominal function with the JVP one\n", "* for each variable in the program allocate a \"differential\" variable and pass it\n", " into the JVP whereever we also pass the nominal variable\n", " \n", " \n", "**In the backward mode**:\n", "\n", "* Run the program forward, keep track of all values\n", "* keep track of the order of operations on a \"record\" of sorts\n", "* allocate \"differential\" variables for all values and initialize to zero\n", "* use the record to replay the order of operations backwards, passing along the \n", " appropriate differential values, and updating the relevant ones with the result\n", " of the VJP\n", "\n", "\n", "All of this is pretty mechanistic and hence \"automatable\". And given that it's a very narrow\n", "domain of only implementing JVP/JVP operations this is easy to do in any language.\n", "\n", "That's why it's **automatic differentiation**\n", " \n", " \n", "What we gain from this is that we get\n", "\n", "* exact derivatives (to machine precision) for arbitrary composed of the operations we define\n", "* complexity of a derivative-pass through the program is of same order of complexity as the original program\n", "* often only a single pass is necessary (e.g. scalar multi-variate functions)\n", "* unlike symbolic differrentiation, the structure of the program is preserved and allows naturally to avoid\n", " repetitive calculations of the same values\n", "* (we will see that) arbitrary control flows are handles naturally\n", "* it's something that is easy for a comoputer do and for a progarmmer to imlpement\n", "\n", "\n", "\n", "Some notes on pros and cons:\n", "\n", "**In the forward mode**:\n", "\n", "the signature of each opeartion basically extends \n", " ```c++\n", " float f(float x,float y,float z)\n", " ```\n", " to\n", " ```c++\n", " pair f(float x,float dx,float y,float float dy, float z,float dz)\n", " ```\n", " * if you use composite types (\"dual numbers\") that hold both x,dx you can basically \n", " keep the signature unchanged\n", " ```c++\n", " f(dual x, dual x, dual z)\n", " ```\n", " * together with operator overloading on these dual types e.g. `dual * dual` you can \n", " essentially keep the source code unchanged\n", " ```c++\n", " float f(float x, float y): return x*y\n", " ``` \n", " ->\n", " ```c++\n", " dual f(dual x,dual y): return x*y\n", " ```\n", " \n", "* That means it's very easy implement. And memory efficient, no superfluous values are kept when they run out of scope.\n", "* But forward more better for vector-value functions of few parameters\n", "\n", "\n", "**In the reverse mode**:\n", "\n", "* very efficient, but we need to keep track of order (need a \"tape\" of sorts)\n", "* since we need to access all intermediate varriables, we can run into memory bounds\n", "* the procedurer is a bit more complex than fwd: 1) run fwd, 2) zero grads 3) run bwd\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## I don't want to implement an autodiff system.. Aren't there libraries for this??" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Yes there are! And a lot of them in many languages. On the othe rhand, try finding CAS systems in each of those \n", "\n", "\"A\n", "\n", "This is PyHEP, so let's focus on Python. Here, basically what you think of as \"Machine Learning frameworks\" are at the core autodiff libraries\n", "\n", "* Tensorflow\n", "* PyTorch\n", "* JAX" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's focus on jax" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "import jax\n", "import jax.numpy as jnp" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "def f(x):\n", " return x**2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`jax.numpy` is almost a drop-in rerplacement for `numpy`. I do `import jax.numpy as jnp` but if you're daring you could do `import jax.numpy as np`" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)\n" ] } ], "source": [ "x = jnp.array([1,2,3])\n", "y = jnp.array([2,3,4])" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[3 5 7]\n", "[ 2 6 12]\n", "[0. 0.69314718 1.09861229]\n", "[ 7.3890561 20.08553692 54.59815003]\n" ] } ], "source": [ "print(x+y)\n", "print(x*y)\n", "print(jnp.log(x))\n", "print(jnp.exp(y))" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "def f(x):\n", " return x**3" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "64.0\n", "48.0\n", "24.0\n", "6.0\n", "0.0\n" ] } ], "source": [ "print(f(4.0))\n", "print(jax.grad(f)(4.0)) #boom!\n", "print(jax.grad(jax.grad(f))(4.0)) #boom!\n", "print(jax.grad(jax.grad(jax.grad(f)))(4.0)) #boom!\n", "print(jax.grad(jax.grad(jax.grad(jax.grad(f))))(4.0)) #boom!" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "xi = jnp.linspace(-5,5)\n", "yi = f(xi)\n", "\n", "plt.plot(xi,yi)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "Gradient only defined for scalar-output functions. Output had shape: (50,).", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "Input \u001b[0;32mIn [31]\u001b[0m, in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mjax\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgrad\u001b[49m\u001b[43m(\u001b[49m\u001b[43mf\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43mxi\u001b[49m\u001b[43m)\u001b[49m\n", " \u001b[0;31m[... skipping hidden 4 frame]\u001b[0m\n", "File \u001b[0;32m~/Code/iml_tutorial/_venv/lib/python3.9/site-packages/jax/_src/api.py:1019\u001b[0m, in \u001b[0;36m_check_scalar\u001b[0;34m(x)\u001b[0m\n\u001b[1;32m 1017\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(aval, ShapedArray):\n\u001b[1;32m 1018\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m aval\u001b[38;5;241m.\u001b[39mshape \u001b[38;5;241m!=\u001b[39m ():\n\u001b[0;32m-> 1019\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(msg(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhad shape: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00maval\u001b[38;5;241m.\u001b[39mshape\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m))\n\u001b[1;32m 1020\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 1021\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(msg(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhad abstract value \u001b[39m\u001b[38;5;132;01m{\u001b[39;00maval\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m))\n", "\u001b[0;31mTypeError\u001b[0m: Gradient only defined for scalar-output functions. Output had shape: (50,)." ] } ], "source": [ "jax.grad(f)(xi)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Whoops, jax.grad defaults to reverse mode with a single backward pass, but through broadcasting we get a `vector -> vector` map. We can use some jax magic to \"unbroadcast\" the function, take the gradient and re-broadcast it" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DeviceArray([7.50000000e+01, 6.90024990e+01, 6.32548938e+01,\n", " 5.77571845e+01, 5.25093711e+01, 4.75114536e+01,\n", " 4.27634319e+01, 3.82653061e+01, 3.40170762e+01,\n", " 3.00187422e+01, 2.62703040e+01, 2.27717618e+01,\n", " 1.95231154e+01, 1.65243648e+01, 1.37755102e+01,\n", " 1.12765514e+01, 9.02748855e+00, 7.02832153e+00,\n", " 5.27905040e+00, 3.77967514e+00, 2.53019575e+00,\n", " 1.53061224e+00, 7.80924615e-01, 2.81132861e-01,\n", " 3.12369846e-02, 3.12369846e-02, 2.81132861e-01,\n", " 7.80924615e-01, 1.53061224e+00, 2.53019575e+00,\n", " 3.77967514e+00, 5.27905040e+00, 7.02832153e+00,\n", " 9.02748855e+00, 1.12765514e+01, 1.37755102e+01,\n", " 1.65243648e+01, 1.95231154e+01, 2.27717618e+01,\n", " 2.62703040e+01, 3.00187422e+01, 3.40170762e+01,\n", " 3.82653061e+01, 4.27634319e+01, 4.75114536e+01,\n", " 5.25093711e+01, 5.77571845e+01, 6.32548938e+01,\n", " 6.90024990e+01, 7.50000000e+01], dtype=float64)" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "jax.vmap(jax.grad(f))(xi)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "that looks better!\n", "\n", "`jax.grad(f)` just returns another function. Of course we can just \n", "take the gradient of that as well. And so on..." ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "g1i = jax.vmap(jax.grad(f))(xi)\n", "g2i = jax.vmap(jax.grad(jax.grad(f)))(xi)\n", "g3i = jax.vmap(jax.grad(jax.grad(jax.grad(f))))(xi)\n", "plt.plot(xi,yi, label = \"f\")\n", "plt.plot(xi,g1i, label = \"f'\")\n", "plt.plot(xi,g2i, label = \"f''\")\n", "plt.plot(xi,g3i, label = \"f'''\")\n", "plt.legend()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Control Flow\n", "\n", "Back when discussing symbolic differentiation we hit a snag when adding \n", "control flow through to our prorgam. In Jax this just passes through\n", "transparently. \n", "\n", "\n", "Let's compare this to finite differences. So far the only system\n", "we had to compute derivatives of control-flow-ful programs" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "def control_flow_func(x):\n", " if x > 2:\n", " return x**2\n", " else:\n", " return x**3\n", " \n", "\n", "first_gradient_of_cflow = jax.grad(control_flow_func)\n", " \n", "xi = jnp.linspace(-2,5,101)\n", "yi = np.asarray([first_gradient_of_cflow(xx) for xx in xi])\n", "plt.plot(xi,yi,c = 'k')\n", "\n", "xi = jnp.linspace(-2,5,11)\n", "yi = np.asarray([first_gradient_of_cflow(xx) for xx in xi])\n", "plt.scatter(xi,yi, label = 'jax autodiff')\n", "\n", "\n", "\n", "xi = jnp.linspace(-2,5,11)\n", "yi = np.asarray([control_flow_func(xx) for xx in xi])\n", "plt.scatter(xi,np.gradient(yi,xi), label = 'finite differences')\n", "\n", "plt.legend()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can start to see the benefits autodiff. Among other things, finite differnces becomes\n", "quite sensitive to exactly where the evaluation points are (e.g. wrt to the discontinuity)\n", "\n", "\n", "As we compute higher derivatives, this error compounds badly for finite differences. But for\n", "autodiff, it's smooth sailing!" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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nly9ehUvLy+6detGy5YtrZi66NLS0qhXrx4bNmwo9GO8vb3x9vY2MFX+Fi5cyJNPPkmFChXu6vGjR4/O+Tk0NJT+/fszffp0AN577z127tyJq6urVbLaivTks2RkZPD000+zd+9ePv74Yzp37mx2JFFCZV9LIO5KMhqIu5LMtJDvCT0cd9fHrFu3Lp6engBUqlSJFi1aEBeXebwuXbrw8ssv07ZtW5o2bcrevXsBSE5OZvDgwbRo0YI+ffqQnJz3Cqjbtm2jefPmeHp6EhISkrP92rVrDB8+nLZt2+Lh4UFYWBiQ2bPt1asXjzzyCF27duXMmTM5H/578MEH+eGHH3KOkde7h9zvFg4ePEj79u3x8PCgQ4cOxMRkLsUdFBTE8OHDgczrIrdq1eq2HviZM2fo3Lkznp6eeHp6cuDAgduODzBu3DhWrlzJokWLOH/+PD4+Pvj4+ADw6aef0rp1a1q1asXLL7+c85gVK1bQtGlT2rZty/79+3O2z5o1i3nz5hEREcHChQt5//338fHxYfTo0fzyyy/4+voSFBSU339jyaS1vusvYADwA5ABeN9y3zTgZyAG6F6Y43l5eWmzTJo0SQN67ty5pmUQ5jlx4kSh9+3wVpS+7+Wtt311eCvKKll+/fVX3aBBA52YmKi11vrhhx/WEydO1FprHR4errt27aq11nr+/Pn6mWee0VprffToUW2xWPS3335707GSk5O1q6urPnXqlM7IyNADBgzQ/v7+Wmutp02bplevXq211vry5cu6SZMmOikpSa9YsULXr19fJyQk5ORxc3PTWmu9YMECPXPmTK211ufPn9dNmza9Lf+uXbty2khMTNSpqalaa60///xz3bdvX6211unp6bpz5846JCREe3l56X379t12nGvXrunk5GSttdanTp3S2fUh9/G11nrs2LF6xYoVWmut77vvPh0fH6+11jouLk43aNBAX7hwQaempmofHx+9adMmff78+Zzt169f1x06dNBjx47VWmv96quv5tSA3D/femwz5fW7CkTrfOpqcYdrjgN9gf/m3qiUagkMBtyAesBOpVRTrXV6MdszxOLFi5k3bx5jx47lpZdeMjuOKOHyu2aANa4lkJSURL9+/Vi4cCGVK1fO2d63b18AvLy8OHPmDAB79uzJGft2d3fH3d39tuOdPHmSxo0b06RJEwCefPJJli1bBsCOHTvYvHkz8+bNAzKHK8+ePQtAt27dqF69+m3HGzhwII899hivvfYa69evv+NYfWJiIk8//TQ//fQTSilSU1MBKFOmDCtXrsTd3Z1nn32Wjh073vbY1NRUxo0bx5EjR7BYLJw6darAtm717bff0qVLF2rVqgXAkCFD2LNnD8BN2wcNGlTkY9uTYhV5rfWPkOe0nt7AOq31deBXpdTPQFvgq+K0Z4SwsDBeeOEFevXqxbvvvivT6MQd1avqQlweBb241xJITU2lX79+DBkyJKeoZytfvjwAFouFtLS0YrWTTWvNxo0badbs5uWxv/nmGypWrJjnY+rXr0+NGjU4duwYn332GUuXLi2wjRkzZuDj48OmTZs4c+YMXbp0ybnvp59+4p577uH8+fN5PjYoKIg6depw9OhRMjIycHZ2BjLPX2RkZOTsJ59SLphRY/L1gXO5bsdmbbuNUmqUUipaKRUdHx9vUJy8ffPNNzz++ON4e3vz6aefYrFYbNq+sE+TuzfDxenm35XiXktAZ62P1KJFCyZOnFioxzz00EN88sknABw/fpxjx47dtk/z5s05c+YMp0+fBjLHqLN1796d//znP9nDqxw+fLhQ7Q4aNIh33nmHxMTEPN895JaYmEj9+pkv/ZUrV960ffz48ezZs4eEhIQ8T+wmJiZSt25dypQpw+rVq0lPzxwIuO+++zhx4gTXr1/nypUrREVF5TymUqVKXL16FYC2bduye/duLl68SHp6Op9++ikPP/ww7dq1Y/fu3SQkJJCamkpwcHChnre9umORV0rtVEodz+OrtzUCaK2Xaa29tdbe2W+fbOH06dMEBARQt25dtmzZctdn40XpE+hRn7f6tqZ+VRerXUtg//79rF69mi+++II2bdrQpk0bIiIiCnzMc889R1JSEi1atGDmzJl4eXndto+zszPLli3D398fT09PateunXPfjBkzSE1Nxd3dHTc3N2bMmFGorP3792fdunUMHDgw332y3xFPmTKFadOm4eHhcdM7kBdffJGxY8fStGlTPvzwQ6ZOncqFCxduOsaYMWNYtWoVDzzwACdPnsx5d9GgQQMGDhxIq1atcj6wmG3UqFH06NEDHx8f6taty5w5c/Dx8eGBBx7Ay8uL3r17U7duXWbNmkX79u3p2LEjLVq0KNTztlcq+694sQ6i1JfAJK11dNbt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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "second_gradient_of_cflow = jax.grad(first_gradient_of_cflow)\n", "xi = jnp.linspace(-2,5,101)\n", "yi = np.asarray([second_gradient_of_cflow(xx) for xx in xi])\n", "plt.plot(xi,yi,c = 'k')\n", "\n", "xi = jnp.linspace(-2,5,11)\n", "yi = np.asarray([second_gradient_of_cflow(xx) for xx in xi])\n", "plt.scatter(xi,yi, label = '2nd deriv jax autodiff')\n", "\n", "xi = jnp.linspace(-2,5,11)\n", "yi = np.asarray([control_flow_func(xx) for xx in xi])\n", "plt.scatter(xi,np.gradient(np.gradient(yi),xi), label = '2nd deriv finite differences',)\n", "\n", "plt.legend()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## In HEP\n", "\n", "\n", "Of course we can use automatic differentiation\n", "for neural networks. But other things in HEP also \n", "can make use of gradients. A prime example where this is the \n", "case is statistical analysis\n", "\n", "For a maximum likelihood fit we want to minimize the log likelihood\n", "\n", "$\\theta^* = \\mathrm{argmin}_\\theta(\\log L)$ " ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [], "source": [ "import jax\n", "import jax.numpy as jnp\n", "import numpy as np\n", "import pyhf\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [], "source": [ "pyhf.set_backend('jax')" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DeviceArray([-4.25748227], dtype=float64)" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "m = pyhf.simplemodels.uncorrelated_background([5.],[10.],[3.5])\n", "pars = jnp.array(m.config.suggested_init())\n", "data = jnp.array([15.] + m.config.auxdata)\n", "m.logpdf(pars,data)" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DeviceArray([1., 1.], dtype=float64)" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bestfit = pyhf.infer.mle.fit(data,m)\n", "bestfit" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "grid = x,y = np.mgrid[.5:1.5:101j,.5:1.5:101j]\n", "\n", "points = np.swapaxes(grid,0,-1).reshape(-1,2)\n", "v = jax.vmap(m.logpdf, in_axes = (0,None))(points,data)\n", "v = np.swapaxes(v.reshape(101,101),0,-1)\n", "plt.contourf(x,y,v, levels = 100)\n", "plt.contour(x,y,v, levels = 20, colors = 'w')\n", "\n", "\n", "\n", "grid = x,y = np.mgrid[.5:1.5:11j,.5:1.5:11j]\n", "points = np.swapaxes(grid,0,-1).reshape(-1,2)\n", "values, gradients = jax.vmap(\n", " jax.value_and_grad(\n", " lambda p,d: m.logpdf(p,d)[0]\n", " ), in_axes = (0,None)\n", ")(points,data)\n", "\n", "plt.quiver(\n", " points[:,0],\n", " points[:,1],\n", " gradients[:,0],\n", " gradients[:,1],\n", " angles = 'xy',\n", " scale = 75\n", ")\n", "plt.scatter(bestfit[0],bestfit[1], c = 'r')\n", "\n", "plt.xlim(0.5,1.5)\n", "plt.ylim(0.5,1.5)\n", "plt.gcf().set_size_inches(5,5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Thanks for joining the Tutorial!\n", "\n", "\n", "\n", "\"A\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.11" } }, "nbformat": 4, "nbformat_minor": 4 }