{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Demo of Convolutional Neural Network on CIFAR10\n",
"\n",
"David I. Inouye\n",
"\n",
"## Demo of Convolutional Neural Network in PyTorch on CIFAR10\n",
"\n",
"Adapted from PyTorch tutorial from (skipping details):\n",
"https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html\n",
"\n",
"## Load data (skipping details see tutorial for details)"
],
"id": "80ab3ad0-6585-4986-9217-7c579a3f8154"
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import torch\n",
"import torchvision\n",
"import torchvision.transforms as transforms\n",
"\n",
"transform = transforms.Compose(\n",
" [transforms.ToTensor(),\n",
" transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])\n",
"\n",
"trainset = torchvision.datasets.CIFAR10(\n",
" root='./data', train=True,\n",
" download=True, transform=transform)\n",
"trainloader = torch.utils.data.DataLoader(\n",
" trainset, batch_size=4,\n",
" shuffle=True, num_workers=2)\n",
"\n",
"testset = torchvision.datasets.CIFAR10(\n",
" root='./data', train=False,\n",
" download=True, transform=transform)\n",
"testloader = torch.utils.data.DataLoader(\n",
" testset, batch_size=4,\n",
" shuffle=False, num_workers=2)\n",
"\n",
"classes = ('plane', 'car', 'bird', 'cat',\n",
" 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')"
],
"id": "092618aa"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Show some images from CIFAR10"
],
"id": "e35b9959-3bdf-4210-911c-d67991918845"
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"output_type": "display_data",
"metadata": {},
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAjYAAAC2CAYAAADKmcfEAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90\nbGliIHZlcnNpb24zLjEwLjUsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvWftoOwAAAAlwSFlzAAAO\nxAAADsQBlSsOGwAASw1JREFUeJztvXmQXNV59//07X2b6ZnunlXLaIERQiCEkGR2hOItOJjXP2Nw\n4hSL/YtSTlKOqeT1QghlVyC4sMtOcBWV2IaE1wm/vHYo41hR3h9IIIwFWtCC0L7MSDOavWd6unt6\n73vfPxz3Od+npW41Giyp9XyqVHWfOd33nnvuuaePzvM9z2OzLMsiQRAEQRCEBsC40BUQBEEQBEGY\nLWRiIwiCIAhCwyATG0EQBEEQGgaZ2AiCIAiC0DDIxEYQBEEQhIZBJjaCIAiCIDQMMrERBEEQBKFh\nkImNIAiCIAgNg0xsBEEQBEFoGGRiIwiCIAhCw/CBTGyeeuop6urqIp/PR3fffTeNjIx8EJcRBEEQ\nBEEAbLOdK+r555+nP/uzP6MXXniBFi5cSH/+539OlmXRli1ban7XNE2Kx+Pk8XjIZrPNZrUEQRAE\nQbiEsSyLstkshUIhMoyzr8vM+sTm+uuvp49//OP0xBNPEBHRiRMnaNGiRbR792667rrrqn53cnKS\nwuHwbFZHEARBEIQGIhaLUWtr61nLHbN5sVwuR3v37qWnn366/LeFCxdST08Pbdu2rWJiUygUqFgs\nlu3fzLH+8i//kpxO52xWTRAEQRCES5hCoUBPP/00eTyeqp+b1YlNLBYj0zSpra0N/h6NRmlsbKzi\n80888QR94xvfqPi70+mUiY0gCIIgCBXUkqrMqni4Xq/Wo48+Sul0uvwvFovNZnUEQRAEQbjMmNUV\nm0gkQoZhVKzOjI+PV6ziEMnKjCAIgiAIs8usrti43W5avnw5vfbaa+W/9fX1UX9/P61Zs2Y2LyUI\ngiAIglDBrK7YEBH96Z/+KX3pS1+ilStX0sKFC+nLX/4y3XrrrTV3RAmCIAiCIJwvsz6xefjhh2l0\ndJS++MUvUjwep9/5nd+hH/zgB7N9GUEQBEEQhApmfWJDRPS1r32Nvva1r30Qp6bp6enycalUqvpZ\nrpzWbS50nuVwPhcEfr+17ul8giDOZnvp9Whpaan62S996UtgFwqFs372fO6fB3/i5+J9r9q5qvXD\nM2GaZtXycz03L6v1vlQ7d6174HWu1va8zOVygf33f//3Z/3uqg/PgJ1LpMG2+9xgR8JzyselNGvX\nPD7j1HgC7HRuqnw8ncaNDSUXDp2uiBfsaCSClxpS9ZwZyUGZP4T1cAeDYAc6l5aPbakhKCskRsHO\nzGDbprKE5QV17WigGco8dnwO+RyeazKm2mdkYBDPm54Gu60dY4x43KildIcC5eO+GN5TNncdVWPV\njTdrFvZDpx2fv529x1zTqb/n/K00+TtvYf+xGeobAReed35nJ9iWhe9epqAejNeFdXa7cCtz3+Bp\nsLO5Ith2u13ViZCK3zn2Ce0WyMaEKYUC3m+hiPeQL2I98tpYXGRlRRPt6WQc7P5T/aqOGXyn3w+S\nK0oQBEEQhIZBJjaCIAiCIDQMH4gr6oPE7VbLdny5i8PdCfryeT1L5+fLpZD3it9/PXX+IF1eHP35\nE7Fl2BquOG5XyzVSi2rnrtf1VO3ctZ5LPS6welxctc7NqXbuWuepJ+TDWB5DSWSymGDXX8QhrZDO\nq89m8Hm3tXSzc8XBzlpqSdzwoWsl4EO3zXQW6zU0iu6mVYtWlo9jNAFlUwa6dcwIuojMkLqnxBQu\n06di6AIKt+I9RZrQRXZ88GT5eLyUgbJAAW0rw/peUbkaCnm8P2LPOB6Pg+1jLkK7qZ6LYVSPIsux\nTHUthxOfN+9LbuZfcdixXB8/LIv3YTaucfe0ocqdDiwzLeYuMpjLTKsnfz+cDjvYgYAP7EIRXaYW\nqXpzd5nDwPYx2LUyOXWuNHMnGgbWw8bOlcujDCBfVNfO5tEHeuDQfrD37NsFdv/JvvLx//jwp+h8\nkRUbQRAEQRAaBpnYCIIgCILQMMjERhAEQRCEhuGS09jA9rzz0DKcrw6iLixunrueZza1LtXOXes6\n1bQe9X63Wj1qUc89ns89ne+5z+c6s9UXa123luZIt3lZLY2arl3g28zPJ9TC6cHtYE+lp8Be2LwY\n7KI5XD6Odi2FMsOPOpmsHzUGxXy8fNzWfA2U2Q3UPWSnk2AnT2O9Rkunysc5O+oPLDdqWxxsu28m\nlSof503UNXjao2D7WjF1jZlCLcy8hQuU0Yr3MDVwCuyZdBzs7q52Vacs3sP01CTYNgM1JlOTKbDz\nU6peZpBpTFCOU4HLrdqnyPpWMoXPMM/0Kq2tqJUqlFQ9HHb8OeS9cjw2DnZO27Id0bavExGFg36w\nDaYN7DuhNCVtLDSAz4u6KK5P6htEPddb7+woH7vYdW5cuRps/tx27n69fDw2PoB1tqEeaWaG9Vs2\nTOWLmp4ti8+/72Q/2LFJFj6huly2bmTFRhAEQRCEhkEmNoIgCIIgNAwysREEQRAEoWG45DQ2GHfg\n/WskhEuTCxY/hsWhMHj88SrXrTdmUjUdWS19CrYHPy/qDRwOFpcih3qMRELFuJiZwVQG6TTGUzl5\n8iTYEU03sGLFCqpGXdKwabypqH0e2I4Yah0sh/L7j53oh7LOMDr2LZQuUC6rNDiJSYw9429h2pZS\nCGx7Ac893q/FqunGOto8qMeID2JsHkdI3bMRZAIUGzbejIHPKZlH/Y4/rDQmTgP1KU0+1PbES/iM\nbR7VX9zsl6M1jGkgyI59bTqB+h3Do43jmjbj1yenqhw/9V75+NixY1A2OoY6kWAT3tOSJUvATiZV\nHw8GMZ1LqYRte/DwIbDzeVXvu27/OJR1M90Mj68zM6PaNu1j7cyeacnE9vnV9tfB3rxjS/nY60Hd\n1PDoCbATKdSCpbLqvXV7cZwaG8J6DZ9GnZSThR+yOdT3eSwemxPfW7cfO5DtPGKKnQlZsREEQRAE\noWGQiY0gCIIgCA2DTGwEQRAEQWgYRGMjXFLwZ1wt39P5xEuxM41ARSwi8+zn4jlnbPzLNm7yfqt9\nnt2vnelk+FdNrV48xkcqhT7y/fsxf8v27RgjZmhIaT1Gx0ahLOhHX/5kDDUoLa1Kr/CtJd+CMr8P\nv2uznXsOq5kx1K7kYhgPYySOQpnOHpU7afGSLiizx7A9AjEcDoeHlbahZT7WMdjEnmkahSGBph6w\nLZuKAZJjwy5LuUNulmfHXVJanziLLWN3oi5qYmYY7EAQ7zkxotorP4pt5Ujjdec2oeYkYKl7PM36\nUiCKGps4i5/jdKPGxBNQttuOcVsmanSHn/7sx+XjoonXKbD8V/YxPNlI/DjYXq+6JycLoJNJobZl\nOo76Ja8vVD72efG7Bn/l2Xt89bKrtc9iWbGI763DwXKpsThIHr9qg0wBy46c2gu2ru0hIvL5tD4e\nxRg/4U58T8mF99jSilqxTF7plabG8b30WvjdQh5ty850VueJrNgIgiAIgtAwyMRGEARBEISG4ZJz\nRfFtcxcDlR6wWXSJ1bEVtr6ECvV9o9od8bPw9uAeoFpbmOuhmvuxlquSb8OuJ00Ev2vdMpkLyGbg\nddwsZD5POZDNqeVktipdsSWbu5dOnz5dPh4awW3Dx47hMvzevbhMPTQ0BHYmr9w+dubyaw+HwPZ5\n8L2cTsbLx0ePH4Gy5ddgegJbHc+/yRYGezyHLrBcBpe0C9rK+8QQhtt3aq4EIqLmIKZYuCq4qHyc\nzWI7m0lc0k/G8LoZE9sj2KLcLe4SuhPzU+g+aWL18kyr7/oyWI+slvaBiMjpxL5WzGAagNhxZbcF\n2qGs2dOE5yLsfC59+7MD349kErcR2+zYlnYW6t9lqp8en6PG/m5GLKHSN0SiLHUBc+v4A+gucXnZ\n74dDC4/gQJ9gSwveg9eDz80fUK66ZnYdZ4UrG5+LoY0vmTS6uDxufl08d0trM9hNQdWWriLrW1m8\nJ6+XPRetvSZGsG+5WWgBpxfdwOkcupt0l3JrK085gn2pwNye3pb3/xtwJmTFRhAEQRCEhkEmNoIg\nCIIgNAwysREEQRAEoWG45DQ2+jbcahqJiwqe312H61GYdoPvhDW0cn5ak81TLZ5igF9aTyHAyoyK\nHcj8E8o2a2h1bFXSD3CKxer56+vR59TS7lTdOl7xXBCz4txa2HuWqmByEn3RJ0++B/bYGG67HRhU\n4fdnsuiLHh9HzcT0NOpG4vF4+TjN0yBkUBfC9To8xUKrFmI+x+rhYdtbuzpRr7Fb0++88MILUPY/\n/+IvwO6Zi2kRqpHHpqQ5kR6sVwdqLnx+pU/w+nH7stNAvYHpxGdasJS2JT2DL2KbD3UOrSZqGVIZ\nbK8re7QUDDbs41NTeN1cBjU3R0+odATzF/RAmcvqBHsmi898LI6pLpqi6p5Cc/GZTQ9iP7TbsB4O\nLeWCoxm1KrYCvjAFQq2HnYUHMGyqr9nduN2b8BYqcLrVe5qaQW1PuM3JPsu2TrvwOZqmqmc8jufy\nsDQAfj/2l9awqkeA3Z+dbdG22G9VoaT6S6lUfatzIY/9w+/FvmfTxn2rxH4w2DjlZakMnJb6bjKJ\nGptMHs+VSeO5UjPYP9we1V7tbVjHhKa5I6r8TXA5ZncqIis2giAIgiA0DDKxEQRBEAShYZCJjSAI\ngiAIDcMlp7HRdRA87P1Fq7ExmfZF18mwqSUPv++w4wc82j1zLUeBaQYyTK+SnUEfqqH5Y20s7IKd\nxQuy87gtmu/WIPTFVuiEeBqAKtTS2NQDT7dQT7wcrqGpUNSwvqefe997qKH55S9/Cfa2bdvAnmBp\nAaYTSjeTLaD/vfIesM+HIyosuseBdeSP4corF4Pd3Ix+8ZMDKibO4EAflGVTk2BPxTBmzviE0mvs\nP4CpGwY1DRER0cL5PXSuzO1cgH9gIjSXE7UOLrvqx6kp1FDMsBgfwShqcF7ftq98PD6BWqbbb8RY\nPFf2dICdHEBty+G8ihG0ctUyKDP8eA+jLFaNS4u1UsyjZiTgj4BdymPMk2Yv9p9Ap2qPQZqCMgdm\nRaBmD2pfhgqqn2aDOD50Gdh3igWmbWnFGDmnTqr2GB3FdB1GGHVDHD3eUDaHz7ApgHVOZ1FXRiYb\nI1Oq7adiqDmzG6ytWfss6LpClXmx3T1Mc5PP47ldhhq7TRPHcR7XyuXFc7WGomAbmp7JYO+D24Ht\nkZ/B9soXlJ2Is/hbLCZSIo5jc2aGaTgd6h5zMwn8bBw/WzJ5vJ3Z/e2ua8XmpZdeonXr1lFzczPZ\nbLaKH6EjR47Q2rVryev1Uk9PDz333HOzWllBEARBEIRq1DWxSafTdOedd9JXv/rVirJCoUB33XUX\nRSIR2rFjBz322GO0fv162rRp06xVVhAEQRAEoRp1uaI+97nPERHR66+/XlG2ceNGGhgYoF27dlEw\nGKRly5bRli1b6JlnnqF169bNSmUFQRAEQRCqMWsam+3bt9OqVasoGFSOyHXr1p1xded84Lqai5GK\nWCsm00Vo2g8nywvCA8hYJrM1XUyBlZkGxhaJp9G/PDI0DHY2EVfHOdQf+AMYD6S7swvstojy8xoW\nj53A/KUfoPbpfOLYVMPkNnsup0+jTuTtt98qH7/5y1+xz2K7j7K4NdPTcbB1H7vLh/0j2ob+daeT\n5X7RNFl+N+og5s7pBpvn0dm/H7Uww6OqnhFNu0NEZFhMQ8FGkiuuUPqdJUuuhjKfDzUD9eiqRiaw\n3UssbofTjnm4ehf2lo/9DtSbGH5sHzOL5T5Tu8dsHMoSk2hnQtgAWZb/5+ARpUnq7MLnEGpBHcTR\nI0fBjsfVMx0awNxYkS7U9jhd2LaToxj3yJNQ9zzhxjrOjeK5jBSOJw6POrcjiM9sbAw1FbYEapJa\n57O+16F+J4pM+8dUMRUsXqTq4fXh+8DHnpFhHAPcTEyYKaj7SE1jXBYP0xE1Gdi2TlLvj9OObWUw\nfRsLXUQzKXWXx4/3Q9lVvUvxumF897werIdV0u6ZDXm5NN5TTzfqyAJu9YVcDseD8Sl8LkP9qKOb\nSWBbB5tVP52exDhOiViRfRbraRK+t+fLrE1sxsbGqK2tDf4WjUYrAorpFAoFGNQyLDCVIAiCIAhC\nPczadu/387/jJ554gnw+X/lfOByu/SVBEARBEISzMGsTm/b29orQ8OPj4xSNRs/yDaJHH32U0ul0\n+V+MbXsVBEEQBEGoh1lzRa1evZq+853vUCqVosB/++43b95Ma9asOet3nE4nOVm8lFpU+/zFEseG\nr17ZXViv5pZQ+TgYCkFZLI6+6dFxnOx1tCk/eCHHcnfkcJ46NcNiJwQxlsTQkMpBYxn42Y72OWCf\nHB0CO6u5EBfMmQ9ltoocXjRr8Lbl+cKqfpY/FxbnRu8/die+Gvve2wf2P/8z5j86fORI+XgqhjFe\nUil0sfJ6+QP4XOwOTSfThFqnjg7M78Pdt4mE0jr4WvC8FtNC/epXb4A9w3JLLdZ8/fwRpqbxHqOt\n6LvPaXlmli9fDmULFiwEuzLv1tnJpFCBwfU6qSRqPXS9UkcHakhKedTUJJJ4//O61ec7ujBeTIrV\nIxbD685j+a9cAfX9QwdRQ3Pdiqvws07U3MTG1Xva1IKr2pkkjhexEsam4WnaskPq85E5qN0wS/iU\n+/oxFo/XpXQQqRnUWM248EI+J2pO6DSOY55WdS4PyzN2Cpuygq4upV/x8MsM4HNJJ/EZO+z4+xEM\nKl1JJIz90GAatYq4aeQGS4d3aT5O5bRcYi7WVk4X036ZqE8JeDGgjk27lseGmju3B59LKIDjWntE\n9bV8EX8DQmHU3EwMoW7m+DHsa20dSjjj9mA9PAaOUx3zsNzhnd3f7romNpOTk3Tq1Ck6duwYERHt\n3buX7HY7LV68mD72sY9Rd3c3Pfzww/T444/Ttm3b6MUXX6SNGzfOaoUFQRAEQRDORl0Tm5///Of0\n0EMPle0bbriBiIhee+01uuOOO2jDhg20fv16WrlyJbW3t9Ozzz4rW70FQRAEQfitUdfE5sEHH6QH\nH3zwrOW9vb1njHEzm+jLgXx5bzZdURVbtuvYVuxw4pJlaxsu00fb1RJ3qBWXuMd27cGTu3Ab3LUr\nbygfx8bQHXBqMA62P4hLhatW3gT2m3a1xDkZR1fTuo9/GOy+46fAfmvL1vKxh20xnd+FbiyzhMvB\n/DGdz7bsqrALcddTjoU511Mw7Nm9G8p+8Pw/gX38+DGws1m1TJtM4DZJB9ti6vPjEm+A2Q6Xei1L\nFtZxkLkHePj1cKtyLzhsuKR94vgJvI4T2+e663FbdrBJ7XLMstD0DgNDs7e1zwV7wXy13fv2W9dC\nmceN/cU0z13q52JL/sU0Lo8HfdiW/f396jod2A/Dzeiqa/bju2Z1KBeBi4Xq/6//HwOPepmbr60N\nXUZ+bevw0Clsy6Eh1CZ2dWJbugx1TxYLO5DM4hJ/0IV9rYVpHKc1HWOwgC6Q3DS2Ty6Nz3jylKpn\nwBeCMm8U9+86WZiCUgndKemMagOjzmE7OaO+m57B+49P4clSGXw/ig68J7db3bPHg+PQ5BR+NhHH\nkBj2q1U/TmWwH7ayMa2Yx/v3eVV/WtCDrqUiaytiYT2cLHVOU7P6fpufbf9nKRbGEzh+jGj1TKdx\n3LIsnB4s6gmBPZXA/lLQXOgdLDyEw4ltZ9nwWskEtvX5IkkwBUEQBEFoGGRiIwiCIAhCwyATG0EQ\nBEEQGoZZ2+7920LXQVRsv6tDY8N1Hfy7tc6lf98wsB7tHRiBuWMe+j39TSF1HvYIsnn0CbeGcSuk\n3VC+ep8H/f5dHUxTMdgPdoqFObdpqR5iYxghupltQV7Ntu1PDKvQ7vt2vAtl7ZFOsP0evn0R77Ee\nqj0nXpYvot/2wMGDYG/duhXsvLb998iJPig7zdJRGHZ8brmc7qvH5xJi2+x5f+E6mckR1baWhf72\nArunEAsXoPfLSbYV2OnFei1dvgzsBPv82IjSXXV1ohaMSniu5dddC/bHP3J3+Tjgxy3r/H5txrn/\n/6qzDd+l0REM855lW9bd2jbSNEsx4nXhMwx4UGMTDStt3GQyDmUmew7Dw6NgL7oCdWb6LuNsFnVT\n2TTaRwcO4Xe1NAHzF2BohZEJ7JfFDNar2cu2w2v6FK+B72U+hbqHliBqA6fH4+Xjw/34Ll3pxC38\nNg/2+YwfdSF5rZ6p/Lmn1CAisrTw+243aqoS0/gcCky/lWMhMDwl9b4EmBbOYcP+YXdiP/Z5lLaF\npzbhvx7FAt6jnvqEfzgeR+1kCw9cazD9jqbvGhg/jR9lKUdKhPUo2tS7mExi38llsK06I/jOuwPY\nXmOaJsnuRH0nH/Mt1ufzM+//N+FMyIqNIAiCIAgNg0xsBEEQBEFoGGRiIwiCIAhCw3DJaWwcDlXl\nSp1M9XmaLsHg3603lopej2AQ4xDkCyz+wzTGCHd4lf+5xOJfkIF+zGgragoyWnj++DjGv3j3vcNg\nH9iLsVi2vYF+z+kxzT9vwzonJ+Jgt7ahD7m7s7t8fDzQD2X7D2E9brrhGrAtC59TtbQItaimhdq1\nB+//tTcwhcC7e/eCPa2lI/Cy2DIeN95/kWks/JqOxGJ+bd63siz2SC6H/uaClq7C68XrGnZsO37u\nZFLFi8haGGdiQQ/qM1IzGHsjGUd9ii6L6G7HuBS9t98O9k233Am2Hn6fa2rO53kXi6gRiLAUAw6W\nYqGojQmtHagTCjLt04EDqBu5ZqnSmISdGKdl9aoVYO97dz+euwWvFUuody+ZQS2Tw4Z6nKkkxvxI\narFaVt1+C5SlTOxLh/bjuzcRj4OdnlE6mtEC78M49mRT2D9uWLmqfHzwGKYYybP4MCE39tMC07aQ\n9o5k0iyHQg2p5MCgGveWXoXvqc+P1x2ewPejQNgX3XbVyVui2B/GRjANRGkGK9bkV32itRXfDx5D\nK8/SdzgdSp9iOFicqwCLp8R+I7xMv6T/vJTy+MzyLOWKzYbvT0lLwZAv4liTTGGd50WwbZe1Yz2y\nWhqFCabXG2D6LXsQpx7nIbs8I7JiIwiCIAhCwyATG0EQBEEQGgaZ2AiCIAiC0DBcchobPXZNrVg0\nRFV0NEznYbHP8tgauqaGiMjpUDEgTBO/OzqCeZfiJ46D3RJWsQbaO+dBWdAfAjvcjL56S9NjvMU0\nI//7Jz8Fu8DuIRhAf7RLa48Mi63x0v/3M7AND97/6IiKtZBDVyyNjqOW58qFmPumvQ3viWsw6kF/\n5inmx93zLsbX2bsfdQEGy+nlb1JaqdOn8RlyXRCvs9Op+oOXxbGZnpw862eJiFwu9G3rGhyXCz87\nNoZty/u8R4tVk05g3JbxUYz5kmexWa5ZcgXYNyy/snx87fKVUNY1dwnYpgPrWdKc5gZhO3Pq0bd5\nurAvmSwGij+AsUZsTvXc3CHUycwUWb9juaNKPpVLKc9ierS2Yw6m+Yt7wHYyrU+bT+kmuubgPYzF\nUGNiON3MVvU8cXIAypYuQ/1asAm1HskEaixGNV1eqYTtnsvzMRHvORJRfW1OJ+q14kXsl3YWA4aY\nxiYcUO1joUSRRvA1riA+rXQkCfbOd3dhDK2TfWwsZjFiSNMZRdgYl0sxfQrL0RRpCZWPLR6nhY0X\nPP6UHscmnWI5qJg+qWRiHw8GUFdmmGpcN4t4Li/LB1dk9cpozceqSPkci4GTwf5yUy/2vSZTvXu7\nD7E4YPtQz5h1s/yK1rnHoDsXZMVGEARBEISGQSY2giAIgiA0DJecK8qhbY0rsXDzxEJik8WW/7Ql\nb48b1z/dPlzC9rIlba8Hl5a92vcDbrxu4QrcNjuRRF+NqS27uZ3otrAFcRnaXsJH5NGWKWOTuIS9\ncBEuDc5bfBXYSRZuPqeFmI9N4VLy8UF0YxT5luWMugfmiSN/ANt26x5cPp/Tjku8i+dj2ohqVNum\nbzDX20wG7yHLtlX7Waj/wZMny8fJJLYVd1262fbvVi3sOU+hkJrGrY/cjcW3Hcfj6lmkUlgPvt2Z\npxUZHVUh5b3MHTKvHUMHXLcU3aBrVqB7aeECFSa/NYyfNQjbji+9k83UC1lZfelLdAIdzBWVxXeL\nZbqg6ZRqSztzPZWKuNS+YMlSsJu0LdsWC4mfL6GLw8/cXMf6T4DdPUe5SDrmYFtOTWE/bWNbp+2a\na/edHbugLMdCB8ydi+1zBRsDmppUXzt48AiUDQxhP53D6jkWU33Racd3KRQJgT01iaEomh24hTkY\nVm0bj2EahFo4XOoeTvbh/WfHsS0nBtH15Gtm6T20MbDE3JpOB77jHe1dYLe2hsrHJuvjPKRBkW2t\nJ5ca5wcHTkGRtwXf2452dPv5mat7bptyi7Y2YTt7PVivA8fwWgN96jekWMJ3yeHG9zKVw/cn0IGu\n6ybtuRRPodvbxrawe1EVQZSsL61GLWTFRhAEQRCEhkEmNoIgCIIgNAwysREEQRAEoWG45DQ2hqYp\nMCzcYko21Kf4POj3jrYqX6RZwu+mmP4izbY/2wh9pIa2PdzlRU2Jvx01I51N6LscH1N+30Qct+c1\nsbDmdrbNfGJyonyct9AH3Hv1DWCHO9BHPjCEugByqL1+bT62rdyGvtk8i4JfyOv+Vyw0mbYpXcBz\n9Q2iniefUb77+d3oX+ZwOYa+S9DNNDNd3ag3KDJtSy6L4cdzGXUfdgP7UqGAn+W6ED0cQDqNuph8\nAXUAPAWHw4XnMi1Vz2QC+45hw347MTEBdiik0gDMnbMQynp7F4G9YgWWz53TDXZTSNlOTwuU8W2j\nrAuQHmqhIiwD+2Q9GpuxY8fAdhv4fsyw99ihbbOOBLGPGyxUvZuNH/m0anu/EzUCkWgb2Jk8Xncv\nS9cxOq7evbnzsd1NN2qsmpkuIhpW2o533tkBZUcOY3scO4ahJZax7eCLFqk+kGA6svEE9vEC2+49\nOqnGixYvartcOGyRmWNbydk9pUldy+1l4zhKfSpIJtX7UTDwGY4N4fbvRALvoaUF2zoUVmNGRXob\nC/uWg/3eOF1aGhUL24OPNSUL7aKmwRk5iVuj292oqbGVWEgHFgLixuWajsqJesZsCX9fnM4FYM8N\nqfd4/7HTUDadwwfhb8XUH2kHjrfHtVQXByeYrpCFg3Cy9pjbyVJSnCeyYiMIgiAIQsMgExtBEARB\nEBoGmdgIgiAIgtAwXHIaG7sWq8TOQlxbhPqMfAHtvQfGy8cZFiLdxny1XZ3oi42G0E5qsUZ2HR+H\nsv4p3JM/feow2E6buvbcORgCvMRiBQwNos80mYqXj6emMY7N2CRqW0bjGNOBC1Tymi5geARjSXSy\n0OQepjEwNN2Ew4HnHRrG9nCzFALBIPpm85CTobrGhpj2x9LuqcTm6aEW1IW0NGPwhOGRYbDtml6D\npzLI59PMRu3LtBarhodI55/lmpOxUWx7hxaMxdOEOrHYBH7WH8B3oElLCzDEUnvEprE9Cib623Ml\nfMZOr4p7U2TaHpuB92CwuB16HA+eMKEeTQ0nn2ApJVg9XF5sr6aAds8sVIaLxVYxDLzHXE69T2n2\nrunxYIiIyMShNM1SCFx1pdK7ZZKoAzGYxsTwoQYrkVCfb+3EWEQ2Fso/PhkDe/e7mEYkpb1rHhan\npbcX+8PJARx7CgX13TTLRmGzWPqFMGqQTDs+p8kRVc+eCMaHqcVov2qP3l7s024H1sPuxIqOx/H9\n6ZqrdGRTMdQYnTyJOpGWILa9oY03PG5NvsBilzFlWTqv9E1WCceWENNO8nQMTi+Oc74mNZ7uP4px\ne0wHan+iHtQdLlyu9F6TU29CmSuNY/HiBRjnadmyq8HOF1Rfs1hAqXQan4vHieVeFkfufJEVG0EQ\nBEEQGgaZ2AiCIAiC0DDIxEYQBEEQhIbhktPYODS9RjKNPtH+PowHMDCCvuys5m4Nt6Av3iygDz2R\nQD/n6b6DYB/bf6h8vHcAnfdDefS/u7OYN8PnUv5Gtwt9z37ma3Q70d9OhhbHx4l1tNvRV5/OYPsY\nBvp5da1HSygEZTy3ST7PnOpa3Aaecycaxra1WIyPUh7jurj8qHWoBvdl63PzEycwP8//+T8bwW5p\nZbqp9hDYO7crH3E+h/fv86E+Z3QUn6musXEw/3K4CWM0TMWwXw4Po9anQ9NRZDLoMw+yXDe33HIT\n2P2n+tV383Eo87P8Z1t++Q7Yc+69FmyXR30+k60ex6ceuMaI586qRqAlDLYtjZobpwv70pSmSUrF\nWU431m89Aewffrd6jjPT+BzaOzCmh98bAjvM6rmgR2lskizH24lhPHezFm+LiKhroTpXuA1j8Zw+\niToYN9PN+Ftx/Dh1WsUqaXJj8Jm1H/4drPMi1Nzs2K5i6MzEsM+6mZZjoA9johhO7C/TM+q5BOex\nnyE70y8xdF1RNoVtmZrC2DxB9kxLTnzmQwPq8/kZlg8sg+fyBnAMsBVVPy6y98NimqIC6+LFvNLh\nzZ+Lz9sdQm1LYQY1e+TCk+lDdX8f5uiKs99IRwnjXnUGlZ3LYFvO6WLxtpz4rk3E3gU7X1Tjb9CH\nY77PgZojPechEVE8h2Pi+VLXis2TTz5J119/PQUCAers7KSHHnqIxsdRKHrkyBFau3Yteb1e6unp\noeeee25WKywIgiAIgnA26prYvPnmm/TII4/Qzp076eWXX6YDBw7QfffdVy4vFAp01113USQSoR07\ndtBjjz1G69evp02bNs16xQVBEARBEDh1uaL+8z//E+zvfe97dNNNN9H09DQ1NzfTxo0baWBggHbt\n2kXBYJCWLVtGW7ZsoWeeeYbWrVs3qxUXBEEQBEHgnJfGZmJigjweD/n/O0fP9u3badWqVZALZ926\ndfTVr371/Gqp4XZp+Vws9B8eOnQE7OMD6CbLaPkpIhH0H65Zhv7kcDP6Zn18370Wi8abRb+mOc5y\nbqSxHsNJ5Z+2TNSbNIdQj9F7zS1gOzVfvmnigptZQv+xnefo4bEnNJ2EYeC5CgUW9IPQh25pfm7D\nYbIy9K8e3b+b1QMr0rzqOs1CPzaHazv09C5bt/4Kyn71q7fAvrIXc2ddq+dYIaKrl11ZPt7/Hubc\nyaTxObWzfGB6LBom3aDJSfRNz8xg3AoWigTLbXjdxfPwHuJxPPeoptcJhbGPHzt6EuxpVq+FPRjz\npDWqrtXSEqJqcJ1MNQ0OL+N9rxqWA/UHMyl89yiDvvpYQsVLKRaxT2dzOH60Ml1Mk6b9sliusJEh\nfKdXrrkD7K5uzLuVzajnaBXw/Qh4UBvnZnGh0jNK69HC4uckWd6xQAQ1ODEt7hURUUDTWaWnsa2m\nWF/yM02JPq6bOeyXTg9qm0w7aipCrN6mlj8tPoptSV2LqRo33XRd+djtxPxesYH9YHuacdx2e9EO\naJqsSDOOvQs6Q2CvWbEcbK9ftYfXi/UYnsB4QlmmUbTyqj91sPyAyUOo50zfgPUKFFArt3ThsvLx\nTBLfh+Mj+Fs0MIS6oaKh6hXuRG3k3MU41gQD2NcmkyxmkEe9m6tXr4Cy1jaMN9Q31A92ocS1k+fH\n+57Y5HI5+uY3v0kPPPBAOQHg2NgYtbVhYKZoNFqhw/kNhUIBBptMJnPGzwmCIAiCIJwL72u7d6lU\nos997nNERPTtb3+7/He+26EWTzzxBPl8vvK/cDhc+0uCIAiCIAhnoe4VG9M06cEHH6RDhw7Rli1b\nKKAtV7a3t9OhQ4fg8+Pj4xSNRvlpiIjo0Ucfpa985StlO5PJ1JzcFLXw0oeP4JLdiT50RSXYVreC\n5otxtuGczmniVrfSNG73PTSIobj3vberfJxMsHDRWTx3IoHLkgaplSkWuZ8y07i6FRvDsPjdPWpZ\nsmThknXJxKV2GwvjbWPzWLsd3Us6VpVt1b8ut7RjvO74xCDYQ6fwOdlteN3jx9QW1St7MZUDh9/T\nzIxaTud9L5PGeg0O4lZHh/Mo+7x6jh3tGD49n8NztbTi8rBTC0PQdxzdWCbb/t0cwiV+nw9XOcFn\naOB3SyYu8Q+ylBtFzQ9WyOIzHBvFPj5//kKwj5zEcAmpn/zv8vH1y3EZvnfJErCbm3EZuxr8P0D1\n/IdoTie6KTKsLU0bPpcel+prPLXFIE8ZkEUX4cCw6sepOL6XLWF0+fBQEx6WJoE0NziVsB4L5+PW\n8dMx3P7ta1Zj4ggLMzA5iZ+1MRd6J0vBYGgu9X0n0DXZx+6hiT1T/RmHglg2dPoU2LqLg4jIwdqj\nu2dR+bhk4jg9UGP3f0/PqvJxmIWpmN+1Eux4EsdPrw3fieaI+m1KM9eKK4Bb2lf2ous6lVPvU1MT\nupP0NBhERNk8/p4kNJnEzOFtUOZgW/jNZvz9nEzjPTRp70C+gC4fHwul0d6N41hQcwM77Njw0xn8\nbiKNoQQME+8pnVPvMRviydWEzz9SwvenIpzIeVLXio1lWfSFL3yB3n77bXrllVeolQ3uq1evpp07\nd1IqpR7q5s2bac2aNWc8n9PpJK/XC/8EQRAEQRDeL3Wt2PzxH/8x/cd//Adt2LCBiIhGRn79v4do\nNEp2u50+9rGPUXd3Nz388MP0+OOP07Zt2+jFF1+kjRs3VjutIAiCIAjCrFDXxOYf//EfiYgqVmD6\n+vqop6eHXC4XbdiwgdavX08rV66k9vZ2evbZZ2WrtyAIgiAIvxXqmticiy+8t7eXXn/99fdbn5r0\n9/eXj48dQ+2GzUAfaZMfHX02LQXBzBRuizuwCzU0ve2oexgewG1zxzS7yByKZgk9fEWWlj6qbX2L\ntqJPtP8E6lPSKQyn7dTSIhgW073Y0H9qMA2N3YZ+Trvj7BobrmUxWFextH3WJQt9rVwX1N6GOohM\nGjUGiQRqX6rB70nfGj02huexTBbm/SQ+49OD2NY2m2rPefNx+38giPeQmI6DPW/e3PIxiwxAbie+\nN3a2E/r6FdeBnZpRvvtgM26xPHAAdWTZDLa9x6u2XH7oxtugjG9BDgRx6/ScuajHOHFQXSuRwH7I\nt0qHbCGw691IcM6w59/chVtS29tR+2MVVD+dYNvbfSFsjxaWZmVyQukg0ok4lk2h1mWMaV+aTXzX\nll6pQgmMs7ZMTKIGb3wI+3GHU23v9XtRQ1NsxXd+bBz7eKgD9Rm6Nm5sBHVD8xO4FTjUFALb61Zb\nmo8dRz1OOsP0KUxidOIkvmuGXfW9ngWoMSKsRgUnB9X4cXoE79fnQTmD3cJxfGgcn5NpV78JR/cd\nhrLJ3Rimom3+1XgtLRVCwcT+brBxe2gI7398rwqtEN+0Gco6rsQ+3XkK6+y243trD1xRPh6eRK1K\nMs/CdLBxPKFpKU0TBybTwe7JwLGmwMaAYkl9PstySGSzeF3TQI2NzTW7270lCaYgCIIgCA2DTGwE\nQRAEQWgYZGIjCIIgCELDcF4pFS4EB7VYJfv27YWyXI6FrWYpB/Il5Y/OslTwwyy+gYOFkx6OoR88\nr+kxLDf6PPMs/D6fPt58q0qTsHrlaij78Y//DezxKdSjODUBh8uOcQYsljPBxvQIpsXj2ijbZHFr\nbHastK4/ISKyaW1bZO2eZ2Ht//D+e8HetxdD9586iTEwqmFZPKWCsgt5FqOB6WImmZbBtPCevV7V\nnn3HsU5NzTz2DIZQtyx17St650PZkl7UrtgK2D8WdrM4T5byP9sDXVA0No76i/FJ7MfxlNLnLOpd\nBGUf/fBHwPY4UQgxpwtjCA0v1WLXMMlMZyd+lqdU+KAYT6IupMM/F+x8chrsmWmlwUqnUQfSHMG0\nGMHWKCtX2g8P026cHj4Btrnrl2BfOQc1BF6X0nLwmB0zOXyGPvZc4lp4/lAL9v/mFgy5YbD0DCWW\nrsKmvT92J8YleeuN7WB/6OZVYFuWGosSM/iOL71qGdgJFounrw/fJ3dAvT/79vdDWUsP3hPH7lHf\nNZmWK8dSv0D8ICLae/AY2M0+9V53RPDnMD8PNVenJ+Jgd2uSrXQQ+1ZqFHWGfUcOgN3kUM+ldQXG\n3mlafQPYwSt7wS6xe05OqnpFWEqe/BTWuULJoqc34WlR2EtfZOVcV6RnRbCzfudy4nPJZlGfY4Ox\nGMfW94Os2AiCIAiC0DDIxEYQBEEQhIZBJjaCIAiCIDQMl5zGRs/Jk5pGP2++gPvsi0X0CYIOgPkp\n8x706x2OYV6dRAp9gg7dP22g3ztbRF1MgKWlv2KRynezgsUwOXwY45Rs3Pw22JZd1dsw6pyX8tgi\nNr2I5e8hbLsi8846tJg4uQzG6fG40J9626134Hft6NvPF85dn8Hr6fUpfZPP74cyuwOfi8uN1/X5\nUBvl1uJ0jI5inCObDZ+/wWIXTUyo/pLO4HNZ1INajit6MN9RZ1sI7I42pcnxtWI8neN9qBPq68fY\nLA6n6nv73kMtU4jlEbrlQzeCHWP6Hb9PtaeeE46otqaGa7aqYbPZan/ovwmFMJfc4ADm8xkuoR3U\n4vpYdnzHnWmmTzqB+pwmLYZQqAXjCXlyOPYsacNnPMl0Y+6I+n6SxXyZnkE7X8L2KGp5hrwB1NCY\nhO+e24ljzTQbx3bvea98nC3gu3R6DHUxUyyuTVOzasvepddAWbSdaa7YuXMF1LbMaVft0VLEOtcI\nY0OG1l8cTI/Ex2LDge/iyuuuBXvJPKWlDEVRk3Zy8RVgG4R9wKVdKz3D+k47aqw+FLoFbNK0TlYJ\nn/8Rps/Z/RrGuTHY79ptN6t4VXNZbrBUDs89w76b1/oW11GWSqhZ5O80t/Xcg/y3Kc9yZXFmO+yV\nrNgIgiAIgtAwyMRGEARBEISG4ZJzRV23/Lry8aGDh6Ds0CG0Z2ZwUdOmzeP4Mlo6j+6jgQlcluXY\n7er7jhKeq1jAc7VHcfl8wfye8rHfi1u2vV5cLnewJ5RNqyVPq4Tbhi22Pc+0MZttb9YXbU2+dY9w\n6ZBvMbRrIePjo7jsHvTjPXh96CJqZ8vWt92Gof+rwVM9BDUXyZxuDM1+8DCGSA8EsK17FuC27PY2\nFX79V2/i1lenA7/LUxkkEirFxu23oYvnhhV4f90dGOZ9bje6MQJae3kCWLZowVKw8/lNYEfC6vPH\njh2HslIR62yx7fHhUAjsq5eqawWDuAzP3UfcRVjNTXo+6RaOHzvJTobuxbnMBZDPK1eNh7mbHU68\nh1Azpjdp61DbfUfH8LozEwNgj5zAtj5+HF0v41G1DdfDXKaGE9sqNoUuwVg8Xj6e0Lb2EhH52bnc\nDrRTSZZmplmNRU43uhebwvhexpPo5rrqGtUfbG50H00mcSxqieK5OrsxfIapeURaWnB8nEHvWQUZ\nLZxGJIzfdTrQNcWymdAVN94E9vxOtcX/nd17oGzDpl1gT8cxtcG27VvKxzffuhbKbl+DridnHisy\nNqnG8dEpDGEwNoW/W5kZ/D2x2I72o0PKdWU4WDgIlr7DsrEfFK1a3L2cTLIwBH503ZdKTM6Rz2ll\nXAbCfnuYK79YrO6qqhdZsREEQRAEoWGQiY0gCIIgCA2DTGwEQRAEQWgYLjmNzaJFakveddddB2VH\njx4Fu9o20mIR9QW1NAL88/q5nWzLIf8s9+2Hw8rfHp/GbYKZNPq1rQL6yEdPq1DuBgs9zbe3F030\nzRZL6MfUtze7XCyMtcG267JtlA5TdZ2pCdQfNDeh/3Qmhb5aP/PVdmpbFA8ePEjV4NoohyZCWrCg\nB8qKbNt91xz0+ycSuFX6U5+6u3wcZuH1N29+A+yhYfS3O7Ut7p/85Ceh7J670c6xcOI8X0FR2/7O\nXc83rMQw9+3tqNcZHFJaH8OOr/fJk/icXk1jPe77fz4Ntr59k/dpO0/XUcf27orQAnVobk6fxna/\naglu32UZNyilCTb8zRgiv8C2bI+w8PMup2pbl51tb/fi/edYmgyXHzVZJUN9PsO0TQ4P6mLaOrrB\nNhxKC8Pf8WQCO0jBjvXgWga3V2ljmiPYx5uSXLOH9cxk1bVybMu6P4hte+wQjsVtUdyG7NZSTPCw\nC5RgKWkYU5NK/+h1szGwgHXm/3OPTaN28vAppasaGh3Ecxn4/jhcqMEa14a1fUdRZ5gubgPbabBt\n+pqmMcfClLSG8Z1ubkHd2HgiDvZQTNlM9kI59l5a2Dzw28XDpeSy+Iz5a1oo8O3gqm/y7d18fND1\nOL/m3EM+nAuyYiMIgiAIQsMgExtBEARBEBoGmdgIgiAIgtAwXHIaG5fmm73yyiuhbN26dWBv2bIF\n7CFtvz/X33DNQDPzx3NdhJ7CnceS4Hv4p5mO5rAWX6WnpwfKHA6sx6rrl4PdPUfFXvG40Tf9zju7\n0d61H2ynGx/3xz/+u+Xj+fMxpouNaWwcTvyuWwtPv+kVvN+dO7eCfZKFl8+xMN9tbehTrgddn/Gh\nD30Iyra/g7FoTvRjrJHWFvT779r1Tvn42muug7KWcAjsfB51AF1dKn7MTTehDibLUk6UWMwgk/mX\nTT3eEhPZtLM4Lffd9z/AfvkX/1E+HhvH+BjNQUypcNVVV4FdZP124JSK1dIUwDg2ARbXpppuhpfx\nd6+elAom883bbdg+YxNxsLMZ9d5ag6gxctqZbsyD95RPqfd6amwUypIxTN3gYjqZjnbUfmQ0PQIL\naUIzKRZvi4W2b2pS584x7UImg/2QpxCwmMbGq2l//D6sY9CDn52eRg3a1IRqg0QSg82sYNqvZArL\nHSydSUtLqHxcZO9HLb1FekbdcyyGdSyUuIgE78nB2iOeUv2Jq8Taoqh18nZje/malV4pwGJ1nRxF\nLQ8LPUMOTbNosH5YMPE9TDPtC4+hZdfO7mC6uhJP98N0Mz6/6i92g08H8LuZDP4G8thnulaQ98sC\nvwf2ewpj4nzUfr0fZMVGEARBEISGQSY2giAIgiA0DDKxEQRBEAShYbjkNDa6FkaPaUNUqRPhWpef\n/OQn5WPu9+e5cO677z6wuY4mrcWbCbN8JS//7Gdg79v3Ltijo8pX7fVizpWpKfQZf/yjHwV7fo/K\nucJj7TQFMXbG9h2/BHteB7bP7betKR9Ho6hzMVnAAwe7lp6TZWToBJS9+eZrYG/YsAFsHn/o+uuv\np3OGud8tLb7KFQswH81X/uIRsF/41/8FdiwWA1uPy/DmW9h2viA+/2VXXw329atXlo89Pnym3BfN\nFQQG+4thqM/b2Hctlv/rU7/3e2B/6IYbyscjI6gL4RqbefOwvTwsllGJxa7R4XEpeF+sprHh1BPH\nxk8Ym8hIMx3IyBjY4ajSPvXMnQtlwSZ8pq3sHZgcURql3dt2QBmTnJHDgc8wlcQYOVMJTWfH2jkQ\nwJxNPJ6I3aH0KQ4nalWcTENi2PE52F0YP0WX8HGNUYHnEmNaj5wWx8bGygZPoX7Jz2LTFJn2Rbft\nDq5Aqa6xcWnawkyO5bRj/bKUxf7i82K9DFL3kWS6ITtvS6YToqy6BydLShUIhsCeSWF/0GvFdTGZ\nPGqOEgmm0WOvpder9Q871tHk8ad4PB2t2Mb6QzCAOlOD6XUSCWwvXUdjML2Oy8XiKbFcY+k011md\nH7JiIwiCIAhCwyATG0EQBEEQGgaZ2AiCIAiC0DBcchobPY4Nz1+jlxER3XLLLWBv3ariq/T19UFZ\nZyfmEeIxctwsJ4kei8XJ/N7t7e1g73wH/cBvv/12+fjo0WNQxnUfp7XcP0RE00kVH8FiOphEEvUG\nV1+NcUq6uvEeBwdVnJLh4SEoM1hsEZ8P9Tu6X9jL9Ee33nYH2G7mm164cCHYXGdUFR4TxVI+cquE\n/vU57H7/389/Hux9+/aBfeTwkfLxO+9iTCCXG33T+w9ijKARLc7Jp38Pc0Ndf9UysLn2y2Yzma21\nPZMb2CpERmj3dM874/GZqJWzSc/DxTU1tXQx+j3wODX1aGo4ZhbjYxx57z0sZ+3j1mLC7J6YgLLO\n7i60Exhv6uQxFffIZLmg4ml8p6eZhuLEMYyZpMeBmtODWh8eQ8vG9Eq6zoo/B56njp/LbmBbu+zK\nzqYxh1uK3QMfX2EMZI+Q6y0iUXz3JlgeLr1P8OsQMS0LI19QMVBKOXyXSmwMCAZQV8bHj4wWQ4fH\nWrHbccxPMt2UHhMmF0YtT5hp43gOQEPTFdmLWOfJSWxLiz1zux2f+ZTWtvz5ezw4bvPfMX0syuXw\nHjwefA65HMaeGRtDPZuus+PvPI9dVhnbanbXWOo621NPPUVLliwhn89H4XCY7r77bjpyRP0YHDly\nhNauXUter5d6enroueeem9XKCoIgCIIgVKOuic2iRYvo+9//Pu3fv582b95Mdrud7rrrLiL69Wz3\nrrvuokgkQjt27KDHHnuM1q9fT5s2bfpAKi4IgiAIgsCpyxV17733gv3Nb36Trr32WhodHaVt27bR\nwMAA7dq1i4LBIC1btoy2bNlCzzzzTEWqg/OqsOPsVebLoXw57Pbbby8fL168GMr4kt3OnTvB5suU\n+hIeX1YzLVw6XHb10rN+t1DA5T++9TnAtugGm1U9XW5cdoy24fLv1ddgOgY3u0e9Lfl2Xe6KcrFQ\n7fqKf89CbMtVq25iH8X2aGlpAbse1wR/poa+9MrKigVc4m5txuveefsdYK9aobZsL1i4AMoyLJQ/\nDzUwPKxC7B8+cBDKnLhaXrFVvFpKAe56qJWOQP88/y6nVioDvZz3j1rn0p9prXrUOrfO8f4RsJMJ\ndKf0LsaQBpP5wfJxuojXibbj+7Jvzy6wjx44UD628swt09QKdpH9HzFTwIfeom3pdrHt3nxs4aEl\nnJorl6fj4O3eFMDtzG4Xjpe6u4m7Vtw+3HbOXUT6lly+9bdUxPvlzyWfx3FuZgbTSCDhKmVE8YRy\nuRvMhcFlATx0P3fV6K4Z7qbhdebuFH0QzLBUBQl2/zzFgF5Prw/rVMizUAo1ZAG6S4y/a/x+uVxD\nv0f+W5TNovuMu6L4e1vtNzHL2o5v78Zz4Tv8fnjfjq1MJkP/9E//RL29vRSNRmn79u20atUqiAez\nbt062rZt21nPUSgUKJPJwD9BEARBEIT3S90Tm1/84hcUCATI7/fThg0baOPGjWQYBo2NjVUkM4xG\nozTOEvHpPPHEE+Tz+cr/eKA7QRAEQRCEeqh7YrN27Vras2cPvfHGG3TVVVfRZz/7WSoUCu9rp8Oj\njz5K6XS6/I/vCBIEQRAEQaiHurd7+/1+Wrx4MS1evJhWr15NLS0ttHHjRmpvb6dDhw7BZ8fHxyka\nPXsKcqfTWbFdsRa6T5n7C1tb0e/NfdV6CHnuP+b+VL4ll9v6RK5C92GcXffAP8/vn6d2cLnQn2po\n2zXtdn5d1pY2to20mj6Db7+rCGvOJq62sxoVW5Atpjkq8ZjgdVBti3JFqgKu++Dh1tkzbdJ0EGtv\nuQ3KpqZxKzDv11ctuqJ8PDI0DGXTk7gNn/v9eT/V61VrqzS3dV8196/X+i5H77eVffzsKRS4XU0H\ndCa7Gq4A9vGoLwS2jYWn7x9U2/BvueN2KPN4sH1G+fZVbYv/DNMXdHfie9re1Q2234/1OHnyVPk4\nn+e6D2zLQgG/6/dq2g+2fdvNQvk72dgzk0QtQyqltC3ZDOoeuMaGp2fQbT4+2Nn/kW0l1A152ViV\nTqn3ycl1k57qK/c2Us/NyX4DXA6ecgL7C++3uubIMKqPl1yHadf6Gtfn2B1sG74DxzyPFuLCyfJz\neL3Vt2jz8Bj672Ctd5xrm/SxiN8vvy7/DeBti9pRfP6eOsNFnC/nvXncsixyOBy0evVq2rlzJ3SU\nzZs305o1a6p8WxAEQRAEYfaoa8XmK1/5Ct1zzz3U1dVFo6Oj9NRTT1EkEqGbb76ZvF4vdXd308MP\nP0yPP/44bdu2jV588UXauHHjB1V3QRAEQRAEoK6JzalTp+jee+8tu5huvfVW2rRpEzU3/zoL6IYN\nG2j9+vW0cuVKam9vp2effXZWt3oLgiAIgiBUo66JzYsvvli1vLe3l15//fXzqU9dcA0Bj3HDfaI6\n9YSEP5fP13MuLOP1qn4uvR5cu8K/WytOSfWL1aqIfprqsVa45ohrgepp23p0IvzuuS7AZN8taXFv\nXEyr0RGO4HdZGHS9J87pxFD9Xe0dWI8ampN62qOaPsVufHAam1rvR7V61VsPnZtuWYV/YPFl4lMY\nMqJZC+0fbEYtU1/fEbCDzRgzKhxVz9zHdFCRCGqsurvYM++YA/a77+5VdWR6rQLT95km6hOKWjqH\nYADrwbopjY2hvsvhwrg2mYzSVKRmMNaK3cM1E2ePiWIYeGEX04m4sOtRqYj35NC7j1nf2OrW7qlS\nY4YXDgRQN8TTRiRTqg3cTtSUOFhMHI8HtS0+n9a2bLAxuL6NfWBySqXGsbPx8TcLBeo6eF2efsDv\nD6nr1NDU8Fg8ui6G60zzLK4N10LxMUDXrXL9IsfPdEL2KvHp3g+SBFMQBEEQhIZBJjaCIAiCIDQM\nMrERBEEQBKFhmF3H1m8BXUfD/Xj16GJmU0NT69w1Pg0W16NUx177Iw0G11VVpcYztbOYFui7Zt9l\npr2i/6hjk2kGeJ15LI1a+aCqwXVlVfVcFaqj6qCmor7/A+mfr/Wu1fNMcxmMy5JJs/ggftRUdGvR\nzKcTGAB0bGwI7HwedSC6HoHrK9oiPVgxE8sXLUbNzbXL1Vg1xuLlnDp1EmxdB0NE5NTi2GRYDKhc\nGjUjRab9MlnHbWpW9fQFUUNSrNBFoe3zq+9OTcaxHjnsh3kWA8XDNBXwwthYfCmqTlbrA1ybkWP6\nk3gc9UyZLLYXXNrkV0a7UMTnkpnRNCVMj2Kydy1XJW4a1700NYfA5s+0yPRKOPbgZ3nMLF7u9Sqd\nEGiGiKhUoUHE65qsHjoGE38Vs9g+DhvT5BXOfq73g6zYCIIgCILQMMjERhAEQRCEhsFmfdCxjesg\nk8mQz+ejr3/963WnWhAEQRAEoXEpFAr05JNPUjqdrkgtoSMrNoIgCIIgNAwysREEQRAEoWGQiY0g\nCIIgCA2DTGwEQRAEQWgYZGIjCIIgCELDIBMbQRAEQRAahosq8vBvdp4XZjkKoSAIgiAIlza/mRvU\nilJzUcWxmZycpLAWAl0QBEEQBEEnFotRa2vrWcsvqomNaZoUj8fJsiyKRCIUi8WqBuERfh3UMBwO\nS1udI9Je5460VX1Ie5070lb1Ie31ayzLomw2S6FQqGr+uovKFWUYBrW2tlImkyEiIq/Xe1k/xHqQ\ntqoPaa9zR9qqPqS9zh1pq/qQ9qpM1nkmRDwsCIIgCELDIBMbQRAEQRAahotyYuNwOOjxxx8nh+Oi\n8pRdlEhb1Ye017kjbVUf0l7njrRVfUh71cdFJR4WBEEQBEE4Hy7KFRtBEARBEIT3g0xsBEEQBEFo\nGGRiIwiCIAhCw3DRTWyeeuop6urqIp/PR3fffTeNjIxc6CpdFDz55JN0/fXXUyAQoM7OTnrooYdo\nfHwcPnPkyBFau3Yteb1e6unpoeeee+4C1fbi4p577iGbzUavvvpq+W/SVpXs2rWL1q1bRz6fj1pa\nWugzn/lMuUzaSxGPx+nzn/88dXR0UCAQoJtuuoneeOONcvnl3FYvvfQSrVu3jpqbm8lms1GxWITy\nc2mby+U3oFpb7dmzhz7zmc9QV1cX+f1+WrFiBf30pz+tOMfl0lb1clFNbJ5//nn6m7/5G/r+979P\nW7dupUQiQffdd9+FrtZFwZtvvkmPPPII7dy5k15++WU6cOAAtE2hUKC77rqLIpEI7dixgx577DFa\nv349bdq06QLW+sLz/PPPlwM+/gZpq0oOHjxId955J91yyy20Y8cO2rp1K91///1EJO3FeeSRR2jH\njh30s5/9jPbu3UurV6+mT3ziEzQ1NXXZt1U6naY777yTvvrVr1aUnUvbXE6/AdXaavfu3TRnzhz6\nt3/7N9q3bx899NBDdP/999Prr79e/szl1FZ1Y11ErFixwvr6179eto8fP24RkbV79+4LV6mLlK1b\nt1pEZMXjccuyLOvll1+23G63lUgkyp/5wz/8Q+uTn/zkBarhhae/v9+aO3euNTAwYBGR9corr1iW\nJW11Jj71qU9ZDz744BnLpL2QpUuXWt/97nfLdiKRsIjIeuutt6St/pvXXnvNIiKrUCiU/3YubXM5\n/gacqa3OxEc+8hHry1/+ctm+HNvqXLloVmxyuRzt3buX7rzzzvLfFi5cSD09PbRt27YLWLOLk4mJ\nCfJ4POT3+4mIaPv27bRq1SoKBoPlz6xbt+6ybTvTNOmBBx6gb3zjGzRnzhwok7ZCSqUS/dd//Rct\nWLCA7rjjDmpvb6cPf/jD9O677xKRtBfnxhtvpJdffpkmJiaoVCrRc889R11dXbRs2TJpqyrUahv5\nDajOxMREOfGjtFV1LpqJTSwWI9M0qa2tDf4ejUZpbGzsAtXq4iSXy9E3v/lNeuCBB8oBm8bGxs7Y\ndlyHc7nw3e9+lwKBAD300EMVZdJWyPj4OKXTaXr66afps5/9LG3cuJHmzp1L69ato+npaWkvxjPP\nPEORSISi0Si53W7627/9W9qwYQMFAgFpqyrUahv5DTg7//7v/04HDx6kP/iDPyAiaataXDRhDC2J\nE3hOlEol+tznPkdERN/+9rfLf5f2Uxw8eJC+853v0M6dO89YLm2FmKZJRESf/vSnaf369URE9A//\n8A/0i1/8gn7+859LezH+7u/+jo4ePUqvvPIKhcNheuGFF+juu++m3bt3S1tVoVbbSNudma1bt9JD\nDz1EP/zhD2nBggVEJG1Vi4tmYhOJRMgwjIrZ5vj4eMWs9HLFNE168MEH6dChQ7RlyxYKBALlsvb2\ndjp06BB8fnx8nKLR6G+7mhecbdu20cjICM2bNw/+/tGPfpTuv/9+WrBggbSVRiQSIbvdTr29veW/\nOZ1OWrhwIQ0MDEjf0shkMvTXf/3X9Oqrr9Jtt91GREQrVqygDRs20L/+679KW1WhVtvIb0AlO3bs\noN/93d+lp59+mn7/93+//Hdpq+pcNK4ot9tNy5cvp9dee638t76+Purv76c1a9ZcwJpdHFiWRV/4\nwhfo7bffpldeeaXsa/0Nq1evpp07d1IqlSr/bfPmzZdl291zzz307rvv0p49e8r/iH69CvGtb31L\n2orhcrloxYoVdOzYsfLfisUi9ff307x586S9NAqFAhUKBbLb7fB3wzDINE1pqyrUahv5DUB2795N\nH/3oR+mv/uqvyiupv0HaqgYXTLZ8Bn70ox9ZgUDAeumll6w9e/ZYa9eutW699dYLXa2Lgj/6oz+y\nIpGItW3bNmt4eLj8r1gsWpZlWblczlq0aJF17733Wu+99571ox/9yHI6ndarr756gWt+cUDarihp\nq0r+5V/+xfJ4PNaPf/xj6/Dhw9af/MmfWO3t7db09LS0F+Pmm2+2Vq9ebb399tvW0aNHrUcffdRy\nuVzWgQMHLvu2isVi1u7du60f/OAHFhFZO3futHbv3m0lk8lzapvL6TegWlvt27fPCofD1he/+EUY\n73+zC9ayLq+2qpeLamJjWZb15JNPWh0dHZbH47E+8YlPWMPDwxe6ShcFRHTGf319feXPHDp0yLr9\n9tstt9ttzZs3z/rhD3944Sp8kaFPbCxL2upMfO9737Pmzp1rBQIB64477rD27dtXLpP2UgwODlr3\n33+/1dbWZvn9fuuGG26wNmzYUC6/nNvq+eefP+M49dprr1mWdW5tc7n8BlRrq8cff/yMZQ888ACc\n43Jpq3qR7N6CIAiCIDQMF43GRhAEQRAE4XyRiY0gCIIgCA2DTGwEQRAEQWgYZGIjCIIgCELDIBMb\nQRAEQRAaBpnYCIIgCILQMMjERhAEQRCEhkEmNoIgCIIgNAwysREEQRAEoWGQiY0gCIIgCA2DTGwE\nQRAEQWgYZGIjCIIgCELD8H8B11PSsZH1AJgAAAAASUVORK5CYII=\n"
}
},
{
"output_type": "stream",
"name": "stdout",
"text": [
" car frog frog ship"
]
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"\n",
"# functions to show an image\n",
"def imshow(img):\n",
" img = img / 2 + 0.5 # unnormalize\n",
" npimg = img.numpy()\n",
" plt.imshow(np.transpose(npimg, (1, 2, 0)))\n",
" plt.show()\n",
"\n",
"# get some random training images\n",
"dataiter = iter(trainloader)\n",
"images, labels = next(dataiter)\n",
"\n",
"# show images\n",
"imshow(torchvision.utils.make_grid(images))\n",
"# print labels\n",
"print(' '.join('%5s' % classes[labels[j]] for j in range(4)))"
],
"id": "6fa91907"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Define a Convolutional Neural Network"
],
"id": "7550ad75-9001-4bcb-ac90-13afc6c194e7"
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"import torch.nn as nn\n",
"import torch.nn.functional as F\n",
"\n",
"class Net(nn.Module):\n",
" def __init__(self):\n",
" super(Net, self).__init__()\n",
" # nn.Conv2d(in_channels, out_channels, kernel_size)\n",
" self.conv1 = nn.Conv2d(3, 6, 5)\n",
" # nn.MaxPool2d(kernel_size, stride)\n",
" self.pool = nn.MaxPool2d(2, 2)\n",
" self.conv2 = nn.Conv2d(6, 16, 5)\n",
" # nn.Linear(in_features, out_features)\n",
" self.fc1 = nn.Linear(16 * 5 * 5, 120)\n",
" self.fc2 = nn.Linear(120, 84)\n",
" self.fc3 = nn.Linear(84, 10)\n",
"\n",
" def forward(self, x):\n",
" # Input is (N, 3, 32, 32)\n",
" x = F.relu(self.conv1(x)) # (N, 6, 28, 28)\n",
" x = self.pool(x) # (N, 6, 14, 14)\n",
" x = F.relu(self.conv2(x)) # (N, 16, 10, 10)\n",
" x = self.pool(x) # (N, 16, 5, 5)\n",
" x = x.view(-1, 16 * 5 * 5) # (N, 400)\n",
" x = F.relu(self.fc1(x)) # (N, 120)\n",
" x = F.relu(self.fc2(x)) # (N, 84)\n",
" x = self.fc3(x) # (N, 10)\n",
" return x\n",
"\n",
"net = Net()"
],
"id": "fc3be7d8"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"------------------------------------------------------------------------\n",
"\n",
"## Parameters of layers\n",
"\n",
"- `torch.nn.Conv2d` and similar functions produce object that\n",
" automatically registers its parameters inside the `torch.nn.Module`\n",
"- Thus, when calling `model.parameters()`, it will include these\n",
" parameters\n",
"- Note that simple ReLU and maxpool functions do not have parameters"
],
"id": "48ae7131-55cb-4a96-8287-7f36aac93fc3"
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"conv1.weight , torch.Size([6, 3, 5, 5]) <class 'torch.nn.parameter.Parameter'>\n",
"conv1.bias , torch.Size([6]) <class 'torch.nn.parameter.Parameter'>\n",
"conv2.weight , torch.Size([16, 6, 5, 5]) <class 'torch.nn.parameter.Parameter'>\n",
"conv2.bias , torch.Size([16]) <class 'torch.nn.parameter.Parameter'>\n",
"fc1.weight , torch.Size([120, 400]) <class 'torch.nn.parameter.Parameter'>\n",
"fc1.bias , torch.Size([120]) <class 'torch.nn.parameter.Parameter'>\n",
"fc2.weight , torch.Size([84, 120]) <class 'torch.nn.parameter.Parameter'>\n",
"fc2.bias , torch.Size([84]) <class 'torch.nn.parameter.Parameter'>\n",
"fc3.weight , torch.Size([10, 84]) <class 'torch.nn.parameter.Parameter'>\n",
"fc3.bias , torch.Size([10]) <class 'torch.nn.parameter.Parameter'>\n",
"Total number of parameters: 62006"
]
}
],
"source": [
"# Remember convolution weight has size (out_channels, in_channels, *kernel_size)\n",
"total_num_params = 0\n",
"for name, p in net.named_parameters():\n",
" total_num_params += p.numel() # Number of elements\n",
" print(name, ',', p.size(), type(p))\n",
"print(f'Total number of parameters: {total_num_params}')"
],
"id": "84f9606a"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Define a Loss function and optimizer\n",
"\n",
"Let’s use a Classification Cross-Entropy loss and SGD with momentum."
],
"id": "9c816123-cfe7-4319-823e-b4edae2db528"
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"import torch.optim as optim\n",
"\n",
"criterion = nn.CrossEntropyLoss()\n",
"optimizer = optim.SGD(\n",
" net.parameters(), lr=0.001, momentum=0.9)"
],
"id": "0f6f66dc"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Train the network\n",
"\n",
"This is when things start to get interesting. We simply have to loop\n",
"over our data iterator, and feed the inputs to the network and optimize."
],
"id": "d3663493-f0c5-4697-9ab9-ee33b4e6dbe7"
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Loaded saved model, skipping training"
]
}
],
"source": [
"import os\n",
"PATH = './cifar_net.pth'\n",
"if os.path.isfile(PATH):\n",
" net = Net()\n",
" net.load_state_dict(torch.load(PATH))\n",
" print('Loaded saved model, skipping training')\n",
"else:\n",
" for epoch in range(2): # Loop over dataset\n",
" running_loss = 0.0\n",
" for i, data in enumerate(trainloader, 0):\n",
" inputs, labels = data\n",
" # zero the parameter gradients\n",
" optimizer.zero_grad()\n",
"\n",
" # forward + backward + optimize\n",
" outputs = net(inputs)\n",
" loss = criterion(outputs, labels)\n",
" loss.backward()\n",
" optimizer.step()\n",
"\n",
" # print statistics\n",
" running_loss += loss.item()\n",
" if i % 2000 == 1999: # print every 2000 mini-batches\n",
" print('[%d, %5d] loss: %.3f' %\n",
" (epoch + 1, i + 1, running_loss / 2000))\n",
" running_loss = 0.0\n",
" print('Finished Training')"
],
"id": "9ad3fbae"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Saving and loading trained model\n",
"\n",
"- Note: If you want to restart training, you also need to save the\n",
" optimizer states."
],
"id": "3fdbbc7c-3c17-4124-be55-f7ba2260eff8"
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"output_type": "display_data",
"metadata": {},
"data": {
"text/plain": [
"<All keys matched successfully>"
]
}
}
],
"source": [
"torch.save(net.state_dict(), PATH)\n",
"\n",
"# Load the model from saved path\n",
"net = Net()\n",
"net.load_state_dict(torch.load(PATH))"
],
"id": "00efd10c"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"See `here <https://pytorch.org/docs/stable/notes/serialization.html>`\\_\n",
"for more details on saving PyTorch models.\n",
"\n",
"## Check the network on the test data"
],
"id": "c5c55782-4a10-45c4-8850-424c56da5562"
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"output_type": "display_data",
"metadata": {},
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAjYAAAC2CAYAAADKmcfEAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90\nbGliIHZlcnNpb24zLjEwLjUsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvWftoOwAAAAlwSFlzAAAO\nxAAADsQBlSsOGwAATTJJREFUeJztvXmwXNV1/7vO1PO9t+8sXQ1oAjEIM1ni5wEboSQmxj/iyott\nnDiPIa4oz3EqsatSHgih7AqEFPbPTuEqKrENKb8kvKQS/4JjRakwyvYPIyRLAgwSkkDzdCf1HXo8\n0/vDoc/+fhvdq4uEJZr1qVJVr7u7T++zzz67j/b6rrWsOI5jURRFURRFaQPsc90BRVEURVGUs4U+\n2CiKoiiK0jbog42iKIqiKG2DPtgoiqIoitI26IONoiiKoihtgz7YKIqiKIrSNuiDjaIoiqIobYM+\n2CiKoiiK0jbog42iKIqiKG2DPtgoiqIoitI2vCUPNvfdd58MDQ1JLpeTm2++WY4fP/5WfI2iKIqi\nKApgne1aUQ8//LD80R/9kXzve9+TZcuWyZ/8yZ9IHMeyadOmWT8bRZGUSiXJZDJiWdbZ7JaiKIqi\nKG9j4jiWWq0mxWJRbPvU+zJn/cHm6quvll//9V+Xe+65R0REXnvtNVm+fLls375drrzyyhk/Oz4+\nLr29vWezO4qiKIqitBFjY2PS09Nzynb3bH5ZvV6X559/Xu6///7m35YtWyZLliyRzZs3tzzY+L4v\nQRA07defsf70T/9UPM87m11TFEVRFOVtjO/7cv/990smk5nxfWf1wWZsbEyiKJKBgQH4e39/vwwP\nD7e8/5577pGvfOUrLX/3PE8fbBRFURRFaWE2qcpZFQ/P1at15513SqVSaf4bGxs7m91RFEVRFOUd\nxlndsenr6xPbtlt2Z0ZGRlp2cUR0Z0ZRFEVRlLPLWd2xSafTcsUVV8hTTz3V/Nu+fftk//79cu21\n157Nr1IURVEURWnhrO7YiIh89rOflT/+4z+Wa665RpYtWyaf+9zn5Lrrrps1IkpRFEVRFOVMOesP\nNnfccYecOHFCPvOZz0ipVJJf+ZVfkW9/+9tn+2sURVEURVFaOOsPNiIiX/rSl+RLX/rSW3FouWDi\n0eZrK46gLeXh6ViUwKfRqDdfB6GPn02lwA4jPHYcoTDassPma9vBPsZ+Ht8rIdheqtZ87Qj3Gb8n\n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\nkowv7o0AAAAASUVORK5CYII=\n"
}
},
{
"output_type": "stream",
"name": "stdout",
"text": [
"GroundTruth: cat ship ship plane\n",
"Predicted: frog plane ship ship"
]
}
],
"source": [
"dataiter = iter(testloader)\n",
"images, labels = next(dataiter)\n",
"\n",
"# Show images with ground truth \n",
"imshow(torchvision.utils.make_grid(images))\n",
"print('GroundTruth: ', ' '.join('%5s' % classes[labels[j]] for j in range(4)))\n",
"\n",
"# Predict outputs\n",
"outputs = net(images)\n",
"_, predicted = torch.max(outputs, 1)\n",
"\n",
"print('Predicted: ', ' '.join('%5s' % classes[predicted[j]]\n",
" for j in range(4)))"
],
"id": "db911221"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Evaluate on test dataset"
],
"id": "7beff4e8-8705-4b7d-b789-04c49216ee6e"
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Accuracy of the network on the 10000 test images: 53 %"
]
}
],
"source": [
"correct = 0\n",
"total = 0\n",
"with torch.no_grad():\n",
" for data in testloader:\n",
" images, labels = data\n",
" outputs = net(images)\n",
" _, predicted = torch.max(outputs.data, 1)\n",
" total += labels.size(0)\n",
" correct += (predicted == labels).sum().item()\n",
"\n",
"print(\n",
" 'Accuracy of the network on the 10000 test images: %d %%' \n",
" % (100 * correct / total)\n",
")"
],
"id": "bb1556b5"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Note that 10% is random chance.\n",
"\n",
"## Let’s evaluate per-class accuracies to see which ones performed well"
],
"id": "e1a05444-95c8-4a2a-b33f-dfdee5adf9d3"
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Accuracy of plane : 56 %\n",
"Accuracy of car : 76 %\n",
"Accuracy of bird : 63 %\n",
"Accuracy of cat : 34 %\n",
"Accuracy of deer : 13 %\n",
"Accuracy of dog : 43 %\n",
"Accuracy of frog : 63 %\n",
"Accuracy of horse : 56 %\n",
"Accuracy of ship : 67 %\n",
"Accuracy of truck : 54 %"
]
}
],
"source": [
"class_correct = list(0. for i in range(10))\n",
"class_total = list(0. for i in range(10))\n",
"with torch.no_grad():\n",
" for data in testloader:\n",
" images, labels = data\n",
" outputs = net(images)\n",
" _, predicted = torch.max(outputs, 1)\n",
" c = (predicted == labels).squeeze()\n",
" for i in range(4):\n",
" label = labels[i]\n",
" class_correct[label] += c[i].item()\n",
" class_total[label] += 1\n",
"\n",
"\n",
"for i in range(10):\n",
" print('Accuracy of %5s : %2d %%' % (\n",
" classes[i], 100 * class_correct[i] / class_total[i]))"
],
"id": "fcb3eb71"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## What about running on GPUs?"
],
"id": "b2c6319a-549e-4dcb-9387-61bcd4b76d18"
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"cpu"
]
}
],
"source": [
"device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n",
"\n",
"# Assuming that we are on a CUDA machine, this should print a CUDA device:\n",
"print(device) # Would print GPU if available.\n",
"\n",
"# This would move all model parameters to device`\n",
"net.to(device)\n",
"\n",
"# You would also have to move inputs and target to device\n",
"data = next(iter(trainloader))\n",
"inputs, labels = data[0].to(device), data[1].to(device)"
],
"id": "e4583800"
}
],
"nbformat": 4,
"nbformat_minor": 5,
"metadata": {
"kernelspec": {
"name": "ai-curriculum",
"display_name": "AI Curriculum",
"language": "python"
}
}
}