{"cells": [{"cell_type": "markdown", "id": "3430d66a", "metadata": {"papermill": {"duration": 0.017199, "end_time": "2022-05-12T11:44:36.489157", "exception": false, "start_time": "2022-05-12T11:44:36.471958", "status": "completed"}, "tags": []}, "source": ["\n", "# Tutorial 1: Introduction to PyTorch\n", "\n", "* **Author:** Phillip Lippe\n", "* **License:** CC BY-SA\n", "* **Generated:** 2022-05-12T13:44:14.531736\n", "\n", "This tutorial will give a short introduction to PyTorch basics, and get you setup for writing your own neural networks.\n", "This notebook is part of a lecture series on Deep Learning at the University of Amsterdam.\n", "The full list of tutorials can be found at https://uvadlc-notebooks.rtfd.io.\n", "\n", "\n", "---\n", "Open in [{height=\"20px\" width=\"117px\"}](https://colab.research.google.com/github/PytorchLightning/lightning-tutorials/blob/publication/.notebooks/course_UvA-DL/01-introduction-to-pytorch.ipynb)\n", "\n", "Give us a \u2b50 [on Github](https://www.github.com/PytorchLightning/pytorch-lightning/)\n", "| Check out [the documentation](https://pytorch-lightning.readthedocs.io/en/stable/)\n", "| Join us [on Slack](https://www.pytorchlightning.ai/community)"]}, {"cell_type": "markdown", "id": "63c4bc69", "metadata": {"papermill": {"duration": 0.014088, "end_time": "2022-05-12T11:44:36.519910", "exception": false, "start_time": "2022-05-12T11:44:36.505822", "status": "completed"}, "tags": []}, "source": ["## Setup\n", "This notebook requires some packages besides pytorch-lightning."]}, {"cell_type": "code", "execution_count": 1, "id": "89b5dbf7", "metadata": {"colab": {}, "colab_type": "code", "execution": {"iopub.execute_input": "2022-05-12T11:44:36.552939Z", "iopub.status.busy": "2022-05-12T11:44:36.552077Z", "iopub.status.idle": "2022-05-12T11:44:40.698923Z", "shell.execute_reply": "2022-05-12T11:44:40.697901Z"}, "id": "LfrJLKPFyhsK", "lines_to_next_cell": 0, "papermill": {"duration": 4.167203, "end_time": "2022-05-12T11:44:40.701322", "exception": false, "start_time": "2022-05-12T11:44:36.534119", "status": "completed"}, "tags": []}, "outputs": [], "source": ["! pip install --quiet \"torch>=1.8\" \"pytorch-lightning>=1.4\" \"ipython[notebook]\" \"setuptools==59.5.0\" \"torchmetrics>=0.7\" \"matplotlib\""]}, {"cell_type": "markdown", "id": "faa9e81e", "metadata": {"papermill": {"duration": 0.012897, "end_time": "2022-05-12T11:44:40.728633", "exception": false, "start_time": "2022-05-12T11:44:40.715736", "status": "completed"}, "tags": []}, "source": ["<div class=\"center-wrapper\"><div class=\"video-wrapper\"><iframe src=\"https://www.youtube.com/embed/wnKZZgFQY-E\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe></div></div>\n", "Welcome to our PyTorch tutorial for the Deep Learning course 2020 at the University of Amsterdam!\n", "The following notebook is meant to give a short introduction to PyTorch basics, and get you setup for writing your own neural networks.\n", "PyTorch is an open source machine learning framework that allows you to write your own neural networks and optimize them efficiently.\n", "However, PyTorch is not the only framework of its kind.\n", "Alternatives to PyTorch include [TensorFlow](https://www.tensorflow.org/), [JAX](https://github.com/google/jax) and [Caffe](http://caffe.berkeleyvision.org/).\n", "We choose to teach PyTorch at the University of Amsterdam because it is well established, has a huge developer community (originally developed by Facebook), is very flexible and especially used in research.\n", "Many current papers publish their code in PyTorch, and thus it is good to be familiar with PyTorch as well.\n", "Meanwhile, TensorFlow (developed by Google) is usually known for being a production-grade deep learning library.\n", "Still, if you know one machine learning framework in depth, it is very easy to learn another one because many of them use the same concepts and ideas.\n", "For instance, TensorFlow's version 2 was heavily inspired by the most popular features of PyTorch, making the frameworks even more similar.\n", "If you are already familiar with PyTorch and have created your own neural network projects, feel free to just skim this notebook.\n", "\n", "We are of course not the first ones to create a PyTorch tutorial.\n", "There are many great tutorials online, including the [\"60-min blitz\"](https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html) on the official [PyTorch website](https://pytorch.org/tutorials/).\n", "Yet, we choose to create our own tutorial which is designed to give you the basics particularly necessary for the practicals, but still understand how PyTorch works under the hood.\n", "Over the next few weeks, we will also keep exploring new PyTorch features in the series of Jupyter notebook tutorials about deep learning.\n", "\n", "We will use a set of standard libraries that are often used in machine learning projects.\n", "If you are running this notebook on Google Colab, all libraries should be pre-installed.\n", "If you are running this notebook locally, make sure you have installed our `dl2020` environment ([link](https://github.com/uvadlc/uvadlc_practicals_2020/blob/master/environment.yml)) and have activated it."]}, {"cell_type": "code", "execution_count": 2, "id": "df258032", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:40.756767Z", "iopub.status.busy": "2022-05-12T11:44:40.756012Z", "iopub.status.idle": "2022-05-12T11:44:42.475828Z", "shell.execute_reply": "2022-05-12T11:44:42.475068Z"}, "papermill": {"duration": 1.736237, "end_time": "2022-05-12T11:44:42.477856", "exception": false, "start_time": "2022-05-12T11:44:40.741619", "status": "completed"}, "tags": []}, "outputs": [{"name": "stderr", "output_type": "stream", "text": ["/tmp/ipykernel_2736/3457578344.py:15: DeprecationWarning: `set_matplotlib_formats` is deprecated since IPython 7.23, directly use `matplotlib_inline.backend_inline.set_matplotlib_formats()`\n", " set_matplotlib_formats(\"svg\", \"pdf\")\n"]}], "source": ["import time\n", "\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "import torch\n", "import torch.nn as nn\n", "import torch.utils.data as data\n", "\n", "%matplotlib inline\n", "from IPython.display import set_matplotlib_formats\n", "from matplotlib.colors import to_rgba\n", "from torch import Tensor\n", "from tqdm.notebook import tqdm # Progress bar\n", "\n", "set_matplotlib_formats(\"svg\", \"pdf\")"]}, {"cell_type": "markdown", "id": "143e4d13", "metadata": {"papermill": {"duration": 0.014482, "end_time": "2022-05-12T11:44:42.506873", "exception": false, "start_time": "2022-05-12T11:44:42.492391", "status": "completed"}, "tags": []}, "source": ["## The Basics of PyTorch\n", "\n", "We will start with reviewing the very basic concepts of PyTorch.\n", "As a prerequisite, we recommend to be familiar with the `numpy` package as most machine learning frameworks are based on very similar concepts.\n", "If you are not familiar with numpy yet, don't worry: here is a [tutorial](https://numpy.org/devdocs/user/quickstart.html) to go through.\n", "\n", "So, let's start with importing PyTorch.\n", "The package is called `torch`, based on its original framework [Torch](http://torch.ch/).\n", "As a first step, we can check its version:"]}, {"cell_type": "code", "execution_count": 3, "id": "dad53a11", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:42.537659Z", "iopub.status.busy": "2022-05-12T11:44:42.537047Z", "iopub.status.idle": "2022-05-12T11:44:42.541912Z", "shell.execute_reply": "2022-05-12T11:44:42.541104Z"}, "papermill": {"duration": 0.021328, "end_time": "2022-05-12T11:44:42.543502", "exception": false, "start_time": "2022-05-12T11:44:42.522174", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Using torch 1.9.1+cu111\n"]}], "source": ["print(\"Using torch\", torch.__version__)"]}, {"cell_type": "markdown", "id": "55e54b51", "metadata": {"papermill": {"duration": 0.013161, "end_time": "2022-05-12T11:44:42.570309", "exception": false, "start_time": "2022-05-12T11:44:42.557148", "status": "completed"}, "tags": []}, "source": ["At the time of writing this tutorial (mid of August 2021), the current stable version is 1.9.\n", "You should therefore see the output `Using torch 1.9.0`, eventually with some extension for the CUDA version on Colab.\n", "In case you use the `dl2020` environment, you should see `Using torch 1.6.0` since the environment was provided in October 2020.\n", "It is recommended to update the PyTorch version to the newest one.\n", "If you see a lower version number than 1.6, make sure you have installed the correct the environment, or ask one of your TAs.\n", "In case PyTorch 1.10 or newer will be published during the time of the course, don't worry.\n", "The interface between PyTorch versions doesn't change too much, and hence all code should also be runnable with newer versions.\n", "\n", "As in every machine learning framework, PyTorch provides functions that are stochastic like generating random numbers.\n", "However, a very good practice is to setup your code to be reproducible with the exact same random numbers.\n", "This is why we set a seed below."]}, {"cell_type": "code", "execution_count": 4, "id": "21cefb24", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:42.597792Z", "iopub.status.busy": "2022-05-12T11:44:42.597390Z", "iopub.status.idle": "2022-05-12T11:44:42.605393Z", "shell.execute_reply": "2022-05-12T11:44:42.604675Z"}, "papermill": {"duration": 0.023511, "end_time": "2022-05-12T11:44:42.606931", "exception": false, "start_time": "2022-05-12T11:44:42.583420", "status": "completed"}, "tags": []}, "outputs": [{"data": {"text/plain": ["<torch._C.Generator at 0x7fb4ad211bb0>"]}, "execution_count": 4, "metadata": {}, "output_type": "execute_result"}], "source": ["torch.manual_seed(42) # Setting the seed"]}, {"cell_type": "markdown", "id": "b3ada93e", "metadata": {"papermill": {"duration": 0.013357, "end_time": "2022-05-12T11:44:42.636349", "exception": false, "start_time": "2022-05-12T11:44:42.622992", "status": "completed"}, "tags": []}, "source": ["### Tensors\n", "\n", "Tensors are the PyTorch equivalent to Numpy arrays, with the addition to also have support for GPU acceleration (more on that later).\n", "The name \"tensor\" is a generalization of concepts you already know.\n", "For instance, a vector is a 1-D tensor, and a matrix a 2-D tensor.\n", "When working with neural networks, we will use tensors of various shapes and number of dimensions.\n", "\n", "Most common functions you know from numpy can be used on tensors as well.\n", "Actually, since numpy arrays are so similar to tensors, we can convert most tensors to numpy arrays (and back) but we don't need it too often.\n", "\n", "#### Initialization\n", "\n", "Let's first start by looking at different ways of creating a tensor.\n", "There are many possible options, the most simple one is to call\n", "`Tensor` passing the desired shape as input argument:"]}, {"cell_type": "code", "execution_count": 5, "id": "2be50059", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:42.664914Z", "iopub.status.busy": "2022-05-12T11:44:42.664452Z", "iopub.status.idle": "2022-05-12T11:44:42.670092Z", "shell.execute_reply": "2022-05-12T11:44:42.669442Z"}, "papermill": {"duration": 0.021794, "end_time": "2022-05-12T11:44:42.671546", "exception": false, "start_time": "2022-05-12T11:44:42.649752", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["tensor([[[0., 0., 0., 0.],\n", " [0., 0., 0., 0.],\n", " [0., 0., 0., 0.]],\n", "\n", " [[0., 0., 0., 0.],\n", " [0., 0., 0., 0.],\n", " [0., 0., 0., 0.]]])\n"]}], "source": ["x = Tensor(2, 3, 4)\n", "print(x)"]}, {"cell_type": "markdown", "id": "b0ddbeb7", "metadata": {"papermill": {"duration": 0.013462, "end_time": "2022-05-12T11:44:42.698184", "exception": false, "start_time": "2022-05-12T11:44:42.684722", "status": "completed"}, "tags": []}, "source": ["The function `torch.Tensor` allocates memory for the desired tensor, but reuses any values that have already been in the memory.\n", "To directly assign values to the tensor during initialization, there are many alternatives including:\n", "\n", "* `torch.zeros`: Creates a tensor filled with zeros\n", "* `torch.ones`: Creates a tensor filled with ones\n", "* `torch.rand`: Creates a tensor with random values uniformly sampled between 0 and 1\n", "* `torch.randn`: Creates a tensor with random values sampled from a normal distribution with mean 0 and variance 1\n", "* `torch.arange`: Creates a tensor containing the values $N,N+1,N+2,...,M$\n", "* `torch.Tensor` (input list): Creates a tensor from the list elements you provide"]}, {"cell_type": "code", "execution_count": 6, "id": "d528be70", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:42.726996Z", "iopub.status.busy": "2022-05-12T11:44:42.726520Z", "iopub.status.idle": "2022-05-12T11:44:42.732222Z", "shell.execute_reply": "2022-05-12T11:44:42.731593Z"}, "papermill": {"duration": 0.021733, "end_time": "2022-05-12T11:44:42.733791", "exception": false, "start_time": "2022-05-12T11:44:42.712058", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["tensor([[1., 2.],\n", " [3., 4.]])\n"]}], "source": ["# Create a tensor from a (nested) list\n", "x = Tensor([[1, 2], [3, 4]])\n", "print(x)"]}, {"cell_type": "code", "execution_count": 7, "id": "0800b194", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:42.818669Z", "iopub.status.busy": "2022-05-12T11:44:42.818195Z", "iopub.status.idle": "2022-05-12T11:44:42.823484Z", "shell.execute_reply": "2022-05-12T11:44:42.822851Z"}, "papermill": {"duration": 0.077338, "end_time": "2022-05-12T11:44:42.824950", "exception": false, "start_time": "2022-05-12T11:44:42.747612", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["tensor([[[0.8823, 0.9150, 0.3829, 0.9593],\n", " [0.3904, 0.6009, 0.2566, 0.7936],\n", " [0.9408, 0.1332, 0.9346, 0.5936]],\n", "\n", " [[0.8694, 0.5677, 0.7411, 0.4294],\n", " [0.8854, 0.5739, 0.2666, 0.6274],\n", " [0.2696, 0.4414, 0.2969, 0.8317]]])\n"]}], "source": ["# Create a tensor with random values between 0 and 1 with the shape [2, 3, 4]\n", "x = torch.rand(2, 3, 4)\n", "print(x)"]}, {"cell_type": "markdown", "id": "bc8a4637", "metadata": {"papermill": {"duration": 0.013136, "end_time": "2022-05-12T11:44:42.851415", "exception": false, "start_time": "2022-05-12T11:44:42.838279", "status": "completed"}, "tags": []}, "source": ["You can obtain the shape of a tensor in the same way as in numpy (`x.shape`), or using the `.size` method:"]}, {"cell_type": "code", "execution_count": 8, "id": "c08ce24f", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:42.879359Z", "iopub.status.busy": "2022-05-12T11:44:42.878881Z", "iopub.status.idle": "2022-05-12T11:44:42.883409Z", "shell.execute_reply": "2022-05-12T11:44:42.882772Z"}, "papermill": {"duration": 0.020086, "end_time": "2022-05-12T11:44:42.884919", "exception": false, "start_time": "2022-05-12T11:44:42.864833", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Shape: torch.Size([2, 3, 4])\n", "Size: torch.Size([2, 3, 4])\n", "Size: 2 3 4\n"]}], "source": ["shape = x.shape\n", "print(\"Shape:\", x.shape)\n", "\n", "size = x.size()\n", "print(\"Size:\", size)\n", "\n", "dim1, dim2, dim3 = x.size()\n", "print(\"Size:\", dim1, dim2, dim3)"]}, {"cell_type": "markdown", "id": "2248de2f", "metadata": {"papermill": {"duration": 0.014217, "end_time": "2022-05-12T11:44:42.912998", "exception": false, "start_time": "2022-05-12T11:44:42.898781", "status": "completed"}, "tags": []}, "source": ["#### Tensor to Numpy, and Numpy to Tensor\n", "\n", "Tensors can be converted to numpy arrays, and numpy arrays back to tensors.\n", "To transform a numpy array into a tensor, we can use the function `torch.from_numpy`:"]}, {"cell_type": "code", "execution_count": 9, "id": "0f793dea", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:42.943181Z", "iopub.status.busy": "2022-05-12T11:44:42.942778Z", "iopub.status.idle": "2022-05-12T11:44:42.951031Z", "shell.execute_reply": "2022-05-12T11:44:42.950325Z"}, "papermill": {"duration": 0.029636, "end_time": "2022-05-12T11:44:42.956756", "exception": false, "start_time": "2022-05-12T11:44:42.927120", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Numpy array: [[1 2]\n", " [3 4]]\n", "PyTorch tensor: tensor([[1, 2],\n", " [3, 4]])\n"]}], "source": ["np_arr = np.array([[1, 2], [3, 4]])\n", "tensor = torch.from_numpy(np_arr)\n", "\n", "print(\"Numpy array:\", np_arr)\n", "print(\"PyTorch tensor:\", tensor)"]}, {"cell_type": "markdown", "id": "9f3eaaed", "metadata": {"papermill": {"duration": 0.015573, "end_time": "2022-05-12T11:44:42.988099", "exception": false, "start_time": "2022-05-12T11:44:42.972526", "status": "completed"}, "tags": []}, "source": ["To transform a PyTorch tensor back to a numpy array, we can use the function `.numpy()` on tensors:"]}, {"cell_type": "code", "execution_count": 10, "id": "f932b2ff", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:43.231810Z", "iopub.status.busy": "2022-05-12T11:44:43.231309Z", "iopub.status.idle": "2022-05-12T11:44:43.236712Z", "shell.execute_reply": "2022-05-12T11:44:43.235987Z"}, "papermill": {"duration": 0.024113, "end_time": "2022-05-12T11:44:43.238239", "exception": false, "start_time": "2022-05-12T11:44:43.214126", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["PyTorch tensor: tensor([0, 1, 2, 3])\n", "Numpy array: [0 1 2 3]\n"]}], "source": ["tensor = torch.arange(4)\n", "np_arr = tensor.numpy()\n", "\n", "print(\"PyTorch tensor:\", tensor)\n", "print(\"Numpy array:\", np_arr)"]}, {"cell_type": "markdown", "id": "e588c9b9", "metadata": {"papermill": {"duration": 0.018991, "end_time": "2022-05-12T11:44:43.272768", "exception": false, "start_time": "2022-05-12T11:44:43.253777", "status": "completed"}, "tags": []}, "source": ["The conversion of tensors to numpy require the tensor to be on the CPU, and not the GPU (more on GPU support in a later section).\n", "In case you have a tensor on GPU, you need to call `.cpu()` on the tensor beforehand.\n", "Hence, you get a line like `np_arr = tensor.cpu().numpy()`."]}, {"cell_type": "markdown", "id": "53ea3099", "metadata": {"papermill": {"duration": 0.014022, "end_time": "2022-05-12T11:44:43.302434", "exception": false, "start_time": "2022-05-12T11:44:43.288412", "status": "completed"}, "tags": []}, "source": ["#### Operations\n", "\n", "Most operations that exist in numpy, also exist in PyTorch.\n", "A full list of operations can be found in the [PyTorch documentation](https://pytorch.org/docs/stable/tensors.html#), but we will review the most important ones here.\n", "\n", "The simplest operation is to add two tensors:"]}, {"cell_type": "code", "execution_count": 11, "id": "fca47eaf", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:43.332059Z", "iopub.status.busy": "2022-05-12T11:44:43.331589Z", "iopub.status.idle": "2022-05-12T11:44:43.338013Z", "shell.execute_reply": "2022-05-12T11:44:43.337379Z"}, "papermill": {"duration": 0.022745, "end_time": "2022-05-12T11:44:43.339453", "exception": false, "start_time": "2022-05-12T11:44:43.316708", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["X1 tensor([[0.1053, 0.2695, 0.3588],\n", " [0.1994, 0.5472, 0.0062]])\n", "X2 tensor([[0.9516, 0.0753, 0.8860],\n", " [0.5832, 0.3376, 0.8090]])\n", "Y tensor([[1.0569, 0.3448, 1.2448],\n", " [0.7826, 0.8848, 0.8151]])\n"]}], "source": ["x1 = torch.rand(2, 3)\n", "x2 = torch.rand(2, 3)\n", "y = x1 + x2\n", "\n", "print(\"X1\", x1)\n", "print(\"X2\", x2)\n", "print(\"Y\", y)"]}, {"cell_type": "markdown", "id": "eb46a086", "metadata": {"papermill": {"duration": 0.013609, "end_time": "2022-05-12T11:44:43.366661", "exception": false, "start_time": "2022-05-12T11:44:43.353052", "status": "completed"}, "tags": []}, "source": ["Calling `x1 + x2` creates a new tensor containing the sum of the two inputs.\n", "However, we can also use in-place operations that are applied directly on the memory of a tensor.\n", "We therefore change the values of `x2` without the chance to re-accessing the values of `x2` before the operation.\n", "An example is shown below:"]}, {"cell_type": "code", "execution_count": 12, "id": "8496e562", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:43.396084Z", "iopub.status.busy": "2022-05-12T11:44:43.395539Z", "iopub.status.idle": "2022-05-12T11:44:43.401342Z", "shell.execute_reply": "2022-05-12T11:44:43.400742Z"}, "papermill": {"duration": 0.022114, "end_time": "2022-05-12T11:44:43.402788", "exception": false, "start_time": "2022-05-12T11:44:43.380674", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["X1 (before) tensor([[0.5779, 0.9040, 0.5547],\n", " [0.3423, 0.6343, 0.3644]])\n", "X2 (before) tensor([[0.7104, 0.9464, 0.7890],\n", " [0.2814, 0.7886, 0.5895]])\n", "X1 (after) tensor([[0.5779, 0.9040, 0.5547],\n", " [0.3423, 0.6343, 0.3644]])\n", "X2 (after) tensor([[1.2884, 1.8504, 1.3437],\n", " [0.6237, 1.4230, 0.9539]])\n"]}], "source": ["x1 = torch.rand(2, 3)\n", "x2 = torch.rand(2, 3)\n", "print(\"X1 (before)\", x1)\n", "print(\"X2 (before)\", x2)\n", "\n", "x2.add_(x1)\n", "print(\"X1 (after)\", x1)\n", "print(\"X2 (after)\", x2)"]}, {"cell_type": "markdown", "id": "4f5f0f56", "metadata": {"papermill": {"duration": 0.013919, "end_time": "2022-05-12T11:44:43.431216", "exception": false, "start_time": "2022-05-12T11:44:43.417297", "status": "completed"}, "tags": []}, "source": ["In-place operations are usually marked with a underscore postfix (e.g. \"add_\" instead of \"add\").\n", "\n", "Another common operation aims at changing the shape of a tensor.\n", "A tensor of size (2,3) can be re-organized to any other shape with the same number of elements (e.g. a tensor of size (6), or (3,2), ...).\n", "In PyTorch, this operation is called `view`:"]}, {"cell_type": "code", "execution_count": 13, "id": "9b3ac08b", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:43.460577Z", "iopub.status.busy": "2022-05-12T11:44:43.460120Z", "iopub.status.idle": "2022-05-12T11:44:43.464918Z", "shell.execute_reply": "2022-05-12T11:44:43.464266Z"}, "papermill": {"duration": 0.02132, "end_time": "2022-05-12T11:44:43.466401", "exception": false, "start_time": "2022-05-12T11:44:43.445081", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["X tensor([0, 1, 2, 3, 4, 5])\n"]}], "source": ["x = torch.arange(6)\n", "print(\"X\", x)"]}, {"cell_type": "code", "execution_count": 14, "id": "2173c9df", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:43.495922Z", "iopub.status.busy": "2022-05-12T11:44:43.495226Z", "iopub.status.idle": "2022-05-12T11:44:43.499475Z", "shell.execute_reply": "2022-05-12T11:44:43.498878Z"}, "papermill": {"duration": 0.020745, "end_time": "2022-05-12T11:44:43.500948", "exception": false, "start_time": "2022-05-12T11:44:43.480203", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["X tensor([[0, 1, 2],\n", " [3, 4, 5]])\n"]}], "source": ["x = x.view(2, 3)\n", "print(\"X\", x)"]}, {"cell_type": "code", "execution_count": 15, "id": "caaa18cd", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:43.532678Z", "iopub.status.busy": "2022-05-12T11:44:43.532245Z", "iopub.status.idle": "2022-05-12T11:44:43.536940Z", "shell.execute_reply": "2022-05-12T11:44:43.536322Z"}, "papermill": {"duration": 0.022162, "end_time": "2022-05-12T11:44:43.538426", "exception": false, "start_time": "2022-05-12T11:44:43.516264", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["X tensor([[0, 3],\n", " [1, 4],\n", " [2, 5]])\n"]}], "source": ["x = x.permute(1, 0) # Swapping dimension 0 and 1\n", "print(\"X\", x)"]}, {"cell_type": "markdown", "id": "17a00cb6", "metadata": {"papermill": {"duration": 0.013934, "end_time": "2022-05-12T11:44:43.567241", "exception": false, "start_time": "2022-05-12T11:44:43.553307", "status": "completed"}, "tags": []}, "source": ["Other commonly used operations include matrix multiplications, which are essential for neural networks.\n", "Quite often, we have an input vector $\\mathbf{x}$, which is transformed using a learned weight matrix $\\mathbf{W}$.\n", "There are multiple ways and functions to perform matrix multiplication, some of which we list below:\n", "\n", "* `torch.matmul`: Performs the matrix product over two tensors, where the specific behavior depends on the dimensions.\n", "If both inputs are matrices (2-dimensional tensors), it performs the standard matrix product.\n", "For higher dimensional inputs, the function supports broadcasting (for details see the [documentation](https://pytorch.org/docs/stable/generated/torch.matmul.html?highlight=matmul#torch.matmul)).\n", "Can also be written as `a @ b`, similar to numpy.\n", "* `torch.mm`: Performs the matrix product over two matrices, but doesn't support broadcasting (see [documentation](https://pytorch.org/docs/stable/generated/torch.mm.html?highlight=torch%20mm#torch.mm))\n", "* `torch.bmm`: Performs the matrix product with a support batch dimension.\n", "If the first tensor $T$ is of shape ($b\\times n\\times m$), and the second tensor $R$ ($b\\times m\\times p$), the output $O$ is of shape ($b\\times n\\times p$), and has been calculated by performing $b$ matrix multiplications of the submatrices of $T$ and $R$: $O_i = T_i @ R_i$\n", "* `torch.einsum`: Performs matrix multiplications and more (i.e. sums of products) using the Einstein summation convention.\n", "Explanation of the Einstein sum can be found in assignment 1.\n", "\n", "Usually, we use `torch.matmul` or `torch.bmm`. We can try a matrix multiplication with `torch.matmul` below."]}, {"cell_type": "code", "execution_count": 16, "id": "bf796dd8", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:43.597623Z", "iopub.status.busy": "2022-05-12T11:44:43.596975Z", "iopub.status.idle": "2022-05-12T11:44:43.601290Z", "shell.execute_reply": "2022-05-12T11:44:43.600686Z"}, "papermill": {"duration": 0.021306, "end_time": "2022-05-12T11:44:43.602763", "exception": false, "start_time": "2022-05-12T11:44:43.581457", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["X tensor([[0, 1, 2],\n", " [3, 4, 5]])\n"]}], "source": ["x = torch.arange(6)\n", "x = x.view(2, 3)\n", "print(\"X\", x)"]}, {"cell_type": "code", "execution_count": 17, "id": "4a3c5860", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:43.633059Z", "iopub.status.busy": "2022-05-12T11:44:43.632454Z", "iopub.status.idle": "2022-05-12T11:44:43.636641Z", "shell.execute_reply": "2022-05-12T11:44:43.636038Z"}, "papermill": {"duration": 0.02075, "end_time": "2022-05-12T11:44:43.638108", "exception": false, "start_time": "2022-05-12T11:44:43.617358", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["W tensor([[0, 1, 2],\n", " [3, 4, 5],\n", " [6, 7, 8]])\n"]}], "source": ["W = torch.arange(9).view(3, 3) # We can also stack multiple operations in a single line\n", "print(\"W\", W)"]}, {"cell_type": "code", "execution_count": 18, "id": "57d7a44e", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:43.667560Z", "iopub.status.busy": "2022-05-12T11:44:43.666897Z", "iopub.status.idle": "2022-05-12T11:44:43.671035Z", "shell.execute_reply": "2022-05-12T11:44:43.670402Z"}, "papermill": {"duration": 0.020378, "end_time": "2022-05-12T11:44:43.672489", "exception": false, "start_time": "2022-05-12T11:44:43.652111", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["h tensor([[15, 18, 21],\n", " [42, 54, 66]])\n"]}], "source": ["h = torch.matmul(x, W) # Verify the result by calculating it by hand too!\n", "print(\"h\", h)"]}, {"cell_type": "markdown", "id": "2c4e5903", "metadata": {"papermill": {"duration": 0.015597, "end_time": "2022-05-12T11:44:43.702284", "exception": false, "start_time": "2022-05-12T11:44:43.686687", "status": "completed"}, "tags": []}, "source": ["#### Indexing\n", "\n", "We often have the situation where we need to select a part of a tensor.\n", "Indexing works just like in numpy, so let's try it:"]}, {"cell_type": "code", "execution_count": 19, "id": "18f66333", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:43.738600Z", "iopub.status.busy": "2022-05-12T11:44:43.738130Z", "iopub.status.idle": "2022-05-12T11:44:43.743026Z", "shell.execute_reply": "2022-05-12T11:44:43.742313Z"}, "papermill": {"duration": 0.026422, "end_time": "2022-05-12T11:44:43.744557", "exception": false, "start_time": "2022-05-12T11:44:43.718135", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["X tensor([[ 0, 1, 2, 3],\n", " [ 4, 5, 6, 7],\n", " [ 8, 9, 10, 11]])\n"]}], "source": ["x = torch.arange(12).view(3, 4)\n", "print(\"X\", x)"]}, {"cell_type": "code", "execution_count": 20, "id": "9362fd98", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:43.779615Z", "iopub.status.busy": "2022-05-12T11:44:43.779145Z", "iopub.status.idle": "2022-05-12T11:44:43.784104Z", "shell.execute_reply": "2022-05-12T11:44:43.783420Z"}, "papermill": {"duration": 0.024702, "end_time": "2022-05-12T11:44:43.785719", "exception": false, "start_time": "2022-05-12T11:44:43.761017", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["tensor([1, 5, 9])\n"]}], "source": ["print(x[:, 1]) # Second column"]}, {"cell_type": "code", "execution_count": 21, "id": "80f1b1d7", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:43.822416Z", "iopub.status.busy": "2022-05-12T11:44:43.821938Z", "iopub.status.idle": "2022-05-12T11:44:43.826643Z", "shell.execute_reply": "2022-05-12T11:44:43.825945Z"}, "papermill": {"duration": 0.025265, "end_time": "2022-05-12T11:44:43.828237", "exception": false, "start_time": "2022-05-12T11:44:43.802972", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["tensor([0, 1, 2, 3])\n"]}], "source": ["print(x[0]) # First row"]}, {"cell_type": "code", "execution_count": 22, "id": "20db07b5", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:43.862122Z", "iopub.status.busy": "2022-05-12T11:44:43.861614Z", "iopub.status.idle": "2022-05-12T11:44:43.866678Z", "shell.execute_reply": "2022-05-12T11:44:43.865756Z"}, "papermill": {"duration": 0.024299, "end_time": "2022-05-12T11:44:43.868250", "exception": false, "start_time": "2022-05-12T11:44:43.843951", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["tensor([3, 7])\n"]}], "source": ["print(x[:2, -1]) # First two rows, last column"]}, {"cell_type": "code", "execution_count": 23, "id": "8a62424a", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:43.902294Z", "iopub.status.busy": "2022-05-12T11:44:43.901812Z", "iopub.status.idle": "2022-05-12T11:44:43.906694Z", "shell.execute_reply": "2022-05-12T11:44:43.905919Z"}, "papermill": {"duration": 0.024362, "end_time": "2022-05-12T11:44:43.908338", "exception": false, "start_time": "2022-05-12T11:44:43.883976", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["tensor([[ 4, 5, 6, 7],\n", " [ 8, 9, 10, 11]])\n"]}], "source": ["print(x[1:3, :]) # Middle two rows"]}, {"cell_type": "markdown", "id": "f40fbcaf", "metadata": {"papermill": {"duration": 0.016539, "end_time": "2022-05-12T11:44:43.941488", "exception": false, "start_time": "2022-05-12T11:44:43.924949", "status": "completed"}, "tags": []}, "source": ["### Dynamic Computation Graph and Backpropagation\n", "\n", "One of the main reasons for using PyTorch in Deep Learning projects is that we can automatically get **gradients/derivatives** of functions that we define.\n", "We will mainly use PyTorch for implementing neural networks, and they are just fancy functions.\n", "If we use weight matrices in our function that we want to learn, then those are called the **parameters** or simply the **weights**.\n", "\n", "If our neural network would output a single scalar value, we would talk about taking the **derivative**, but you will see that quite often we will have **multiple** output variables (\"values\"); in that case we talk about **gradients**.\n", "It's a more general term.\n", "\n", "Given an input $\\mathbf{x}$, we define our function by **manipulating** that input, usually by matrix-multiplications with weight matrices and additions with so-called bias vectors.\n", "As we manipulate our input, we are automatically creating a **computational graph**.\n", "This graph shows how to arrive at our output from our input.\n", "PyTorch is a **define-by-run** framework; this means that we can just do our manipulations, and PyTorch will keep track of that graph for us.\n", "Thus, we create a dynamic computation graph along the way.\n", "\n", "So, to recap: the only thing we have to do is to compute the **output**, and then we can ask PyTorch to automatically get the **gradients**.\n", "\n", "> **Note: Why do we want gradients?\n", "** Consider that we have defined a function, a neural net, that is supposed to compute a certain output $y$ for an input vector $\\mathbf{x}$.\n", "We then define an **error measure** that tells us how wrong our network is; how bad it is in predicting output $y$ from input $\\mathbf{x}$.\n", "Based on this error measure, we can use the gradients to **update** the weights $\\mathbf{W}$ that were responsible for the output, so that the next time we present input $\\mathbf{x}$ to our network, the output will be closer to what we want.\n", "\n", "The first thing we have to do is to specify which tensors require gradients.\n", "By default, when we create a tensor, it does not require gradients."]}, {"cell_type": "code", "execution_count": 24, "id": "dd88cfab", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:43.976222Z", "iopub.status.busy": "2022-05-12T11:44:43.975387Z", "iopub.status.idle": "2022-05-12T11:44:43.980297Z", "shell.execute_reply": "2022-05-12T11:44:43.979620Z"}, "papermill": {"duration": 0.023995, "end_time": "2022-05-12T11:44:43.981820", "exception": false, "start_time": "2022-05-12T11:44:43.957825", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["False\n"]}], "source": ["x = torch.ones((3,))\n", "print(x.requires_grad)"]}, {"cell_type": "markdown", "id": "74ee330b", "metadata": {"papermill": {"duration": 0.01619, "end_time": "2022-05-12T11:44:44.014287", "exception": false, "start_time": "2022-05-12T11:44:43.998097", "status": "completed"}, "tags": []}, "source": ["We can change this for an existing tensor using the function `requires_grad_()` (underscore indicating that this is a in-place operation).\n", "Alternatively, when creating a tensor, you can pass the argument\n", "`requires_grad=True` to most initializers we have seen above."]}, {"cell_type": "code", "execution_count": 25, "id": "9d41429e", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:44.048210Z", "iopub.status.busy": "2022-05-12T11:44:44.047474Z", "iopub.status.idle": "2022-05-12T11:44:44.051628Z", "shell.execute_reply": "2022-05-12T11:44:44.051028Z"}, "papermill": {"duration": 0.022814, "end_time": "2022-05-12T11:44:44.053080", "exception": false, "start_time": "2022-05-12T11:44:44.030266", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["True\n"]}], "source": ["x.requires_grad_(True)\n", "print(x.requires_grad)"]}, {"cell_type": "markdown", "id": "1606e7cf", "metadata": {"papermill": {"duration": 0.01569, "end_time": "2022-05-12T11:44:44.085749", "exception": false, "start_time": "2022-05-12T11:44:44.070059", "status": "completed"}, "tags": []}, "source": ["In order to get familiar with the concept of a computation graph, we will create one for the following function:\n", "\n", "$$y = \\frac{1}{|x|}\\sum_i \\left[(x_i + 2)^2 + 3\\right]$$\n", "\n", "You could imagine that $x$ are our parameters, and we want to optimize (either maximize or minimize) the output $y$.\n", "For this, we want to obtain the gradients $\\partial y / \\partial \\mathbf{x}$.\n", "For our example, we'll use $\\mathbf{x}=[0,1,2]$ as our input."]}, {"cell_type": "code", "execution_count": 26, "id": "adeab680", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:44.119279Z", "iopub.status.busy": "2022-05-12T11:44:44.118813Z", "iopub.status.idle": "2022-05-12T11:44:44.123920Z", "shell.execute_reply": "2022-05-12T11:44:44.123288Z"}, "papermill": {"duration": 0.024177, "end_time": "2022-05-12T11:44:44.125380", "exception": false, "start_time": "2022-05-12T11:44:44.101203", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["X tensor([0., 1., 2.], requires_grad=True)\n"]}], "source": ["x = torch.arange(3, dtype=torch.float32, requires_grad=True) # Only float tensors can have gradients\n", "print(\"X\", x)"]}, {"cell_type": "markdown", "id": "296441b8", "metadata": {"papermill": {"duration": 0.016221, "end_time": "2022-05-12T11:44:44.157486", "exception": false, "start_time": "2022-05-12T11:44:44.141265", "status": "completed"}, "tags": []}, "source": ["Now let's build the computation graph step by step.\n", "You can combine multiple operations in a single line, but we will\n", "separate them here to get a better understanding of how each operation\n", "is added to the computation graph."]}, {"cell_type": "code", "execution_count": 27, "id": "4168dae9", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:44.190122Z", "iopub.status.busy": "2022-05-12T11:44:44.189636Z", "iopub.status.idle": "2022-05-12T11:44:44.195332Z", "shell.execute_reply": "2022-05-12T11:44:44.194690Z"}, "papermill": {"duration": 0.023786, "end_time": "2022-05-12T11:44:44.196788", "exception": false, "start_time": "2022-05-12T11:44:44.173002", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Y tensor(12.6667, grad_fn=<MeanBackward0>)\n"]}], "source": ["a = x + 2\n", "b = a**2\n", "c = b + 3\n", "y = c.mean()\n", "print(\"Y\", y)"]}, {"cell_type": "markdown", "id": "2dfedf84", "metadata": {"papermill": {"duration": 0.014832, "end_time": "2022-05-12T11:44:44.227271", "exception": false, "start_time": "2022-05-12T11:44:44.212439", "status": "completed"}, "tags": []}, "source": ["Using the statements above, we have created a computation graph that looks similar to the figure below:\n", "\n", "<center style=\"width: 100%\"><img src=\"https://github.com/PyTorchLightning/lightning-tutorials/raw/main/course_UvA-DL/01-introduction-to-pytorch/pytorch_computation_graph.svg\" width=\"200px\"></center>\n", "\n", "We calculate $a$ based on the inputs $x$ and the constant $2$, $b$ is $a$ squared, and so on.\n", "The visualization is an abstraction of the dependencies between inputs and outputs of the operations we have applied.\n", "Each node of the computation graph has automatically defined a function for calculating the gradients with respect to its inputs, `grad_fn`.\n", "You can see this when we printed the output tensor $y$.\n", "This is why the computation graph is usually visualized in the reverse direction (arrows point from the result to the inputs).\n", "We can perform backpropagation on the computation graph by calling the\n", "function `backward()` on the last output, which effectively calculates\n", "the gradients for each tensor that has the property\n", "`requires_grad=True`:"]}, {"cell_type": "code", "execution_count": 28, "id": "ea065b9c", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:44.259558Z", "iopub.status.busy": "2022-05-12T11:44:44.258818Z", "iopub.status.idle": "2022-05-12T11:44:44.486699Z", "shell.execute_reply": "2022-05-12T11:44:44.485840Z"}, "papermill": {"duration": 0.246256, "end_time": "2022-05-12T11:44:44.488899", "exception": false, "start_time": "2022-05-12T11:44:44.242643", "status": "completed"}, "tags": []}, "outputs": [], "source": ["y.backward()"]}, {"cell_type": "markdown", "id": "f781096d", "metadata": {"papermill": {"duration": 0.016452, "end_time": "2022-05-12T11:44:44.521994", "exception": false, "start_time": "2022-05-12T11:44:44.505542", "status": "completed"}, "tags": []}, "source": ["`x.grad` will now contain the gradient $\\partial y/ \\partial \\mathcal{x}$, and this gradient indicates how a change in $\\mathbf{x}$ will affect output $y$ given the current input $\\mathbf{x}=[0,1,2]$:"]}, {"cell_type": "code", "execution_count": 29, "id": "ec71974f", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:44.554342Z", "iopub.status.busy": "2022-05-12T11:44:44.553873Z", "iopub.status.idle": "2022-05-12T11:44:44.558586Z", "shell.execute_reply": "2022-05-12T11:44:44.557949Z"}, "papermill": {"duration": 0.023002, "end_time": "2022-05-12T11:44:44.560048", "exception": false, "start_time": "2022-05-12T11:44:44.537046", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["tensor([1.3333, 2.0000, 2.6667])\n"]}], "source": ["print(x.grad)"]}, {"cell_type": "markdown", "id": "2ec556f7", "metadata": {"papermill": {"duration": 0.014871, "end_time": "2022-05-12T11:44:44.590264", "exception": false, "start_time": "2022-05-12T11:44:44.575393", "status": "completed"}, "tags": []}, "source": ["We can also verify these gradients by hand.\n", "We will calculate the gradients using the chain rule, in the same way as PyTorch did it:\n", "\n", "$$\\frac{\\partial y}{\\partial x_i} = \\frac{\\partial y}{\\partial c_i}\\frac{\\partial c_i}{\\partial b_i}\\frac{\\partial b_i}{\\partial a_i}\\frac{\\partial a_i}{\\partial x_i}$$\n", "\n", "Note that we have simplified this equation to index notation, and by using the fact that all operation besides the mean do not combine the elements in the tensor.\n", "The partial derivatives are:\n", "\n", "$$\n", "\\frac{\\partial a_i}{\\partial x_i} = 1,\\hspace{1cm}\n", "\\frac{\\partial b_i}{\\partial a_i} = 2\\cdot a_i\\hspace{1cm}\n", "\\frac{\\partial c_i}{\\partial b_i} = 1\\hspace{1cm}\n", "\\frac{\\partial y}{\\partial c_i} = \\frac{1}{3}\n", "$$\n", "\n", "Hence, with the input being $\\mathbf{x}=[0,1,2]$, our gradients are $\\partial y/\\partial \\mathbf{x}=[4/3,2,8/3]$.\n", "The previous code cell should have printed the same result."]}, {"cell_type": "markdown", "id": "b892340e", "metadata": {"papermill": {"duration": 0.015493, "end_time": "2022-05-12T11:44:44.620504", "exception": false, "start_time": "2022-05-12T11:44:44.605011", "status": "completed"}, "tags": []}, "source": ["### GPU support\n", "\n", "A crucial feature of PyTorch is the support of GPUs, short for Graphics Processing Unit.\n", "A GPU can perform many thousands of small operations in parallel, making it very well suitable for performing large matrix operations in neural networks.\n", "When comparing GPUs to CPUs, we can list the following main differences (credit: [Kevin Krewell, 2009](https://blogs.nvidia.com/blog/2009/12/16/whats-the-difference-between-a-cpu-and-a-gpu/))\n", "\n", "<center style=\"width: 100%\"><img src=\"https://github.com/PyTorchLightning/lightning-tutorials/raw/main/course_UvA-DL/01-introduction-to-pytorch/comparison_CPU_GPU.png\" width=\"700px\"></center>\n", "\n", "CPUs and GPUs have both different advantages and disadvantages, which is why many computers contain both components and use them for different tasks.\n", "In case you are not familiar with GPUs, you can read up more details in this [NVIDIA blog post](https://blogs.nvidia.com/blog/2009/12/16/whats-the-difference-between-a-cpu-and-a-gpu/) or [here](https://www.intel.com/content/www/us/en/products/docs/processors/what-is-a-gpu.html).\n", "\n", "GPUs can accelerate the training of your network up to a factor of $100$ which is essential for large neural networks.\n", "PyTorch implements a lot of functionality for supporting GPUs (mostly those of NVIDIA due to the libraries [CUDA](https://developer.nvidia.com/cuda-zone) and [cuDNN](https://developer.nvidia.com/cudnn)).\n", "First, let's check whether you have a GPU available:"]}, {"cell_type": "code", "execution_count": 30, "id": "21ea39bf", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:44.655135Z", "iopub.status.busy": "2022-05-12T11:44:44.654691Z", "iopub.status.idle": "2022-05-12T11:44:44.659136Z", "shell.execute_reply": "2022-05-12T11:44:44.658501Z"}, "papermill": {"duration": 0.024744, "end_time": "2022-05-12T11:44:44.660738", "exception": false, "start_time": "2022-05-12T11:44:44.635994", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Is the GPU available? True\n"]}], "source": ["gpu_avail = torch.cuda.is_available()\n", "print(f\"Is the GPU available? {gpu_avail}\")"]}, {"cell_type": "markdown", "id": "4a7c8317", "metadata": {"papermill": {"duration": 0.015413, "end_time": "2022-05-12T11:44:44.693248", "exception": false, "start_time": "2022-05-12T11:44:44.677835", "status": "completed"}, "tags": []}, "source": ["If you have a GPU on your computer but the command above returns False, make sure you have the correct CUDA-version installed.\n", "The `dl2020` environment comes with the CUDA-toolkit 10.1, which is selected for the Lisa supercomputer.\n", "Please change it if necessary (CUDA 10.2 is currently common).\n", "On Google Colab, make sure that you have selected a GPU in your runtime setup (in the menu, check under `Runtime -> Change runtime type`).\n", "\n", "By default, all tensors you create are stored on the CPU.\n", "We can push a tensor to the GPU by using the function `.to(...)`, or `.cuda()`.\n", "However, it is often a good practice to define a `device` object in your code which points to the GPU if you have one, and otherwise to the CPU.\n", "Then, you can write your code with respect to this device object, and it allows you to run the same code on both a CPU-only system, and one with a GPU.\n", "Let's try it below.\n", "We can specify the device as follows:"]}, {"cell_type": "code", "execution_count": 31, "id": "89563f5d", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:44.725370Z", "iopub.status.busy": "2022-05-12T11:44:44.724934Z", "iopub.status.idle": "2022-05-12T11:44:44.729675Z", "shell.execute_reply": "2022-05-12T11:44:44.728986Z"}, "papermill": {"duration": 0.022765, "end_time": "2022-05-12T11:44:44.731227", "exception": false, "start_time": "2022-05-12T11:44:44.708462", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Device cuda\n"]}], "source": ["device = torch.device(\"cuda\") if torch.cuda.is_available() else torch.device(\"cpu\")\n", "print(\"Device\", device)"]}, {"cell_type": "markdown", "id": "0e4dd198", "metadata": {"papermill": {"duration": 0.015261, "end_time": "2022-05-12T11:44:44.761463", "exception": false, "start_time": "2022-05-12T11:44:44.746202", "status": "completed"}, "tags": []}, "source": ["Now let's create a tensor and push it to the device:"]}, {"cell_type": "code", "execution_count": 32, "id": "6cb1ce1a", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:44.794538Z", "iopub.status.busy": "2022-05-12T11:44:44.793969Z", "iopub.status.idle": "2022-05-12T11:44:48.969704Z", "shell.execute_reply": "2022-05-12T11:44:48.968974Z"}, "papermill": {"duration": 4.193858, "end_time": "2022-05-12T11:44:48.971327", "exception": false, "start_time": "2022-05-12T11:44:44.777469", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["X tensor([[0., 0., 0.],\n", " [0., 0., 0.]], device='cuda:0')\n"]}], "source": ["x = torch.zeros(2, 3)\n", "x = x.to(device)\n", "print(\"X\", x)"]}, {"cell_type": "markdown", "id": "1705debc", "metadata": {"papermill": {"duration": 0.015673, "end_time": "2022-05-12T11:44:49.004062", "exception": false, "start_time": "2022-05-12T11:44:48.988389", "status": "completed"}, "tags": []}, "source": ["In case you have a GPU, you should now see the attribute `device='cuda:0'` being printed next to your tensor.\n", "The zero next to cuda indicates that this is the zero-th GPU device on your computer.\n", "PyTorch also supports multi-GPU systems, but this you will only need once you have very big networks to train (if interested, see the [PyTorch documentation](https://pytorch.org/docs/stable/distributed.html#distributed-basics)).\n", "We can also compare the runtime of a large matrix multiplication on the CPU with a operation on the GPU:"]}, {"cell_type": "code", "execution_count": 33, "id": "172211b0", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:49.037810Z", "iopub.status.busy": "2022-05-12T11:44:49.037170Z", "iopub.status.idle": "2022-05-12T11:44:49.553368Z", "shell.execute_reply": "2022-05-12T11:44:49.552617Z"}, "papermill": {"duration": 0.535227, "end_time": "2022-05-12T11:44:49.554964", "exception": false, "start_time": "2022-05-12T11:44:49.019737", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["CPU time: 0.27849s\n", "GPU time: 0.02576s\n"]}], "source": ["x = torch.randn(5000, 5000)\n", "\n", "# CPU version\n", "start_time = time.time()\n", "_ = torch.matmul(x, x)\n", "end_time = time.time()\n", "print(f\"CPU time: {(end_time - start_time):6.5f}s\")\n", "\n", "# GPU version\n", "if torch.cuda.is_available():\n", " x = x.to(device)\n", " # CUDA is asynchronous, so we need to use different timing functions\n", " start = torch.cuda.Event(enable_timing=True)\n", " end = torch.cuda.Event(enable_timing=True)\n", " start.record()\n", " _ = torch.matmul(x, x)\n", " end.record()\n", " torch.cuda.synchronize() # Waits for everything to finish running on the GPU\n", " print(f\"GPU time: {0.001 * start.elapsed_time(end):6.5f}s\") # Milliseconds to seconds"]}, {"cell_type": "markdown", "id": "e4c10ef9", "metadata": {"papermill": {"duration": 0.015167, "end_time": "2022-05-12T11:44:49.586900", "exception": false, "start_time": "2022-05-12T11:44:49.571733", "status": "completed"}, "tags": []}, "source": ["Depending on the size of the operation and the CPU/GPU in your system, the speedup of this operation can be >50x.\n", "As `matmul` operations are very common in neural networks, we can already see the great benefit of training a NN on a GPU.\n", "The time estimate can be relatively noisy here because we haven't run it for multiple times.\n", "Feel free to extend this, but it also takes longer to run.\n", "\n", "When generating random numbers, the seed between CPU and GPU is not synchronized.\n", "Hence, we need to set the seed on the GPU separately to ensure a reproducible code.\n", "Note that due to different GPU architectures, running the same code on different GPUs does not guarantee the same random numbers.\n", "Still, we don't want that our code gives us a different output every time we run it on the exact same hardware.\n", "Hence, we also set the seed on the GPU:"]}, {"cell_type": "code", "execution_count": 34, "id": "f745f2bc", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:49.618735Z", "iopub.status.busy": "2022-05-12T11:44:49.618389Z", "iopub.status.idle": "2022-05-12T11:44:49.622500Z", "shell.execute_reply": "2022-05-12T11:44:49.621897Z"}, "papermill": {"duration": 0.021752, "end_time": "2022-05-12T11:44:49.623954", "exception": false, "start_time": "2022-05-12T11:44:49.602202", "status": "completed"}, "tags": []}, "outputs": [], "source": ["# GPU operations have a separate seed we also want to set\n", "if torch.cuda.is_available():\n", " torch.cuda.manual_seed(42)\n", " torch.cuda.manual_seed_all(42)\n", "\n", "# Additionally, some operations on a GPU are implemented stochastic for efficiency\n", "# We want to ensure that all operations are deterministic on GPU (if used) for reproducibility\n", "torch.backends.cudnn.determinstic = True\n", "torch.backends.cudnn.benchmark = False"]}, {"cell_type": "markdown", "id": "d9038634", "metadata": {"papermill": {"duration": 0.01524, "end_time": "2022-05-12T11:44:49.654657", "exception": false, "start_time": "2022-05-12T11:44:49.639417", "status": "completed"}, "tags": []}, "source": ["## Learning by example: Continuous XOR\n", "<div class=\"center-wrapper\"><div class=\"video-wrapper\"><iframe src=\"https://www.youtube.com/embed/schbjeU5X2g\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe></div></div>\n", "\n", "If we want to build a neural network in PyTorch, we could specify all our parameters (weight matrices, bias vectors) using `Tensors` (with `requires_grad=True`), ask PyTorch to calculate the gradients and then adjust the parameters.\n", "But things can quickly get cumbersome if we have a lot of parameters.\n", "In PyTorch, there is a package called `torch.nn` that makes building neural networks more convenient.\n", "\n", "We will introduce the libraries and all additional parts you might need to train a neural network in PyTorch, using a simple example classifier on a simple yet well known example: XOR.\n", "Given two binary inputs $x_1$ and $x_2$, the label to predict is $1$ if either $x_1$ or $x_2$ is $1$ while the other is $0$, or the label is $0$ in all other cases.\n", "The example became famous by the fact that a single neuron, i.e. a linear classifier, cannot learn this simple function.\n", "Hence, we will learn how to build a small neural network that can learn this function.\n", "To make it a little bit more interesting, we move the XOR into continuous space and introduce some gaussian noise on the binary inputs.\n", "Our desired separation of an XOR dataset could look as follows:\n", "\n", "<center style=\"width: 100%\"><img src=\"https://github.com/PyTorchLightning/lightning-tutorials/raw/main/course_UvA-DL/01-introduction-to-pytorch/continuous_xor.svg\" width=\"350px\"></center>"]}, {"cell_type": "markdown", "id": "7b98682a", "metadata": {"papermill": {"duration": 0.015126, "end_time": "2022-05-12T11:44:49.685122", "exception": false, "start_time": "2022-05-12T11:44:49.669996", "status": "completed"}, "tags": []}, "source": ["### The model\n", "\n", "The package `torch.nn` defines a series of useful classes like linear networks layers, activation functions, loss functions etc.\n", "A full list can be found [here](https://pytorch.org/docs/stable/nn.html).\n", "In case you need a certain network layer, check the documentation of the package first before writing the layer yourself as the package likely contains the code for it already.\n", "We import it below:"]}, {"cell_type": "code", "execution_count": null, "id": "86274fc9", "metadata": {"lines_to_next_cell": 0, "papermill": {"duration": 0.016012, "end_time": "2022-05-12T11:44:49.716603", "exception": false, "start_time": "2022-05-12T11:44:49.700591", "status": "completed"}, "tags": []}, "outputs": [], "source": []}, {"cell_type": "code", "execution_count": null, "id": "fcaac71f", "metadata": {"papermill": {"duration": 0.015533, "end_time": "2022-05-12T11:44:49.748472", "exception": false, "start_time": "2022-05-12T11:44:49.732939", "status": "completed"}, "tags": []}, "outputs": [], "source": []}, {"cell_type": "markdown", "id": "a09bee23", "metadata": {"papermill": {"duration": 0.015664, "end_time": "2022-05-12T11:44:49.779625", "exception": false, "start_time": "2022-05-12T11:44:49.763961", "status": "completed"}, "tags": []}, "source": ["Additionally to `torch.nn`, there is also `torch.nn.functional`.\n", "It contains functions that are used in network layers.\n", "This is in contrast to `torch.nn` which defines them as `nn.Modules` (more on it below), and `torch.nn` actually uses a lot of functionalities from `torch.nn.functional`.\n", "Hence, the functional package is useful in many situations, and so we import it as well here."]}, {"cell_type": "markdown", "id": "18363ce3", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.015687, "end_time": "2022-05-12T11:44:49.810866", "exception": false, "start_time": "2022-05-12T11:44:49.795179", "status": "completed"}, "tags": []}, "source": ["#### nn.Module\n", "\n", "In PyTorch, a neural network is built up out of modules.\n", "Modules can contain other modules, and a neural network is considered to be a module itself as well.\n", "The basic template of a module is as follows:"]}, {"cell_type": "code", "execution_count": 35, "id": "f1a9cc19", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:49.845870Z", "iopub.status.busy": "2022-05-12T11:44:49.845383Z", "iopub.status.idle": "2022-05-12T11:44:49.849782Z", "shell.execute_reply": "2022-05-12T11:44:49.849106Z"}, "lines_to_next_cell": 2, "papermill": {"duration": 0.024448, "end_time": "2022-05-12T11:44:49.851415", "exception": false, "start_time": "2022-05-12T11:44:49.826967", "status": "completed"}, "tags": []}, "outputs": [], "source": ["class MyModule(nn.Module):\n", " def __init__(self):\n", " super().__init__()\n", " # Some init for my module\n", "\n", " def forward(self, x):\n", " # Function for performing the calculation of the module.\n", " pass"]}, {"cell_type": "markdown", "id": "f99fed81", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.015329, "end_time": "2022-05-12T11:44:49.882236", "exception": false, "start_time": "2022-05-12T11:44:49.866907", "status": "completed"}, "tags": []}, "source": ["The forward function is where the computation of the module is taken place, and is executed when you call the module (`nn = MyModule(); nn(x)`).\n", "In the init function, we usually create the parameters of the module, using `nn.Parameter`, or defining other modules that are used in the forward function.\n", "The backward calculation is done automatically, but could be overwritten as well if wanted.\n", "\n", "#### Simple classifier\n", "We can now make use of the pre-defined modules in the `torch.nn` package, and define our own small neural network.\n", "We will use a minimal network with a input layer, one hidden layer with tanh as activation function, and a output layer.\n", "In other words, our networks should look something like this:\n", "\n", "<center width=\"100%\"><img src=\"https://github.com/PyTorchLightning/lightning-tutorials/raw/main/course_UvA-DL/01-introduction-to-pytorch/small_neural_network.svg\" width=\"300px\"></center>\n", "\n", "The input neurons are shown in blue, which represent the coordinates $x_1$ and $x_2$ of a data point.\n", "The hidden neurons including a tanh activation are shown in white, and the output neuron in red.\n", "In PyTorch, we can define this as follows:"]}, {"cell_type": "code", "execution_count": 36, "id": "8d35d753", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:49.915216Z", "iopub.status.busy": "2022-05-12T11:44:49.914630Z", "iopub.status.idle": "2022-05-12T11:44:49.919768Z", "shell.execute_reply": "2022-05-12T11:44:49.919067Z"}, "papermill": {"duration": 0.023908, "end_time": "2022-05-12T11:44:49.921442", "exception": false, "start_time": "2022-05-12T11:44:49.897534", "status": "completed"}, "tags": []}, "outputs": [], "source": ["class SimpleClassifier(nn.Module):\n", " def __init__(self, num_inputs, num_hidden, num_outputs):\n", " super().__init__()\n", " # Initialize the modules we need to build the network\n", " self.linear1 = nn.Linear(num_inputs, num_hidden)\n", " self.act_fn = nn.Tanh()\n", " self.linear2 = nn.Linear(num_hidden, num_outputs)\n", "\n", " def forward(self, x):\n", " # Perform the calculation of the model to determine the prediction\n", " x = self.linear1(x)\n", " x = self.act_fn(x)\n", " x = self.linear2(x)\n", " return x"]}, {"cell_type": "markdown", "id": "a5eb3088", "metadata": {"papermill": {"duration": 0.016244, "end_time": "2022-05-12T11:44:49.954879", "exception": false, "start_time": "2022-05-12T11:44:49.938635", "status": "completed"}, "tags": []}, "source": ["For the examples in this notebook, we will use a tiny neural network with two input neurons and four hidden neurons.\n", "As we perform binary classification, we will use a single output neuron.\n", "Note that we do not apply a sigmoid on the output yet.\n", "This is because other functions, especially the loss, are more efficient and precise to calculate on the original outputs instead of the sigmoid output.\n", "We will discuss the detailed reason later."]}, {"cell_type": "code", "execution_count": 37, "id": "e09ef283", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:49.987821Z", "iopub.status.busy": "2022-05-12T11:44:49.987346Z", "iopub.status.idle": "2022-05-12T11:44:49.992594Z", "shell.execute_reply": "2022-05-12T11:44:49.991951Z"}, "papermill": {"duration": 0.023574, "end_time": "2022-05-12T11:44:49.994116", "exception": false, "start_time": "2022-05-12T11:44:49.970542", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["SimpleClassifier(\n", " (linear1): Linear(in_features=2, out_features=4, bias=True)\n", " (act_fn): Tanh()\n", " (linear2): Linear(in_features=4, out_features=1, bias=True)\n", ")\n"]}], "source": ["model = SimpleClassifier(num_inputs=2, num_hidden=4, num_outputs=1)\n", "# Printing a module shows all its submodules\n", "print(model)"]}, {"cell_type": "markdown", "id": "ed582eb5", "metadata": {"papermill": {"duration": 0.015436, "end_time": "2022-05-12T11:44:50.025407", "exception": false, "start_time": "2022-05-12T11:44:50.009971", "status": "completed"}, "tags": []}, "source": ["Printing the model lists all submodules it contains.\n", "The parameters of a module can be obtained by using its `parameters()` functions, or `named_parameters()` to get a name to each parameter object.\n", "For our small neural network, we have the following parameters:"]}, {"cell_type": "code", "execution_count": 38, "id": "cc016db5", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:50.059042Z", "iopub.status.busy": "2022-05-12T11:44:50.058596Z", "iopub.status.idle": "2022-05-12T11:44:50.062911Z", "shell.execute_reply": "2022-05-12T11:44:50.062315Z"}, "papermill": {"duration": 0.022484, "end_time": "2022-05-12T11:44:50.064342", "exception": false, "start_time": "2022-05-12T11:44:50.041858", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Parameter linear1.weight, shape torch.Size([4, 2])\n", "Parameter linear1.bias, shape torch.Size([4])\n", "Parameter linear2.weight, shape torch.Size([1, 4])\n", "Parameter linear2.bias, shape torch.Size([1])\n"]}], "source": ["for name, param in model.named_parameters():\n", " print(f\"Parameter {name}, shape {param.shape}\")"]}, {"cell_type": "markdown", "id": "73819d56", "metadata": {"papermill": {"duration": 0.015409, "end_time": "2022-05-12T11:44:50.095767", "exception": false, "start_time": "2022-05-12T11:44:50.080358", "status": "completed"}, "tags": []}, "source": ["Each linear layer has a weight matrix of the shape `[output, input]`, and a bias of the shape `[output]`.\n", "The tanh activation function does not have any parameters.\n", "Note that parameters are only registered for `nn.Module` objects that are direct object attributes, i.e. `self.a = ...`.\n", "If you define a list of modules, the parameters of those are not registered for the outer module and can cause some issues when you try to optimize your module.\n", "There are alternatives, like `nn.ModuleList`, `nn.ModuleDict` and `nn.Sequential`, that allow you to have different data structures of modules.\n", "We will use them in a few later tutorials and explain them there."]}, {"cell_type": "markdown", "id": "82210e53", "metadata": {"papermill": {"duration": 0.015614, "end_time": "2022-05-12T11:44:50.127010", "exception": false, "start_time": "2022-05-12T11:44:50.111396", "status": "completed"}, "tags": []}, "source": ["### The data\n", "\n", "PyTorch also provides a few functionalities to load the training and\n", "test data efficiently, summarized in the package `torch.utils.data`."]}, {"cell_type": "code", "execution_count": null, "id": "e818b770", "metadata": {"papermill": {"duration": 0.015562, "end_time": "2022-05-12T11:44:50.158860", "exception": false, "start_time": "2022-05-12T11:44:50.143298", "status": "completed"}, "tags": []}, "outputs": [], "source": []}, {"cell_type": "markdown", "id": "d19e084e", "metadata": {"papermill": {"duration": 0.015535, "end_time": "2022-05-12T11:44:50.190051", "exception": false, "start_time": "2022-05-12T11:44:50.174516", "status": "completed"}, "tags": []}, "source": ["The data package defines two classes which are the standard interface for handling data in PyTorch: `data.Dataset`, and `data.DataLoader`.\n", "The dataset class provides an uniform interface to access the\n", "training/test data, while the data loader makes sure to efficiently load\n", "and stack the data points from the dataset into batches during training."]}, {"cell_type": "markdown", "id": "03598d83", "metadata": {"papermill": {"duration": 0.015405, "end_time": "2022-05-12T11:44:50.221266", "exception": false, "start_time": "2022-05-12T11:44:50.205861", "status": "completed"}, "tags": []}, "source": ["#### The dataset class\n", "\n", "The dataset class summarizes the basic functionality of a dataset in a natural way.\n", "To define a dataset in PyTorch, we simply specify two functions: `__getitem__`, and `__len__`.\n", "The get-item function has to return the $i$-th data point in the dataset, while the len function returns the size of the dataset.\n", "For the XOR dataset, we can define the dataset class as follows:"]}, {"cell_type": "code", "execution_count": 39, "id": "5d66713c", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:50.254673Z", "iopub.status.busy": "2022-05-12T11:44:50.254198Z", "iopub.status.idle": "2022-05-12T11:44:50.260981Z", "shell.execute_reply": "2022-05-12T11:44:50.260364Z"}, "papermill": {"duration": 0.025247, "end_time": "2022-05-12T11:44:50.262481", "exception": false, "start_time": "2022-05-12T11:44:50.237234", "status": "completed"}, "tags": []}, "outputs": [], "source": ["\n", "\n", "class XORDataset(data.Dataset):\n", " def __init__(self, size, std=0.1):\n", " \"\"\"\n", " Inputs:\n", " size - Number of data points we want to generate\n", " std - Standard deviation of the noise (see generate_continuous_xor function)\n", " \"\"\"\n", " super().__init__()\n", " self.size = size\n", " self.std = std\n", " self.generate_continuous_xor()\n", "\n", " def generate_continuous_xor(self):\n", " # Each data point in the XOR dataset has two variables, x and y, that can be either 0 or 1\n", " # The label is their XOR combination, i.e. 1 if only x or only y is 1 while the other is 0.\n", " # If x=y, the label is 0.\n", " data = torch.randint(low=0, high=2, size=(self.size, 2), dtype=torch.float32)\n", " label = (data.sum(dim=1) == 1).to(torch.long)\n", " # To make it slightly more challenging, we add a bit of gaussian noise to the data points.\n", " data += self.std * torch.randn(data.shape)\n", "\n", " self.data = data\n", " self.label = label\n", "\n", " def __len__(self):\n", " # Number of data point we have. Alternatively self.data.shape[0], or self.label.shape[0]\n", " return self.size\n", "\n", " def __getitem__(self, idx):\n", " # Return the idx-th data point of the dataset\n", " # If we have multiple things to return (data point and label), we can return them as tuple\n", " data_point = self.data[idx]\n", " data_label = self.label[idx]\n", " return data_point, data_label"]}, {"cell_type": "markdown", "id": "e6d27353", "metadata": {"papermill": {"duration": 0.015559, "end_time": "2022-05-12T11:44:50.293863", "exception": false, "start_time": "2022-05-12T11:44:50.278304", "status": "completed"}, "tags": []}, "source": ["Let's try to create such a dataset and inspect it:"]}, {"cell_type": "code", "execution_count": 40, "id": "2d3d3a98", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:50.326854Z", "iopub.status.busy": "2022-05-12T11:44:50.326427Z", "iopub.status.idle": "2022-05-12T11:44:50.332601Z", "shell.execute_reply": "2022-05-12T11:44:50.331951Z"}, "papermill": {"duration": 0.024535, "end_time": "2022-05-12T11:44:50.334161", "exception": false, "start_time": "2022-05-12T11:44:50.309626", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Size of dataset: 200\n", "Data point 0: (tensor([0.9632, 0.1117]), tensor(1))\n"]}], "source": ["dataset = XORDataset(size=200)\n", "print(\"Size of dataset:\", len(dataset))\n", "print(\"Data point 0:\", dataset[0])"]}, {"cell_type": "markdown", "id": "22638699", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.015588, "end_time": "2022-05-12T11:44:50.365423", "exception": false, "start_time": "2022-05-12T11:44:50.349835", "status": "completed"}, "tags": []}, "source": ["To better relate to the dataset, we visualize the samples below."]}, {"cell_type": "code", "execution_count": 41, "id": "c498b015", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:50.398644Z", "iopub.status.busy": "2022-05-12T11:44:50.397912Z", "iopub.status.idle": "2022-05-12T11:44:50.403448Z", "shell.execute_reply": "2022-05-12T11:44:50.402837Z"}, "papermill": {"duration": 0.023688, "end_time": "2022-05-12T11:44:50.404910", "exception": false, "start_time": "2022-05-12T11:44:50.381222", "status": "completed"}, "tags": []}, "outputs": [], "source": ["def visualize_samples(data, label):\n", " if isinstance(data, Tensor):\n", " data = data.cpu().numpy()\n", " if isinstance(label, Tensor):\n", " label = label.cpu().numpy()\n", " data_0 = data[label == 0]\n", " data_1 = data[label == 1]\n", "\n", " plt.figure(figsize=(4, 4))\n", " plt.scatter(data_0[:, 0], data_0[:, 1], edgecolor=\"#333\", label=\"Class 0\")\n", " plt.scatter(data_1[:, 0], data_1[:, 1], edgecolor=\"#333\", label=\"Class 1\")\n", " plt.title(\"Dataset samples\")\n", " plt.ylabel(r\"$x_2$\")\n", " plt.xlabel(r\"$x_1$\")\n", " plt.legend()"]}, {"cell_type": "code", "execution_count": 42, "id": "f00ab628", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:50.442736Z", "iopub.status.busy": "2022-05-12T11:44:50.442270Z", "iopub.status.idle": "2022-05-12T11:44:51.050788Z", "shell.execute_reply": "2022-05-12T11:44:51.050098Z"}, "papermill": {"duration": 0.631045, "end_time": "2022-05-12T11:44:51.053184", "exception": false, "start_time": "2022-05-12T11:44:50.422139", "status": "completed"}, "tags": []}, "outputs": [{"data": {"application/pdf": "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THZhSjcoDiucVRXFG84kHz6SvcNax5CimUdDnN3cFg5LjRSrWBYWnmERpLQ1zPi8KGtgSinqaWf1v7vlegH/nxwsCmVuZHN0cmVhbQplbmRvYmoKMTcgMCBvYmoKPDwgL0Jhc2VGb250IC9HQ1dYRFYrRGVqYVZ1U2Fucy1PYmxpcXVlIC9DaGFyUHJvY3MgMTggMCBSCi9FbmNvZGluZyA8PCAvRGlmZmVyZW5jZXMgWyAxMjAgL3ggXSAvVHlwZSAvRW5jb2RpbmcgPj4gL0ZpcnN0Q2hhciAwCi9Gb250QkJveCBbIC0xMDE2IC0zNTEgMTY2MCAxMDY4IF0gL0ZvbnREZXNjcmlwdG9yIDE2IDAgUgovRm9udE1hdHJpeCBbIDAuMDAxIDAgMCAwLjAwMSAwIDAgXSAvTGFzdENoYXIgMjU1Ci9OYW1lIC9HQ1dYRFYrRGVqYVZ1U2Fucy1PYmxpcXVlIC9TdWJ0eXBlIC9UeXBlMyAvVHlwZSAvRm9udCAvV2lkdGhzIDE1IDAgUgo+PgplbmRvYmoKMTYgMCBvYmoKPDwgL0FzY2VudCA5MjkgL0NhcEhlaWdodCAwIC9EZXNjZW50IC0yMzYgL0ZsYWdzIDk2Ci9Gb250QkJveCBbIC0xMDE2IC0zNTEgMTY2MCAxMDY4IF0gL0ZvbnROYW1lIC9HQ1dYRFYrRGVqYVZ1U2Fucy1PYmxpcXVlCi9JdGFsaWNBbmdsZSAwIC9NYXhXaWR0aCAxMzUwIC9TdGVtViAwIC9UeXBlIC9Gb250RGVzY3JpcHRvciAvWEhlaWdodCAwID4+CmVuZG9iagoxNSAwIG9iagpbIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwCjYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgMzE4IDQwMSA0NjAgODM4IDYzNgo5NTAgNzgwIDI3NSAzOTAgMzkwIDUwMCA4MzggMzE4IDM2MSAzMTggMzM3IDYzNiA2MzYgNjM2IDYzNiA2MzYgNjM2IDYzNiA2MzYKNjM2IDYzNiAzMzcgMzM3IDgzOCA4MzggODM4IDUzMSAxMDAwIDY4NCA2ODYgNjk4IDc3MCA2MzIgNTc1IDc3NSA3NTIgMjk1CjI5NSA2NTYgNTU3IDg2MyA3NDggNzg3IDYwMyA3ODcgNjk1IDYzNSA2MTEgNzMyIDY4NCA5ODkgNjg1IDYxMSA2ODUgMzkwIDMzNwozOTAgODM4IDUwMCA1MDAgNjEzIDYzNSA1NTAgNjM1IDYxNSAzNTIgNjM1IDYzNCAyNzggMjc4IDU3OSAyNzggOTc0IDYzNCA2MTIKNjM1IDYzNSA0MTEgNTIxIDM5MiA2MzQgNTkyIDgxOCA1OTIgNTkyIDUyNSA2MzYgMzM3IDYzNiA4MzggNjAwIDYzNiA2MDAgMzE4CjM1MiA1MTggMTAwMCA1MDAgNTAwIDUwMCAxMzUwIDYzNSA0MDAgMTA3MCA2MDAgNjg1IDYwMCA2MDAgMzE4IDMxOCA1MTggNTE4CjU5MCA1MDAgMTAwMCA1MDAgMTAwMCA1MjEgNDAwIDEwMjggNjAwIDUyNSA2MTEgMzE4IDQwMSA2MzYgNjM2IDYzNiA2MzYgMzM3CjUwMCA1MDAgMTAwMCA0NzEgNjE3IDgzOCAzNjEgMTAwMCA1MDAgNTAwIDgzOCA0MDEgNDAxIDUwMCA2MzYgNjM2IDMxOCA1MDAKNDAxIDQ3MSA2MTcgOTY5IDk2OSA5NjkgNTMxIDY4NCA2ODQgNjg0IDY4NCA2ODQgNjg0IDk3NCA2OTggNjMyIDYzMiA2MzIgNjMyCjI5NSAyOTUgMjk1IDI5NSA3NzUgNzQ4IDc4NyA3ODcgNzg3IDc4NyA3ODcgODM4IDc4NyA3MzIgNzMyIDczMiA3MzIgNjExIDYwOAo2MzAgNjEzIDYxMyA2MTMgNjEzIDYxMyA2MTMgOTk1IDU1MCA2MTUgNjE1IDYxNSA2MTUgMjc4IDI3OCAyNzggMjc4IDYxMiA2MzQKNjEyIDYxMiA2MTIgNjEyIDYxMiA4MzggNjEyIDYzNCA2MzQgNjM0IDYzNCA1OTIgNjM1IDU5MiBdCmVuZG9iagoxOCAwIG9iago8PCAveCAxOSAwIFIgPj4KZW5kb2JqCjI0IDAgb2JqCjw8IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlIC9MZW5ndGggMjM1ID4+CnN0cmVhbQp4nDVRSW4AMQi75xX+QKWwJ++Zquqh/f+1hlEvAwPY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Y29kaW5nID4+Ci9GaXJzdENoYXIgMCAvRm9udEJCb3ggWyAtMTAyMSAtNDYzIDE3OTQgMTIzMyBdIC9Gb250RGVzY3JpcHRvciAyMSAwIFIKL0ZvbnRNYXRyaXggWyAwLjAwMSAwIDAgMC4wMDEgMCAwIF0gL0xhc3RDaGFyIDI1NSAvTmFtZSAvQk1RUURWK0RlamFWdVNhbnMKL1N1YnR5cGUgL1R5cGUzIC9UeXBlIC9Gb250IC9XaWR0aHMgMjAgMCBSID4+CmVuZG9iagoyMSAwIG9iago8PCAvQXNjZW50IDkyOSAvQ2FwSGVpZ2h0IDAgL0Rlc2NlbnQgLTIzNiAvRmxhZ3MgMzIKL0ZvbnRCQm94IFsgLTEwMjEgLTQ2MyAxNzk0IDEyMzMgXSAvRm9udE5hbWUgL0JNUVFEVitEZWphVnVTYW5zCi9JdGFsaWNBbmdsZSAwIC9NYXhXaWR0aCAxMzQyIC9TdGVtViAwIC9UeXBlIC9Gb250RGVzY3JpcHRvciAvWEhlaWdodCAwID4+CmVuZG9iagoyMCAwIG9iagpbIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwCjYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgMzE4IDQwMSA0NjAgODM4IDYzNgo5NTAgNzgwIDI3NSAzOTAgMzkwIDUwMCA4MzggMzE4IDM2MSAzMTggMzM3IDYzNiA2MzYgNjM2IDYzNiA2MzYgNjM2IDYzNiA2MzYKNjM2IDYzNiAzMzcgMzM3IDgzOCA4MzggODM4IDUzMSAxMDAwIDY4NCA2ODYgNjk4IDc3MCA2MzIgNTc1IDc3NSA3NTIgMjk1CjI5NSA2NTYgNTU3IDg2MyA3NDggNzg3IDYwMyA3ODcgNjk1IDYzNSA2MTEgNzMyIDY4NCA5ODkgNjg1IDYxMSA2ODUgMzkwIDMzNwozOTAgODM4IDUwMCA1MDAgNjEzIDYzNSA1NTAgNjM1IDYxNSAzNTIgNjM1IDYzNCAyNzggMjc4IDU3OSAyNzggOTc0IDYzNCA2MTIKNjM1IDYzNSA0MTEgNTIxIDM5MiA2MzQgNTkyIDgxOCA1OTIgNTkyIDUyNSA2MzYgMzM3IDYzNiA4MzggNjAwIDYzNiA2MDAgMzE4CjM1MiA1MTggMTAwMCA1MDAgNTAwIDUwMCAxMzQyIDYzNSA0MDAgMTA3MCA2MDAgNjg1IDYwMCA2MDAgMzE4IDMxOCA1MTggNTE4CjU5MCA1MDAgMTAwMCA1MDAgMTAwMCA1MjEgNDAwIDEwMjMgNjAwIDUyNSA2MTEgMzE4IDQwMSA2MzYgNjM2IDYzNiA2MzYgMzM3CjUwMCA1MDAgMTAwMCA0NzEgNjEyIDgzOCAzNjEgMTAwMCA1MDAgNTAwIDgzOCA0MDEgNDAxIDUwMCA2MzYgNjM2IDMxOCA1MDAKNDAxIDQ3MSA2MTIgOTY5IDk2OSA5NjkgNTMxIDY4NCA2ODQgNjg0IDY4NCA2ODQgNjg0IDk3NCA2OTggNjMyIDYzMiA2MzIgNjMyCjI5NSAyOTUgMjk1IDI5NSA3NzUgNzQ4IDc4NyA3ODcgNzg3IDc4NyA3ODcgODM4IDc4NyA3MzIgNzMyIDczMiA3MzIgNjExIDYwNQo2MzAgNjEzIDYxMyA2MTMgNjEzIDYxMyA2MTMgOTgyIDU1MCA2MTUgNjE1IDYxNSA2MTUgMjc4IDI3OCAyNzggMjc4IDYxMiA2MzQKNjEyIDYxMiA2MTIgNjEyIDYxMiA4MzggNjEyIDYzNCA2MzQgNjM0IDYzNCA1OTIgNjM1IDU5MiBdCmVuZG9iagoyMyAwIG9iago8PCAvQyAyNCAwIFIgL0QgMjUgMCBSIC9hIDI2IDAgUiAvZSAyNyAwIFIgL2VpZ2h0IDI4IDAgUiAvZml2ZSAyOSAwIFIKL2ZvdXIgMzAgMCBSIC9sIDMxIDAgUiAvbSAzMiAwIFIgL29uZSAzNCAwIFIgL3AgMzUgMCBSIC9wZXJpb2QgMzYgMCBSCi9zIDM3IDAgUiAvc2V2ZW4gMzggMCBSIC9zaXggMzkgMCBSIC9zcGFjZSA0MCAwIFIgL3QgNDEgMCBSIC90d28gNDIgMCBSCi96ZXJvIDQzIDAgUiA+PgplbmRvYmoKMyAwIG9iago8PCAvRjEgMjIgMCBSIC9GMiAxNyAwIFIgPj4KZW5kb2JqCjQgMCBvYmoKPDwgL0ExIDw8IC9DQSAwIC9UeXBlIC9FeHRHU3RhdGUgL2NhIDEgPj4KL0EyIDw8IC9DQSAxIC9UeXBlIC9FeHRHU3RhdGUgL2NhIDEgPj4KL0EzIDw8IC9DQSAwLjggL1R5cGUgL0V4dEdTdGF0ZSAvY2EgMC44ID4+ID4+CmVuZG9iago1IDAgb2JqCjw8ID4+CmVuZG9iago2IDAgb2JqCjw8ID4+CmVuZG9iago3IDAgb2JqCjw8IC9GMS1EZWphVnVTYW5zLW1pbnVzIDMzIDAgUiAvTTAgMTMgMCBSIC9NMSAxNCAwIFIgPj4KZW5kb2JqCjEzIDAgb2JqCjw8IC9CQm94IFsgLTggLTggOCA4IF0gL0ZpbHRlciAvRmxhdGVEZWNvZGUgL0xlbmd0aCAxMzEgL1N1YnR5cGUgL0Zvcm0KL1R5cGUgL1hPYmplY3QgPj4Kc3RyZWFtCnicbZBBDoQgDEX3PUUv8ElLRWXr0mu4mUzi/bcDcUBM3TTQvjx+Uf6S8E6lwPgkCUtOs+R605DSukyMGObVsijHoFEt1s51OKjP0HBjdIuxFKbU1uh4o5vpNt6TP/qwWSFGPxwOr4R7FkMmXCkxBoffCy/bw/8Rnl7UwB+ijX5jWkP9CmVuZHN0cmVhbQplbmRvYmoKMTQgMCBvYmoKPDwgL0JCb3ggWyAtOCAtOCA4IDggXSAvRmlsdGVyIC9GbGF0ZURlY29kZSAvTGVuZ3RoIDEzMSAvU3VidHlwZSAvRm9ybQovVHlwZSAvWE9iamVjdCA+PgpzdHJlYW0KeJxtkEEOhCAMRfc9RS/wSUtFZevSa7iZTOL9twNxQEzdNNC+PH5R/pLwTqXA+CQJS06z5HrTkNK6TIwY5tWyKMegUS3WznU4qM/QcGN0i7EUptTW6Hijm+k23pM/+rBZIUY/HA6vhHsWQyZcKTEGh98LL9vD/xGeXtTAH6KNfmNaQ/0KZW5kc3RyZWFtCmVuZG9iagoyIDAgb2JqCjw8IC9Db3VudCAxIC9LaWRzIFsgMTEgMCBSIF0gL1R5cGUgL1BhZ2VzID4+CmVuZG9iago0NCAwIG9iago8PCAvQ3JlYXRpb25EYXRlIChEOjIwMjIwNTEyMTM0NDUwKzAyJzAwJykKL0NyZWF0b3IgKE1hdHBsb3RsaWIgdjMuNS4yLCBodHRwczovL21hdHBsb3RsaWIub3JnKQovUHJvZHVjZXIgKE1hdHBsb3RsaWIgcGRmIGJhY2tlbmQgdjMuNS4yKSA+PgplbmRvYmoKeHJlZgowIDQ1CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNiAwMDAwMCBuIAowMDAwMDE1MTE5IDAwMDAwIG4gCjAwMDAwMTQzMTMgMDAwMDAgbiAKMDAwMDAxNDM1NiAwMDAwMCBuIAowMDAwMDE0NDk4IDAwMDAwIG4gCjAwMDAwMTQ1MTkgMDAwMDAgbiAKMDAwMDAxNDU0MCAwMDAwMCBuIAowMDAwMDAwMDY1IDAwMDAwIG4gCjAwMDAwMDAzNDcgMDAwMDAgbiAKMDAwMDAwNTI5NyAwMDAwMCBuIAowMDAwMDAwMjA4IDAwMDAwIG4gCjAwMDAwMDUyNzYgMDAwMDAgbiAKMDAwMDAxNDYxMSAwMDAwMCBuIAowMDAwMDE0ODY1IDAwMDAwIG4gCjAwMDAwMDYwMjkgMDAwMDAgbiAKMDAwMDAwNTgxNCAwMDAwMCBuIAowMDAwMDA1NDg0IDAwMDAwIG4gCjAwMDAwMDcwODIgMDAwMDAgbiAKMDAwMDAwNTMxNyAwMDAwMCBuIAowMDAwMDEzMDE2IDAwMDAwIG4gCjAwMDAwMTI4MDkgMDAwMDAgbiAKMDAwMDAxMjM3OSAwMDAwMCBuIAowMDAwMDE0MDY5IDAwMDAwIG4gCjAwMDAwMDcxMTQgMDAwMDAgbiAKMDAwMDAwNzQyMiAwMDAwMCBuIAowMDAwMDA3NjU5IDAwMDAwIG4gCjAwMDAwMDgwMzkgMDAwMDAgbiAKMDAwMDAwODM2MSAwMDAwMCBuIAowMDAwMDA4ODI5IDAwMDAwIG4gCjAwMDAwMDkxNTEgMDAwMDAgbiAKMDAwMDAwOTMxNyAwMDAwMCBuIAowMDAwMDA5NDM2IDAwMDAwIG4gCjAwMDAwMDk3NjcgMDAwMDAgbiAKMDAwMDAwOTkzOSAwMDAwMCBuIAowMDAwMDEwMDk0IDAwMDAwIG4gCjAwMDAwMTA0MDYgMDAwMDAgbiAKMDAwMDAxMDUyOSAwMDAwMCBuIAowMDAwMDEwOTM2IDAwMDAwIG4gCjAwMDAwMTEwNzggMDAwMDAgbiAKMDAwMDAxMTQ3MSAwMDAwMCBuIAowMDAwMDExNTYxIDAwMDAwIG4gCjAwMDAwMTE3NjcgMDAwMDAgbiAKMDAwMDAxMjA5MSAwMDAwMCBuIAowMDAwMDE1MTc5IDAwMDAwIG4gCnRyYWlsZXIKPDwgL0luZm8gNDQgMCBSIC9Sb290IDEgMCBSIC9TaXplIDQ1ID4+CnN0YXJ0eHJlZgoxNTMzNgolJUVPRgo=\n", "image/svg+xml": ["<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n", "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n", " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n", "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"288.985258pt\" height=\"277.314375pt\" viewBox=\"0 0 288.985258 277.314375\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n", " <metadata>\n", " <rdf:RDF xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n", " <cc:Work>\n", " <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/>\n", " <dc:date>2022-05-12T13:44:50.676329</dc:date>\n", " <dc:format>image/svg+xml</dc:format>\n", " <dc:creator>\n", " <cc:Agent>\n", " <dc:title>Matplotlib v3.5.2, https://matplotlib.org/</dc:title>\n", " </cc:Agent>\n", " </dc:creator>\n", " </cc:Work>\n", " </rdf:RDF>\n", " </metadata>\n", " <defs>\n", " <style type=\"text/css\">*{stroke-linejoin: round; stroke-linecap: butt}</style>\n", " </defs>\n", " <g id=\"figure_1\">\n", " <g id=\"patch_1\">\n", " <path d=\"M 0 277.314375 \n", "L 288.985258 277.314375 \n", "L 288.985258 0 \n", "L 0 0 \n", "L 0 277.314375 \n", "z\n", "\" style=\"fill: none\"/>\n", " </g>\n", " <g id=\"axes_1\">\n", " <g id=\"patch_2\">\n", " <path d=\"M 52.160938 239.758125 \n", "L 275.360937 239.758125 \n", "L 275.360937 22.318125 \n", "L 52.160938 22.318125 \n", "z\n", "\" style=\"fill: #ffffff\"/>\n", " </g>\n", " <g id=\"PathCollection_1\">\n", " <defs>\n", " <path id=\"m9c4bf21dd3\" d=\"M 0 3 \n", "C 0.795609 3 1.55874 2.683901 2.12132 2.12132 \n", "C 2.683901 1.55874 3 0.795609 3 0 \n", "C 3 -0.795609 2.683901 -1.55874 2.12132 -2.12132 \n", "C 1.55874 -2.683901 0.795609 -3 0 -3 \n", "C -0.795609 -3 -1.55874 -2.683901 -2.12132 -2.12132 \n", "C -2.683901 -1.55874 -3 -0.795609 -3 0 \n", "C -3 0.795609 -2.683901 1.55874 -2.12132 2.12132 \n", "C -1.55874 2.683901 -0.795609 3 0 3 \n", "z\n", "\" style=\"stroke: #333333\"/>\n", " </defs>\n", " <g clip-path=\"url(#pc602fbd1d7)\">\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"96.31168\" y=\"193.325344\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"232.057657\" y=\"62.145049\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"258.979442\" y=\"63.780462\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"108.913368\" y=\"204.409578\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"101.325808\" y=\"205.043015\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"70.983454\" y=\"189.560429\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"242.885541\" y=\"58.566133\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"232.016709\" y=\"51.440521\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"93.978943\" y=\"204.550687\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"237.538974\" y=\"53.572047\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"103.543109\" y=\"200.309835\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"255.555098\" y=\"32.201761\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"238.058002\" y=\"62.589723\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"232.170061\" y=\"57.754453\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"94.264177\" y=\"212.626168\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"89.231835\" y=\"185.037671\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"251.267421\" y=\"90.813692\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"254.815479\" y=\"83.753102\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"226.105337\" y=\"59.138235\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"82.022892\" y=\"209.202243\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"253.973129\" y=\"32.62492\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"245.15091\" y=\"59.955798\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"114.421987\" y=\"175.83743\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"228.657784\" y=\"32.336249\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"99.781014\" y=\"194.777215\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"227.807175\" y=\"51.50491\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"86.881354\" y=\"179.492748\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"250.727063\" y=\"48.77409\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"246.39628\" y=\"61.512745\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"240.179519\" y=\"43.69401\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"92.34098\" y=\"184.373252\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"104.506115\" y=\"209.709719\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"87.360439\" y=\"169.625602\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"97.745486\" y=\"201.318829\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"112.202457\" y=\"200.867622\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"93.386735\" y=\"195.701852\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"112.962408\" y=\"212.211753\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"213.923524\" y=\"39.620323\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"253.408944\" y=\"64.604829\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"238.202599\" y=\"63.759786\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"93.334759\" y=\"205.410605\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"222.697015\" y=\"89.092646\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"246.067518\" y=\"56.781365\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"97.908356\" y=\"212.127081\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"110.608912\" y=\"217.677792\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"119.278606\" y=\"177.02797\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"229.431275\" y=\"71.868079\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"217.108023\" y=\"44.358713\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"90.421001\" y=\"205.813556\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"230.637614\" y=\"68.485687\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"98.642521\" y=\"201.033344\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"242.296554\" y=\"33.609264\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"95.167044\" y=\"188.760034\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"227.659933\" y=\"76.575953\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"239.162594\" y=\"47.436505\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"70.985535\" y=\"190.609003\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"216.984682\" y=\"47.197067\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"247.342435\" y=\"65.6149\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"82.942512\" y=\"196.823089\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"94.610207\" y=\"229.874489\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"94.065144\" y=\"199.872245\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"75.9265\" y=\"200.007537\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"261.562131\" y=\"65.752612\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"227.651459\" y=\"73.759575\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"253.566025\" y=\"39.679857\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"76.490724\" y=\"185.321057\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"238.897525\" y=\"82.429587\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"249.223089\" y=\"89.661589\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"118.387936\" y=\"218.303568\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"108.710707\" y=\"207.070547\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"94.960359\" y=\"190.023846\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"95.804305\" y=\"187.711556\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"239.509346\" y=\"53.869424\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"226.971018\" y=\"88.154106\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"94.916859\" y=\"195.521558\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"106.991269\" y=\"186.850471\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"108.567957\" y=\"194.117803\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"239.227411\" y=\"37.590473\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"238.317384\" y=\"35.754283\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"96.994499\" y=\"208.108344\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"250.032038\" y=\"37.701594\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"232.359401\" y=\"72.374698\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"248.199716\" y=\"33.573869\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"88.429047\" y=\"192.95304\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"234.27057\" y=\"47.995435\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"98.536004\" y=\"212.515425\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"107.800107\" y=\"204.310706\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"87.726796\" y=\"191.216589\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"212.816998\" y=\"53.841351\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"225.168168\" y=\"47.841136\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"202.642744\" y=\"44.693113\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"86.981531\" y=\"191.534849\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"116.687423\" y=\"206.975146\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"91.776781\" y=\"209.817871\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"225.892096\" y=\"90.705434\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"102.087238\" y=\"195.303274\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"94.905243\" y=\"189.148117\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"89.515988\" y=\"200.223394\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"99.167164\" y=\"208.206126\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"211.577945\" y=\"57.867977\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"220.751413\" y=\"41.469595\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"72.137778\" y=\"214.445482\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"235.916363\" y=\"80.464924\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " </g>\n", " </g>\n", " <g id=\"PathCollection_2\">\n", " <defs>\n", " <path id=\"me3c1da6825\" d=\"M 0 3 \n", "C 0.795609 3 1.55874 2.683901 2.12132 2.12132 \n", "C 2.683901 1.55874 3 0.795609 3 0 \n", "C 3 -0.795609 2.683901 -1.55874 2.12132 -2.12132 \n", "C 1.55874 -2.683901 0.795609 -3 0 -3 \n", "C -0.795609 -3 -1.55874 -2.683901 -2.12132 -2.12132 \n", "C -2.683901 -1.55874 -3 -0.795609 -3 0 \n", "C -3 0.795609 -2.683901 1.55874 -2.12132 2.12132 \n", "C -1.55874 2.683901 -0.795609 3 0 3 \n", "z\n", "\" style=\"stroke: #333333\"/>\n", " </defs>\n", " <g clip-path=\"url(#pc602fbd1d7)\">\n", " <use xlink:href=\"#me3c1da6825\" x=\"230.877063\" y=\"180.913557\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"243.842427\" y=\"181.183986\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"232.017097\" y=\"198.932324\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"89.746376\" y=\"45.392998\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"250.686437\" y=\"201.599728\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"100.400405\" y=\"63.553489\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"219.862038\" y=\"211.350014\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"130.59866\" y=\"59.599027\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"247.536058\" y=\"217.196966\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"214.797166\" y=\"185.557909\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"229.906907\" y=\"173.017888\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"65.731142\" y=\"44.566804\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"116.585574\" y=\"45.533014\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"96.4775\" y=\"76.495825\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"96.788387\" y=\"42.091466\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"75.708547\" y=\"39.030573\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"233.922057\" y=\"201.757218\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"216.28277\" y=\"180.766731\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"225.945553\" y=\"182.832732\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"107.888844\" y=\"59.25904\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"212.266314\" y=\"192.147409\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"257.089413\" y=\"200.542537\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"248.528097\" y=\"198.107913\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"223.275659\" y=\"202.11576\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"254.62465\" y=\"176.456154\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"83.200733\" y=\"70.175377\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"251.724096\" y=\"179.390064\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"110.819287\" y=\"55.123203\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"232.126351\" y=\"178.669064\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"68.497902\" y=\"56.973626\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"95.226666\" y=\"66.120244\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"223.392974\" y=\"208.672634\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"214.945261\" y=\"183.133722\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"100.205618\" y=\"60.661631\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"244.127174\" y=\"183.85959\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"100.782099\" y=\"68.534007\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"97.685973\" y=\"71.284393\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"261.24119\" y=\"209.357586\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"231.536281\" y=\"180.074569\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"84.432042\" y=\"55.826098\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"114.704427\" y=\"57.881371\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"118.139583\" y=\"40.282525\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"244.331312\" y=\"206.328325\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"84.937455\" y=\"59.985039\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"229.111028\" y=\"185.254639\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"99.865846\" y=\"73.50443\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"107.774522\" y=\"50.128195\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"106.681533\" y=\"53.57626\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"220.300095\" y=\"186.154142\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"84.93114\" y=\"77.508109\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"105.491498\" y=\"48.161599\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"212.017878\" y=\"182.204423\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"238.780524\" y=\"210.592034\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"102.920944\" y=\"48.671279\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"109.227118\" y=\"67.791241\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"218.916511\" y=\"195.110735\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"210.412471\" y=\"197.807546\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"106.409234\" y=\"62.370039\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"62.306392\" y=\"69.539331\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"91.834453\" y=\"77.469177\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"109.483259\" y=\"52.116365\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"87.52736\" y=\"63.223243\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"94.034599\" y=\"55.768785\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"110.113367\" y=\"68.261083\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"257.318305\" y=\"202.317721\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"79.762115\" y=\"39.847979\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"258.048499\" y=\"185.012766\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"244.789162\" y=\"171.865302\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"214.47439\" y=\"211.299351\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"218.387835\" y=\"227.253664\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"98.247032\" y=\"41.347367\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"221.09122\" y=\"178.959826\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"207.783237\" y=\"165.02484\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"84.486389\" y=\"47.120304\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"108.320496\" y=\"59.847104\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"247.02495\" y=\"184.293941\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"92.024123\" y=\"51.399993\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"103.976033\" y=\"61.578541\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"102.375453\" y=\"64.816787\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"230.527021\" y=\"177.171327\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"238.484799\" y=\"167.950176\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"247.340005\" y=\"185.179964\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"134.8086\" y=\"59.304711\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"213.726653\" y=\"213.578161\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"265.215483\" y=\"212.626448\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"226.839442\" y=\"209.593202\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"88.454985\" y=\"69.802283\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"86.200641\" y=\"59.30147\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"249.708568\" y=\"212.467168\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"86.639713\" y=\"66.734504\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"72.549088\" y=\"61.78785\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"116.327234\" y=\"48.616483\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"89.624632\" y=\"51.591563\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"257.369976\" y=\"209.982902\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"209.334228\" y=\"191.955712\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"98.138755\" y=\"44.566278\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#me3c1da6825\" x=\"254.619078\" y=\"207.56031\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " </g>\n", " </g>\n", " <g id=\"matplotlib.axis_1\">\n", " <g id=\"xtick_1\">\n", " <g id=\"line2d_1\">\n", " <defs>\n", " <path id=\"mbabefb4364\" d=\"M 0 0 \n", "L 0 3.5 \n", "\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </defs>\n", " <g>\n", " <use xlink:href=\"#mbabefb4364\" x=\"62.596276\" y=\"239.758125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_1\">\n", " <!-- \u22120.25 -->\n", " <g transform=\"translate(47.27362 254.356562)scale(0.1 -0.1)\">\n", " <defs>\n", " <path id=\"DejaVuSans-2212\" d=\"M 678 2272 \n", "L 4684 2272 \n", "L 4684 1741 \n", "L 678 1741 \n", "L 678 2272 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-30\" d=\"M 2034 4250 \n", "Q 1547 4250 1301 3770 \n", "Q 1056 3291 1056 2328 \n", "Q 1056 1369 1301 889 \n", "Q 1547 409 2034 409 \n", "Q 2525 409 2770 889 \n", "Q 3016 1369 3016 2328 \n", "Q 3016 3291 2770 3770 \n", "Q 2525 4250 2034 4250 \n", "z\n", "M 2034 4750 \n", "Q 2819 4750 3233 4129 \n", "Q 3647 3509 3647 2328 \n", "Q 3647 1150 3233 529 \n", "Q 2819 -91 2034 -91 \n", "Q 1250 -91 836 529 \n", "Q 422 1150 422 2328 \n", "Q 422 3509 836 4129 \n", "Q 1250 4750 2034 4750 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-2e\" d=\"M 684 794 \n", "L 1344 794 \n", "L 1344 0 \n", "L 684 0 \n", "L 684 794 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-32\" d=\"M 1228 531 \n", "L 3431 531 \n", "L 3431 0 \n", "L 469 0 \n", "L 469 531 \n", "Q 828 903 1448 1529 \n", "Q 2069 2156 2228 2338 \n", "Q 2531 2678 2651 2914 \n", "Q 2772 3150 2772 3378 \n", "Q 2772 3750 2511 3984 \n", "Q 2250 4219 1831 4219 \n", "Q 1534 4219 1204 4116 \n", "Q 875 4013 500 3803 \n", "L 500 4441 \n", "Q 881 4594 1212 4672 \n", "Q 1544 4750 1819 4750 \n", "Q 2544 4750 2975 4387 \n", "Q 3406 4025 3406 3419 \n", "Q 3406 3131 3298 2873 \n", "Q 3191 2616 2906 2266 \n", "Q 2828 2175 2409 1742 \n", "Q 1991 1309 1228 531 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-35\" d=\"M 691 4666 \n", "L 3169 4666 \n", "L 3169 4134 \n", "L 1269 4134 \n", "L 1269 2991 \n", "Q 1406 3038 1543 3061 \n", "Q 1681 3084 1819 3084 \n", "Q 2600 3084 3056 2656 \n", "Q 3513 2228 3513 1497 \n", "Q 3513 744 3044 326 \n", "Q 2575 -91 1722 -91 \n", "Q 1428 -91 1123 -41 \n", "Q 819 9 494 109 \n", "L 494 744 \n", "Q 775 591 1075 516 \n", "Q 1375 441 1709 441 \n", "Q 2250 441 2565 725 \n", "Q 2881 1009 2881 1497 \n", "Q 2881 1984 2565 2268 \n", "Q 2250 2553 1709 2553 \n", "Q 1456 2553 1204 2497 \n", "Q 953 2441 691 2322 \n", "L 691 4666 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " </defs>\n", " <use xlink:href=\"#DejaVuSans-2212\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"83.789062\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"147.412109\"/>\n", " <use xlink:href=\"#DejaVuSans-32\" x=\"179.199219\"/>\n", " <use xlink:href=\"#DejaVuSans-35\" x=\"242.822266\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"xtick_2\">\n", " <g id=\"line2d_2\">\n", " <g>\n", " <use xlink:href=\"#mbabefb4364\" x=\"97.272305\" y=\"239.758125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_2\">\n", " <!-- 0.00 -->\n", " <g transform=\"translate(86.139492 254.356562)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-30\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"95.410156\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"159.033203\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"xtick_3\">\n", " <g id=\"line2d_3\">\n", " <g>\n", " <use xlink:href=\"#mbabefb4364\" x=\"131.948333\" y=\"239.758125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_3\">\n", " <!-- 0.25 -->\n", " <g transform=\"translate(120.81552 254.356562)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-30\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-32\" x=\"95.410156\"/>\n", " <use xlink:href=\"#DejaVuSans-35\" x=\"159.033203\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"xtick_4\">\n", " <g id=\"line2d_4\">\n", " <g>\n", " <use xlink:href=\"#mbabefb4364\" x=\"166.624361\" y=\"239.758125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_4\">\n", " <!-- 0.50 -->\n", " <g transform=\"translate(155.491548 254.356562)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-30\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-35\" x=\"95.410156\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"159.033203\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"xtick_5\">\n", " <g id=\"line2d_5\">\n", " <g>\n", " <use xlink:href=\"#mbabefb4364\" x=\"201.300389\" y=\"239.758125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_5\">\n", " <!-- 0.75 -->\n", " <g transform=\"translate(190.167577 254.356562)scale(0.1 -0.1)\">\n", " <defs>\n", " <path id=\"DejaVuSans-37\" d=\"M 525 4666 \n", "L 3525 4666 \n", "L 3525 4397 \n", "L 1831 0 \n", "L 1172 0 \n", "L 2766 4134 \n", "L 525 4134 \n", "L 525 4666 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " </defs>\n", " <use xlink:href=\"#DejaVuSans-30\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-37\" x=\"95.410156\"/>\n", " <use xlink:href=\"#DejaVuSans-35\" x=\"159.033203\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"xtick_6\">\n", " <g id=\"line2d_6\">\n", " <g>\n", " <use xlink:href=\"#mbabefb4364\" x=\"235.976417\" y=\"239.758125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_6\">\n", " <!-- 1.00 -->\n", " <g transform=\"translate(224.843605 254.356562)scale(0.1 -0.1)\">\n", " <defs>\n", " <path id=\"DejaVuSans-31\" d=\"M 794 531 \n", "L 1825 531 \n", "L 1825 4091 \n", "L 703 3866 \n", "L 703 4441 \n", "L 1819 4666 \n", "L 2450 4666 \n", "L 2450 531 \n", "L 3481 531 \n", "L 3481 0 \n", "L 794 0 \n", "L 794 531 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " </defs>\n", " <use xlink:href=\"#DejaVuSans-31\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"95.410156\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"159.033203\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"xtick_7\">\n", " <g id=\"line2d_7\">\n", " <g>\n", " <use xlink:href=\"#mbabefb4364\" x=\"270.652446\" y=\"239.758125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_7\">\n", " <!-- 1.25 -->\n", " <g transform=\"translate(259.519633 254.356562)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-31\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-32\" x=\"95.410156\"/>\n", " <use xlink:href=\"#DejaVuSans-35\" x=\"159.033203\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"text_8\">\n", " <!-- $x_1$ -->\n", " <g transform=\"translate(158.410938 268.034687)scale(0.1 -0.1)\">\n", " <defs>\n", " <path id=\"DejaVuSans-Oblique-78\" d=\"M 3841 3500 \n", "L 2234 1784 \n", "L 3219 0 \n", "L 2559 0 \n", "L 1819 1388 \n", "L 531 0 \n", "L -166 0 \n", "L 1556 1844 \n", "L 641 3500 \n", "L 1300 3500 \n", "L 1972 2234 \n", "L 3144 3500 \n", "L 3841 3500 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " </defs>\n", " <use xlink:href=\"#DejaVuSans-Oblique-78\" transform=\"translate(0 0.3125)\"/>\n", " <use xlink:href=\"#DejaVuSans-31\" transform=\"translate(59.179688 -16.09375)scale(0.7)\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"matplotlib.axis_2\">\n", " <g id=\"ytick_1\">\n", " <g id=\"line2d_8\">\n", " <defs>\n", " <path id=\"ma11233275a\" d=\"M 0 0 \n", "L -3.5 0 \n", "\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </defs>\n", " <g>\n", " <use xlink:href=\"#ma11233275a\" x=\"52.160938\" y=\"223.94267\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_9\">\n", " <!-- \u22120.2 -->\n", " <g transform=\"translate(20.878125 227.741889)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-2212\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"83.789062\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"147.412109\"/>\n", " <use xlink:href=\"#DejaVuSans-32\" x=\"179.199219\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"ytick_2\">\n", " <g id=\"line2d_9\">\n", " <g>\n", " <use xlink:href=\"#ma11233275a\" x=\"52.160938\" y=\"196.335617\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_10\">\n", " <!-- 0.0 -->\n", " <g transform=\"translate(29.257812 200.134836)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-30\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"95.410156\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"ytick_3\">\n", " <g id=\"line2d_10\">\n", " <g>\n", " <use xlink:href=\"#ma11233275a\" x=\"52.160938\" y=\"168.728564\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_11\">\n", " <!-- 0.2 -->\n", " <g transform=\"translate(29.257812 172.527783)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-30\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-32\" x=\"95.410156\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"ytick_4\">\n", " <g id=\"line2d_11\">\n", " <g>\n", " <use xlink:href=\"#ma11233275a\" x=\"52.160938\" y=\"141.12151\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_12\">\n", " <!-- 0.4 -->\n", " <g transform=\"translate(29.257812 144.920729)scale(0.1 -0.1)\">\n", " <defs>\n", " <path id=\"DejaVuSans-34\" d=\"M 2419 4116 \n", "L 825 1625 \n", "L 2419 1625 \n", "L 2419 4116 \n", "z\n", "M 2253 4666 \n", "L 3047 4666 \n", "L 3047 1625 \n", "L 3713 1625 \n", "L 3713 1100 \n", "L 3047 1100 \n", "L 3047 0 \n", "L 2419 0 \n", "L 2419 1100 \n", "L 313 1100 \n", "L 313 1709 \n", "L 2253 4666 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " </defs>\n", " <use xlink:href=\"#DejaVuSans-30\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-34\" x=\"95.410156\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"ytick_5\">\n", " <g id=\"line2d_12\">\n", " <g>\n", " <use xlink:href=\"#ma11233275a\" x=\"52.160938\" y=\"113.514457\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_13\">\n", " <!-- 0.6 -->\n", " <g transform=\"translate(29.257812 117.313676)scale(0.1 -0.1)\">\n", " <defs>\n", " <path id=\"DejaVuSans-36\" d=\"M 2113 2584 \n", "Q 1688 2584 1439 2293 \n", "Q 1191 2003 1191 1497 \n", "Q 1191 994 1439 701 \n", "Q 1688 409 2113 409 \n", "Q 2538 409 2786 701 \n", "Q 3034 994 3034 1497 \n", "Q 3034 2003 2786 2293 \n", "Q 2538 2584 2113 2584 \n", "z\n", "M 3366 4563 \n", "L 3366 3988 \n", "Q 3128 4100 2886 4159 \n", "Q 2644 4219 2406 4219 \n", "Q 1781 4219 1451 3797 \n", "Q 1122 3375 1075 2522 \n", "Q 1259 2794 1537 2939 \n", "Q 1816 3084 2150 3084 \n", "Q 2853 3084 3261 2657 \n", "Q 3669 2231 3669 1497 \n", "Q 3669 778 3244 343 \n", "Q 2819 -91 2113 -91 \n", "Q 1303 -91 875 529 \n", "Q 447 1150 447 2328 \n", "Q 447 3434 972 4092 \n", "Q 1497 4750 2381 4750 \n", "Q 2619 4750 2861 4703 \n", "Q 3103 4656 3366 4563 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " </defs>\n", " <use xlink:href=\"#DejaVuSans-30\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-36\" x=\"95.410156\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"ytick_6\">\n", " <g id=\"line2d_13\">\n", " <g>\n", " <use xlink:href=\"#ma11233275a\" x=\"52.160938\" y=\"85.907404\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_14\">\n", " <!-- 0.8 -->\n", " <g transform=\"translate(29.257812 89.706623)scale(0.1 -0.1)\">\n", " <defs>\n", " <path id=\"DejaVuSans-38\" d=\"M 2034 2216 \n", "Q 1584 2216 1326 1975 \n", "Q 1069 1734 1069 1313 \n", "Q 1069 891 1326 650 \n", "Q 1584 409 2034 409 \n", "Q 2484 409 2743 651 \n", "Q 3003 894 3003 1313 \n", "Q 3003 1734 2745 1975 \n", "Q 2488 2216 2034 2216 \n", "z\n", "M 1403 2484 \n", "Q 997 2584 770 2862 \n", "Q 544 3141 544 3541 \n", "Q 544 4100 942 4425 \n", "Q 1341 4750 2034 4750 \n", "Q 2731 4750 3128 4425 \n", "Q 3525 4100 3525 3541 \n", "Q 3525 3141 3298 2862 \n", "Q 3072 2584 2669 2484 \n", "Q 3125 2378 3379 2068 \n", "Q 3634 1759 3634 1313 \n", "Q 3634 634 3220 271 \n", "Q 2806 -91 2034 -91 \n", "Q 1263 -91 848 271 \n", "Q 434 634 434 1313 \n", "Q 434 1759 690 2068 \n", "Q 947 2378 1403 2484 \n", "z\n", "M 1172 3481 \n", "Q 1172 3119 1398 2916 \n", "Q 1625 2713 2034 2713 \n", "Q 2441 2713 2670 2916 \n", "Q 2900 3119 2900 3481 \n", "Q 2900 3844 2670 4047 \n", "Q 2441 4250 2034 4250 \n", "Q 1625 4250 1398 4047 \n", "Q 1172 3844 1172 3481 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " </defs>\n", " <use xlink:href=\"#DejaVuSans-30\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-38\" x=\"95.410156\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"ytick_7\">\n", " <g id=\"line2d_14\">\n", " <g>\n", " <use xlink:href=\"#ma11233275a\" x=\"52.160938\" y=\"58.300351\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_15\">\n", " <!-- 1.0 -->\n", " <g transform=\"translate(29.257812 62.099569)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-31\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"95.410156\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"ytick_8\">\n", " <g id=\"line2d_15\">\n", " <g>\n", " <use xlink:href=\"#ma11233275a\" x=\"52.160938\" y=\"30.693297\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_16\">\n", " <!-- 1.2 -->\n", " <g transform=\"translate(29.257812 34.492516)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-31\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-32\" x=\"95.410156\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"text_17\">\n", " <!-- $x_2$ -->\n", " <g transform=\"translate(14.798438 136.388125)rotate(-90)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-Oblique-78\" transform=\"translate(0 0.3125)\"/>\n", " <use xlink:href=\"#DejaVuSans-32\" transform=\"translate(59.179688 -16.09375)scale(0.7)\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"patch_3\">\n", " <path d=\"M 52.160938 239.758125 \n", "L 52.160938 22.318125 \n", "\" style=\"fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square\"/>\n", " </g>\n", " <g id=\"patch_4\">\n", " <path d=\"M 275.360937 239.758125 \n", "L 275.360937 22.318125 \n", "\" style=\"fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square\"/>\n", " </g>\n", " <g id=\"patch_5\">\n", " <path d=\"M 52.160937 239.758125 \n", "L 275.360937 239.758125 \n", "\" style=\"fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square\"/>\n", " </g>\n", " <g id=\"patch_6\">\n", " <path d=\"M 52.160937 22.318125 \n", "L 275.360937 22.318125 \n", "\" style=\"fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square\"/>\n", " </g>\n", " <g id=\"text_18\">\n", " <!-- Dataset samples -->\n", " <g transform=\"translate(113.418125 16.318125)scale(0.12 -0.12)\">\n", " <defs>\n", " <path id=\"DejaVuSans-44\" d=\"M 1259 4147 \n", "L 1259 519 \n", "L 2022 519 \n", "Q 2988 519 3436 956 \n", "Q 3884 1394 3884 2338 \n", "Q 3884 3275 3436 3711 \n", "Q 2988 4147 2022 4147 \n", "L 1259 4147 \n", "z\n", "M 628 4666 \n", "L 1925 4666 \n", "Q 3281 4666 3915 4102 \n", "Q 4550 3538 4550 2338 \n", "Q 4550 1131 3912 565 \n", "Q 3275 0 1925 0 \n", "L 628 0 \n", "L 628 4666 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-61\" d=\"M 2194 1759 \n", "Q 1497 1759 1228 1600 \n", "Q 959 1441 959 1056 \n", "Q 959 750 1161 570 \n", "Q 1363 391 1709 391 \n", "Q 2188 391 2477 730 \n", "Q 2766 1069 2766 1631 \n", "L 2766 1759 \n", "L 2194 1759 \n", "z\n", "M 3341 1997 \n", "L 3341 0 \n", "L 2766 0 \n", "L 2766 531 \n", "Q 2569 213 2275 61 \n", "Q 1981 -91 1556 -91 \n", "Q 1019 -91 701 211 \n", "Q 384 513 384 1019 \n", "Q 384 1609 779 1909 \n", "Q 1175 2209 1959 2209 \n", "L 2766 2209 \n", "L 2766 2266 \n", "Q 2766 2663 2505 2880 \n", "Q 2244 3097 1772 3097 \n", "Q 1472 3097 1187 3025 \n", "Q 903 2953 641 2809 \n", "L 641 3341 \n", "Q 956 3463 1253 3523 \n", "Q 1550 3584 1831 3584 \n", "Q 2591 3584 2966 3190 \n", "Q 3341 2797 3341 1997 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-74\" d=\"M 1172 4494 \n", "L 1172 3500 \n", "L 2356 3500 \n", "L 2356 3053 \n", "L 1172 3053 \n", "L 1172 1153 \n", "Q 1172 725 1289 603 \n", "Q 1406 481 1766 481 \n", "L 2356 481 \n", "L 2356 0 \n", "L 1766 0 \n", "Q 1100 0 847 248 \n", "Q 594 497 594 1153 \n", "L 594 3053 \n", "L 172 3053 \n", "L 172 3500 \n", "L 594 3500 \n", "L 594 4494 \n", "L 1172 4494 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-73\" d=\"M 2834 3397 \n", "L 2834 2853 \n", "Q 2591 2978 2328 3040 \n", "Q 2066 3103 1784 3103 \n", "Q 1356 3103 1142 2972 \n", "Q 928 2841 928 2578 \n", "Q 928 2378 1081 2264 \n", "Q 1234 2150 1697 2047 \n", "L 1894 2003 \n", "Q 2506 1872 2764 1633 \n", "Q 3022 1394 3022 966 \n", "Q 3022 478 2636 193 \n", "Q 2250 -91 1575 -91 \n", "Q 1294 -91 989 -36 \n", "Q 684 19 347 128 \n", "L 347 722 \n", "Q 666 556 975 473 \n", "Q 1284 391 1588 391 \n", "Q 1994 391 2212 530 \n", "Q 2431 669 2431 922 \n", "Q 2431 1156 2273 1281 \n", "Q 2116 1406 1581 1522 \n", "L 1381 1569 \n", "Q 847 1681 609 1914 \n", "Q 372 2147 372 2553 \n", "Q 372 3047 722 3315 \n", "Q 1072 3584 1716 3584 \n", "Q 2034 3584 2315 3537 \n", "Q 2597 3491 2834 3397 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-65\" d=\"M 3597 1894 \n", "L 3597 1613 \n", "L 953 1613 \n", "Q 991 1019 1311 708 \n", "Q 1631 397 2203 397 \n", "Q 2534 397 2845 478 \n", "Q 3156 559 3463 722 \n", "L 3463 178 \n", "Q 3153 47 2828 -22 \n", "Q 2503 -91 2169 -91 \n", "Q 1331 -91 842 396 \n", "Q 353 884 353 1716 \n", "Q 353 2575 817 3079 \n", "Q 1281 3584 2069 3584 \n", "Q 2775 3584 3186 3129 \n", "Q 3597 2675 3597 1894 \n", "z\n", "M 3022 2063 \n", "Q 3016 2534 2758 2815 \n", "Q 2500 3097 2075 3097 \n", "Q 1594 3097 1305 2825 \n", "Q 1016 2553 972 2059 \n", "L 3022 2063 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-20\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-6d\" d=\"M 3328 2828 \n", "Q 3544 3216 3844 3400 \n", "Q 4144 3584 4550 3584 \n", "Q 5097 3584 5394 3201 \n", "Q 5691 2819 5691 2113 \n", "L 5691 0 \n", "L 5113 0 \n", "L 5113 2094 \n", "Q 5113 2597 4934 2840 \n", "Q 4756 3084 4391 3084 \n", "Q 3944 3084 3684 2787 \n", "Q 3425 2491 3425 1978 \n", "L 3425 0 \n", "L 2847 0 \n", "L 2847 2094 \n", "Q 2847 2600 2669 2842 \n", "Q 2491 3084 2119 3084 \n", "Q 1678 3084 1418 2786 \n", "Q 1159 2488 1159 1978 \n", "L 1159 0 \n", "L 581 0 \n", "L 581 3500 \n", "L 1159 3500 \n", "L 1159 2956 \n", "Q 1356 3278 1631 3431 \n", "Q 1906 3584 2284 3584 \n", "Q 2666 3584 2933 3390 \n", "Q 3200 3197 3328 2828 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-70\" d=\"M 1159 525 \n", "L 1159 -1331 \n", "L 581 -1331 \n", "L 581 3500 \n", "L 1159 3500 \n", "L 1159 2969 \n", "Q 1341 3281 1617 3432 \n", "Q 1894 3584 2278 3584 \n", "Q 2916 3584 3314 3078 \n", "Q 3713 2572 3713 1747 \n", "Q 3713 922 3314 415 \n", "Q 2916 -91 2278 -91 \n", "Q 1894 -91 1617 61 \n", "Q 1341 213 1159 525 \n", "z\n", "M 3116 1747 \n", "Q 3116 2381 2855 2742 \n", "Q 2594 3103 2138 3103 \n", "Q 1681 3103 1420 2742 \n", "Q 1159 2381 1159 1747 \n", "Q 1159 1113 1420 752 \n", "Q 1681 391 2138 391 \n", "Q 2594 391 2855 752 \n", "Q 3116 1113 3116 1747 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-6c\" d=\"M 603 4863 \n", "L 1178 4863 \n", "L 1178 0 \n", "L 603 0 \n", "L 603 4863 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " </defs>\n", " <use xlink:href=\"#DejaVuSans-44\"/>\n", " <use xlink:href=\"#DejaVuSans-61\" x=\"77.001953\"/>\n", " <use xlink:href=\"#DejaVuSans-74\" x=\"138.28125\"/>\n", " <use xlink:href=\"#DejaVuSans-61\" x=\"177.490234\"/>\n", " <use xlink:href=\"#DejaVuSans-73\" x=\"238.769531\"/>\n", " <use xlink:href=\"#DejaVuSans-65\" x=\"290.869141\"/>\n", " <use xlink:href=\"#DejaVuSans-74\" x=\"352.392578\"/>\n", " <use xlink:href=\"#DejaVuSans-20\" x=\"391.601562\"/>\n", " <use xlink:href=\"#DejaVuSans-73\" x=\"423.388672\"/>\n", " <use xlink:href=\"#DejaVuSans-61\" x=\"475.488281\"/>\n", " <use xlink:href=\"#DejaVuSans-6d\" x=\"536.767578\"/>\n", " <use xlink:href=\"#DejaVuSans-70\" x=\"634.179688\"/>\n", " <use xlink:href=\"#DejaVuSans-6c\" x=\"697.65625\"/>\n", " <use xlink:href=\"#DejaVuSans-65\" x=\"725.439453\"/>\n", " <use xlink:href=\"#DejaVuSans-73\" x=\"786.962891\"/>\n", " </g>\n", " </g>\n", " <g id=\"legend_1\">\n", " <g id=\"patch_7\">\n", " <path d=\"M 200.5125 147.21625 \n", "L 268.360937 147.21625 \n", "Q 270.360937 147.21625 270.360937 145.21625 \n", "L 270.360937 116.86 \n", "Q 270.360937 114.86 268.360937 114.86 \n", "L 200.5125 114.86 \n", "Q 198.5125 114.86 198.5125 116.86 \n", "L 198.5125 145.21625 \n", "Q 198.5125 147.21625 200.5125 147.21625 \n", "z\n", "\" style=\"fill: #ffffff; opacity: 0.8; stroke: #cccccc; stroke-linejoin: miter\"/>\n", " </g>\n", " <g id=\"PathCollection_3\">\n", " <g>\n", " <use xlink:href=\"#m9c4bf21dd3\" x=\"212.5125\" y=\"123.833437\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_19\">\n", " <!-- Class 0 -->\n", " <g transform=\"translate(230.5125 126.458437)scale(0.1 -0.1)\">\n", " <defs>\n", " <path id=\"DejaVuSans-43\" d=\"M 4122 4306 \n", "L 4122 3641 \n", "Q 3803 3938 3442 4084 \n", "Q 3081 4231 2675 4231 \n", "Q 1875 4231 1450 3742 \n", "Q 1025 3253 1025 2328 \n", "Q 1025 1406 1450 917 \n", "Q 1875 428 2675 428 \n", "Q 3081 428 3442 575 \n", "Q 3803 722 4122 1019 \n", "L 4122 359 \n", "Q 3791 134 3420 21 \n", "Q 3050 -91 2638 -91 \n", "Q 1578 -91 968 557 \n", "Q 359 1206 359 2328 \n", "Q 359 3453 968 4101 \n", "Q 1578 4750 2638 4750 \n", "Q 3056 4750 3426 4639 \n", "Q 3797 4528 4122 4306 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " </defs>\n", " <use xlink:href=\"#DejaVuSans-43\"/>\n", " <use xlink:href=\"#DejaVuSans-6c\" x=\"69.824219\"/>\n", " <use xlink:href=\"#DejaVuSans-61\" x=\"97.607422\"/>\n", " <use xlink:href=\"#DejaVuSans-73\" x=\"158.886719\"/>\n", " <use xlink:href=\"#DejaVuSans-73\" x=\"210.986328\"/>\n", " <use xlink:href=\"#DejaVuSans-20\" x=\"263.085938\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"294.873047\"/>\n", " </g>\n", " </g>\n", " <g id=\"PathCollection_4\">\n", " <g>\n", " <use xlink:href=\"#me3c1da6825\" x=\"212.5125\" y=\"138.511562\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_20\">\n", " <!-- Class 1 -->\n", " <g transform=\"translate(230.5125 141.136562)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-43\"/>\n", " <use xlink:href=\"#DejaVuSans-6c\" x=\"69.824219\"/>\n", " <use xlink:href=\"#DejaVuSans-61\" x=\"97.607422\"/>\n", " <use xlink:href=\"#DejaVuSans-73\" x=\"158.886719\"/>\n", " <use xlink:href=\"#DejaVuSans-73\" x=\"210.986328\"/>\n", " <use xlink:href=\"#DejaVuSans-20\" x=\"263.085938\"/>\n", " <use xlink:href=\"#DejaVuSans-31\" x=\"294.873047\"/>\n", " </g>\n", " </g>\n", " </g>\n", " </g>\n", " </g>\n", " <defs>\n", " <clipPath id=\"pc602fbd1d7\">\n", " <rect x=\"52.160938\" y=\"22.318125\" width=\"223.2\" height=\"217.44\"/>\n", " </clipPath>\n", " </defs>\n", "</svg>\n"], "text/plain": ["<Figure size 288x288 with 1 Axes>"]}, "metadata": {"needs_background": "light"}, "output_type": "display_data"}], "source": ["visualize_samples(dataset.data, dataset.label)\n", "plt.show()"]}, {"cell_type": "markdown", "id": "15517be1", "metadata": {"papermill": {"duration": 0.018173, "end_time": "2022-05-12T11:44:51.091968", "exception": false, "start_time": "2022-05-12T11:44:51.073795", "status": "completed"}, "tags": []}, "source": ["#### The data loader class\n", "\n", "The class `torch.utils.data.DataLoader` represents a Python iterable over a dataset with support for automatic batching, multi-process data loading and many more features.\n", "The data loader communicates with the dataset using the function `__getitem__`, and stacks its outputs as tensors over the first dimension to form a batch.\n", "In contrast to the dataset class, we usually don't have to define our own data loader class, but can just create an object of it with the dataset as input.\n", "Additionally, we can configure our data loader with the following input arguments (only a selection, see full list [here](https://pytorch.org/docs/stable/data.html#torch.utils.data.DataLoader)):\n", "\n", "* `batch_size`: Number of samples to stack per batch\n", "* `shuffle`: If True, the data is returned in a random order.\n", "This is important during training for introducing stochasticity.\n", "* `num_workers`: Number of subprocesses to use for data loading.\n", "The default, 0, means that the data will be loaded in the main process which can slow down training for datasets where loading a data point takes a considerable amount of time (e.g. large images).\n", "More workers are recommended for those, but can cause issues on Windows computers.\n", "For tiny datasets as ours, 0 workers are usually faster.\n", "* `pin_memory`: If True, the data loader will copy Tensors into CUDA pinned memory before returning them.\n", "This can save some time for large data points on GPUs.\n", "Usually a good practice to use for a training set, but not necessarily for validation and test to save memory on the GPU.\n", "* `drop_last`: If True, the last batch is dropped in case it is smaller than the specified batch size.\n", "This occurs when the dataset size is not a multiple of the batch size.\n", "Only potentially helpful during training to keep a consistent batch size.\n", "\n", "Let's create a simple data loader below:"]}, {"cell_type": "code", "execution_count": 43, "id": "c92e0b1f", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:51.132953Z", "iopub.status.busy": "2022-05-12T11:44:51.132455Z", "iopub.status.idle": "2022-05-12T11:44:51.137249Z", "shell.execute_reply": "2022-05-12T11:44:51.136504Z"}, "papermill": {"duration": 0.027282, "end_time": "2022-05-12T11:44:51.138825", "exception": false, "start_time": "2022-05-12T11:44:51.111543", "status": "completed"}, "tags": []}, "outputs": [], "source": ["data_loader = data.DataLoader(dataset, batch_size=8, shuffle=True)"]}, {"cell_type": "code", "execution_count": 44, "id": "3cecbb71", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:51.179767Z", "iopub.status.busy": "2022-05-12T11:44:51.179277Z", "iopub.status.idle": "2022-05-12T11:44:51.186082Z", "shell.execute_reply": "2022-05-12T11:44:51.185384Z"}, "papermill": {"duration": 0.029377, "end_time": "2022-05-12T11:44:51.187671", "exception": false, "start_time": "2022-05-12T11:44:51.158294", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Data inputs torch.Size([8, 2]) \n", " tensor([[-0.0890, 0.8608],\n", " [ 1.0905, -0.0128],\n", " [ 0.7967, 0.2268],\n", " [-0.0688, 0.0371],\n", " [ 0.8732, -0.2240],\n", " [-0.0559, -0.0282],\n", " [ 0.9277, 0.0978],\n", " [ 1.0150, 0.9689]])\n", "Data labels torch.Size([8]) \n", " tensor([1, 1, 1, 0, 1, 0, 1, 0])\n"]}], "source": ["# next(iter(...)) catches the first batch of the data loader\n", "# If shuffle is True, this will return a different batch every time we run this cell\n", "# For iterating over the whole dataset, we can simple use \"for batch in data_loader: ...\"\n", "data_inputs, data_labels = next(iter(data_loader))\n", "\n", "# The shape of the outputs are [batch_size, d_1,...,d_N] where d_1,...,d_N are the\n", "# dimensions of the data point returned from the dataset class\n", "print(\"Data inputs\", data_inputs.shape, \"\\n\", data_inputs)\n", "print(\"Data labels\", data_labels.shape, \"\\n\", data_labels)"]}, {"cell_type": "markdown", "id": "0ea28926", "metadata": {"papermill": {"duration": 0.018884, "end_time": "2022-05-12T11:44:51.225856", "exception": false, "start_time": "2022-05-12T11:44:51.206972", "status": "completed"}, "tags": []}, "source": ["### Optimization\n", "\n", "After defining the model and the dataset, it is time to prepare the optimization of the model.\n", "During training, we will perform the following steps:\n", "\n", "1. Get a batch from the data loader\n", "2. Obtain the predictions from the model for the batch\n", "3. Calculate the loss based on the difference between predictions and labels\n", "4. Backpropagation: calculate the gradients for every parameter with respect to the loss\n", "5. Update the parameters of the model in the direction of the gradients\n", "\n", "We have seen how we can do step 1, 2 and 4 in PyTorch. Now, we will look at step 3 and 5."]}, {"cell_type": "markdown", "id": "23d434aa", "metadata": {"papermill": {"duration": 0.018939, "end_time": "2022-05-12T11:44:51.265448", "exception": false, "start_time": "2022-05-12T11:44:51.246509", "status": "completed"}, "tags": []}, "source": ["#### Loss modules\n", "\n", "We can calculate the loss for a batch by simply performing a few tensor operations as those are automatically added to the computation graph.\n", "For instance, for binary classification, we can use Binary Cross Entropy (BCE) which is defined as follows:\n", "\n", "$$\\mathcal{L}_{BCE} = -\\sum_i \\left[ y_i \\log x_i + (1 - y_i) \\log (1 - x_i) \\right]$$\n", "\n", "where $y$ are our labels, and $x$ our predictions, both in the range of $[0,1]$.\n", "However, PyTorch already provides a list of predefined loss functions which we can use (see [here](https://pytorch.org/docs/stable/nn.html#loss-functions) for a full list).\n", "For instance, for BCE, PyTorch has two modules: `nn.BCELoss()`, `nn.BCEWithLogitsLoss()`.\n", "While `nn.BCELoss` expects the inputs $x$ to be in the range $[0,1]$, i.e. the output of a sigmoid, `nn.BCEWithLogitsLoss` combines a sigmoid layer and the BCE loss in a single class.\n", "This version is numerically more stable than using a plain Sigmoid followed by a BCE loss because of the logarithms applied in the loss function.\n", "Hence, it is adviced to use loss functions applied on \"logits\" where possible (remember to not apply a sigmoid on the output of the model in this case!).\n", "For our model defined above, we therefore use the module `nn.BCEWithLogitsLoss`."]}, {"cell_type": "code", "execution_count": 45, "id": "1bd60358", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:51.305947Z", "iopub.status.busy": "2022-05-12T11:44:51.305432Z", "iopub.status.idle": "2022-05-12T11:44:51.309449Z", "shell.execute_reply": "2022-05-12T11:44:51.308812Z"}, "papermill": {"duration": 0.026566, "end_time": "2022-05-12T11:44:51.310959", "exception": false, "start_time": "2022-05-12T11:44:51.284393", "status": "completed"}, "tags": []}, "outputs": [], "source": ["loss_module = nn.BCEWithLogitsLoss()"]}, {"cell_type": "markdown", "id": "c5c33644", "metadata": {"papermill": {"duration": 0.020223, "end_time": "2022-05-12T11:44:51.350213", "exception": false, "start_time": "2022-05-12T11:44:51.329990", "status": "completed"}, "tags": []}, "source": ["#### Stochastic Gradient Descent\n", "\n", "For updating the parameters, PyTorch provides the package `torch.optim` that has most popular optimizers implemented.\n", "We will discuss the specific optimizers and their differences later in the course, but will for now use the simplest of them: `torch.optim.SGD`.\n", "Stochastic Gradient Descent updates parameters by multiplying the gradients with a small constant, called learning rate, and subtracting those from the parameters (hence minimizing the loss).\n", "Therefore, we slowly move towards the direction of minimizing the loss.\n", "A good default value of the learning rate for a small network as ours is 0.1."]}, {"cell_type": "code", "execution_count": 46, "id": "efbcc924", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:51.389163Z", "iopub.status.busy": "2022-05-12T11:44:51.388685Z", "iopub.status.idle": "2022-05-12T11:44:51.392786Z", "shell.execute_reply": "2022-05-12T11:44:51.392156Z"}, "papermill": {"duration": 0.025047, "end_time": "2022-05-12T11:44:51.394344", "exception": false, "start_time": "2022-05-12T11:44:51.369297", "status": "completed"}, "tags": []}, "outputs": [], "source": ["# Input to the optimizer are the parameters of the model: model.parameters()\n", "optimizer = torch.optim.SGD(model.parameters(), lr=0.1)"]}, {"cell_type": "markdown", "id": "19480eaf", "metadata": {"papermill": {"duration": 0.017798, "end_time": "2022-05-12T11:44:51.429939", "exception": false, "start_time": "2022-05-12T11:44:51.412141", "status": "completed"}, "tags": []}, "source": ["The optimizer provides two useful functions: `optimizer.step()`, and `optimizer.zero_grad()`.\n", "The step function updates the parameters based on the gradients as explained above.\n", "The function `optimizer.zero_grad()` sets the gradients of all parameters to zero.\n", "While this function seems less relevant at first, it is a crucial pre-step before performing backpropagation.\n", "If we would call the `backward` function on the loss while the parameter gradients are non-zero from the previous batch, the new gradients would actually be added to the previous ones instead of overwriting them.\n", "This is done because a parameter might occur multiple times in a computation graph, and we need to sum the gradients in this case instead of replacing them.\n", "Hence, remember to call `optimizer.zero_grad()` before calculating the gradients of a batch."]}, {"cell_type": "markdown", "id": "ccaab844", "metadata": {"papermill": {"duration": 0.017645, "end_time": "2022-05-12T11:44:51.465911", "exception": false, "start_time": "2022-05-12T11:44:51.448266", "status": "completed"}, "tags": []}, "source": ["### Training\n", "\n", "Finally, we are ready to train our model.\n", "As a first step, we create a slightly larger dataset and specify a data loader with a larger batch size."]}, {"cell_type": "code", "execution_count": 47, "id": "460b33b3", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:51.503355Z", "iopub.status.busy": "2022-05-12T11:44:51.502870Z", "iopub.status.idle": "2022-05-12T11:44:51.507486Z", "shell.execute_reply": "2022-05-12T11:44:51.506855Z"}, "papermill": {"duration": 0.025412, "end_time": "2022-05-12T11:44:51.508996", "exception": false, "start_time": "2022-05-12T11:44:51.483584", "status": "completed"}, "tags": []}, "outputs": [], "source": ["train_dataset = XORDataset(size=1000)\n", "train_data_loader = data.DataLoader(train_dataset, batch_size=128, shuffle=True)"]}, {"cell_type": "markdown", "id": "f44c0887", "metadata": {"papermill": {"duration": 0.017844, "end_time": "2022-05-12T11:44:51.544208", "exception": false, "start_time": "2022-05-12T11:44:51.526364", "status": "completed"}, "tags": []}, "source": ["Now, we can write a small training function.\n", "Remember our five steps: load a batch, obtain the predictions, calculate the loss, backpropagate, and update.\n", "Additionally, we have to push all data and model parameters to the device of our choice (GPU if available).\n", "For the tiny neural network we have, communicating the data to the GPU actually takes much more time than we could save from running the operation on GPU.\n", "For large networks, the communication time is significantly smaller than the actual runtime making a GPU crucial in these cases.\n", "Still, to practice, we will push the data to GPU here."]}, {"cell_type": "code", "execution_count": 48, "id": "149cf212", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:51.580193Z", "iopub.status.busy": "2022-05-12T11:44:51.579757Z", "iopub.status.idle": "2022-05-12T11:44:51.585260Z", "shell.execute_reply": "2022-05-12T11:44:51.584669Z"}, "papermill": {"duration": 0.025374, "end_time": "2022-05-12T11:44:51.586790", "exception": false, "start_time": "2022-05-12T11:44:51.561416", "status": "completed"}, "tags": []}, "outputs": [{"data": {"text/plain": ["SimpleClassifier(\n", " (linear1): Linear(in_features=2, out_features=4, bias=True)\n", " (act_fn): Tanh()\n", " (linear2): Linear(in_features=4, out_features=1, bias=True)\n", ")"]}, "execution_count": 48, "metadata": {}, "output_type": "execute_result"}], "source": ["# Push model to device. Has to be only done once\n", "model.to(device)"]}, {"cell_type": "markdown", "id": "96a036aa", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.017275, "end_time": "2022-05-12T11:44:51.621536", "exception": false, "start_time": "2022-05-12T11:44:51.604261", "status": "completed"}, "tags": []}, "source": ["In addition, we set our model to training mode.\n", "This is done by calling `model.train()`.\n", "There exist certain modules that need to perform a different forward\n", "step during training than during testing (e.g. BatchNorm and Dropout),\n", "and we can switch between them using `model.train()` and `model.eval()`."]}, {"cell_type": "code", "execution_count": 49, "id": "751e4fec", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:51.658853Z", "iopub.status.busy": "2022-05-12T11:44:51.658393Z", "iopub.status.idle": "2022-05-12T11:44:51.663890Z", "shell.execute_reply": "2022-05-12T11:44:51.663279Z"}, "papermill": {"duration": 0.025777, "end_time": "2022-05-12T11:44:51.665380", "exception": false, "start_time": "2022-05-12T11:44:51.639603", "status": "completed"}, "tags": []}, "outputs": [], "source": ["def train_model(model, optimizer, data_loader, loss_module, num_epochs=100):\n", " # Set model to train mode\n", " model.train()\n", "\n", " # Training loop\n", " for epoch in tqdm(range(num_epochs)):\n", " for data_inputs, data_labels in data_loader:\n", "\n", " # Step 1: Move input data to device (only strictly necessary if we use GPU)\n", " data_inputs = data_inputs.to(device)\n", " data_labels = data_labels.to(device)\n", "\n", " # Step 2: Run the model on the input data\n", " preds = model(data_inputs)\n", " preds = preds.squeeze(dim=1) # Output is [Batch size, 1], but we want [Batch size]\n", "\n", " # Step 3: Calculate the loss\n", " loss = loss_module(preds, data_labels.float())\n", "\n", " # Step 4: Perform backpropagation\n", " # Before calculating the gradients, we need to ensure that they are all zero.\n", " # The gradients would not be overwritten, but actually added to the existing ones.\n", " optimizer.zero_grad()\n", " # Perform backpropagation\n", " loss.backward()\n", "\n", " # Step 5: Update the parameters\n", " optimizer.step()"]}, {"cell_type": "code", "execution_count": 50, "id": "32bacfb9", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:51.701338Z", "iopub.status.busy": "2022-05-12T11:44:51.700790Z", "iopub.status.idle": "2022-05-12T11:44:52.936363Z", "shell.execute_reply": "2022-05-12T11:44:52.935636Z"}, "papermill": {"duration": 1.255539, "end_time": "2022-05-12T11:44:52.938272", "exception": false, "start_time": "2022-05-12T11:44:51.682733", "status": "completed"}, "tags": []}, "outputs": [{"data": {"application/vnd.jupyter.widget-view+json": {"model_id": "6c81d8acef7946e88461ecd6916a7ba3", "version_major": 2, "version_minor": 0}, "text/plain": [" 0%| | 0/100 [00:00<?, ?it/s]"]}, "metadata": {}, "output_type": "display_data"}], "source": ["train_model(model, optimizer, train_data_loader, loss_module)"]}, {"cell_type": "markdown", "id": "3a0e4186", "metadata": {"papermill": {"duration": 0.017549, "end_time": "2022-05-12T11:44:52.975305", "exception": false, "start_time": "2022-05-12T11:44:52.957756", "status": "completed"}, "tags": []}, "source": ["#### Saving a model\n", "\n", "After finish training a model, we save the model to disk so that we can load the same weights at a later time.\n", "For this, we extract the so-called `state_dict` from the model which contains all learnable parameters.\n", "For our simple model, the state dict contains the following entries:"]}, {"cell_type": "code", "execution_count": 51, "id": "2667b854", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:53.011804Z", "iopub.status.busy": "2022-05-12T11:44:53.011367Z", "iopub.status.idle": "2022-05-12T11:44:53.018660Z", "shell.execute_reply": "2022-05-12T11:44:53.018057Z"}, "papermill": {"duration": 0.027403, "end_time": "2022-05-12T11:44:53.020101", "exception": false, "start_time": "2022-05-12T11:44:52.992698", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["OrderedDict([('linear1.weight', tensor([[-2.0209, -2.3101],\n", " [ 1.3066, -1.8463],\n", " [-1.5089, -0.6550],\n", " [-0.7824, -0.9385]], device='cuda:0')), ('linear1.bias', tensor([ 0.7382, -0.9136, 1.4607, -0.1769], device='cuda:0')), ('linear2.weight', tensor([[-2.5543, 1.9722, 2.1591, -0.4553]], device='cuda:0')), ('linear2.bias', tensor([-1.0225], device='cuda:0'))])\n"]}], "source": ["state_dict = model.state_dict()\n", "print(state_dict)"]}, {"cell_type": "markdown", "id": "1b541cb7", "metadata": {"papermill": {"duration": 0.018227, "end_time": "2022-05-12T11:44:53.056004", "exception": false, "start_time": "2022-05-12T11:44:53.037777", "status": "completed"}, "tags": []}, "source": ["To save the state dictionary, we can use `torch.save`:"]}, {"cell_type": "code", "execution_count": 52, "id": "e7a963bc", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:53.093500Z", "iopub.status.busy": "2022-05-12T11:44:53.093039Z", "iopub.status.idle": "2022-05-12T11:44:53.097830Z", "shell.execute_reply": "2022-05-12T11:44:53.097177Z"}, "papermill": {"duration": 0.025423, "end_time": "2022-05-12T11:44:53.099286", "exception": false, "start_time": "2022-05-12T11:44:53.073863", "status": "completed"}, "tags": []}, "outputs": [], "source": ["# torch.save(object, filename). For the filename, any extension can be used\n", "torch.save(state_dict, \"our_model.tar\")"]}, {"cell_type": "markdown", "id": "4230e123", "metadata": {"papermill": {"duration": 0.017977, "end_time": "2022-05-12T11:44:53.134726", "exception": false, "start_time": "2022-05-12T11:44:53.116749", "status": "completed"}, "tags": []}, "source": ["To load a model from a state dict, we use the function `torch.load` to\n", "load the state dict from the disk, and the module function\n", "`load_state_dict` to overwrite our parameters with the new values:"]}, {"cell_type": "code", "execution_count": 53, "id": "e03d71e7", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:53.173704Z", "iopub.status.busy": "2022-05-12T11:44:53.173212Z", "iopub.status.idle": "2022-05-12T11:44:53.185212Z", "shell.execute_reply": "2022-05-12T11:44:53.184498Z"}, "papermill": {"duration": 0.033241, "end_time": "2022-05-12T11:44:53.186899", "exception": false, "start_time": "2022-05-12T11:44:53.153658", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Original model\n", " OrderedDict([('linear1.weight', tensor([[-2.0209, -2.3101],\n", " [ 1.3066, -1.8463],\n", " [-1.5089, -0.6550],\n", " [-0.7824, -0.9385]], device='cuda:0')), ('linear1.bias', tensor([ 0.7382, -0.9136, 1.4607, -0.1769], device='cuda:0')), ('linear2.weight', tensor([[-2.5543, 1.9722, 2.1591, -0.4553]], device='cuda:0')), ('linear2.bias', tensor([-1.0225], device='cuda:0'))])\n", "\n", "Loaded model\n", " OrderedDict([('linear1.weight', tensor([[-2.0209, -2.3101],\n", " [ 1.3066, -1.8463],\n", " [-1.5089, -0.6550],\n", " [-0.7824, -0.9385]])), ('linear1.bias', tensor([ 0.7382, -0.9136, 1.4607, -0.1769])), ('linear2.weight', tensor([[-2.5543, 1.9722, 2.1591, -0.4553]])), ('linear2.bias', tensor([-1.0225]))])\n"]}], "source": ["# Load state dict from the disk (make sure it is the same name as above)\n", "state_dict = torch.load(\"our_model.tar\")\n", "\n", "# Create a new model and load the state\n", "new_model = SimpleClassifier(num_inputs=2, num_hidden=4, num_outputs=1)\n", "new_model.load_state_dict(state_dict)\n", "\n", "# Verify that the parameters are the same\n", "print(\"Original model\\n\", model.state_dict())\n", "print(\"\\nLoaded model\\n\", new_model.state_dict())"]}, {"cell_type": "markdown", "id": "aa8be316", "metadata": {"papermill": {"duration": 0.266822, "end_time": "2022-05-12T11:44:53.473399", "exception": false, "start_time": "2022-05-12T11:44:53.206577", "status": "completed"}, "tags": []}, "source": ["A detailed tutorial on saving and loading models in PyTorch can be found\n", "[here](https://pytorch.org/tutorials/beginner/saving_loading_models.html)."]}, {"cell_type": "markdown", "id": "0b7a0e3f", "metadata": {"papermill": {"duration": 0.031138, "end_time": "2022-05-12T11:44:53.523764", "exception": false, "start_time": "2022-05-12T11:44:53.492626", "status": "completed"}, "tags": []}, "source": ["### Evaluation\n", "\n", "Once we have trained a model, it is time to evaluate it on a held-out test set.\n", "As our dataset consist of randomly generated data points, we need to\n", "first create a test set with a corresponding data loader."]}, {"cell_type": "code", "execution_count": 54, "id": "5c6f8bdf", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:53.561402Z", "iopub.status.busy": "2022-05-12T11:44:53.560936Z", "iopub.status.idle": "2022-05-12T11:44:53.565688Z", "shell.execute_reply": "2022-05-12T11:44:53.565043Z"}, "papermill": {"duration": 0.025562, "end_time": "2022-05-12T11:44:53.567189", "exception": false, "start_time": "2022-05-12T11:44:53.541627", "status": "completed"}, "tags": []}, "outputs": [], "source": ["test_dataset = XORDataset(size=500)\n", "# drop_last -> Don't drop the last batch although it is smaller than 128\n", "test_data_loader = data.DataLoader(test_dataset, batch_size=128, shuffle=False, drop_last=False)"]}, {"cell_type": "markdown", "id": "301f14ee", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.017588, "end_time": "2022-05-12T11:44:53.602593", "exception": false, "start_time": "2022-05-12T11:44:53.585005", "status": "completed"}, "tags": []}, "source": ["As metric, we will use accuracy which is calculated as follows:\n", "\n", "$$acc = \\frac{\\#\\text{correct predictions}}{\\#\\text{all predictions}} = \\frac{TP+TN}{TP+TN+FP+FN}$$\n", "\n", "where TP are the true positives, TN true negatives, FP false positives, and FN the fale negatives.\n", "\n", "When evaluating the model, we don't need to keep track of the computation graph as we don't intend to calculate the gradients.\n", "This reduces the required memory and speed up the model.\n", "In PyTorch, we can deactivate the computation graph using `with torch.no_grad(): ...`.\n", "Remember to additionally set the model to eval mode."]}, {"cell_type": "code", "execution_count": 55, "id": "2ce4dfdc", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:53.639163Z", "iopub.status.busy": "2022-05-12T11:44:53.638572Z", "iopub.status.idle": "2022-05-12T11:44:53.644410Z", "shell.execute_reply": "2022-05-12T11:44:53.643234Z"}, "papermill": {"duration": 0.025573, "end_time": "2022-05-12T11:44:53.645950", "exception": false, "start_time": "2022-05-12T11:44:53.620377", "status": "completed"}, "tags": []}, "outputs": [], "source": ["def eval_model(model, data_loader):\n", " model.eval() # Set model to eval mode\n", " true_preds, num_preds = 0.0, 0.0\n", "\n", " with torch.no_grad(): # Deactivate gradients for the following code\n", " for data_inputs, data_labels in data_loader:\n", "\n", " # Determine prediction of model on dev set\n", " data_inputs, data_labels = data_inputs.to(device), data_labels.to(device)\n", " preds = model(data_inputs)\n", " preds = preds.squeeze(dim=1)\n", " preds = torch.sigmoid(preds) # Sigmoid to map predictions between 0 and 1\n", " pred_labels = (preds >= 0.5).long() # Binarize predictions to 0 and 1\n", "\n", " # Keep records of predictions for the accuracy metric (true_preds=TP+TN, num_preds=TP+TN+FP+FN)\n", " true_preds += (pred_labels == data_labels).sum()\n", " num_preds += data_labels.shape[0]\n", "\n", " acc = true_preds / num_preds\n", " print(f\"Accuracy of the model: {100.0*acc:4.2f}%\")"]}, {"cell_type": "code", "execution_count": 56, "id": "50dd638b", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:53.684343Z", "iopub.status.busy": "2022-05-12T11:44:53.683785Z", "iopub.status.idle": "2022-05-12T11:44:53.692547Z", "shell.execute_reply": "2022-05-12T11:44:53.691898Z"}, "papermill": {"duration": 0.030384, "end_time": "2022-05-12T11:44:53.694096", "exception": false, "start_time": "2022-05-12T11:44:53.663712", "status": "completed"}, "tags": []}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["Accuracy of the model: 100.00%\n"]}], "source": ["eval_model(model, test_data_loader)"]}, {"cell_type": "markdown", "id": "c3591c0c", "metadata": {"papermill": {"duration": 0.018406, "end_time": "2022-05-12T11:44:53.730871", "exception": false, "start_time": "2022-05-12T11:44:53.712465", "status": "completed"}, "tags": []}, "source": ["If we trained our model correctly, we should see a score close to 100% accuracy.\n", "However, this is only possible because of our simple task, and\n", "unfortunately, we usually don't get such high scores on test sets of\n", "more complex tasks."]}, {"cell_type": "markdown", "id": "11d3d9f0", "metadata": {"lines_to_next_cell": 2, "papermill": {"duration": 0.019643, "end_time": "2022-05-12T11:44:53.770979", "exception": false, "start_time": "2022-05-12T11:44:53.751336", "status": "completed"}, "tags": []}, "source": ["#### Visualizing classification boundaries\n", "\n", "To visualize what our model has learned, we can perform a prediction for every data point in a range of $[-0.5, 1.5]$, and visualize the predicted class as in the sample figure at the beginning of this section.\n", "This shows where the model has created decision boundaries, and which points would be classified as $0$, and which as $1$.\n", "We therefore get a background image out of blue (class 0) and orange (class 1).\n", "The spots where the model is uncertain we will see a blurry overlap.\n", "The specific code is less relevant compared to the output figure which\n", "should hopefully show us a clear separation of classes:"]}, {"cell_type": "code", "execution_count": 57, "id": "21d8dddf", "metadata": {"execution": {"iopub.execute_input": "2022-05-12T11:44:53.812221Z", "iopub.status.busy": "2022-05-12T11:44:53.811746Z", "iopub.status.idle": "2022-05-12T11:44:54.277287Z", "shell.execute_reply": "2022-05-12T11:44:54.276542Z"}, "papermill": {"duration": 0.489666, "end_time": "2022-05-12T11:44:54.280158", "exception": false, "start_time": "2022-05-12T11:44:53.790492", "status": "completed"}, "tags": []}, "outputs": [{"data": {"application/pdf": "JVBERi0xLjQKJazcIKu6CjEgMCBvYmoKPDwgL1BhZ2VzIDIgMCBSIC9UeXBlIC9DYXRhbG9nID4+CmVuZG9iago4IDAgb2JqCjw8IC9FeHRHU3RhdGUgNCAwIFIgL0ZvbnQgMyAwIFIgL1BhdHRlcm4gNSAwIFIKL1Byb2NTZXQgWyAvUERGIC9UZXh0IC9JbWFnZUIgL0ltYWdlQyAvSW1hZ2VJIF0gL1NoYWRpbmcgNiAwIFIKL1hPYmplY3QgNyAwIFIgPj4KZW5kb2JqCjExIDAgb2JqCjw8IC9Bbm5vdHMgMTAgMCBSIC9Db250ZW50cyA5IDAgUiAvTWVkaWFCb3ggWyAwIDAgMjkxLjEwNTYyNSAyNzcuMzA4NzUgXQovUGFyZW50IDIgMCBSIC9SZXNvdXJjZXMgOCAwIFIgL1R5cGUgL1BhZ2UgPj4KZW5kb2JqCjkgMCBvYmoKPDwgL0ZpbHRlciAvRmxhdGVEZWNvZGUgL0xlbmd0aCAxMiAwIFIgPj4Kc3RyZWFtCnicrZtLsxw3coX3/StqObO4RQCJ51IaWQpPhBeyGOOFwwsGzaFHQcnWcMbyz/d3UN1d1X2z76Ud0pOFiyok8nHyZAL3zTcf/vsv7z/883dfL3/44fRmf3r/+RSXH09vvorLx89LWH7k31+XuHy33E4KjP90SiOuMZSaCo+fjo+ptdVCb4XhcPekqf9xOv3MSh95+I7PfzydSl9L5E1ra8nGVD7fyjrKcezTPpZKXkffBi/vHsdY4c+nX5Znn02xrTlf/vfXD8u/LD8vb75K2i9b599fp1C3+/2FF/oi2fX/Zx99/9Py5h/j8s1/Lt+fvl/+j6uGNaZYaq/sjYdcz3+1U1hbKL0nK2ksf/24y7cmJHz43nL33ukXVC3Z4xJjWmMcxVqM0ZaR19Ryi8V6qXMX/xTYxT491DWHaGaljMGjrZZCLyXmUJz5SQ6QQqyIlZanuKbew0ixju7MfoqoA29hyuhN8yOS1zR6sBy9F7B9bmZp5MR09jz6QMYRkjc72dq6xRJCrn3RzkfmT2jIkyZaXluOuTIL4bXX2LKVFpo7/0k2HqmnUPJYylpjMqlmZHerobN8QxEDE/GcwlqGWc01RG+vslRJCNNbG5XHvo6YC+5HNPkrlDWkgTDJtEAsa0F+XCRVcxcYayzSHnJo+wlT19D7KNG3FupEPXzeyqbdYdnYCIt48zMqIQqwZ7DF1h6IzB5L8xxt6icMvoQ4TEc/kVAOPeRYm6tRls8591w66md2S8N6xniuI6e2hoA35BhGWxp+Hy1myz160xOOg2ZSl+rRY+WtkoP76aeEoYLhJCnlBaUavtzk0MP3+YTeiA/5StGzHCPjfc2qZ9jpl22kkJphmGhjDQ0fxmjV1XvFUUoY0XqUdFFulFtLNTzQPIavvVvCO/PyBIinFlNu4LUnTx9gWkSXQja8yPA6lgv4nitODHENsYVaLGQFOaYgfovlYtHdcAiroVHQC++fgdAxNAYj2HyVCv1kTUNPWjHgbdUGBiyu66e+5lRBqVLQuTQwShMQVXN1BOwNHM0Amqzvr0iX5CHdjZS8Yv0uAXDlmJmdUWcgcn3xC/Nx9pbrtpnOMlireB9H+8bfvcao2QPJybhDqPggaLONBIijO8MXZNoMfnuWXYF10A5LdRyHXFoTicKIcRc/Vn7SKv8E5R9ShCm8H+CfwLWn2gi/vqAScJgMlVyfRCHYchAPOfW5hxAMhQxzoaABZPwY71AERSNLGNEHhHTv6xbwPxQW8JgyVUhCAGZKd/eJRQgosJeAtcFG8RtAjE0/yGm2kh9JUUTI0DNKrxP4S3DzDvFhZIagkMsL4YcrD6VE112AC2AA7wWOIDzQiRFrxaQPfKuiG0IotDCzAmBlhK+NiMu57oU/BSPbpypHxv4koNKKl+7r2oasXkmvpA/yvhDbvJDrFZMGciTAunQiOsnL4CGu2JikjKnCKu6EyiE0AwbpqnyAuQGHSgm6sQGMrKn4d4kBYL6OgOCCOLEaHB+osCoM8SHMBDAkMiBDWgxZJmNBduA6sJI3FuywYUF2XHttBC3Mwl9AHk+QlgSMts1M/LGAStFNxpKoE8VNQGBLxyn4ei2huBEyZBul1wqLS0I78hk+Uf0UJXkhbSxQ85ax8PekhFh9qpIBGVI1IXUGbLJlG42k4GZXk98o9uuMkEz+rGRmcMzXDnDNNkNlkZQ2cxjIkHKpw1sAPMgFkJN/AWQVAEb6ZL17XiwemVpSyiFbIFy1ULBIs0dIBo0v8CzYmF5GMFhf9UMEQbS72CPkcBFHA9OUnXt3v46wpKEwCFCbudzYtoDNBQNIJOCsPEq2XHgXYAiGXf00BiVA8/yQ0JskS6gss8IF6yPalOTGkEhs08nkBrMh4l1+LgpHWs9BOAxZxzqESpKeHhCPgheOXkfLG1HATgQh77vyU031AjkBlFir5waipOQyOCXpBicjZMm+i9LghMwO8DvTheqQJsgtATq9n8+2B0UR/k1uxyMr6p42zRigUyU9ADOQHBCtyqNPk4hanvj2CGtKIK5ZHTDrBEeFwEnjfmTnioaxqAmPOwUAUZrdQILYgRKFREnCxjz4/DBom4sCkxZGhTU8U55gFHO5CzOGKzj6hiqwNVyEpai0gMcR8oO8JPNAwTI+KMdEGlG+mW4eFCuztMG/W5ucOE2Mly4f8B5cBRIGStvUuimo8DQ/q2qzMAwkIO/BEEoNmcIoPuDMJN5kBB4paUIkzzwQKaCsi9dEGvVGVr2I3fUYGwiIpV2O8qTKG95mfei/WmFMYAA7ogs0BGpVfUheSjiCtA+Zo75xv466zTCkMhimRjZ2w4ddEjmIaxgJeBrGli7JTVG1l3mSkLypPOAyIuMATEKNfiQ9qf5H09TozKbq4hURXzDBDSSiFJNTkZe85UxejhTRw60pN4+laoJkzJxKlocPBbEZVxg0nIgeSsoil8HCJLCgkHLjo6wERWzU2HUZuFuUuwSVl57shL0ynJKSwhoa1sV/qEDdvbI3+M+kMAUlSpnUW64xCQXCAnhDD+pKENaRdFpcXARCySeEmhROeqHE5TXM75Z6ECP22TEmjqFKlcIP4gQJcnk4hWzIBACpXxFFGUqMU/X56oaaZlZXCd9EqgxpcNlB1eSyQtEACgASilih9K/CFr5db6b/Pzpwwv+srtNIiHyivANq4DKVlP2s7XY7ebmbfOi1aSkYHAaG6ZBVII3EO8TIyiW9xVuPEg2tYoD4BHhKEkIZpI3hzCatpMq6ShUTQVfxLSIpmffxrQ6JCjYSKAkR6jAwO3BkvjSwCeoQcAFWOiHORKMIhkuZf//9BrcgcfYzpVYFDNWhdHemD7GsJvSBwp19gUgLEIaLMW8/X8F/igB1K9vMBgJ3ILteelu3n49CCn4oXUp24Jaslwv0xBPnCfyGABBspv6dSt84VHL05uoGhpAhrOqUFfCOWd3m265m8NuqQgFlj63ei1ThGFpdzOcv2NjYblXLYeZVnrCziL73+aIJFI95whyyW29qdSXztopbAVgd00KiREYGMdrIpb5VqxQNEJHOhc8Y1opgz/UYHBzTwGz7dMmkuqoVdnmtTu++bqoDyVqwnUVLkXxFTrK3UYIJqIKBEGtqLVdxdoQprkEH3NJqUOGLxUFfSxgUFDVPEogtBB1k5tttq+9wHrH85H0dtgLVKZSEJU2Sjv7h0HZtEN75rkh2gRsMQlPNBDKQKhI3rHFthKRwqSbr20rMqtlH8nCmo/LSABqIEeQyCTPIzIRG8M0JbyLcIZ8Dj1w6hRisSAmxe/PVE+bnVAEU18paVFJpQl1y9bJ14mA5FUQk8FA7FTaloxipF6ZlVVMYQ6pQVI40Ndsp3S4k6nkkkaEphuTvel2ZDOdqw7OqIA6ClYKavBQPiQwMgWr+XoOaiCF2OOBsIpLAEhF1rk5csyJHyVmm1FoQktn9cIP6qQNgOCTlCAG1jMnQqNalThdh0grbKqp12tjoAzyGMqBlP5SiGjsNc/YB54MqdbUo8XkfNZLqIYJvbPSYQCWeqGJcO81I1skFVWssW7O+ZbW44wNHm9xLFXUv7E+pg+KLWuN6VHAvfVnVHYbwoM3pN1UUMhIynmFN2YUqHYTMEwuoGsgGKbkxQh2K17SsboYgh2hlenDz5NAxC3hF5TKRgFIAMZqeHiheyYKyRfFaxeypDKq6kYjjyT4b5gFAGL3ozIsFiUeCxlr3AUFlMfABzaE6EScLlA6s4KuerD3EA/o8sBNji6TNmpureNwEzQB9QmjcoEFpRN59lByrPFaqn418UDKn2TmzB/hOETP5Y56FSNeJFLlDFYybVqtiqBGEJU4jR7UCVLN5swGvLO8NXU21efwFjmVQP7voITRQquu9yYdnIxQ3gCM8IDQ6+0STekEHcORK8lPXSU/z3CzrVGOQYeLMT0Bb0TlPG8NLlugCaeC+I87yDvRJTIVvgVgP0IZqR2Ad8gxYuDL5afhO03XqI+JW8N15jFuVPAMljZuiTG0GkKNTlPRZfWTcAkITPeiTaSj/IG+mToJ4+zxqdGVRxJm6922eworHTdQebpZXSSgaCLJ2NYUENDACeG32Pk4ipiDJMEdiW8coUbVP8TEVIFC3A6PLYWBZOhixYdFzlwlJsLqWzy1f3Eu5gWzopz5oG3GTCOsM5M5TLqo90kcvnrtovr6dweGtnCU1k/fZdXNhTB2t2a+xGX5xnrgkdayC52Dz9BuCYvAlZRCLckhdCfBxQxCNhZKaLLNYZtvkjuizyKcBo64DwpTYXcyESspAzd4Pv0VVFZogDdXA7PiSP4y8Sh0XfH8UjzBMYNmC/JdgKQX3Lb678/2ayY+UHGkscD9KDyhUupaet6oXH4/AHJngfJxHXGT1TV1eO4sZMLRJFgE2Gs2i+8GXPUWAw7qOQ2YtBJmkloCTXw/SbpUDJaMMUwu3yOH1XtNcH1NhQGI8Saj4pA6qCEXtbu0xSU3GbclGVbDQJVkiT47mOT1mAmCU6jGjOko4C5zD/LngCXinKxWTyrPDqn6Yj19dXSOdiw3B71CLHg6nHO/5V4WQ41zkdHS9qVRHFvw9XKqXFQ2UPFlnVbr/ouYdpYXvLiT1IPMwo6ntZGR7vuzTPJk/1+2uQdBFDHX8wep5hO9bqGFvtbQg8Owaw6uh7/L3rUZCTLw3nq+FUBhHyMmjnAqwQEiaTjj7bCTCZ1WrXM+i76nVGjBREBhVXcNQT77NKxwOCGxdyq4m/2xIqN9ClUsguRCjHkIQCe4bfSBcU65uFaRDJT6cBqA1j13hTa3MMz7rbiYwNQd1caDqWE8dUwCDqGuu6E+9rTp9liUVdZAJ3TgDYnUE52medAC+iAFPB57dJbxR4XGUZ+snXe5qLVs7CN50vifGiHd37TpETXy+unb6msV/PTeInqbX1u18tWxncix6+vrt8uZbqX55++fTlGiE7X7d238//evyu7CW3y//trz94+kf3p5+Ufdp29D1DxL82/j0zYcf3/3p7z+8+/nz009/+fnvn5ftbtppCn6a5UW7lXgfe0lkodmIwx7KHA6ihl3U68q1zc75zcrXsRdXLkMU6ctWLs9XTsKQcXfD8Dr20sopqlv1RStHb8/P7zEe7za+uDKaAfG+bOWbPR8VB5g2qVf66zGdv6J3YbR65gtvvk3nT/7uf36/vP3xVNSnEFkqs8DK0wvnxLi0OS/OeYd9emEADY63NzidXQYRN61kcJY81/yyUAi/QSxcpK46qriV+jr0stQVGExfLnX6LSL4IvWIq2qUo9TXIVdqnGDTsJr7wZX6JoQdf76srTZs6LeL72Mvrz7r5P7q8skJ5OvywCel9u3y17FXls+69Pbq8uWl3TcK0Ds338deWb4OVVivLd9e2D3sc613/rqPvbL80EnxK8vHF22fREPuHG8fe3n5pEbxa64XX7T9ftP7sPzh9veLy5e4xtdcL97Z/pfTxqbEHfK6paGY1Zu39lsBatoBNS1/XMKVZ9zeRX+Bbdyo4IeXE8/d3C+8f3+YebTBo6+GuY/DEdry8SY1wdJ0Q3wmOMFot1urpFurfPPub+8+f/jb8vndT//16cPno4HefGXbUd7Hq+LOv1lQy1lenTZn8Q3SjPV2Hfl0mndsE7hllzHdSDjP6bqDU883C89jCt/l/Wkfye267cMgpR0EVldKDgswuk3d5bgOvd+lvY59OlXdFhjQpMNotX3eeZF9qO2fu4xtIn86DFz3dfj8tvk7jb3XL1N8fXrt1xXuf+3gTJTvf1Xh9OKvKpxaO69tqoTlW02C9hjGdazpCrT6MBqgcNK1BMaqWU9zTPUrpP/UWXgQampZjTXraszC2FlLOi3RRavDUJzfny9eR3TPl8UP3yJ5lKa7qPui2XQHVd3t0y4dg7r3ySuHPeS87eGyz/Mz7+mcqPYR9zkKKqPOP34J5xq6FHizZAbPZ8f3IFt+toXj0HnN/EwZh29ddbYvelDuLt3BCvseLra6s+fZmcL5d3/uAGGUfbaNF/D5D5/efcYXjwjw8sH8l53e7+6XdMdwgvmNB+7Du5l1ZZAqIh39IelWRtRFqxsvVNHbs+ns7eJhujqUm4rzfaheFjl4om61mu5LHD1RXUadWZXj0upX5JzLjS+S/0LSScDRFxm87Oa677GvfbDmYebV7IdPXv3jZvHdkw5y5mf72YcO+94Hr/o5fu+qx8PSB5UfhNyNc9iNPd+37Wt/kYeqvxr3cuoFL41HL/3+9L+IOil2CmVuZHN0cmVhbQplbmRvYmoKMTIgMCBvYmoKNDY5MQplbmRvYmoKMTAgMCBvYmoKWyBdCmVuZG9iagoyMCAwIG9iago8PCAvRmlsdGVyIC9GbGF0ZURlY29kZSAvTGVuZ3RoIDk1ID4+CnN0cmVhbQp4nD2MQQ7AIAgE77xiP9AEERX/0zQ92P9fu0bbC0x2YUo3KA4rnFUVxRvOJB8+kr3DWseQoplHQ5zd3BYOS40Uq1gWFp5hEaS0Ncz4vChrYEop6mln9b+75XoB/58cLAplbmRzdHJlYW0KZW5kb2JqCjE4IDAgb2JqCjw8IC9CYXNlRm9udCAvR0NXWERWK0RlamFWdVNhbnMtT2JsaXF1ZSAvQ2hhclByb2NzIDE5IDAgUgovRW5jb2RpbmcgPDwgL0RpZmZlcmVuY2VzIFsgMTIwIC94IF0gL1R5cGUgL0VuY29kaW5nID4+IC9GaXJzdENoYXIgMAovRm9udEJCb3ggWyAtMTAxNiAtMzUxIDE2NjAgMTA2OCBdIC9Gb250RGVzY3JpcHRvciAxNyAwIFIKL0ZvbnRNYXRyaXggWyAwLjAwMSAwIDAgMC4wMDEgMCAwIF0gL0xhc3RDaGFyIDI1NQovTmFtZSAvR0NXWERWK0RlamFWdVNhbnMtT2JsaXF1ZSAvU3VidHlwZSAvVHlwZTMgL1R5cGUgL0ZvbnQgL1dpZHRocyAxNiAwIFIKPj4KZW5kb2JqCjE3IDAgb2JqCjw8IC9Bc2NlbnQgOTI5IC9DYXBIZWlnaHQgMCAvRGVzY2VudCAtMjM2IC9GbGFncyA5NgovRm9udEJCb3ggWyAtMTAxNiAtMzUxIDE2NjAgMTA2OCBdIC9Gb250TmFtZSAvR0NXWERWK0RlamFWdVNhbnMtT2JsaXF1ZQovSXRhbGljQW5nbGUgMCAvTWF4V2lkdGggMTM1MCAvU3RlbVYgMCAvVHlwZSAvRm9udERlc2NyaXB0b3IgL1hIZWlnaHQgMCA+PgplbmRvYmoKMTYgMCBvYmoKWyA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMAo2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDMxOCA0MDEgNDYwIDgzOCA2MzYKOTUwIDc4MCAyNzUgMzkwIDM5MCA1MDAgODM4IDMxOCAzNjEgMzE4IDMzNyA2MzYgNjM2IDYzNiA2MzYgNjM2IDYzNiA2MzYgNjM2CjYzNiA2MzYgMzM3IDMzNyA4MzggODM4IDgzOCA1MzEgMTAwMCA2ODQgNjg2IDY5OCA3NzAgNjMyIDU3NSA3NzUgNzUyIDI5NQoyOTUgNjU2IDU1NyA4NjMgNzQ4IDc4NyA2MDMgNzg3IDY5NSA2MzUgNjExIDczMiA2ODQgOTg5IDY4NSA2MTEgNjg1IDM5MCAzMzcKMzkwIDgzOCA1MDAgNTAwIDYxMyA2MzUgNTUwIDYzNSA2MTUgMzUyIDYzNSA2MzQgMjc4IDI3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dE5hbWUgL0JNUVFEVitEZWphVnVTYW5zCi9JdGFsaWNBbmdsZSAwIC9NYXhXaWR0aCAxMzQyIC9TdGVtViAwIC9UeXBlIC9Gb250RGVzY3JpcHRvciAvWEhlaWdodCAwID4+CmVuZG9iagoyMSAwIG9iagpbIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwCjYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgNjAwIDYwMCA2MDAgMzE4IDQwMSA0NjAgODM4IDYzNgo5NTAgNzgwIDI3NSAzOTAgMzkwIDUwMCA4MzggMzE4IDM2MSAzMTggMzM3IDYzNiA2MzYgNjM2IDYzNiA2MzYgNjM2IDYzNiA2MzYKNjM2IDYzNiAzMzcgMzM3IDgzOCA4MzggODM4IDUzMSAxMDAwIDY4NCA2ODYgNjk4IDc3MCA2MzIgNTc1IDc3NSA3NTIgMjk1CjI5NSA2NTYgNTU3IDg2MyA3NDggNzg3IDYwMyA3ODcgNjk1IDYzNSA2MTEgNzMyIDY4NCA5ODkgNjg1IDYxMSA2ODUgMzkwIDMzNwozOTAgODM4IDUwMCA1MDAgNjEzIDYzNSA1NTAgNjM1IDYxNSAzNTIgNjM1IDYzNCAyNzggMjc4IDU3OSAyNzggOTc0IDYzNCA2MTIKNjM1IDYzNSA0MTEgNTIxIDM5MiA2MzQgNTkyIDgxOCA1OTIgNTkyIDUyNSA2MzYgMzM3IDYzNiA4MzggNjAwIDYzNiA2MDAgMzE4CjM1MiA1MTggMTAwMCA1MDAgNTAwIDUwMCAxMzQyIDYzNSA0MDAgMTA3MCA2MDAgNjg1IDYwMCA2MDAgMzE4IDMxOCA1MTggNTE4CjU5MCA1MDAgMTAwMCA1MDAgMTAwMCA1MjEgNDAwIDEwMjMgNjAwIDUyNSA2MTEgMzE4IDQwMSA2MzYgNjM2IDYzNiA2MzYgMzM3CjUwMCA1MDAgMTAwMCA0NzEgNjEyIDgzOCAzNjEgMTAwMCA1MDAgNTAwIDgzOCA0MDEgNDAxIDUwMCA2MzYgNjM2IDMxOCA1MDAKNDAxIDQ3MSA2MTIgOTY5IDk2OSA5NjkgNTMxIDY4NCA2ODQgNjg0IDY4NCA2ODQgNjg0IDk3NCA2OTggNjMyIDYzMiA2MzIgNjMyCjI5NSAyOTUgMjk1IDI5NSA3NzUgNzQ4IDc4NyA3ODcgNzg3IDc4NyA3ODcgODM4IDc4NyA3MzIgNzMyIDczMiA3MzIgNjExIDYwNQo2MzAgNjEzIDYxMyA2MTMgNjEzIDYxMyA2MTMgOTgyIDU1MCA2MTUgNjE1IDYxNSA2MTUgMjc4IDI3OCAyNzggMjc4IDYxMiA2MzQKNjEyIDYxMiA2MTIgNjEyIDYxMiA4MzggNjEyIDYzNCA2MzQgNjM0IDYzNCA1OTIgNjM1IDU5MiBdCmVuZG9iagoyNCAwIG9iago8PCAvQyAyNSAwIFIgL0QgMjYgMCBSIC9hIDI3IDAgUiAvZSAyOCAwIFIgL2ZpdmUgMjkgMCBSIC9sIDMwIDAgUgovbSAzMSAwIFIgL29uZSAzMyAwIFIgL3AgMzQgMCBSIC9wZXJpb2QgMzUgMCBSIC9zIDM2IDAgUiAvc2V2ZW4gMzcgMCBSCi9zcGFjZSAzOCAwIFIgL3QgMzkgMCBSIC90d28gNDAgMCBSIC96ZXJvIDQxIDAgUiA+PgplbmRvYmoKMyAwIG9iago8PCAvRjEgMjMgMCBSIC9GMiAxOCAwIFIgPj4KZW5kb2JqCjQgMCBvYmoKPDwgL0ExIDw8IC9DQSAwIC9UeXBlIC9FeHRHU3RhdGUgL2NhIDEgPj4KL0EyIDw8IC9DQSAxIC9UeXBlIC9FeHRHU3RhdGUgL2NhIDEgPj4KL0EzIDw8IC9DQSAwLjggL1R5cGUgL0V4dEdTdGF0ZSAvY2EgMC44ID4+ID4+CmVuZG9iago1IDAgb2JqCjw8ID4+CmVuZG9iago2IDAgb2JqCjw8ID4+CmVuZG9iago3IDAgb2JqCjw8IC9GMS1EZWphVnVTYW5zLW1pbnVzIDMyIDAgUiAvSTEgMTMgMCBSIC9NMCAxNCAwIFIgL00xIDE1IDAgUiA+PgplbmRvYmoKMTMgMCBvYmoKPDwgL0JpdHNQZXJDb21wb25lbnQgOCAvQ29sb3JTcGFjZSAvRGV2aWNlUkdCCi9EZWNvZGVQYXJtcyA8PCAvQ29sb3JzIDMgL0NvbHVtbnMgMjE4IC9QcmVkaWN0b3IgMTAgPj4KL0ZpbHRlciAvRmxhdGVE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MDAwMzI1MTcgMDAwMDAgbiAKMDAwMDAwNTg2MiAwMDAwMCBuIAowMDAwMDA1NjQ3IDAwMDAwIG4gCjAwMDAwMDUzMTcgMDAwMDAgbiAKMDAwMDAwNjkxNSAwMDAwMCBuIAowMDAwMDA1MTUwIDAwMDAwIG4gCjAwMDAwMTE4MDcgMDAwMDAgbiAKMDAwMDAxMTYwMCAwMDAwMCBuIAowMDAwMDExMTg1IDAwMDAwIG4gCjAwMDAwMTI4NjAgMDAwMDAgbiAKMDAwMDAwNjk0NyAwMDAwMCBuIAowMDAwMDA3MjU1IDAwMDAwIG4gCjAwMDAwMDc0OTIgMDAwMDAgbiAKMDAwMDAwNzg3MiAwMDAwMCBuIAowMDAwMDA4MTk0IDAwMDAwIG4gCjAwMDAwMDg1MTYgMDAwMDAgbiAKMDAwMDAwODYzNSAwMDAwMCBuIAowMDAwMDA4OTY2IDAwMDAwIG4gCjAwMDAwMDkxMzggMDAwMDAgbiAKMDAwMDAwOTI5MyAwMDAwMCBuIAowMDAwMDA5NjA1IDAwMDAwIG4gCjAwMDAwMDk3MjggMDAwMDAgbiAKMDAwMDAxMDEzNSAwMDAwMCBuIAowMDAwMDEwMjc3IDAwMDAwIG4gCjAwMDAwMTAzNjcgMDAwMDAgbiAKMDAwMDAxMDU3MyAwMDAwMCBuIAowMDAwMDEwODk3IDAwMDAwIG4gCjAwMDAwMzIyNDEgMDAwMDAgbiAKMDAwMDAzMjgzMSAwMDAwMCBuIAp0cmFpbGVyCjw8IC9JbmZvIDQzIDAgUiAvUm9vdCAxIDAgUiAvU2l6ZSA0NCA+PgpzdGFydHhyZWYKMzI5ODgKJSVFT0YK\n", "image/svg+xml": ["<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n", "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n", " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n", "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"291.115pt\" height=\"277.314375pt\" viewBox=\"0 0 291.115 277.314375\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n", " <metadata>\n", " <rdf:RDF xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n", " <cc:Work>\n", " <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/>\n", " <dc:date>2022-05-12T13:44:53.955818</dc:date>\n", " <dc:format>image/svg+xml</dc:format>\n", " <dc:creator>\n", " <cc:Agent>\n", " <dc:title>Matplotlib v3.5.2, https://matplotlib.org/</dc:title>\n", " </cc:Agent>\n", " </dc:creator>\n", " </cc:Work>\n", " </rdf:RDF>\n", " </metadata>\n", " <defs>\n", " <style type=\"text/css\">*{stroke-linejoin: round; stroke-linecap: butt}</style>\n", " </defs>\n", " <g id=\"figure_1\">\n", " <g id=\"patch_1\">\n", " <path d=\"M 0 277.314375 \n", "L 291.115 277.314375 \n", "L 291.115 0 \n", "L 0 0 \n", "L 0 277.314375 \n", "z\n", "\" style=\"fill: none\"/>\n", " </g>\n", " <g id=\"axes_1\">\n", " <g id=\"patch_2\">\n", " <path d=\"M 58.523438 239.758125 \n", "L 275.963437 239.758125 \n", "L 275.963437 22.318125 \n", "L 58.523438 22.318125 \n", "z\n", "\" style=\"fill: #ffffff\"/>\n", " </g>\n", " <g clip-path=\"url(#pa373f7f6d0)\">\n", " <image xlink:href=\"data:image/png;base64,\n", "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\" id=\"imagef6ffdf17ed\" transform=\"scale(1 -1)translate(0 -218)\" x=\"58.523438\" y=\"-21.758125\" width=\"218\" height=\"218\"/>\n", " </g>\n", " <g id=\"PathCollection_1\">\n", " <defs>\n", " <path id=\"mf4076b0dc9\" d=\"M 0 3 \n", "C 0.795609 3 1.55874 2.683901 2.12132 2.12132 \n", "C 2.683901 1.55874 3 0.795609 3 0 \n", "C 3 -0.795609 2.683901 -1.55874 2.12132 -2.12132 \n", "C 1.55874 -2.683901 0.795609 -3 0 -3 \n", "C -0.795609 -3 -1.55874 -2.683901 -2.12132 -2.12132 \n", "C -2.683901 -1.55874 -3 -0.795609 -3 0 \n", "C -3 0.795609 -2.683901 1.55874 -2.12132 2.12132 \n", "C -1.55874 2.683901 -0.795609 3 0 3 \n", "z\n", "\" style=\"stroke: #333333\"/>\n", " </defs>\n", " <g clip-path=\"url(#pa373f7f6d0)\">\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"112.130475\" y=\"183.02716\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"218.531808\" y=\"79.706304\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"239.633825\" y=\"80.994397\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"122.008015\" y=\"191.757377\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"116.060682\" y=\"192.256288\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"92.277532\" y=\"180.061819\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"227.018994\" y=\"76.887462\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"218.499712\" y=\"71.275153\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"110.302013\" y=\"191.868518\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"222.828211\" y=\"72.953996\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"117.798662\" y=\"188.528318\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"236.949732\" y=\"56.122229\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"223.235039\" y=\"80.056541\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"218.619913\" y=\"76.248163\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"110.525586\" y=\"198.228967\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"106.581102\" y=\"176.499583\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"233.588936\" y=\"102.286439\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"236.369999\" y=\"96.725344\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"213.86622\" y=\"77.338064\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"100.93054\" y=\"195.532199\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"235.709742\" y=\"56.455519\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"228.794651\" y=\"77.981996\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"126.325818\" y=\"169.253244\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"215.866897\" y=\"56.228154\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"114.849831\" y=\"184.170689\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"215.200167\" y=\"71.325868\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"104.738732\" y=\"172.132264\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"233.165389\" y=\"69.175006\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"229.770805\" y=\"79.208287\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"224.897941\" y=\"65.173809\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"109.018133\" y=\"175.976269\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"118.553492\" y=\"195.931899\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"105.114252\" y=\"164.360655\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"113.25433\" y=\"189.323026\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"124.586091\" y=\"188.967644\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"109.837824\" y=\"184.898956\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"125.181761\" y=\"197.902563\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"204.317789\" y=\"61.965272\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"235.267519\" y=\"81.643688\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"223.348378\" y=\"80.978112\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"109.797084\" y=\"192.545811\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"211.194686\" y=\"100.930901\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"229.513113\" y=\"75.481734\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"113.381992\" y=\"197.835874\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"123.337028\" y=\"202.207751\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"130.132567\" y=\"170.190943\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"216.473179\" y=\"87.364405\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"206.813885\" y=\"65.697345\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"107.513202\" y=\"192.863185\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"217.41874\" y=\"84.700348\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"113.95745\" y=\"189.098171\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"226.55733\" y=\"57.230812\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"111.233278\" y=\"179.431408\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"215.084754\" y=\"91.072443\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"224.100848\" y=\"68.121491\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"92.279163\" y=\"180.887702\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"206.717206\" y=\"67.932904\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"230.512427\" y=\"82.439245\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"101.651362\" y=\"185.78207\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"110.796814\" y=\"211.814172\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"110.369579\" y=\"188.183661\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"96.152024\" y=\"188.29022\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"241.658206\" y=\"82.547711\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"215.078112\" y=\"88.854193\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"235.390643\" y=\"62.012163\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"96.594278\" y=\"176.722784\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"223.89308\" y=\"95.68291\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"231.986534\" y=\"101.379014\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"129.434435\" y=\"202.700628\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"121.849164\" y=\"193.853222\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"111.071273\" y=\"180.426817\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"111.73278\" y=\"178.6056\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"224.372642\" y=\"73.188217\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"214.544764\" y=\"100.191683\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"111.037176\" y=\"184.756952\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"120.501423\" y=\"177.927389\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"121.737273\" y=\"183.651319\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"224.151653\" y=\"60.366512\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"223.43835\" y=\"58.920283\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"112.665686\" y=\"194.670616\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"232.62061\" y=\"60.454033\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"218.768323\" y=\"87.76343\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"231.184386\" y=\"57.202935\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"105.951856\" y=\"182.733923\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"220.266348\" y=\"68.561718\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"113.873959\" y=\"198.141743\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"121.135411\" y=\"191.679503\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"105.401412\" y=\"181.366251\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"203.450464\" y=\"73.166107\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"213.131642\" y=\"68.440188\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"195.475611\" y=\"65.960727\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"104.817254\" y=\"181.616921\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"128.101527\" y=\"193.778082\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"108.575899\" y=\"196.017082\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"213.699076\" y=\"102.201172\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"116.657511\" y=\"184.585026\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"111.028071\" y=\"179.737071\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"106.803829\" y=\"188.460235\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"114.368679\" y=\"194.747632\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"202.479261\" y=\"76.337577\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"209.669671\" y=\"63.421804\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"93.182322\" y=\"199.661904\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"221.556365\" y=\"94.135493\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " </g>\n", " </g>\n", " <g id=\"PathCollection_2\">\n", " <defs>\n", " <path id=\"m104dfd571b\" d=\"M 0 3 \n", "C 0.795609 3 1.55874 2.683901 2.12132 2.12132 \n", "C 2.683901 1.55874 3 0.795609 3 0 \n", "C 3 -0.795609 2.683901 -1.55874 2.12132 -2.12132 \n", "C 1.55874 -2.683901 0.795609 -3 0 -3 \n", "C -0.795609 -3 -1.55874 -2.683901 -2.12132 -2.12132 \n", "C -2.683901 -1.55874 -3 -0.795609 -3 0 \n", "C -3 0.795609 -2.683901 1.55874 -2.12132 2.12132 \n", "C -1.55874 2.683901 -0.795609 3 0 3 \n", "z\n", "\" style=\"stroke: #333333\"/>\n", " </defs>\n", " <g clip-path=\"url(#pa373f7f6d0)\">\n", " <use xlink:href=\"#m104dfd571b\" x=\"217.606427\" y=\"173.251328\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"227.769027\" y=\"173.464324\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"218.500016\" y=\"187.443356\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"106.984413\" y=\"66.511974\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"233.133545\" y=\"189.544269\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"115.335326\" y=\"80.815627\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"208.972555\" y=\"197.223837\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"139.005527\" y=\"77.700995\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"230.664194\" y=\"201.829041\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"205.002573\" y=\"176.909335\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"216.845993\" y=\"167.032503\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"88.160629\" y=\"65.861243\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"128.021696\" y=\"66.622254\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"112.260448\" y=\"91.009332\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"112.50413\" y=\"63.911605\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"95.981186\" y=\"61.50077\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"219.993175\" y=\"189.668312\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"206.167029\" y=\"173.135684\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"213.740977\" y=\"174.762918\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"121.204965\" y=\"77.433213\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"203.018823\" y=\"182.099388\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"238.152369\" y=\"188.7116\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"231.441781\" y=\"186.794029\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"211.648243\" y=\"189.950709\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"236.220422\" y=\"169.740566\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"101.853762\" y=\"86.031191\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"233.94689\" y=\"172.051387\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"123.501925\" y=\"74.175724\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"218.585652\" y=\"171.48351\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"90.32929\" y=\"75.633164\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"111.280011\" y=\"82.837267\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"211.740197\" y=\"195.115065\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"205.118653\" y=\"174.999985\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"115.182647\" y=\"78.537928\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"227.992219\" y=\"175.571697\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"115.634509\" y=\"84.738407\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"113.207682\" y=\"86.904679\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"241.406644\" y=\"195.654551\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"218.12314\" y=\"172.59052\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"102.818896\" y=\"74.729342\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"126.547202\" y=\"76.348126\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"129.239769\" y=\"62.486839\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"228.152228\" y=\"193.26863\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"103.215052\" y=\"78.005027\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"216.222162\" y=\"176.670472\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"114.916325\" y=\"88.653235\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"121.115357\" y=\"70.241533\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"120.258643\" y=\"72.957314\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"209.315916\" y=\"177.378942\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"103.210102\" y=\"91.806632\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"119.325862\" y=\"68.692592\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"202.824093\" y=\"174.268046\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"223.801372\" y=\"196.626833\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"117.310993\" y=\"69.094029\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"122.253941\" y=\"84.153386\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"208.231426\" y=\"184.433377\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"201.565732\" y=\"186.557453\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"120.045207\" y=\"79.883512\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"85.476218\" y=\"85.530225\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"108.621104\" y=\"91.775968\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"122.454711\" y=\"71.807464\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"105.245089\" y=\"80.555517\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"110.345637\" y=\"74.684201\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"122.948606\" y=\"84.523445\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"238.331781\" y=\"190.109778\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"99.158482\" y=\"62.144579\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"238.904126\" y=\"176.479967\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"228.511103\" y=\"166.124698\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"204.749573\" y=\"197.183933\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"207.817035\" y=\"209.749946\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"113.647455\" y=\"63.325534\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"209.936021\" y=\"171.712521\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"199.504867\" y=\"160.73698\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"102.861494\" y=\"67.872443\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"121.543306\" y=\"77.896386\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"230.263574\" y=\"175.913803\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"108.769772\" y=\"71.243232\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"118.137999\" y=\"79.260109\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"116.883422\" y=\"81.810632\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"217.332054\" y=\"170.303854\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"223.569574\" y=\"163.041048\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"230.510522\" y=\"176.611656\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"142.305392\" y=\"77.469185\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"204.163476\" y=\"198.978781\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"244.521801\" y=\"198.229188\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"214.441631\" y=\"195.840128\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"105.972186\" y=\"85.737332\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"104.205171\" y=\"77.466631\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"232.367065\" y=\"198.103735\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"104.549328\" y=\"83.321073\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"93.504718\" y=\"79.424966\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"127.819202\" y=\"69.050871\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"106.888986\" y=\"71.394117\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"238.372282\" y=\"196.147065\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"200.720575\" y=\"181.948403\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"113.562585\" y=\"65.860828\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " <use xlink:href=\"#m104dfd571b\" x=\"236.216055\" y=\"194.238972\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " </g>\n", " </g>\n", " <g id=\"matplotlib.axis_1\">\n", " <g id=\"xtick_1\">\n", " <g id=\"line2d_1\">\n", " <defs>\n", " <path id=\"m096f24f7ab\" d=\"M 0 0 \n", "L 0 3.5 \n", "\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </defs>\n", " <g>\n", " <use xlink:href=\"#m096f24f7ab\" x=\"58.523438\" y=\"239.758125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_1\">\n", " <!-- \u22120.5 -->\n", " <g transform=\"translate(46.382031 254.356562)scale(0.1 -0.1)\">\n", " <defs>\n", " <path id=\"DejaVuSans-2212\" d=\"M 678 2272 \n", "L 4684 2272 \n", "L 4684 1741 \n", "L 678 1741 \n", "L 678 2272 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-30\" d=\"M 2034 4250 \n", "Q 1547 4250 1301 3770 \n", "Q 1056 3291 1056 2328 \n", "Q 1056 1369 1301 889 \n", "Q 1547 409 2034 409 \n", "Q 2525 409 2770 889 \n", "Q 3016 1369 3016 2328 \n", "Q 3016 3291 2770 3770 \n", "Q 2525 4250 2034 4250 \n", "z\n", "M 2034 4750 \n", "Q 2819 4750 3233 4129 \n", "Q 3647 3509 3647 2328 \n", "Q 3647 1150 3233 529 \n", "Q 2819 -91 2034 -91 \n", "Q 1250 -91 836 529 \n", "Q 422 1150 422 2328 \n", "Q 422 3509 836 4129 \n", "Q 1250 4750 2034 4750 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-2e\" d=\"M 684 794 \n", "L 1344 794 \n", "L 1344 0 \n", "L 684 0 \n", "L 684 794 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-35\" d=\"M 691 4666 \n", "L 3169 4666 \n", "L 3169 4134 \n", "L 1269 4134 \n", "L 1269 2991 \n", "Q 1406 3038 1543 3061 \n", "Q 1681 3084 1819 3084 \n", "Q 2600 3084 3056 2656 \n", "Q 3513 2228 3513 1497 \n", "Q 3513 744 3044 326 \n", "Q 2575 -91 1722 -91 \n", "Q 1428 -91 1123 -41 \n", "Q 819 9 494 109 \n", "L 494 744 \n", "Q 775 591 1075 516 \n", "Q 1375 441 1709 441 \n", "Q 2250 441 2565 725 \n", "Q 2881 1009 2881 1497 \n", "Q 2881 1984 2565 2268 \n", "Q 2250 2553 1709 2553 \n", "Q 1456 2553 1204 2497 \n", "Q 953 2441 691 2322 \n", "L 691 4666 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " </defs>\n", " <use xlink:href=\"#DejaVuSans-2212\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"83.789062\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"147.412109\"/>\n", " <use xlink:href=\"#DejaVuSans-35\" x=\"179.199219\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"xtick_2\">\n", " <g id=\"line2d_2\">\n", " <g>\n", " <use xlink:href=\"#m096f24f7ab\" x=\"112.883437\" y=\"239.758125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_2\">\n", " <!-- 0.0 -->\n", " <g transform=\"translate(104.931875 254.356562)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-30\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"95.410156\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"xtick_3\">\n", " <g id=\"line2d_3\">\n", " <g>\n", " <use xlink:href=\"#m096f24f7ab\" x=\"167.243437\" y=\"239.758125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_3\">\n", " <!-- 0.5 -->\n", " <g transform=\"translate(159.291875 254.356562)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-30\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-35\" x=\"95.410156\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"xtick_4\">\n", " <g id=\"line2d_4\">\n", " <g>\n", " <use xlink:href=\"#m096f24f7ab\" x=\"221.603437\" y=\"239.758125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_4\">\n", " <!-- 1.0 -->\n", " <g transform=\"translate(213.651875 254.356562)scale(0.1 -0.1)\">\n", " <defs>\n", " <path id=\"DejaVuSans-31\" d=\"M 794 531 \n", "L 1825 531 \n", "L 1825 4091 \n", "L 703 3866 \n", "L 703 4441 \n", "L 1819 4666 \n", "L 2450 4666 \n", "L 2450 531 \n", "L 3481 531 \n", "L 3481 0 \n", "L 794 0 \n", "L 794 531 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " </defs>\n", " <use xlink:href=\"#DejaVuSans-31\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"95.410156\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"xtick_5\">\n", " <g id=\"line2d_5\">\n", " <g>\n", " <use xlink:href=\"#m096f24f7ab\" x=\"275.963437\" y=\"239.758125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_5\">\n", " <!-- 1.5 -->\n", " <g transform=\"translate(268.011875 254.356562)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-31\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-35\" x=\"95.410156\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"text_6\">\n", " <!-- $x_1$ -->\n", " <g transform=\"translate(161.893438 268.034687)scale(0.1 -0.1)\">\n", " <defs>\n", " <path id=\"DejaVuSans-Oblique-78\" d=\"M 3841 3500 \n", "L 2234 1784 \n", "L 3219 0 \n", "L 2559 0 \n", "L 1819 1388 \n", "L 531 0 \n", "L -166 0 \n", "L 1556 1844 \n", "L 641 3500 \n", "L 1300 3500 \n", "L 1972 2234 \n", "L 3144 3500 \n", "L 3841 3500 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " </defs>\n", " <use xlink:href=\"#DejaVuSans-Oblique-78\" transform=\"translate(0 0.3125)\"/>\n", " <use xlink:href=\"#DejaVuSans-31\" transform=\"translate(59.179688 -16.09375)scale(0.7)\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"matplotlib.axis_2\">\n", " <g id=\"ytick_1\">\n", " <g id=\"line2d_6\">\n", " <defs>\n", " <path id=\"m7a06f5d612\" d=\"M 0 0 \n", "L -3.5 0 \n", "\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </defs>\n", " <g>\n", " <use xlink:href=\"#m7a06f5d612\" x=\"58.523438\" y=\"239.758125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_7\">\n", " <!-- \u22120.50 -->\n", " <g transform=\"translate(20.878125 243.557344)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-2212\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"83.789062\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"147.412109\"/>\n", " <use xlink:href=\"#DejaVuSans-35\" x=\"179.199219\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"242.822266\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"ytick_2\">\n", " <g id=\"line2d_7\">\n", " <g>\n", " <use xlink:href=\"#m7a06f5d612\" x=\"58.523438\" y=\"212.578125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_8\">\n", " <!-- \u22120.25 -->\n", " <g transform=\"translate(20.878125 216.377344)scale(0.1 -0.1)\">\n", " <defs>\n", " <path id=\"DejaVuSans-32\" d=\"M 1228 531 \n", "L 3431 531 \n", "L 3431 0 \n", "L 469 0 \n", "L 469 531 \n", "Q 828 903 1448 1529 \n", "Q 2069 2156 2228 2338 \n", "Q 2531 2678 2651 2914 \n", "Q 2772 3150 2772 3378 \n", "Q 2772 3750 2511 3984 \n", "Q 2250 4219 1831 4219 \n", "Q 1534 4219 1204 4116 \n", "Q 875 4013 500 3803 \n", "L 500 4441 \n", "Q 881 4594 1212 4672 \n", "Q 1544 4750 1819 4750 \n", "Q 2544 4750 2975 4387 \n", "Q 3406 4025 3406 3419 \n", "Q 3406 3131 3298 2873 \n", "Q 3191 2616 2906 2266 \n", "Q 2828 2175 2409 1742 \n", "Q 1991 1309 1228 531 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " </defs>\n", " <use xlink:href=\"#DejaVuSans-2212\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"83.789062\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"147.412109\"/>\n", " <use xlink:href=\"#DejaVuSans-32\" x=\"179.199219\"/>\n", " <use xlink:href=\"#DejaVuSans-35\" x=\"242.822266\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"ytick_3\">\n", " <g id=\"line2d_8\">\n", " <g>\n", " <use xlink:href=\"#m7a06f5d612\" x=\"58.523438\" y=\"185.398125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_9\">\n", " <!-- 0.00 -->\n", " <g transform=\"translate(29.257812 189.197344)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-30\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"95.410156\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"159.033203\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"ytick_4\">\n", " <g id=\"line2d_9\">\n", " <g>\n", " <use xlink:href=\"#m7a06f5d612\" x=\"58.523438\" y=\"158.218125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_10\">\n", " <!-- 0.25 -->\n", " <g transform=\"translate(29.257812 162.017344)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-30\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-32\" x=\"95.410156\"/>\n", " <use xlink:href=\"#DejaVuSans-35\" x=\"159.033203\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"ytick_5\">\n", " <g id=\"line2d_10\">\n", " <g>\n", " <use xlink:href=\"#m7a06f5d612\" x=\"58.523438\" y=\"131.038125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_11\">\n", " <!-- 0.50 -->\n", " <g transform=\"translate(29.257812 134.837344)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-30\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-35\" x=\"95.410156\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"159.033203\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"ytick_6\">\n", " <g id=\"line2d_11\">\n", " <g>\n", " <use xlink:href=\"#m7a06f5d612\" x=\"58.523438\" y=\"103.858125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_12\">\n", " <!-- 0.75 -->\n", " <g transform=\"translate(29.257812 107.657344)scale(0.1 -0.1)\">\n", " <defs>\n", " <path id=\"DejaVuSans-37\" d=\"M 525 4666 \n", "L 3525 4666 \n", "L 3525 4397 \n", "L 1831 0 \n", "L 1172 0 \n", "L 2766 4134 \n", "L 525 4134 \n", "L 525 4666 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " </defs>\n", " <use xlink:href=\"#DejaVuSans-30\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-37\" x=\"95.410156\"/>\n", " <use xlink:href=\"#DejaVuSans-35\" x=\"159.033203\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"ytick_7\">\n", " <g id=\"line2d_12\">\n", " <g>\n", " <use xlink:href=\"#m7a06f5d612\" x=\"58.523438\" y=\"76.678125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_13\">\n", " <!-- 1.00 -->\n", " <g transform=\"translate(29.257812 80.477344)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-31\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"95.410156\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"159.033203\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"ytick_8\">\n", " <g id=\"line2d_13\">\n", " <g>\n", " <use xlink:href=\"#m7a06f5d612\" x=\"58.523438\" y=\"49.498125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_14\">\n", " <!-- 1.25 -->\n", " <g transform=\"translate(29.257812 53.297344)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-31\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-32\" x=\"95.410156\"/>\n", " <use xlink:href=\"#DejaVuSans-35\" x=\"159.033203\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"ytick_9\">\n", " <g id=\"line2d_14\">\n", " <g>\n", " <use xlink:href=\"#m7a06f5d612\" x=\"58.523438\" y=\"22.318125\" style=\"stroke: #000000; stroke-width: 0.8\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_15\">\n", " <!-- 1.50 -->\n", " <g transform=\"translate(29.257812 26.117344)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-31\"/>\n", " <use xlink:href=\"#DejaVuSans-2e\" x=\"63.623047\"/>\n", " <use xlink:href=\"#DejaVuSans-35\" x=\"95.410156\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"159.033203\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"text_16\">\n", " <!-- $x_2$ -->\n", " <g transform=\"translate(14.798437 136.388125)rotate(-90)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-Oblique-78\" transform=\"translate(0 0.3125)\"/>\n", " <use xlink:href=\"#DejaVuSans-32\" transform=\"translate(59.179688 -16.09375)scale(0.7)\"/>\n", " </g>\n", " </g>\n", " </g>\n", " <g id=\"patch_3\">\n", " <path d=\"M 58.523438 239.758125 \n", "L 58.523438 22.318125 \n", "\" style=\"fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square\"/>\n", " </g>\n", " <g id=\"patch_4\">\n", " <path d=\"M 275.963437 239.758125 \n", "L 275.963437 22.318125 \n", "\" style=\"fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square\"/>\n", " </g>\n", " <g id=\"patch_5\">\n", " <path d=\"M 58.523438 239.758125 \n", "L 275.963437 239.758125 \n", "\" style=\"fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square\"/>\n", " </g>\n", " <g id=\"patch_6\">\n", " <path d=\"M 58.523438 22.318125 \n", "L 275.963437 22.318125 \n", "\" style=\"fill: none; stroke: #000000; stroke-width: 0.8; stroke-linejoin: miter; stroke-linecap: square\"/>\n", " </g>\n", " <g id=\"text_17\">\n", " <!-- Dataset samples -->\n", " <g transform=\"translate(116.900625 16.318125)scale(0.12 -0.12)\">\n", " <defs>\n", " <path id=\"DejaVuSans-44\" d=\"M 1259 4147 \n", "L 1259 519 \n", "L 2022 519 \n", "Q 2988 519 3436 956 \n", "Q 3884 1394 3884 2338 \n", "Q 3884 3275 3436 3711 \n", "Q 2988 4147 2022 4147 \n", "L 1259 4147 \n", "z\n", "M 628 4666 \n", "L 1925 4666 \n", "Q 3281 4666 3915 4102 \n", "Q 4550 3538 4550 2338 \n", "Q 4550 1131 3912 565 \n", "Q 3275 0 1925 0 \n", "L 628 0 \n", "L 628 4666 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-61\" d=\"M 2194 1759 \n", "Q 1497 1759 1228 1600 \n", "Q 959 1441 959 1056 \n", "Q 959 750 1161 570 \n", "Q 1363 391 1709 391 \n", "Q 2188 391 2477 730 \n", "Q 2766 1069 2766 1631 \n", "L 2766 1759 \n", "L 2194 1759 \n", "z\n", "M 3341 1997 \n", "L 3341 0 \n", "L 2766 0 \n", "L 2766 531 \n", "Q 2569 213 2275 61 \n", "Q 1981 -91 1556 -91 \n", "Q 1019 -91 701 211 \n", "Q 384 513 384 1019 \n", "Q 384 1609 779 1909 \n", "Q 1175 2209 1959 2209 \n", "L 2766 2209 \n", "L 2766 2266 \n", "Q 2766 2663 2505 2880 \n", "Q 2244 3097 1772 3097 \n", "Q 1472 3097 1187 3025 \n", "Q 903 2953 641 2809 \n", "L 641 3341 \n", "Q 956 3463 1253 3523 \n", "Q 1550 3584 1831 3584 \n", "Q 2591 3584 2966 3190 \n", "Q 3341 2797 3341 1997 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-74\" d=\"M 1172 4494 \n", "L 1172 3500 \n", "L 2356 3500 \n", "L 2356 3053 \n", "L 1172 3053 \n", "L 1172 1153 \n", "Q 1172 725 1289 603 \n", "Q 1406 481 1766 481 \n", "L 2356 481 \n", "L 2356 0 \n", "L 1766 0 \n", "Q 1100 0 847 248 \n", "Q 594 497 594 1153 \n", "L 594 3053 \n", "L 172 3053 \n", "L 172 3500 \n", "L 594 3500 \n", "L 594 4494 \n", "L 1172 4494 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-73\" d=\"M 2834 3397 \n", "L 2834 2853 \n", "Q 2591 2978 2328 3040 \n", "Q 2066 3103 1784 3103 \n", "Q 1356 3103 1142 2972 \n", "Q 928 2841 928 2578 \n", "Q 928 2378 1081 2264 \n", "Q 1234 2150 1697 2047 \n", "L 1894 2003 \n", "Q 2506 1872 2764 1633 \n", "Q 3022 1394 3022 966 \n", "Q 3022 478 2636 193 \n", "Q 2250 -91 1575 -91 \n", "Q 1294 -91 989 -36 \n", "Q 684 19 347 128 \n", "L 347 722 \n", "Q 666 556 975 473 \n", "Q 1284 391 1588 391 \n", "Q 1994 391 2212 530 \n", "Q 2431 669 2431 922 \n", "Q 2431 1156 2273 1281 \n", "Q 2116 1406 1581 1522 \n", "L 1381 1569 \n", "Q 847 1681 609 1914 \n", "Q 372 2147 372 2553 \n", "Q 372 3047 722 3315 \n", "Q 1072 3584 1716 3584 \n", "Q 2034 3584 2315 3537 \n", "Q 2597 3491 2834 3397 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-65\" d=\"M 3597 1894 \n", "L 3597 1613 \n", "L 953 1613 \n", "Q 991 1019 1311 708 \n", "Q 1631 397 2203 397 \n", "Q 2534 397 2845 478 \n", "Q 3156 559 3463 722 \n", "L 3463 178 \n", "Q 3153 47 2828 -22 \n", "Q 2503 -91 2169 -91 \n", "Q 1331 -91 842 396 \n", "Q 353 884 353 1716 \n", "Q 353 2575 817 3079 \n", "Q 1281 3584 2069 3584 \n", "Q 2775 3584 3186 3129 \n", "Q 3597 2675 3597 1894 \n", "z\n", "M 3022 2063 \n", "Q 3016 2534 2758 2815 \n", "Q 2500 3097 2075 3097 \n", "Q 1594 3097 1305 2825 \n", "Q 1016 2553 972 2059 \n", "L 3022 2063 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-20\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-6d\" d=\"M 3328 2828 \n", "Q 3544 3216 3844 3400 \n", "Q 4144 3584 4550 3584 \n", "Q 5097 3584 5394 3201 \n", "Q 5691 2819 5691 2113 \n", "L 5691 0 \n", "L 5113 0 \n", "L 5113 2094 \n", "Q 5113 2597 4934 2840 \n", "Q 4756 3084 4391 3084 \n", "Q 3944 3084 3684 2787 \n", "Q 3425 2491 3425 1978 \n", "L 3425 0 \n", "L 2847 0 \n", "L 2847 2094 \n", "Q 2847 2600 2669 2842 \n", "Q 2491 3084 2119 3084 \n", "Q 1678 3084 1418 2786 \n", "Q 1159 2488 1159 1978 \n", "L 1159 0 \n", "L 581 0 \n", "L 581 3500 \n", "L 1159 3500 \n", "L 1159 2956 \n", "Q 1356 3278 1631 3431 \n", "Q 1906 3584 2284 3584 \n", "Q 2666 3584 2933 3390 \n", "Q 3200 3197 3328 2828 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-70\" d=\"M 1159 525 \n", "L 1159 -1331 \n", "L 581 -1331 \n", "L 581 3500 \n", "L 1159 3500 \n", "L 1159 2969 \n", "Q 1341 3281 1617 3432 \n", "Q 1894 3584 2278 3584 \n", "Q 2916 3584 3314 3078 \n", "Q 3713 2572 3713 1747 \n", "Q 3713 922 3314 415 \n", "Q 2916 -91 2278 -91 \n", "Q 1894 -91 1617 61 \n", "Q 1341 213 1159 525 \n", "z\n", "M 3116 1747 \n", "Q 3116 2381 2855 2742 \n", "Q 2594 3103 2138 3103 \n", "Q 1681 3103 1420 2742 \n", "Q 1159 2381 1159 1747 \n", "Q 1159 1113 1420 752 \n", "Q 1681 391 2138 391 \n", "Q 2594 391 2855 752 \n", "Q 3116 1113 3116 1747 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " <path id=\"DejaVuSans-6c\" d=\"M 603 4863 \n", "L 1178 4863 \n", "L 1178 0 \n", "L 603 0 \n", "L 603 4863 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " </defs>\n", " <use xlink:href=\"#DejaVuSans-44\"/>\n", " <use xlink:href=\"#DejaVuSans-61\" x=\"77.001953\"/>\n", " <use xlink:href=\"#DejaVuSans-74\" x=\"138.28125\"/>\n", " <use xlink:href=\"#DejaVuSans-61\" x=\"177.490234\"/>\n", " <use xlink:href=\"#DejaVuSans-73\" x=\"238.769531\"/>\n", " <use xlink:href=\"#DejaVuSans-65\" x=\"290.869141\"/>\n", " <use xlink:href=\"#DejaVuSans-74\" x=\"352.392578\"/>\n", " <use xlink:href=\"#DejaVuSans-20\" x=\"391.601562\"/>\n", " <use xlink:href=\"#DejaVuSans-73\" x=\"423.388672\"/>\n", " <use xlink:href=\"#DejaVuSans-61\" x=\"475.488281\"/>\n", " <use xlink:href=\"#DejaVuSans-6d\" x=\"536.767578\"/>\n", " <use xlink:href=\"#DejaVuSans-70\" x=\"634.179688\"/>\n", " <use xlink:href=\"#DejaVuSans-6c\" x=\"697.65625\"/>\n", " <use xlink:href=\"#DejaVuSans-65\" x=\"725.439453\"/>\n", " <use xlink:href=\"#DejaVuSans-73\" x=\"786.962891\"/>\n", " </g>\n", " </g>\n", " <g id=\"legend_1\">\n", " <g id=\"patch_7\">\n", " <path d=\"M 65.523438 59.674375 \n", "L 133.371875 59.674375 \n", "Q 135.371875 59.674375 135.371875 57.674375 \n", "L 135.371875 29.318125 \n", "Q 135.371875 27.318125 133.371875 27.318125 \n", "L 65.523438 27.318125 \n", "Q 63.523438 27.318125 63.523438 29.318125 \n", "L 63.523438 57.674375 \n", "Q 63.523438 59.674375 65.523438 59.674375 \n", "z\n", "\" style=\"fill: #ffffff; opacity: 0.8; stroke: #cccccc; stroke-linejoin: miter\"/>\n", " </g>\n", " <g id=\"PathCollection_3\">\n", " <g>\n", " <use xlink:href=\"#mf4076b0dc9\" x=\"77.523438\" y=\"36.291562\" style=\"fill: #1f77b4; stroke: #333333\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_18\">\n", " <!-- Class 0 -->\n", " <g transform=\"translate(95.523438 38.916562)scale(0.1 -0.1)\">\n", " <defs>\n", " <path id=\"DejaVuSans-43\" d=\"M 4122 4306 \n", "L 4122 3641 \n", "Q 3803 3938 3442 4084 \n", "Q 3081 4231 2675 4231 \n", "Q 1875 4231 1450 3742 \n", "Q 1025 3253 1025 2328 \n", "Q 1025 1406 1450 917 \n", "Q 1875 428 2675 428 \n", "Q 3081 428 3442 575 \n", "Q 3803 722 4122 1019 \n", "L 4122 359 \n", "Q 3791 134 3420 21 \n", "Q 3050 -91 2638 -91 \n", "Q 1578 -91 968 557 \n", "Q 359 1206 359 2328 \n", "Q 359 3453 968 4101 \n", "Q 1578 4750 2638 4750 \n", "Q 3056 4750 3426 4639 \n", "Q 3797 4528 4122 4306 \n", "z\n", "\" transform=\"scale(0.015625)\"/>\n", " </defs>\n", " <use xlink:href=\"#DejaVuSans-43\"/>\n", " <use xlink:href=\"#DejaVuSans-6c\" x=\"69.824219\"/>\n", " <use xlink:href=\"#DejaVuSans-61\" x=\"97.607422\"/>\n", " <use xlink:href=\"#DejaVuSans-73\" x=\"158.886719\"/>\n", " <use xlink:href=\"#DejaVuSans-73\" x=\"210.986328\"/>\n", " <use xlink:href=\"#DejaVuSans-20\" x=\"263.085938\"/>\n", " <use xlink:href=\"#DejaVuSans-30\" x=\"294.873047\"/>\n", " </g>\n", " </g>\n", " <g id=\"PathCollection_4\">\n", " <g>\n", " <use xlink:href=\"#m104dfd571b\" x=\"77.523438\" y=\"50.969687\" style=\"fill: #ff7f0e; stroke: #333333\"/>\n", " </g>\n", " </g>\n", " <g id=\"text_19\">\n", " <!-- Class 1 -->\n", " <g transform=\"translate(95.523438 53.594687)scale(0.1 -0.1)\">\n", " <use xlink:href=\"#DejaVuSans-43\"/>\n", " <use xlink:href=\"#DejaVuSans-6c\" x=\"69.824219\"/>\n", " <use xlink:href=\"#DejaVuSans-61\" x=\"97.607422\"/>\n", " <use xlink:href=\"#DejaVuSans-73\" x=\"158.886719\"/>\n", " <use xlink:href=\"#DejaVuSans-73\" x=\"210.986328\"/>\n", " <use xlink:href=\"#DejaVuSans-20\" x=\"263.085938\"/>\n", " <use xlink:href=\"#DejaVuSans-31\" x=\"294.873047\"/>\n", " </g>\n", " </g>\n", " </g>\n", " </g>\n", " </g>\n", " <defs>\n", " <clipPath id=\"pa373f7f6d0\">\n", " <rect x=\"58.523438\" y=\"22.318125\" width=\"217.44\" height=\"217.44\"/>\n", " </clipPath>\n", " </defs>\n", "</svg>\n"], "text/plain": ["<Figure size 288x288 with 1 Axes>"]}, "metadata": {"needs_background": "light"}, "output_type": "display_data"}], "source": ["@torch.no_grad() # Decorator, same effect as \"with torch.no_grad(): ...\" over the whole function.\n", "def visualize_classification(model, data, label):\n", " if isinstance(data, Tensor):\n", " data = data.cpu().numpy()\n", " if isinstance(label, Tensor):\n", " label = label.cpu().numpy()\n", " data_0 = data[label == 0]\n", " data_1 = data[label == 1]\n", "\n", " plt.figure(figsize=(4, 4))\n", " plt.scatter(data_0[:, 0], data_0[:, 1], edgecolor=\"#333\", label=\"Class 0\")\n", " plt.scatter(data_1[:, 0], data_1[:, 1], edgecolor=\"#333\", label=\"Class 1\")\n", " plt.title(\"Dataset samples\")\n", " plt.ylabel(r\"$x_2$\")\n", " plt.xlabel(r\"$x_1$\")\n", " plt.legend()\n", "\n", " # Let's make use of a lot of operations we have learned above\n", " model.to(device)\n", " c0 = Tensor(to_rgba(\"C0\")).to(device)\n", " c1 = Tensor(to_rgba(\"C1\")).to(device)\n", " x1 = torch.arange(-0.5, 1.5, step=0.01, device=device)\n", " x2 = torch.arange(-0.5, 1.5, step=0.01, device=device)\n", " xx1, xx2 = torch.meshgrid(x1, x2) # Meshgrid function as in numpy\n", " model_inputs = torch.stack([xx1, xx2], dim=-1)\n", " preds = model(model_inputs)\n", " preds = torch.sigmoid(preds)\n", " # Specifying \"None\" in a dimension creates a new one\n", " output_image = (1 - preds) * c0[None, None] + preds * c1[None, None]\n", " output_image = (\n", " output_image.cpu().numpy()\n", " ) # Convert to numpy array. This only works for tensors on CPU, hence first push to CPU\n", " plt.imshow(output_image, origin=\"lower\", extent=(-0.5, 1.5, -0.5, 1.5))\n", " plt.grid(False)\n", "\n", "\n", "visualize_classification(model, dataset.data, dataset.label)\n", "plt.show()"]}, {"cell_type": "markdown", "id": "59da563c", "metadata": {"papermill": {"duration": 0.019724, "end_time": "2022-05-12T11:44:54.321449", "exception": false, "start_time": "2022-05-12T11:44:54.301725", "status": "completed"}, "tags": []}, "source": ["The decision boundaries might not look exactly as in the figure in the preamble of this section which can be caused by running it on CPU or a different GPU architecture.\n", "Nevertheless, the result on the accuracy metric should be the approximately the same."]}, {"cell_type": "markdown", "id": "25062ca3", "metadata": {"papermill": {"duration": 0.02104, "end_time": "2022-05-12T11:44:54.362467", "exception": false, "start_time": "2022-05-12T11:44:54.341427", "status": "completed"}, "tags": []}, "source": ["## Additional features we didn't get to discuss yet\n", "\n", "Finally, you are all set to start with your own PyTorch project!\n", "In summary, we have looked at how we can build neural networks in PyTorch, and train and test them on data.\n", "However, there is still much more to PyTorch we haven't discussed yet.\n", "In the comming series of Jupyter notebooks, we will discover more and more functionalities of PyTorch, so that you also get familiar to PyTorch concepts beyond the basics.\n", "If you are already interested in learning more of PyTorch, we recommend the official [tutorial website](https://pytorch.org/tutorials/) that contains many tutorials on various topics.\n", "Especially logging with Tensorboard ([tutorial\n", "here](https://pytorch.org/tutorials/intermediate/tensorboard_tutorial.html))\n", "is a good practice that we will explore from Tutorial 5 on."]}, {"cell_type": "markdown", "id": "88bc5fd4", "metadata": {"papermill": {"duration": 0.020688, "end_time": "2022-05-12T11:44:54.402723", "exception": false, "start_time": "2022-05-12T11:44:54.382035", "status": "completed"}, "tags": []}, "source": ["## Congratulations - Time to Join the Community!\n", "\n", "Congratulations on completing this notebook tutorial! If you enjoyed this and would like to join the Lightning\n", "movement, you can do so in the following ways!\n", "\n", "### Star [Lightning](https://github.com/PyTorchLightning/pytorch-lightning) on GitHub\n", "The easiest way to help our community is just by starring the GitHub repos! This helps raise awareness of the cool\n", "tools we're building.\n", "\n", "### Join our [Slack](https://www.pytorchlightning.ai/community)!\n", "The best way to keep up to date on the latest advancements is to join our community! Make sure to introduce yourself\n", "and share your interests in `#general` channel\n", "\n", "\n", "### Contributions !\n", "The best way to contribute to our community is to become a code contributor! At any time you can go to\n", "[Lightning](https://github.com/PyTorchLightning/pytorch-lightning) or [Bolt](https://github.com/PyTorchLightning/lightning-bolts)\n", "GitHub Issues page and filter for \"good first issue\".\n", "\n", "* [Lightning good first issue](https://github.com/PyTorchLightning/pytorch-lightning/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)\n", "* [Bolt good first issue](https://github.com/PyTorchLightning/lightning-bolts/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)\n", "* You can also contribute your own notebooks with useful examples !\n", "\n", "### Great thanks from the entire Pytorch Lightning Team for your interest !\n", "\n", "[{height=\"60px\" width=\"240px\"}](https://pytorchlightning.ai)"]}, {"cell_type": "raw", "metadata": {"raw_mimetype": "text/restructuredtext"}, "source": [".. customcarditem::\n", " :header: Tutorial 1: Introduction to PyTorch\n", " :card_description: This tutorial will give a short introduction to PyTorch basics, and get you setup for writing your own neural networks. This notebook is part of a lecture series on Deep...\n", " :tags: GPU/TPU,UvA-DL-Course\n", " :image: _static/images/course_UvA-DL/01-introduction-to-pytorch.jpg"]}], "metadata": {"jupytext": {"cell_metadata_filter": "colab,id,colab_type,-all", "formats": "ipynb,py:percent", "main_language": "python"}, "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.8.10"}, "papermill": {"default_parameters": {}, "duration": 20.166319, "end_time": "2022-05-12T11:44:55.247041", "environment_variables": {}, "exception": null, "input_path": "course_UvA-DL/01-introduction-to-pytorch/Introduction_to_PyTorch.ipynb", "output_path": ".notebooks/course_UvA-DL/01-introduction-to-pytorch.ipynb", "parameters": {}, "start_time": "2022-05-12T11:44:35.080722", "version": "2.3.4"}, "widgets": {"application/vnd.jupyter.widget-state+json": {"state": {"0f0e04f0bb0b49578cd1a4ec0e705a37": {"model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": ""}}, "1842fbfd51eb4549bdc75800dcf2367c": {"model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_76dd1394c50a4b09be83cc90763ea2c0", "placeholder": "\u200b", "style": "IPY_MODEL_f5e21fffef4746439eba373464d635aa", "value": " 100/100 [00:01<00:00, 82.94it/s]"}}, "43648726b0b14815b31ed518e69416a1": {"model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "4cfa006bd89e46dda9cddece832af303": {"model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "ProgressStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": ""}}, "6c81d8acef7946e88461ecd6916a7ba3": {"model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": ["IPY_MODEL_c0dd94a27ffc4f75bfce4ae1f1749c74", "IPY_MODEL_a621291ee9d648ff820280a3fefee0d5", "IPY_MODEL_1842fbfd51eb4549bdc75800dcf2367c"], "layout": "IPY_MODEL_81898bdcaeac4fc0aa406593315d5f14"}}, "76dd1394c50a4b09be83cc90763ea2c0": {"model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "81898bdcaeac4fc0aa406593315d5f14": {"model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "a621291ee9d648ff820280a3fefee0d5": {"model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "FloatProgressModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "success", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_43648726b0b14815b31ed518e69416a1", "max": 100.0, "min": 0.0, "orientation": "horizontal", "style": "IPY_MODEL_4cfa006bd89e46dda9cddece832af303", "value": 100.0}}, "c0dd94a27ffc4f75bfce4ae1f1749c74": {"model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_f48253d59eb44455aa5af04d324fec62", "placeholder": "\u200b", "style": "IPY_MODEL_0f0e04f0bb0b49578cd1a4ec0e705a37", "value": "100%"}}, "f48253d59eb44455aa5af04d324fec62": {"model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "f5e21fffef4746439eba373464d635aa": {"model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": {"_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": ""}}}, "version_major": 2, "version_minor": 0}}}, "nbformat": 4, "nbformat_minor": 5}