{ "cells": [ { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "RnacmDDKr1ed" }, "source": [ "# Neural Networks for Data Science Applications\n", "\n", "## Lab session 1: TensorFlow 2.0 basics & Automatic differentiation\n", "\n", "**Contents of the lab session**:\n", "* Linear algebra in TensorFlow.\n", "* Automatic gradient computation with tf.GradientTape.\n", "* Simple example of gradient descent." ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "colab": {}, "colab_type": "code", "id": "qWW6GORKtaT3" }, "outputs": [], "source": [ "# Install the latest version of TF\n", "# The '!' sign means a command that is executed externally\n", "!pip install tensorflow==2.0.0" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "UKlXIe-DsTox" }, "source": [ "### 1 - Linear algebra" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "colab": {}, "colab_type": "code", "id": "GwNQKhmEuoJz" }, "outputs": [], "source": [ "import tensorflow as tf" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 34 }, "colab_type": "code", "id": "b91S_4m_vi5-", "outputId": "3c19a2e9-0a69-4f3c-a70e-33c79433cbc6" }, "outputs": [ { "data": { "text/plain": [ "'2.0.0'" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Check the version\n", "tf.__version__" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 34 }, "colab_type": "code", "id": "35abT2ymv-9c", "outputId": "29f3763f-eba5-4f94-9f0f-a74e0f83ad36" }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Check whether a GPU is available\n", "# Hint: try to enable one from Runtime >> Change Runtime Type in Colab, and installling tensorflow-gpu.\n", "tf.test.is_gpu_available()" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "colab": {}, "colab_type": "code", "id": "8gCYlBpywWMk" }, "outputs": [], "source": [ "# Simple matrix in NumPy\n", "import numpy as np\n", "A = np.random.rand(3, 2)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 69 }, "colab_type": "code", "id": "1Axouagrw8x5", "outputId": "415120d8-2587-40f2-cf57-5cb3b916e9e7" }, "outputs": [ { "data": { "text/plain": [ "array([[0.74938785, 0.0231844 ],\n", " [0.15683247, 0.35414634],\n", " [0.91603059, 0.58474034]])" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 86 }, "colab_type": "code", "id": "h0qGHk0fw_HS", "outputId": "36a6022a-105c-47a1-dd88-f32739077769" }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Similar sintax in TF\n", "tf.random.normal((3, 2))" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "colab": {}, "colab_type": "code", "id": "y6ugoeGDxTWy" }, "outputs": [], "source": [ "# Default type is tf.float32, but you can force a different one\n", "B = tf.ones((5, 4), dtype=tf.float64)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 121 }, "colab_type": "code", "id": "_BHRRXC9x9KW", "outputId": "1f9542da-1042-4399-cbba-d8e6c60d445b" }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Casting in TF\n", "tf.cast(B, tf.int32)" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 86 }, "colab_type": "code", "id": "dbUJE2JSyY-h", "outputId": "8a2a2c95-a738-4e14-9656-278f14c08cf3" }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# NumPy --> TensorFlow\n", "tf.constant(A)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 103 }, "colab_type": "code", "id": "kskupNrXyuiw", "outputId": "080399d9-646a-488e-d8f6-190aad903c6c" }, "outputs": [ { "data": { "text/plain": [ "array([[1., 1., 1., 1.],\n", " [1., 1., 1., 1.],\n", " [1., 1., 1., 1.],\n", " [1., 1., 1., 1.],\n", " [1., 1., 1., 1.]])" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# TensorFlow --> NumPy\n", "B.numpy()" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 34 }, "colab_type": "code", "id": "jK72SEvNzAjr", "outputId": "852cb296-97ad-45c9-9e7e-3e1d4e0363b1" }, "outputs": [ { "data": { "text/plain": [ "TensorShape([5, 4])" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "B.shape" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "colab": {}, "colab_type": "code", "id": "ObGtmHE3zUgW" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tf.Tensor([1. 1. 1. 1.], shape=(4,), dtype=float64)\n", "tf.Tensor(1.0, shape=(), dtype=float64)\n", "tf.Tensor(\n", "[[1. 1. 1. 1.]\n", " [1. 1. 1. 1.]], shape=(2, 4), dtype=float64)\n", "tf.Tensor([1. 1. 1. 1.], shape=(4,), dtype=float64)\n" ] } ], "source": [ "# Simple indexing\n", "print(B[0])\n", "print(B[0, 3])\n", "print(B[0:2])\n", "print(B[-1])" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 34 }, "colab_type": "code", "id": "RyseiZQg0Q7V", "outputId": "0fadecc7-d6f3-430d-b995-ae99449dce69" }, "outputs": [ { "data": { "text/plain": [ "array([1.8222509 , 0.96207107])" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Getting summaries from an array (NumPy version)\n", "A.sum(axis=0)" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 54 }, "colab_type": "code", "id": "tN2gO9Jj0fwx", "outputId": "3a5bcd11-8a91-4e5f-8174-479c9aa0d4b9" }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Getting summaries from an array (TensorFlow version)\n", "tf.reduce_sum(B, axis=1)" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 121 }, "colab_type": "code", "id": "JOKf2lN506Ws", "outputId": "624844a5-bfa7-4ca5-ce45-e0277d82c797" }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# All operators are element-wise\n", "B * B" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 121 }, "colab_type": "code", "id": "9hAm0QgL1I5u", "outputId": "f5450940-918b-43a0-b899-d98d7c1f49b2" }, "outputs": [ { "data": { "text/plain": [ "array([[0.74938785],\n", " [0.0231844 ],\n", " [0.15683247],\n", " [0.35414634],\n", " [0.91603059],\n", " [0.58474034]])" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Reshaping in NumPy\n", "A.reshape(6, 1)" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 103 }, "colab_type": "code", "id": "CkebDGvS1gf8", "outputId": "0702bb8d-f80f-4fca-fbd0-83cc129e9025" }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Reshaping in TensorFlow\n", "tf.reshape(B, (4, 5))" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "colab": {}, "colab_type": "code", "id": "0Ti9HEsz1oBl" }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Broadcasting (once)\n", "A = tf.random.uniform((3,))\n", "B = tf.random.uniform((1, 3))\n", "A + B" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "colab": {}, "colab_type": "code", "id": "tUeq-Nzo3i4Q" }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Broadcasting (twice)\n", "A = tf.random.uniform((4, 3, 1))\n", "B = tf.random.uniform((1, 3, 5))\n", "A + B" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "14hiU8L7ts06" }, "source": [ "### 2 - Automatic differentiation" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "colab": {}, "colab_type": "code", "id": "9dSfRr0r3keM" }, "outputs": [], "source": [ "# Define a simple function\n", "def fcn(x):\n", " return 2.0 * tf.cos(x)" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "colab": {}, "colab_type": "code", "id": "pHxC4O9h40QP" }, "outputs": [], "source": [ "# Plot the function (note: automatic NumPy -> TensorFlow conversion)\n", "x_range = np.linspace(0, 5, 100)\n", "y_range = fcn(x_range)" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 286 }, "colab_type": "code", "id": "l7HTMzdH5Rul", "outputId": "711ef46e-774a-4b61-b1c3-c2b6a0ef2cb6" }, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "plt.plot(x_range, y_range)" ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "colab": {}, "colab_type": "code", "id": "aiLLfCjI53z1" }, "outputs": [], "source": [ "# Run the operations inside a tf.GradientTape\n", "x = tf.constant(1.0)\n", "with tf.GradientTape() as tape:\n", " tape.watch(x)\n", " y = fcn(x)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "colab": {}, "colab_type": "code", "id": "a0RQ2jQj8Ej6" }, "outputs": [], "source": [ "# Get the gradient\n", "g = tape.gradient(y, x)" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 34 }, "colab_type": "code", "id": "Nn42biKC8dVf", "outputId": "5b1db8c3-f2db-436a-ffb3-2a738bc290e2" }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Check it is correct to numerical precision\n", "# g == -2.0*tf.sin(x)\n", "tf.reduce_all(tf.equal(g, -2.0*tf.sin(x))) # Alternative definition with TF functions" ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "colab": {}, "colab_type": "code", "id": "8uz8JTJHCCsr" }, "outputs": [], "source": [ "# Same, with tf.Variable (does not need to be watched)\n", "x = tf.random.uniform((3, 2))\n", "x = tf.Variable(x)" ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "colab": {}, "colab_type": "code", "id": "EoEgj6ITDRMW" }, "outputs": [], "source": [ "with tf.GradientTape() as tape:\n", " y = fcn(x)\n", " z = tf.reduce_sum(y) # Note: we need a scalar in output" ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 86 }, "colab_type": "code", "id": "5Z6CZhPDDycL", "outputId": "1565d4ef-25fb-4ef9-d687-9f240f246ab2" }, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 41, "metadata": { "tags": [] }, "output_type": "execute_result" } ], "source": [ "tape.gradient(z, [x])" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "RDtK63zxuIxh" }, "source": [ "### 3 - Gradient Descent" ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "colab": {}, "colab_type": "code", "id": "Lw4JmcinER-e" }, "outputs": [], "source": [ "x = tf.Variable(tf.ones(1))\n", "x_history = [] # Evolution of x\n", "y_history = [] # Evolution of the function\n", "g_history = [] # Evolution of the gradient\n", "for i in range(50):\n", " with tf.GradientTape() as tape:\n", " y = fcn(x)\n", " x_history.append(x.numpy())\n", " y_history.append(y.numpy())\n", " g = tape.gradient(y, x)\n", " g_history.append(g.numpy())\n", " x.assign_sub(0.05*g) # We cannot reassign a Variable with standard operators, otherwise it becomes a tensor" ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 286 }, "colab_type": "code", "id": "rKTFCNnXFaYM", "outputId": "9448b4b8-c0de-43a1-bf6c-b3096708fd2e" }, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 55, "metadata": { "tags": [] }, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "tags": [] }, "output_type": "display_data" } ], "source": [ "plt.plot(x_range, y_range)\n", "plt.plot(x_history, fcn(x_history), 'o')" ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 286 }, "colab_type": "code", "id": "Sjq3MomcHmAS", "outputId": "08d6e805-22a8-44fa-ffc0-7fa6b76a5414" }, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 57, "metadata": { "tags": [] }, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "tags": [] }, "output_type": "display_data" } ], "source": [ "plt.plot(y_history)\n", "plt.xlabel('Iteration')\n", "plt.ylabel('Value of function')" ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 286 }, "colab_type": "code", "id": "vRuYKDoyIwZ4", "outputId": "fd7bb218-f66a-4679-9d49-ad3ed50ac969" }, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 65, "metadata": { "tags": [] }, "output_type": "execute_result" }, { "data": { "image/png": "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\nHicjvQAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": { "tags": [] }, "output_type": "display_data" } ], "source": [ "plt.plot(g_history)\n", "plt.xlabel('Iteration')\n", "plt.ylabel('Value of gradient')" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "OfOlzka_uWsz" }, "source": [ "### 4 - Advanced use cases" ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "colab": {}, "colab_type": "code", "id": "p8AK84gYJTKP" }, "outputs": [], "source": [ "# Two variables!\n", "v1 = tf.Variable(2.0)\n", "v2 = tf.Variable(tf.ones(4))" ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "colab": {}, "colab_type": "code", "id": "0l-UErK4JxLB" }, "outputs": [], "source": [ "# You can use conditional control flow (and other stuff) inside the GradientTape\n", "use_sqrt = True\n", "with tf.GradientTape() as tape:\n", " if use_sqrt:\n", " y = v1 + tf.reduce_sum(tf.sqrt(v2))\n", " else:\n", " y = v1 + tf.reduce_sum(v2)" ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 71 }, "colab_type": "code", "id": "f-RnWdoxKD4F", "outputId": "82dec159-2fde-4633-d2bc-c230eac90c1d" }, "outputs": [ { "data": { "text/plain": [ "[,\n", " ]" ] }, "execution_count": 71, "metadata": { "tags": [] }, "output_type": "execute_result" } ], "source": [ "tape.gradient(y, [v1, v2])" ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "colab": {}, "colab_type": "code", "id": "FlS6x4tAKPaD" }, "outputs": [], "source": [ "# Second-order derivatives\n", "# Learn more: https://www.tensorflow.org/tutorials/customization/autodiff#higher-order_gradients\n", "with tf.GradientTape() as outer_tape:\n", " with tf.GradientTape() as tape:\n", " y = tf.reduce_sum(tf.sqrt(v2))\n", " grad = tape.gradient(y, v2)\n", "gradgrad = outer_tape.gradient(grad, v2)" ] }, { "cell_type": "code", "execution_count": 0, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 54 }, "colab_type": "code", "id": "V_kxYOBvM415", "outputId": "f9c2abff-aab8-42b1-d2f9-10c51a2de64d" }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 77, "metadata": { "tags": [] }, "output_type": "execute_result" } ], "source": [ "gradgrad" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "OPErWCheuwLS" }, "source": [ "### Some reading material\n", "* https://www.tensorflow.org/tutorials/customization/basics\n", "* https://www.tensorflow.org/tutorials/customization/autodiff" ] } ], "metadata": { "colab": { "collapsed_sections": [], "name": "Notebook_1_Basics_and_automatic_differentiation.ipynb", "provenance": [] }, "kernelspec": { "display_name": "Python 3", "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.6.8" } }, "nbformat": 4, "nbformat_minor": 1 }