diff --git a/environment.yml b/environment.yml index e69e0c342..405874d64 100644 --- a/environment.yml +++ b/environment.yml @@ -1,6 +1,6 @@ name: nma-dl dependencies: - - python=3.7 + - python=3.9 - requests - numpy - scipy @@ -8,7 +8,36 @@ dependencies: - scikit-learn - pytorch - torchvision + - torchaudio - ipywidgets - pathlib - tqdm + - pandas + - pillow + - imageio + - seaborn + - nltk + - tensorboard + - flask + - coloredlogs + - conda-forge::fasttext + - conda-forge::imageio-ffmpeg - pip + - pip: + - accelerate + - altair + - datasets + - diffusers + - evaluate + - facenet-pytorch + - flair + - flasgger + - flask-restful + - libsixel-python + - pyngrok + - pytorch-pretrained-biggan + - python-Levenshtein + - textattack + - tokenizers + - transformers + - vibecheck diff --git a/requirements.txt b/requirements.txt index 5989dab78..1f58cc85f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,17 +1,40 @@ -requests -numpy==1.26.4 -scipy -matplotlib -scikit-learn -torch==1.13.1 -torchvision==0.14.1 -ipywidgets -tqdm -torchvision -pathlib -xkcd -decorator==4.0.2 -pyvirtualdisplay -tensorboard -moviepy==1.0.3 -imageio_ffmpeg +# Requirements for Neuromatch Academy Deep Learning tutorials +# Some of these packages are pre-installed on Google Colab/Kaggle. + +numpy>=2.0 +pandas>=2.2 +matplotlib>=3.10 +torch>=2.0 +torchvision>=0.15 +torchaudio>=2.0 +scikit-learn>=1.3 +scipy>=1.13 +Pillow>=10.0 +imageio>=2.30 +imageio-ffmpeg +seaborn>=0.13 +nltk>=3.9 +tensorboard>=2.19 +ipywidgets>=8.0 +tqdm>=4.0 +requests>=2.31 +accelerate +altair +coloredlogs +datasets +diffusers +evaluate +facenet-pytorch +fasttext +flair +flasgger +flask +flask-restful +libsixel-python +pyngrok +pytorch-pretrained-biggan +python-Levenshtein +textattack +tokenizers +transformers +vibecheck diff --git a/tutorials/W1D1_BasicsAndPytorch/W1D1_Tutorial1.ipynb b/tutorials/W1D1_BasicsAndPytorch/W1D1_Tutorial1.ipynb index 4750dadda..dcc96cc02 100644 --- a/tutorials/W1D1_BasicsAndPytorch/W1D1_Tutorial1.ipynb +++ b/tutorials/W1D1_BasicsAndPytorch/W1D1_Tutorial1.ipynb @@ -4,7 +4,6 @@ "cell_type": "markdown", "metadata": { "colab_type": "text", - "execution": {}, "id": "view-in-github" }, "source": [ @@ -13,9 +12,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "# Tutorial 1: PyTorch\n", "**Week 1, Day 1: Basics and PyTorch**\n", @@ -25,7 +22,7 @@ "\n", "__Content creators:__ Shubh Pachchigar, Vladimir Haltakov, Matthew Sargent, Konrad Kording\n", "\n", - "__Content reviewers:__ Deepak Raya, Siwei Bai, Kelson Shilling-Scrivo\n", + "__Content reviewers:__ Deepak Raya, Siwei Bai, Kelson Shilling-Scrivo, Jiaxin Cindy Tu\n", "\n", "__Content editors:__ Anoop Kulkarni, Spiros Chavlis\n", "\n", @@ -34,9 +31,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "---\n", "# Tutorial Objectives\n", @@ -55,23 +50,20 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ "# @title Tutorial slides\n", "from IPython.display import IFrame\n", - "link_id = \"wcjrv\"\n", + "link_id = \"dg4h7\" \n", "print(f\"If you want to download the slides: https://osf.io/download/{link_id}/\")\n", "IFrame(src=f\"https://mfr.ca-1.osf.io/render?url=https://osf.io/{link_id}/?direct%26mode=render%26action=download%26mode=render\", width=854, height=480)" ] }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "---\n", "# Setup" @@ -79,9 +71,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "Throughout your Neuromatch tutorials, most (probably all!) notebooks contain setup cells. These cells will import the required Python packages (e.g., PyTorch, NumPy); set global or environment variables, and load in helper functions for things like plotting. In some tutorials, you will notice that we install some dependencies even if they are preinstalled on Google Colab or Kaggle. This happens because we have added automation to our repository through [GitHub Actions](https://docs.github.com/en/actions/learn-github-actions/introduction-to-github-actions).\n", "\n", @@ -94,21 +84,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} - }, - "outputs": [], - "source": [ - "# @title Install dependencies\n", - "!pip install pandas --quiet" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -135,31 +111,62 @@ "cell_type": "code", "execution_count": null, "metadata": { - "execution": {} + "cellView": "form" }, "outputs": [], + "source": [ + "# @title Install dependencies\n", + "# Most packages are pre-installed on Colab/Kaggle.\n", + "# Running locally? See https://github.com/NeuromatchAcademy/course-content-dl/blob/main/requirements.txt\n", + "import subprocess, sys, importlib\n", + "\n", + "_to_install = {'pandas': 'pandas', 'imageio': 'imageio', 'altair': 'altair', 'vega_datasets': 'vega_datasets'}\n", + "for _pkg, _pip in _to_install.items():\n", + " try:\n", + " importlib.import_module(_pkg)\n", + " except ImportError:\n", + " subprocess.check_call([sys.executable, '-m', 'pip', 'install', _pip, '-q'])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "# Imports\n", "import time\n", "import random\n", + "from pathlib import Path\n", + "\n", "import numpy as np\n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", + "import imageio.v2 as imageio\n", "\n", - "# PyTorch libraries\n", + "# PyTorch\n", "import torch\n", "from torch import nn\n", "from torchvision import datasets\n", + "from torchvision.transforms import Compose, Grayscale, ToTensor\n", "from torch.utils.data import DataLoader\n", - "from torchvision.transforms import ToTensor" + "\n", + "# Scikit-learn\n", + "from sklearn.datasets import make_moons\n", + "\n", + "# IPython display utilities\n", + "from IPython.core.interactiveshell import InteractiveShell\n", + "from IPython.display import Image, display\n", + "\n", + "import re\n", + "import altair as alt\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -176,8 +183,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -239,9 +245,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Important note: Colab users**\n", "\n", @@ -254,9 +258,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "# Section 1: Welcome to Neuromatch Deep learning course\n", "\n", @@ -267,8 +269,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -321,9 +322,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "This will be an intensive 3 week adventure. We will all learn Deep Learning (DL) in a group. Groups need standards. Read our\n", "[Code of Conduct](https://docs.google.com/document/d/1eHKIkaNbAlbx_92tLQelXnicKXEcvFzlyzzeWjEtifM/edit?usp=sharing).\n" @@ -333,8 +332,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -346,8 +344,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -400,9 +397,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Discuss with your pod: What do you hope to get out of this course? [in about 100 words]**" ] @@ -411,8 +406,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -422,9 +416,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "---\n", "# Section 2: The Basics of PyTorch\n", @@ -434,9 +426,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "PyTorch is a Python-based scientific computing package targeted at two sets of\n", "audiences:\n", @@ -456,9 +446,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "## Section 2.1: Creating Tensors\n" ] @@ -467,8 +455,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -523,8 +510,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -534,18 +520,14 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "There are various ways of creating tensors, and when doing any real deep learning project, we will usually have to do so." ] }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Construct tensors directly:**\n", "\n", @@ -556,9 +538,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# We can construct a tensor directly from some common python iterables,\n", @@ -583,9 +563,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Some common tensor constructors:**\n", "\n", @@ -595,9 +573,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# The numerical arguments we pass to these constructors\n", @@ -613,18 +589,14 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "Notice that `.empty()` does not return zeros, but seemingly random numbers. Unlike `.zeros()`, which initialises the elements of the tensor with zeros, `.empty()` just allocates the memory. It is hence a bit faster if you are looking to just create a tensor." ] }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Creating random tensors and tensors like other tensors:**\n", "\n", @@ -634,9 +606,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# There are also constructors for random numbers\n", @@ -662,9 +632,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "*Reproducibility*:\n", "\n", @@ -691,9 +659,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "Here, we define for you a function called `set_seed` that does the job for you!" ] @@ -701,9 +667,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "def set_seed(seed=None, seed_torch=True):\n", @@ -736,9 +700,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "Now, let's use the `set_seed` function in the previous example. Execute the cell multiple times to verify that the numbers printed are always the same." ] @@ -746,9 +708,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "def simplefun(seed=True, my_seed=None):\n", @@ -779,9 +739,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "simplefun(seed=True, my_seed=0) # Turn `seed` to `False` or change `my_seed`" @@ -789,9 +747,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Numpy-like number ranges:**\n", "---\n", @@ -801,9 +757,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "a = torch.arange(0, 10, step=1)\n", @@ -820,9 +774,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "### Coding Exercise 2.1: Creating Tensors\n", "\n", @@ -847,9 +799,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "def tensor_creation(Z):\n", @@ -894,9 +844,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove solution\n", @@ -937,9 +885,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "```\n", "All correct!\n", @@ -950,8 +896,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -961,9 +906,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "## Section 2.2: Operations in PyTorch\n", "\n", @@ -976,8 +919,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -1032,8 +974,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -1043,9 +984,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Tensor-Tensor operations**\n", "\n", @@ -1055,9 +994,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "a = torch.ones(5, 3)\n", @@ -1077,9 +1014,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "However, in PyTorch, most common Python operators are overridden.\n", "The common standard arithmetic operators ($+$, $-$, $*$, $/$, and $**$) have all been lifted to elementwise operations" @@ -1088,9 +1023,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "x = torch.tensor([1, 2, 4, 8])\n", @@ -1100,20 +1033,16 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Tensor Methods**" ] }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ - "Tensors also have a number of common arithmetic operations built in. A full list of **all** methods can be found in the appendix (there are a lot!)\n", + "Tensors also have a number of common arithmetic operations built in. A full list of **all** methods can be found in the **Appendix** at the bottom of this notebook ([Colab link](#scrollTo=appendix)) (there are a lot!)\n", "\n", "All of these operations should have similar syntax to their numpy equivalents (feel free to skip if you already know this!)." ] @@ -1121,9 +1050,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "x = torch.rand(3, 3)\n", @@ -1142,9 +1069,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Matrix Operations**\n", "\n", @@ -1156,9 +1081,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "### Coding Exercise 2.2 : Simple tensor operations\n", "\n", @@ -1193,9 +1116,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "def simple_operations(a1: torch.Tensor, a2: torch.Tensor, a3: torch.Tensor):\n", @@ -1238,9 +1159,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove solution\n", @@ -1278,9 +1197,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "```\n", "tensor([[20, 24],\n", @@ -1291,9 +1208,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "def dot_product(b1: torch.Tensor, b2: torch.Tensor):\n", @@ -1334,9 +1249,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove solution\n", @@ -1373,9 +1286,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "```\n", "tensor(82)\n", @@ -1386,8 +1297,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -1397,9 +1307,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "## Section 2.3 Manipulating Tensors in Pytorch" ] @@ -1408,8 +1316,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -1464,8 +1371,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -1475,9 +1381,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Indexing**\n", "\n", @@ -1489,9 +1393,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "x = torch.arange(0, 10)\n", @@ -1503,9 +1405,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "When we have multidimensional tensors, indexing rules work the same way as NumPy." ] @@ -1513,9 +1413,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# make a 5D tensor\n", @@ -1528,9 +1426,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Flatten and reshape**\n", "\n", @@ -1540,9 +1436,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "z = torch.arange(12).reshape(6, 2)\n", @@ -1559,18 +1453,14 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ - "You will also see the `.view()` methods used a lot to reshape tensors. There is a subtle difference between `.view()` and `.reshape()`, though for now we will just use `.reshape()`. The documentation can be found in the Appendix." + "You will also see the `.view()` methods used a lot to reshape tensors. There is a subtle difference between `.view()` and `.reshape()`, though for now we will just use `.reshape()`. The documentation can be found in the **Appendix** at the bottom of this notebook ([Colab link](#scrollTo=appendix))." ] }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Squeezing tensors**\n", "\n", @@ -1582,9 +1472,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "x = torch.randn(1, 10)\n", @@ -1596,9 +1484,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "Because of that pesky singleton dimension, `x[0]` gave us the first row instead!" ] @@ -1606,9 +1492,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# Let's get rid of that singleton dimension and see what happens now\n", @@ -1620,9 +1504,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# Adding singleton dimensions works a similar way, and is often used when tensors\n", @@ -1638,9 +1520,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Permutation**\n", "\n", @@ -1650,9 +1530,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# `x` has dimensions [color,image_height,image_width]\n", @@ -1669,27 +1547,21 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "You may also see `.transpose()` used. This works in a similar way as permute, but can only swap two dimensions at once." ] }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Concatenation**" ] }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "In this example, we concatenate two matrices along rows (axis 0, the first element of the shape) vs. columns (axis 1, the second element of the shape). We can see that the first output tensor’s axis-0 length (`6`) is the sum of the two input tensors’ axis-0 lengths (`3+3`); while the second output tensor’s axis-1 length (`8`) is the sum of the two input tensors’ axis-1 lengths (`4+4`)." ] @@ -1697,9 +1569,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# Create two tensors of the same shape\n", @@ -1719,9 +1589,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Conversion to Other Python Objects**\n", "\n", @@ -1733,9 +1601,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "x = torch.randn(5)\n", @@ -1750,9 +1616,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "To convert a size-1 tensor to a Python scalar, we can invoke the item function or Python’s built-in functions." ] @@ -1760,9 +1624,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "a = torch.tensor([3.5])\n", @@ -1771,9 +1633,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "### Coding Exercise 2.3: Manipulating Tensors\n", "Using a combination of the methods discussed above, complete the functions below." @@ -1781,9 +1641,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Function A**\n", "\n", @@ -1876,9 +1734,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "def functionA(my_tensor1, my_tensor2):\n", @@ -1980,9 +1836,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove solution\n", @@ -2072,9 +1926,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "```\n", "tensor([24, 24])\n", @@ -2092,8 +1944,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -2103,9 +1954,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "## Section 2.4: GPUs" ] @@ -2114,8 +1963,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -2170,8 +2018,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -2181,9 +2028,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "\n", "By default, when we create a tensor it will *not* live on the GPU!" @@ -2192,9 +2037,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "x = torch.randn(10)\n", @@ -2203,33 +2046,37 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "When using Colab notebooks, by default, will not have access to a GPU. In order to start using GPUs we need to request one. We can do this by going to the runtime tab at the top of the page.\n", "\n", "By following *Runtime* → *Change runtime type* and selecting **GPU** from the *Hardware Accelerator* dropdown list, we can start playing with sending tensors to GPUs.\n", "\n", - "Once you have done this your runtime will restart and you will need to rerun the first setup cell to reimport PyTorch. Then proceed to the next cell.\n", + "Once you have done this your runtime will restart. ⚠️ **Make sure to rerun the Setup cells at the top of the notebook before continuing.**\n", "\n", - "For more information on the GPU usage policy you can view in the Appendix." + "For more information on the GPU usage policy see the **Appendix** at the bottom of this notebook ([Colab link](#scrollTo=appendix))." ] }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, + "source": [ + "> **Colab GPU tips:**\n", + "> - **Switch back to CPU when done:** `Runtime → Change runtime type → Hardware Accelerator: None`. Free Colab GPU time is limited and shared. In future tutorials we will note at the top if GPU is not required.\n", + "> - **End your session properly when finished:** `Runtime → Disconnect and delete runtime`. Closing the browser tab does **not** free the GPU — the session keeps running for up to 90 minutes idle or 12 hours total.\n", + "> - **Avoid opening multiple GPU notebooks** at the same time across tabs." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, "source": [ "**Now we have a GPU.**\n" ] }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "The cell below should return `True`." ] @@ -2237,9 +2084,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "print(torch.cuda.is_available())" @@ -2247,9 +2092,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "[CUDA](https://developer.nvidia.com/cuda-toolkit) is an API developed by Nvidia for interfacing with GPUs. PyTorch provides us with a layer of abstraction, and allows us to launch CUDA kernels using pure Python.\n", "\n", @@ -2267,9 +2110,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "def set_device():\n", @@ -2297,9 +2138,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "Let's make some CUDA tensors!" ] @@ -2307,9 +2146,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# common device agnostic way of writing code that can run on cpu OR gpu\n", @@ -2331,9 +2168,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Operations between cpu tensors and cuda tensors**\n", "\n", @@ -2343,9 +2178,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "x = torch.tensor([0, 1, 2], device=DEVICE)\n", @@ -2357,9 +2190,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "We cannot combine CUDA tensors and CPU tensors in this fashion. If we want to compute an operation that combines tensors on different devices, we need to move them first! We can use the `.to()` method as before, or the `.cpu()` and `.cuda()` methods. Note that using the `.cuda()` will throw an error, if CUDA is not enabled in your machine.\n", "\n", @@ -2369,9 +2200,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "x = torch.tensor([0, 1, 2], device=DEVICE)\n", @@ -2389,9 +2218,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "### Coding Exercise 2.4: Just how much faster are GPUs?\n", "\n", @@ -2407,9 +2234,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "dim = 10000\n", @@ -2419,9 +2244,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "def simpleFun(dim, device):\n", @@ -2468,9 +2291,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove solution\n", @@ -2512,9 +2333,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "Sample output (depends on your hardware)\n", "\n", @@ -2528,8 +2347,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -2539,9 +2357,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Discuss!**\n", "\n", @@ -2551,9 +2367,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove explanation\n", @@ -2575,8 +2389,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -2586,9 +2399,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "## Section 2.5: Datasets and Dataloaders" ] @@ -2597,8 +2408,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -2653,8 +2463,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -2664,33 +2473,14 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "When training neural network models you will be working with large amounts of data. Fortunately, PyTorch offers some great tools that help you organize and manipulate your data samples." ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# Import dataset and dataloaders related packages\n", - "from torchvision import datasets\n", - "from torchvision.transforms import ToTensor\n", - "from torch.utils.data import DataLoader\n", - "from torchvision.transforms import Compose, Grayscale" - ] - }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Datasets**\n", "\n", @@ -2702,9 +2492,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# Download and load the images from the CIFAR10 dataset\n", @@ -2721,9 +2509,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "We have 50,000 samples loaded. Now, let's take a look at one of them in detail. Each sample consists of an image and its corresponding label." ] @@ -2731,9 +2517,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# Choose a random sample\n", @@ -2745,18 +2529,14 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "Color images are modeled as 3 dimensional tensors. The first dimension corresponds to the channels ($\\text{C}$) of the image (in this case we have RGB images). The second dimensions is the height ($\\text{H}$) of the image and the third is the width ($\\text{W}$). We can denote this image format as $\\text{C} \\times \\text{H} \\times \\text{W}$." ] }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "### Coding Exercise 2.5: Display an image from the dataset\n", "\n", @@ -2784,9 +2564,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# TODO: Uncomment the following line to see the error that arises from the current image format\n", @@ -2800,9 +2578,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove solution\n", @@ -2819,8 +2595,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -2832,8 +2607,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -2888,8 +2662,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -2899,9 +2672,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Training and Test Datasets**\n", "\n", @@ -2911,9 +2682,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# Load the training samples\n", @@ -2937,8 +2706,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -2991,9 +2759,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Dataloader**\n", "\n", @@ -3003,9 +2769,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# Create dataloaders with\n", @@ -3015,9 +2779,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "*Reproducibility:* DataLoader will reseed workers following Randomness in multi-process data loading algorithm. Use `worker_init_fn()` and a `generator` to preserve reproducibility:\n", "\n", @@ -3044,18 +2806,14 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Important:** For the `seed_worker` to have an effect, `num_workers` should be 2 or more." ] }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "We can now query the next batch from the data loader and inspect it. For this we need to convert the dataloader object to a Python iterator using the function `iter` and then we can query the next batch using the function `next`.\n", "\n", @@ -3065,9 +2823,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# Load the next batch\n", @@ -3081,9 +2837,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Transformations**\n", "\n", @@ -3092,9 +2846,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "### Coding Exercise 2.6: Load the CIFAR10 dataset as grayscale images\n", "\n", @@ -3104,9 +2856,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "def my_data_load():\n", @@ -3144,9 +2894,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove solution\n", @@ -3181,8 +2929,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -3192,9 +2939,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "---\n", "# Section 3: Neural Networks\n", @@ -3204,9 +2949,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "Now it's time for you to create your first neural network using PyTorch. This section will walk you through the process of:\n", "\n", @@ -3220,8 +2963,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -3276,8 +3018,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -3287,9 +3028,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "## Section 3.1: Data Loading\n", "\n", @@ -3300,14 +3039,12 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ "# @title Generate sample data\n", "# @markdown we used `scikit-learn` module\n", - "from sklearn.datasets import make_moons\n", "\n", "# Create a dataset of 256 points with a little noise\n", "X, y = make_moons(256, noise=0.1)\n", @@ -3319,9 +3056,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "Now we can load the data from the CSV file using the Pandas library. Pandas provides many functions for reading files in various formats. When loading data from a CSV file, we can reference the columns directly by their names." ] @@ -3329,9 +3064,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# Load the data from the CSV file in a Pandas DataFrame\n", @@ -3354,9 +3087,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Prepare Data for PyTorch**\n", "\n", @@ -3366,9 +3097,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# Initialize the device variable\n", @@ -3393,9 +3122,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "## Section 3.2: Create a Simple Neural Network" ] @@ -3404,8 +3131,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -3460,8 +3186,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -3471,9 +3196,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "For this example we want to have a simple neural network consisting of 3 layers:\n", "\n", @@ -3511,9 +3234,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# Inherit from nn.Module - the base class for neural network modules provided by Pytorch\n", @@ -3600,9 +3321,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Check that your network works**\n", "\n", @@ -3612,9 +3331,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# Create new NaiveNet and transfer it to the device\n", @@ -3626,9 +3343,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "### Coding Exercise 3.2: Classify some samples\n", "\n", @@ -3640,9 +3355,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "## Get the samples\n", @@ -3661,9 +3374,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove solution\n", @@ -3682,9 +3393,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "```\n", "Sample input:\n", @@ -3710,8 +3419,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -3721,9 +3429,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "## Section 3.3: Train Your Neural Network" ] @@ -3732,8 +3438,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -3788,8 +3493,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -3799,9 +3503,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "Now it is time to train your network on your dataset. Don't worry if you don't fully understand everything yet - we will cover training in much more details in the next days. For now, the goal is just to see your network in action!\n", "\n", @@ -3812,8 +3514,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -3821,7 +3522,6 @@ "\n", "# Code adapted from this notebook: https://jonchar.net/notebooks/Artificial-Neural-Network-with-Keras/\n", "\n", - "from pathlib import Path\n", "\n", "def plot_decision_boundary(model, X, y, device):\n", " \"\"\"\n", @@ -3871,9 +3571,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# Implement the train function given a training dataset X and correcsponding labels y\n", @@ -3941,9 +3639,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "**Plot the loss during training**\n", "\n", @@ -3953,9 +3649,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "plt.plot(np.linspace(1, len(losses), len(losses)), losses)\n", @@ -3967,20 +3661,13 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ "# @title Visualize the training process\n", "# @markdown Execute this cell!\n", - "!pip install imageio --quiet\n", - "!pip install pathlib --quiet\n", "\n", - "import imageio.v2 as imageio\n", - "from IPython.core.interactiveshell import InteractiveShell\n", - "from IPython.display import Image, display\n", - "from pathlib import Path\n", "\n", "InteractiveShell.ast_node_interactivity = \"all\"\n", "\n", @@ -4000,8 +3687,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -4056,8 +3742,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -4067,9 +3752,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "### Exercise 3.3: Tweak your Network\n", "\n", @@ -4085,9 +3768,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove explanation\n", @@ -4104,8 +3785,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -4117,8 +3797,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -4173,8 +3852,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -4184,9 +3862,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "Exclusive OR (XOR) logical operation gives a true (`1`) output when the number of true inputs is odd. That is, a true output result if one, and only one, of the inputs to the gate is true. If both inputs are false (`0`) or both are true or false output results. Mathematically speaking, XOR represents the inequality function, i.e., the output is true if the inputs are not alike; otherwise, the output is false.\n", "\n", @@ -4206,9 +3882,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "### Interactive Demo 3.3: Solving XOR\n", "\n", @@ -4230,8 +3904,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -4251,8 +3924,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -4270,8 +3942,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -4281,9 +3952,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "---\n", "# Section 4: Ethics And Course Info" @@ -4293,8 +3962,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -4349,8 +4017,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -4362,8 +4029,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -4418,8 +4084,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -4427,118 +4092,30 @@ "content_review(f\"{feedback_prefix}_Be_a_group_Video\")" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {} - }, - "outputs": [], - "source": [ - "# @title Video 17: Syllabus\n", - "from ipywidgets import widgets\n", - "from IPython.display import YouTubeVideo\n", - "from IPython.display import IFrame\n", - "from IPython.display import display\n", - "\n", - "\n", - "class PlayVideo(IFrame):\n", - " def __init__(self, id, source, page=1, width=400, height=300, **kwargs):\n", - " self.id = id\n", - " if source == 'Bilibili':\n", - " src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'\n", - " elif source == 'Osf':\n", - " src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'\n", - " super(PlayVideo, self).__init__(src, width, height, **kwargs)\n", - "\n", - "\n", - "def display_videos(video_ids, W=400, H=300, fs=1):\n", - " tab_contents = []\n", - " for i, video_id in enumerate(video_ids):\n", - " out = widgets.Output()\n", - " with out:\n", - " if video_ids[i][0] == 'Youtube':\n", - " video = YouTubeVideo(id=video_ids[i][1], width=W,\n", - " height=H, fs=fs, rel=0)\n", - " print(f'Video available at https://youtube.com/watch?v={video.id}')\n", - " else:\n", - " video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,\n", - " height=H, fs=fs, autoplay=False)\n", - " if video_ids[i][0] == 'Bilibili':\n", - " print(f'Video available at https://www.bilibili.com/video/{video.id}')\n", - " elif video_ids[i][0] == 'Osf':\n", - " print(f'Video available at https://osf.io/{video.id}')\n", - " display(video)\n", - " tab_contents.append(out)\n", - " return tab_contents\n", - "\n", - "\n", - "video_ids = [('Youtube', 'cDvAqG_hAvQ'), ('Bilibili', 'BV1iB4y1N7uQ')]\n", - "tab_contents = display_videos(video_ids, W=854, H=480)\n", - "tabs = widgets.Tab()\n", - "tabs.children = tab_contents\n", - "for i in range(len(tab_contents)):\n", - " tabs.set_title(i, video_ids[i][0])\n", - "display(tabs)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {} - }, - "outputs": [], - "source": [ - "# @title Submit your feedback\n", - "content_review(f\"{feedback_prefix}_Syllabus_Video\")" - ] - }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "## Meet our lecturers\n", "\n", - "### Week 1: the building blocks\n", "* [Konrad Kording](https://kordinglab.com)\n", "* [Andrew Saxe](https://www.saxelab.org/)\n", "* [Surya Ganguli](https://ganguli-gang.stanford.edu/)\n", "* [Ioannis Mitliagkas](http://mitliagkas.github.io/)\n", "* [Lyle Ungar](https://www.cis.upenn.edu/~ungar/)\n", - "\n", - "### Week 2: making things work\n", "* [Alona Fyshe](https://webdocs.cs.ualberta.ca/~alona/)\n", "* [Alexander Ecker](https://eckerlab.org/)\n", - "* [James Evans](https://sociology.uchicago.edu/directory/james-evans)\n", + "* [Vikash Gilja](https://tnel.ucsd.edu/bio) \n", + "* [Binxu Wang](https://animadversio.github.io/) \n", "* [He He](https://hhexiy.github.io/)\n", - "* [Vikash Gilja](https://tnel.ucsd.edu/bio) and [Akash Srivastava](https://akashgit.github.io/)\n", - "\n", - "### Week 3: more magic\n", - "* [Tim Lillicrap](https://contrastiveconvergence.net/~timothylillicrap/index.php) and [Blake Richards](https://www.mcgill.ca/neuro/blake-richards-phd)\n", - "* [Jane Wang](http://www.janexwang.com/) and [Feryal Behbahani](https://feryal.github.io/)\n", - "* [Tim Lillicrap](https://contrastiveconvergence.net/~timothylillicrap/index.php) and [Blake Richards](https://www.mcgill.ca/neuro/blake-richards-phd)\n", - "* [Josh Vogelstein](https://jovo.me/) and [Vincenzo Lamonaco](https://www.vincenzolomonaco.com/)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now, go to the [visualization of ICLR papers](https://iclr.cc/virtual/2021/paper_vis.html). Read a few abstracts. Look at the various clusters. Where do you see yourself in this map?" + "* [Blake Richards](https://www.mcgill.ca/neuro/blake-richards-phd)\n", + "* [Tim Lillicrap](https://contrastiveconvergence.net/~timothylillicrap/index.php) \n", + "* [Pablo Samuel Castro](https://psc-g.github.io/)" ] }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "---\n", "# Bonus - 60 years of Machine Learning Research in one Plot\n", @@ -4553,26 +4130,15 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ - "# @title Install and Import `altair` and `vega_datasets`.\n", - "!pip install altair vega_datasets --quiet\n", - "\n", - "import altair as alt # altair is defining data visualizations\n", + "# @title Load visualization data\n", "\n", "# Source data files\n", - "# Position data file maps ID to x,y positions\n", - "# original link: http://gltr.io/temp/ml_regexv1_cs_ma_citation+_99perc.pos_umap_cosine_100_d0.1.json\n", "POS_FILE = 'https://osf.io/qyrfn/download'\n", - "# original link: http://gltr.io/temp/ml_regexv1_cs_ma_citation+_99perc_clean.csv\n", - "# Metadata file maps ID to title, abstract, author,....\n", "META_FILE = 'https://osf.io/vfdu6/download'\n", "\n", - "# data loading and wrangling\n", "def load_data():\n", " \"\"\"\n", " Loading the data\n", @@ -4589,17 +4155,13 @@ " return positions.merge(meta, left_on='id', right_on='paper_id')\n", "\n", "\n", - "# load data\n", "data = load_data()" ] }, { "cell_type": "code", "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# @title Define Visualization using ALtair\n", @@ -4609,33 +4171,19 @@ "chart = alt.Chart(data[[\"x\", \"y\", \"authors\", \"title\", YEAR_PERIOD, \"citation_count\"]], width=800,\n", " height=800).mark_circle(radius=2, opacity=0.2).encode(\n", " alt.Color(YEAR_PERIOD+':O',\n", - " scale=alt.Scale(scheme='viridis', reverse=False, clamp=True, domain=list(range(1955,2020,5))),\n", - " # legend=alt.Legend(title='Total Records')\n", - " ),\n", + " scale=alt.Scale(scheme='viridis', reverse=False, clamp=True, domain=list(range(1955,2020,5)))),\n", " alt.Size('citation_count',\n", - " scale=alt.Scale(type=\"pow\", exponent=1, range=[15, 300])\n", - " ),\n", - " alt.X('x:Q',\n", - " scale=alt.Scale(zero=False), axis=alt.Axis(labels=False)\n", - " ),\n", - " alt.Y('y:Q',\n", - " scale=alt.Scale(zero=False), axis=alt.Axis(labels=False)\n", - " ),\n", + " scale=alt.Scale(type=\"pow\", exponent=1, range=[15, 300])),\n", + " alt.X('x:Q', scale=alt.Scale(zero=False), axis=alt.Axis(labels=False)),\n", + " alt.Y('y:Q', scale=alt.Scale(zero=False), axis=alt.Axis(labels=False)),\n", " tooltip=['title', 'authors'],\n", - " # size='citation_count',\n", - " # color=\"decade:O\",\n", " opacity=alt.condition(selection, alt.value(.8), alt.value(0.2)),\n", - "\n", - ").add_selection(\n", - " selection\n", - ").interactive()" + ").add_selection(selection).interactive()" ] }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "Lets look at the Visualization. Each dot represents one paper. Close dots mean that the respective papers are closer related than distant ones. The color indicates the 5-year period of when the paper was published. The dot size indicates the citation count (within S2ORC corpus) as of July 2020.\n", "\n", @@ -4645,22 +4193,9 @@ "3. Zoom in/out with scroll -- double click resets view" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "chart" - ] - }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "## Questions\n", "\n", @@ -4675,9 +4210,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove explanation\n", @@ -4703,10 +4236,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# @title Submit your feedback\n", @@ -4715,9 +4245,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "## Methods\n", "\n", @@ -4733,9 +4261,7 @@ }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "metadata": {}, "source": [ "### Find Authors" ] @@ -4743,10 +4269,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# @title Edit the `AUTHOR_FILTER` variable to full text search for authors.\n", @@ -4755,43 +4278,29 @@ "\n", "### Don't ignore case when searching...\n", "FLAGS = 0\n", - "### uncomment do ignore case\n", + "### uncomment to ignore case\n", "# FLAGS = re.IGNORECASE\n", "\n", - "## --- FILTER CODE.. make it your own ---\n", - "data['issel'] = data['authors'].str.contains(AUTHOR_FILTER, na=False, flags=FLAGS, )\n", - "if data['issel'].mean()<0.0000000001:\n", - " print('No match found')\n", + "data['issel'] = data['authors'].str.contains(AUTHOR_FILTER, na=False, flags=FLAGS)\n", + "if data['issel'].mean() < 0.0000000001:\n", + " print('No match found')\n", "\n", - "## --- FROM HERE ON VIS CODE ---\n", "alt.Chart(data[[\"x\", \"y\", \"authors\", \"title\", YEAR_PERIOD, \"citation_count\", \"issel\"]], width=800,\n", - " height=800) \\\n", - " .mark_circle(stroke=\"black\", strokeOpacity=1).encode(\n", - " alt.Color(YEAR_PERIOD+':O',\n", - " scale=alt.Scale(scheme='viridis', reverse=False),\n", - " # legend=alt.Legend(title='Total Records')\n", - " ),\n", - " alt.Size('citation_count',\n", - " scale=alt.Scale(type=\"pow\", exponent=1, range=[15, 300])\n", - " ),\n", + " height=800).mark_circle(stroke=\"black\", strokeOpacity=1).encode(\n", + " alt.Color(YEAR_PERIOD+':O', scale=alt.Scale(scheme='viridis', reverse=False)),\n", + " alt.Size('citation_count', scale=alt.Scale(type=\"pow\", exponent=1, range=[15, 300])),\n", " alt.StrokeWidth('issel:Q', scale=alt.Scale(type=\"linear\", domain=[0,1], range=[0, 2]), legend=None),\n", - "\n", " alt.Opacity('issel:Q', scale=alt.Scale(type=\"linear\", domain=[0,1], range=[.2, 1]), legend=None),\n", - " alt.X('x:Q',\n", - " scale=alt.Scale(zero=False), axis=alt.Axis(labels=False)\n", - " ),\n", - " alt.Y('y:Q',\n", - " scale=alt.Scale(zero=False), axis=alt.Axis(labels=False)\n", - " ),\n", + " alt.X('x:Q', scale=alt.Scale(zero=False), axis=alt.Axis(labels=False)),\n", + " alt.Y('y:Q', scale=alt.Scale(zero=False), axis=alt.Axis(labels=False)),\n", " tooltip=['title', 'authors'],\n", ").interactive()" ] }, { "cell_type": "markdown", - "metadata": { - "execution": {} - }, + "id": "213", + "metadata": {}, "source": [ "---\n", "# Appendix\n", @@ -4831,7 +4340,8 @@ "name": "python3" }, "kernelspec": { - "display_name": "Python 3", + "display_name": "nma-dl", + "language": "python", "name": "python3" }, "language_info": { @@ -4844,7 +4354,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.11" + "version": "3.9.23" } }, "nbformat": 4, diff --git a/tutorials/W1D2_LinearDeepLearning/W1D2_Tutorial1.ipynb b/tutorials/W1D2_LinearDeepLearning/W1D2_Tutorial1.ipynb index 7ead89bdc..02fa7571b 100644 --- a/tutorials/W1D2_LinearDeepLearning/W1D2_Tutorial1.ipynb +++ b/tutorials/W1D2_LinearDeepLearning/W1D2_Tutorial1.ipynb @@ -26,7 +26,7 @@ "\n", "__Content creators:__ Saeed Salehi, Vladimir Haltakov, Andrew Saxe\n", "\n", - "__Content reviewers:__ Polina Turishcheva, Antoine De Comite, Kelson Shilling-Scrivo\n", + "__Content reviewers:__ Polina Turishcheva, Antoine De Comite, Kelson Shilling-Scrivo, Jiaxin Cindy Tu\n", "\n", "__Content editors:__ Anoop Kulkarni, Spiros Chavlis\n", "\n", diff --git a/tutorials/W1D2_LinearDeepLearning/W1D2_Tutorial2.ipynb b/tutorials/W1D2_LinearDeepLearning/W1D2_Tutorial2.ipynb index 3cd755448..5d3a0feb2 100644 --- a/tutorials/W1D2_LinearDeepLearning/W1D2_Tutorial2.ipynb +++ b/tutorials/W1D2_LinearDeepLearning/W1D2_Tutorial2.ipynb @@ -25,7 +25,7 @@ "\n", "__Content creators:__ Saeed Salehi, Andrew Saxe\n", "\n", - "__Content reviewers:__ Polina Turishcheva, Antoine De Comite, Kelson Shilling-Scrivo\n", + "__Content reviewers:__ Polina Turishcheva, Antoine De Comite, Kelson Shilling-Scrivo, Jiaxin Cindy Tu\n", "\n", "__Content editors:__ Anoop Kulkarni\n", "\n", diff --git a/tutorials/W1D2_LinearDeepLearning/W1D2_Tutorial3.ipynb b/tutorials/W1D2_LinearDeepLearning/W1D2_Tutorial3.ipynb index 73c23c9fb..f71d1c36d 100644 --- a/tutorials/W1D2_LinearDeepLearning/W1D2_Tutorial3.ipynb +++ b/tutorials/W1D2_LinearDeepLearning/W1D2_Tutorial3.ipynb @@ -24,7 +24,7 @@ "\n", "__Content creators:__ Saeed Salehi, Spiros Chavlis, Andrew Saxe\n", "\n", - "__Content reviewers:__ Polina Turishcheva, Antoine De Comite\n", + "__Content reviewers:__ Polina Turishcheva, Antoine De Comite, Jiaxin Cindy Tu\n", "\n", "__Content editors:__ Anoop Kulkarni\n", "\n", diff --git a/tutorials/W1D3_MultiLayerPerceptrons/W1D3_Tutorial1.ipynb b/tutorials/W1D3_MultiLayerPerceptrons/W1D3_Tutorial1.ipynb index 0dac98a50..aab54b954 100644 --- a/tutorials/W1D3_MultiLayerPerceptrons/W1D3_Tutorial1.ipynb +++ b/tutorials/W1D3_MultiLayerPerceptrons/W1D3_Tutorial1.ipynb @@ -25,7 +25,7 @@ "\n", "__Content creators:__ Arash Ash, Surya Ganguli\n", "\n", - "__Content reviewers:__ Saeed Salehi, Felix Bartsch, Yu-Fang Yang, Antoine De Comite, Melvin Selim Atay, Kelson Shilling-Scrivo\n", + "__Content reviewers:__ Saeed Salehi, Felix Bartsch, Yu-Fang Yang, Antoine De Comite, Melvin Selim Atay, Kelson Shilling-Scrivo, Jiaxin Cindy Tu\n", "\n", "__Content editors:__ Gagana B, Kelson Shilling-Scrivo, Spiros Chavlis\n", "\n", @@ -124,7 +124,9 @@ "import torch.optim as optim\n", "from tqdm.auto import tqdm\n", "from IPython.display import display\n", - "from torch.utils.data import DataLoader, TensorDataset" + "from torch.utils.data import DataLoader, TensorDataset\n", + "\n", + "import ipywidgets as widgets\n" ] }, { @@ -140,7 +142,6 @@ "import logging\n", "logging.getLogger('matplotlib.font_manager').disabled = True\n", "\n", - "import ipywidgets as widgets # Interactive display\n", "%config InlineBackend.figure_format = 'retina'\n", "plt.style.use(\"https://raw.githubusercontent.com/NeuromatchAcademy/content-creation/main/nma.mplstyle\")" ] diff --git a/tutorials/W1D3_MultiLayerPerceptrons/W1D3_Tutorial2.ipynb b/tutorials/W1D3_MultiLayerPerceptrons/W1D3_Tutorial2.ipynb index af3d14444..74f4e54b2 100644 --- a/tutorials/W1D3_MultiLayerPerceptrons/W1D3_Tutorial2.ipynb +++ b/tutorials/W1D3_MultiLayerPerceptrons/W1D3_Tutorial2.ipynb @@ -25,7 +25,7 @@ "\n", "__Content creators:__ Arash Ash, Surya Ganguli\n", "\n", - "__Content reviewers:__ Saeed Salehi, Felix Bartsch, Yu-Fang Yang, Melvin Selim Atay, Kelson Shilling-Scrivo\n", + "__Content reviewers:__ Saeed Salehi, Felix Bartsch, Yu-Fang Yang, Melvin Selim Atay, Kelson Shilling-Scrivo, Jiaxin Cindy Tu\n", "\n", "__Content editors:__ Gagana B, Kelson Shilling-Scrivo, Spiros Chavlis\n", "\n", @@ -127,7 +127,9 @@ "from torch.utils.data import DataLoader, TensorDataset\n", "\n", "from tqdm.auto import tqdm\n", - "from IPython.display import display" + "from IPython.display import display\n", + "\n", + "import ipywidgets as widgets\n" ] }, { @@ -143,7 +145,6 @@ "import logging\n", "logging.getLogger('matplotlib.font_manager').disabled = True\n", "\n", - "import ipywidgets as widgets # Interactive display\n", "%config InlineBackend.figure_format = 'retina'\n", "plt.style.use(\"https://raw.githubusercontent.com/NeuromatchAcademy/content-creation/main/nma.mplstyle\")\n", "my_layout = widgets.Layout()" diff --git a/tutorials/W1D4_Optimization/W1D4_Tutorial1.ipynb b/tutorials/W1D4_Optimization/W1D4_Tutorial1.ipynb index 4294dfa55..b91c8d435 100644 --- a/tutorials/W1D4_Optimization/W1D4_Tutorial1.ipynb +++ b/tutorials/W1D4_Optimization/W1D4_Tutorial1.ipynb @@ -25,7 +25,7 @@ "\n", "__Content creators:__ Jose Gallego-Posada, Ioannis Mitliagkas\n", "\n", - "__Content reviewers:__ Piyush Chauhan, Vladimir Haltakov, Siwei Bai, Kelson Shilling-Scrivo\n", + "__Content reviewers:__ Piyush Chauhan, Vladimir Haltakov, Siwei Bai, Kelson Shilling-Scrivo, Jiaxin Cindy Tu\n", "\n", "__Content editors:__ Charles J Edelson, Gagana B, Spiros Chavlis\n", "\n", @@ -2797,7 +2797,7 @@ "execution": {} }, "source": [ - "## Coding Exercise 7: Implement RMSprop\n", + "## Coding Exercise 7 (optional): Implement RMSprop\n", "\n", "In this exercise you will implement the update of the RMSprop optimizer:\n", "\n", diff --git a/tutorials/materials.yml b/tutorials/materials.yml index cd7ddb7a3..7ed129610 100644 --- a/tutorials/materials.yml +++ b/tutorials/materials.yml @@ -4,7 +4,7 @@ playlist: https://youtube.com/playlist?list=PLkBQOLLbi18MGF3aRYZ-Ya_lexek248qJ slides: - - link: https://mfr.ca-1.osf.io/render?url=https://osf.io/wcjrv/?direct%26mode=render%26action=download%26mode=render + - link: https://mfr.ca-1.osf.io/render?url=https://osf.io/dg4h7/?direct%26mode=render%26action=download%26mode=render title: Tutorial 1 tutorials: 1 @@ -128,7 +128,7 @@ - day: W3D2 category: Natural Language Processing - name: DL Case Study + name: DL Case Study 2 playlist: https://youtube.com/playlist?list=PLkBQOLLbi18M6GYMqOSsswELhdxOUWQgR slides: