{ "cells": [ { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "UEBilEjLj5wY" }, "source": [ "Deep Learning Models -- A collection of various deep learning architectures, models, and tips for TensorFlow and PyTorch in Jupyter Notebooks.\n", "- Author: Sebastian Raschka\n", "- GitHub Repository: https://github.com/rasbt/deeplearning-models" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "colab": { "autoexec": { "startup": false, "wait_interval": 0 }, "base_uri": "https://localhost:8080/", "height": 119 }, "colab_type": "code", "executionInfo": { "elapsed": 536, "status": "ok", "timestamp": 1524974472601, "user": { "displayName": "Sebastian Raschka", "photoUrl": "//lh6.googleusercontent.com/-cxK6yOSQ6uE/AAAAAAAAAAI/AAAAAAAAIfw/P9ar_CHsKOQ/s50-c-k-no/photo.jpg", "userId": "118404394130788869227" }, "user_tz": 240 }, "id": "GOzuY8Yvj5wb", "outputId": "c19362ce-f87a-4cc2-84cc-8d7b4b9e6007" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Sebastian Raschka \n", "\n", "CPython 3.6.8\n", "IPython 7.2.0\n", "\n", "torch 1.0.0\n" ] } ], "source": [ "%load_ext watermark\n", "%watermark -a 'Sebastian Raschka' -v -p torch" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "rH4XmErYj5wm" }, "source": [ "# Network in Network CIFAR-10 Classifier" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "based on \n", "\n", "- Lin, Min, Qiang Chen, and Shuicheng Yan. \"Network in network.\" arXiv preprint arXiv:1312.4400 (2013)." ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "MkoGLH_Tj5wn" }, "source": [ "## Imports" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "colab": { "autoexec": { "startup": false, "wait_interval": 0 } }, "colab_type": "code", "id": "ORj09gnrj5wp" }, "outputs": [], "source": [ "import os\n", "import time\n", "\n", "import numpy as np\n", "import pandas as pd\n", "\n", "import torch\n", "import torch.nn as nn\n", "import torch.nn.functional as F\n", "from torch.utils.data import DataLoader\n", "\n", "from torchvision import datasets\n", "from torchvision import transforms\n", "\n", "import matplotlib.pyplot as plt\n", "from PIL import Image\n", "\n", "\n", "if torch.cuda.is_available():\n", " torch.backends.cudnn.deterministic = True" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "I6hghKPxj5w0" }, "source": [ "## Model Settings" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "colab": { "autoexec": { "startup": false, "wait_interval": 0 }, "base_uri": "https://localhost:8080/", "height": 85 }, "colab_type": "code", "executionInfo": { "elapsed": 23936, "status": "ok", "timestamp": 1524974497505, "user": { "displayName": "Sebastian Raschka", "photoUrl": "//lh6.googleusercontent.com/-cxK6yOSQ6uE/AAAAAAAAAAI/AAAAAAAAIfw/P9ar_CHsKOQ/s50-c-k-no/photo.jpg", "userId": "118404394130788869227" }, "user_tz": 240 }, "id": "NnT0sZIwj5wu", "outputId": "55aed925-d17e-4c6a-8c71-0d9b3bde5637" }, "outputs": [], "source": [ "##########################\n", "### SETTINGS\n", "##########################\n", "\n", "# Hyperparameters\n", "RANDOM_SEED = 1\n", "LEARNING_RATE = 0.001\n", "BATCH_SIZE = 256\n", "NUM_EPOCHS = 10\n", "\n", "# Architecture\n", "NUM_CLASSES = 10\n", "\n", "# Other\n", "DEVICE = \"cuda:0\"\n", "GRAYSCALE = False" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The following code cell that implements the ResNet-34 architecture is a derivative of the code provided at https://pytorch.org/docs/0.4.0/_modules/torchvision/models/resnet.html." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Files already downloaded and verified\n", "Image batch dimensions: torch.Size([256, 3, 32, 32])\n", "Image label dimensions: torch.Size([256])\n", "Image batch dimensions: torch.Size([256, 3, 32, 32])\n", "Image label dimensions: torch.Size([256])\n" ] } ], "source": [ "##########################\n", "### CIFAR-10 Dataset\n", "##########################\n", "\n", "\n", "# Note transforms.ToTensor() scales input images\n", "# to 0-1 range\n", "train_dataset = datasets.CIFAR10(root='data', \n", " train=True, \n", " transform=transforms.ToTensor(),\n", " download=True)\n", "\n", "test_dataset = datasets.CIFAR10(root='data', \n", " train=False, \n", " transform=transforms.ToTensor())\n", "\n", "\n", "train_loader = DataLoader(dataset=train_dataset, \n", " batch_size=BATCH_SIZE, \n", " num_workers=8,\n", " shuffle=True)\n", "\n", "test_loader = DataLoader(dataset=test_dataset, \n", " batch_size=BATCH_SIZE,\n", " num_workers=8,\n", " shuffle=False)\n", "\n", "# Checking the dataset\n", "for images, labels in train_loader: \n", " print('Image batch dimensions:', images.shape)\n", " print('Image label dimensions:', labels.shape)\n", " break\n", "\n", "# Checking the dataset\n", "for images, labels in train_loader: \n", " print('Image batch dimensions:', images.shape)\n", " print('Image label dimensions:', labels.shape)\n", " break" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "##########################\n", "### MODEL\n", "##########################\n", "\n", "\n", "class NiN(nn.Module):\n", " def __init__(self, num_classes):\n", " super(NiN, self).__init__()\n", " self.num_classes = num_classes\n", " self.classifier = nn.Sequential(\n", " nn.Conv2d(3, 192, kernel_size=5, stride=1, padding=2),\n", " nn.ReLU(inplace=True),\n", " nn.Conv2d(192, 160, kernel_size=1, stride=1, padding=0),\n", " nn.ReLU(inplace=True),\n", " nn.Conv2d(160, 96, kernel_size=1, stride=1, padding=0),\n", " nn.ReLU(inplace=True),\n", " nn.MaxPool2d(kernel_size=3, stride=2, padding=1),\n", " nn.Dropout(0.5),\n", "\n", " nn.Conv2d(96, 192, kernel_size=5, stride=1, padding=2),\n", " nn.ReLU(inplace=True),\n", " nn.Conv2d(192, 192, kernel_size=1, stride=1, padding=0),\n", " nn.ReLU(inplace=True),\n", " nn.Conv2d(192, 192, kernel_size=1, stride=1, padding=0),\n", " nn.ReLU(inplace=True),\n", " nn.AvgPool2d(kernel_size=3, stride=2, padding=1),\n", " nn.Dropout(0.5),\n", "\n", " nn.Conv2d(192, 192, kernel_size=3, stride=1, padding=1),\n", " nn.ReLU(inplace=True),\n", " nn.Conv2d(192, 192, kernel_size=1, stride=1, padding=0),\n", " nn.ReLU(inplace=True),\n", " nn.Conv2d(192, 10, kernel_size=1, stride=1, padding=0),\n", " nn.ReLU(inplace=True),\n", " nn.AvgPool2d(kernel_size=8, stride=1, padding=0),\n", "\n", " )\n", "\n", " def forward(self, x):\n", " x = self.classifier(x)\n", " logits = x.view(x.size(0), self.num_classes)\n", " probas = torch.softmax(x, dim=1)\n", " return logits, probas" ] }, { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "RAodboScj5w6" }, "source": [ "## Training without Pinned Memory" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "colab": { "autoexec": { "startup": false, "wait_interval": 0 } }, "colab_type": "code", "id": "_lza9t_uj5w1" }, "outputs": [], "source": [ "torch.manual_seed(RANDOM_SEED)\n", "\n", "model = NiN(NUM_CLASSES)\n", "model.to(DEVICE)\n", "\n", "optimizer = torch.optim.Adam(model.parameters(), lr=LEARNING_RATE) " ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "colab": { "autoexec": { "startup": false, "wait_interval": 0 }, "base_uri": "https://localhost:8080/", "height": 1547 }, "colab_type": "code", "executionInfo": { "elapsed": 2384585, "status": "ok", "timestamp": 1524976888520, "user": { "displayName": "Sebastian Raschka", "photoUrl": "//lh6.googleusercontent.com/-cxK6yOSQ6uE/AAAAAAAAAAI/AAAAAAAAIfw/P9ar_CHsKOQ/s50-c-k-no/photo.jpg", "userId": "118404394130788869227" }, "user_tz": 240 }, "id": "Dzh3ROmRj5w7", "outputId": "5f8fd8c9-b076-403a-b0b7-fd2d498b48d7", "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch: 001/010 | Batch 0000/0196 | Cost: 2.6021\n", "Epoch: 001/010 | Batch 0150/0196 | Cost: 1.3961\n", "Epoch: 001/010 | Train: 45.084%\n", "Time elapsed: 0.26 min\n", "Epoch: 002/010 | Batch 0000/0196 | Cost: 1.1228\n", "Epoch: 002/010 | Batch 0150/0196 | Cost: 1.0426\n", "Epoch: 002/010 | Train: 56.166%\n", "Time elapsed: 0.52 min\n", "Epoch: 003/010 | Batch 0000/0196 | Cost: 0.9980\n", "Epoch: 003/010 | Batch 0150/0196 | Cost: 0.8279\n", "Epoch: 003/010 | Train: 66.702%\n", "Time elapsed: 0.80 min\n", "Epoch: 004/010 | Batch 0000/0196 | Cost: 0.6384\n", "Epoch: 004/010 | Batch 0150/0196 | Cost: 0.7103\n", "Epoch: 004/010 | Train: 65.330%\n", "Time elapsed: 1.08 min\n", "Epoch: 005/010 | Batch 0000/0196 | Cost: 0.6308\n", "Epoch: 005/010 | Batch 0150/0196 | Cost: 0.5913\n", "Epoch: 005/010 | Train: 79.636%\n", "Time elapsed: 1.36 min\n", "Epoch: 006/010 | Batch 0000/0196 | Cost: 0.4409\n", "Epoch: 006/010 | Batch 0150/0196 | Cost: 0.5557\n", "Epoch: 006/010 | Train: 76.456%\n", "Time elapsed: 1.62 min\n", "Epoch: 007/010 | Batch 0000/0196 | Cost: 0.4778\n", "Epoch: 007/010 | Batch 0150/0196 | Cost: 0.4815\n", "Epoch: 007/010 | Train: 65.890%\n", "Time elapsed: 1.89 min\n", "Epoch: 008/010 | Batch 0000/0196 | Cost: 0.3782\n", "Epoch: 008/010 | Batch 0150/0196 | Cost: 0.4339\n", "Epoch: 008/010 | Train: 85.200%\n", "Time elapsed: 2.16 min\n", "Epoch: 009/010 | Batch 0000/0196 | Cost: 0.3083\n", "Epoch: 009/010 | Batch 0150/0196 | Cost: 0.3290\n", "Epoch: 009/010 | Train: 78.108%\n", "Time elapsed: 2.42 min\n", "Epoch: 010/010 | Batch 0000/0196 | Cost: 0.2229\n", "Epoch: 010/010 | Batch 0150/0196 | Cost: 0.1945\n", "Epoch: 010/010 | Train: 87.384%\n", "Time elapsed: 2.70 min\n", "Total Training Time: 2.70 min\n", "Test accuracy: 70.67%\n", "Total Time: 2.71 min\n" ] } ], "source": [ "def compute_accuracy(model, data_loader, device):\n", " correct_pred, num_examples = 0, 0\n", " for i, (features, targets) in enumerate(data_loader):\n", " \n", " features = features.to(device)\n", " targets = targets.to(device)\n", "\n", " logits, probas = model(features)\n", " _, predicted_labels = torch.max(probas, 1)\n", " num_examples += targets.size(0)\n", " correct_pred += (predicted_labels == targets).sum()\n", " return correct_pred.float()/num_examples * 100\n", " \n", "\n", "start_time = time.time()\n", "for epoch in range(NUM_EPOCHS):\n", " \n", " model.train()\n", " for batch_idx, (features, targets) in enumerate(train_loader):\n", " \n", " features = features.to(DEVICE)\n", " targets = targets.to(DEVICE)\n", " \n", " ### FORWARD AND BACK PROP\n", " logits, probas = model(features)\n", " cost = F.cross_entropy(logits, targets)\n", " optimizer.zero_grad()\n", " \n", " cost.backward()\n", " \n", " ### UPDATE MODEL PARAMETERS\n", " optimizer.step()\n", " \n", " ### LOGGING\n", " if not batch_idx % 150:\n", " print ('Epoch: %03d/%03d | Batch %04d/%04d | Cost: %.4f' \n", " %(epoch+1, NUM_EPOCHS, batch_idx, \n", " len(train_loader), cost))\n", "\n", " \n", "\n", " model.eval()\n", " with torch.set_grad_enabled(False): # save memory during inference\n", " print('Epoch: %03d/%03d | Train: %.3f%%' % (\n", " epoch+1, NUM_EPOCHS, \n", " compute_accuracy(model, train_loader, device=DEVICE)))\n", " \n", " print('Time elapsed: %.2f min' % ((time.time() - start_time)/60))\n", " \n", "print('Total Training Time: %.2f min' % ((time.time() - start_time)/60))\n", "\n", "\n", "with torch.set_grad_enabled(False): # save memory during inference\n", " print('Test accuracy: %.2f%%' % (compute_accuracy(model, test_loader, device=DEVICE)))\n", " \n", "print('Total Time: %.2f min' % ((time.time() - start_time)/60))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Training with Pinned Memory" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Files already downloaded and verified\n", "Image batch dimensions: torch.Size([256, 3, 32, 32])\n", "Image label dimensions: torch.Size([256])\n", "Image batch dimensions: torch.Size([256, 3, 32, 32])\n", "Image label dimensions: torch.Size([256])\n" ] } ], "source": [ "##########################\n", "### CIFAR-10 Dataset\n", "##########################\n", "\n", "\n", "# Note transforms.ToTensor() scales input images\n", "# to 0-1 range\n", "train_dataset = datasets.CIFAR10(root='data', \n", " train=True, \n", " transform=transforms.ToTensor(),\n", " download=True)\n", "\n", "test_dataset = datasets.CIFAR10(root='data', \n", " train=False, \n", " transform=transforms.ToTensor())\n", "\n", "\n", "train_loader = DataLoader(dataset=train_dataset, \n", " batch_size=BATCH_SIZE, \n", " pin_memory=True,\n", " shuffle=True)\n", "\n", "test_loader = DataLoader(dataset=test_dataset, \n", " batch_size=BATCH_SIZE,\n", " pin_memory=True,\n", " shuffle=False)\n", "\n", "# Checking the dataset\n", "for images, labels in train_loader: \n", " print('Image batch dimensions:', images.shape)\n", " print('Image label dimensions:', labels.shape)\n", " break\n", "\n", "# Checking the dataset\n", "for images, labels in train_loader: \n", " print('Image batch dimensions:', images.shape)\n", " print('Image label dimensions:', labels.shape)\n", " break" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "colab": { "autoexec": { "startup": false, "wait_interval": 0 } }, "colab_type": "code", "id": "_lza9t_uj5w1" }, "outputs": [], "source": [ "torch.manual_seed(RANDOM_SEED)\n", "\n", "model = resnet34(NUM_CLASSES)\n", "model.to(DEVICE)\n", "\n", "optimizer = torch.optim.Adam(model.parameters(), lr=LEARNING_RATE) " ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "colab": { "autoexec": { "startup": false, "wait_interval": 0 }, "base_uri": "https://localhost:8080/", "height": 1547 }, "colab_type": "code", "executionInfo": { "elapsed": 2384585, "status": "ok", "timestamp": 1524976888520, "user": { "displayName": "Sebastian Raschka", "photoUrl": "//lh6.googleusercontent.com/-cxK6yOSQ6uE/AAAAAAAAAAI/AAAAAAAAIfw/P9ar_CHsKOQ/s50-c-k-no/photo.jpg", "userId": "118404394130788869227" }, "user_tz": 240 }, "id": "Dzh3ROmRj5w7", "outputId": "5f8fd8c9-b076-403a-b0b7-fd2d498b48d7", "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch: 001/010 | Batch 0000/0196 | Cost: 2.6021\n", "Epoch: 001/010 | Batch 0150/0196 | Cost: 1.3961\n", "Epoch: 001/010 | Train: 45.084%\n", "Time elapsed: 0.39 min\n", "Epoch: 002/010 | Batch 0000/0196 | Cost: 1.1228\n", "Epoch: 002/010 | Batch 0150/0196 | Cost: 1.0426\n", "Epoch: 002/010 | Train: 56.166%\n", "Time elapsed: 0.77 min\n", "Epoch: 003/010 | Batch 0000/0196 | Cost: 0.9980\n", "Epoch: 003/010 | Batch 0150/0196 | Cost: 0.8279\n", "Epoch: 003/010 | Train: 66.702%\n", "Time elapsed: 1.16 min\n", "Epoch: 004/010 | Batch 0000/0196 | Cost: 0.6384\n", "Epoch: 004/010 | Batch 0150/0196 | Cost: 0.7103\n", "Epoch: 004/010 | Train: 65.330%\n", "Time elapsed: 1.55 min\n", "Epoch: 005/010 | Batch 0000/0196 | Cost: 0.6308\n", "Epoch: 005/010 | Batch 0150/0196 | Cost: 0.5913\n", "Epoch: 005/010 | Train: 79.636%\n", "Time elapsed: 1.94 min\n", "Epoch: 006/010 | Batch 0000/0196 | Cost: 0.4409\n", "Epoch: 006/010 | Batch 0150/0196 | Cost: 0.5557\n", "Epoch: 006/010 | Train: 76.456%\n", "Time elapsed: 2.33 min\n", "Epoch: 007/010 | Batch 0000/0196 | Cost: 0.4778\n", "Epoch: 007/010 | Batch 0150/0196 | Cost: 0.4815\n", "Epoch: 007/010 | Train: 65.890%\n", "Time elapsed: 2.71 min\n", "Epoch: 008/010 | Batch 0000/0196 | Cost: 0.3782\n", "Epoch: 008/010 | Batch 0150/0196 | Cost: 0.4339\n", "Epoch: 008/010 | Train: 85.200%\n", "Time elapsed: 3.10 min\n", "Epoch: 009/010 | Batch 0000/0196 | Cost: 0.3083\n", "Epoch: 009/010 | Batch 0150/0196 | Cost: 0.3290\n", "Epoch: 009/010 | Train: 78.108%\n", "Time elapsed: 3.49 min\n", "Epoch: 010/010 | Batch 0000/0196 | Cost: 0.2229\n", "Epoch: 010/010 | Batch 0150/0196 | Cost: 0.1945\n", "Epoch: 010/010 | Train: 87.384%\n", "Time elapsed: 3.88 min\n", "Total Training Time: 3.88 min\n", "Test accuracy: 70.67%\n", "Total Time: 3.91 min\n" ] } ], "source": [ "def compute_accuracy(model, data_loader, device):\n", " correct_pred, num_examples = 0, 0\n", " for i, (features, targets) in enumerate(data_loader):\n", " \n", " features = features.to(device)\n", " targets = targets.to(device)\n", "\n", " logits, probas = model(features)\n", " _, predicted_labels = torch.max(probas, 1)\n", " num_examples += targets.size(0)\n", " correct_pred += (predicted_labels == targets).sum()\n", " return correct_pred.float()/num_examples * 100\n", " \n", "\n", "start_time = time.time()\n", "for epoch in range(NUM_EPOCHS):\n", " \n", " model.train()\n", " for batch_idx, (features, targets) in enumerate(train_loader):\n", " \n", " features = features.to(DEVICE)\n", " targets = targets.to(DEVICE)\n", " \n", " ### FORWARD AND BACK PROP\n", " logits, probas = model(features)\n", " cost = F.cross_entropy(logits, targets)\n", " optimizer.zero_grad()\n", " \n", " cost.backward()\n", " \n", " ### UPDATE MODEL PARAMETERS\n", " optimizer.step()\n", " \n", " ### LOGGING\n", " if not batch_idx % 150:\n", " print ('Epoch: %03d/%03d | Batch %04d/%04d | Cost: %.4f' \n", " %(epoch+1, NUM_EPOCHS, batch_idx, \n", " len(train_loader), cost))\n", "\n", " \n", "\n", " model.eval()\n", " with torch.set_grad_enabled(False): # save memory during inference\n", " print('Epoch: %03d/%03d | Train: %.3f%%' % (\n", " epoch+1, NUM_EPOCHS, \n", " compute_accuracy(model, train_loader, device=DEVICE)))\n", " \n", " print('Time elapsed: %.2f min' % ((time.time() - start_time)/60))\n", " \n", "print('Total Training Time: %.2f min' % ((time.time() - start_time)/60))\n", "\n", "\n", "with torch.set_grad_enabled(False): # save memory during inference\n", " print('Test accuracy: %.2f%%' % (compute_accuracy(model, test_loader, device=DEVICE)))\n", " \n", "print('Total Time: %.2f min' % ((time.time() - start_time)/60))" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "numpy 1.15.4\n", "pandas 0.23.4\n", "torch 1.0.0\n", "PIL.Image 5.3.0\n", "\n" ] } ], "source": [ "%watermark -iv" ] } ], "metadata": { "accelerator": "GPU", "colab": { "collapsed_sections": [], "default_view": {}, "name": "convnet-vgg16.ipynb", "provenance": [], "version": "0.3.2", "views": {} }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.1" }, "toc": { "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": true, "toc_position": { "height": "calc(100% - 180px)", "left": "10px", "top": "150px", "width": "371px" }, "toc_section_display": true, "toc_window_display": true } }, "nbformat": 4, "nbformat_minor": 2 }