Skip to content

Instantly share code, notes, and snippets.

@myselfHimanshu
Last active June 14, 2020 04:28
Show Gist options
  • Save myselfHimanshu/6a8b74689799aa31fab5c7406c435461 to your computer and use it in GitHub Desktop.
Save myselfHimanshu/6a8b74689799aa31fab5c7406c435461 to your computer and use it in GitHub Desktop.
19th April 2020
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "MNIST_model_04.ipynb",
"provenance": [],
"collapsed_sections": []
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "Q1TXNOvQ9Kaf",
"colab_type": "text"
},
"source": [
"# MNIST CNN model\n",
"\n",
"**Target to achieve** : 99.4% accuracy on test dataset."
]
},
{
"cell_type": "code",
"metadata": {
"id": "aAq7Lvqqs4F5",
"colab_type": "code",
"outputId": "fe99118a-2a70-4154-c63f-b5278f036a59",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 34
}
},
"source": [
"from google.colab import drive\n",
"drive.mount('/content/drive')\n",
"\n",
"import os\n",
"os.chdir(\"./drive/My Drive/EVA/Session04\")"
],
"execution_count": 1,
"outputs": [
{
"output_type": "stream",
"text": [
"Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount(\"/content/drive\", force_remount=True).\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "7OTkpFgt9W06",
"colab_type": "text"
},
"source": [
"## Importing Libraries"
]
},
{
"cell_type": "code",
"metadata": {
"id": "0m2JWFliFfKT",
"colab_type": "code",
"colab": {}
},
"source": [
"from __future__ import print_function\n",
"import torch\n",
"import torch.nn as nn\n",
"import torch.nn.functional as F\n",
"import torch.optim as optim\n",
"from torchvision import datasets, transforms\n",
"\n",
"from torchsummary import summary\n",
"from tqdm import tqdm\n",
"from torch.utils.tensorboard import SummaryWriter\n",
"\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"plt.rcParams['figure.figsize'] = (20,10)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "RcV-OkCe9lP4",
"colab_type": "text"
},
"source": [
"## GPU for training"
]
},
{
"cell_type": "code",
"metadata": {
"id": "50sHOdY39nRz",
"colab_type": "code",
"outputId": "9db8834d-f283-4173-9a8a-8be9ee1ec9aa",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 34
}
},
"source": [
"import tensorflow as tf\n",
"\n",
"device_name = tf.test.gpu_device_name()\n",
"\n",
"try:\n",
" print(f\"Found GPU at : {device_name}\")\n",
"except:\n",
" print(\"GPU device not found.\")"
],
"execution_count": 3,
"outputs": [
{
"output_type": "stream",
"text": [
"Found GPU at : /device:GPU:0\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "v9GmRJ0a9osJ",
"colab_type": "code",
"outputId": "8deefd6d-c143-4241-bdc4-9fc33c759dcc",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 52
}
},
"source": [
"import torch\n",
"\n",
"if torch.cuda.is_available():\n",
" device = torch.device(\"cuda\")\n",
" use_cuda = True\n",
" print(f\"Number of GPU's available : {torch.cuda.device_count()}\")\n",
" print(f\"GPU device name : {torch.cuda.get_device_name(0)}\")\n",
"else:\n",
" print(\"No GPU available, using CPU instead\")\n",
" device = torch.device(\"cpu\")\n",
" use_cuda = False"
],
"execution_count": 4,
"outputs": [
{
"output_type": "stream",
"text": [
"Number of GPU's available : 1\n",
"GPU device name : Tesla T4\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "MHNNLPIB9wbU",
"colab_type": "text"
},
"source": [
"## Downloading MNIST dataset\n",
"\n",
"Things to keep in mind, \n",
"- the dataset is provided by pytorch community.\n",
"- MNIST dataset contains: \n",
" - 60,000 training images\n",
" - 10,000 test images \n",
" - Each image is of size (28x28x1).\n",
"- The values 0.1307 and 0.3081 used for the Normalize() transformation below are the global mean and standard deviation for MNIST dataset."
]
},
{
"cell_type": "code",
"metadata": {
"id": "Bp5eMbQ4-LUp",
"colab_type": "code",
"colab": {}
},
"source": [
"batch_size = 128\n",
"num_epochs = 20\n",
"kernel_size = 3\n",
"pool_size = 2\n",
"\n",
"lr = 0.01\n",
"momentum = 0.9\n",
"\n",
"kwargs = {'num_workers': 1, 'pin_memory': True} if use_cuda else {}"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "EW3MUGF--hgi",
"colab_type": "code",
"colab": {}
},
"source": [
"mnist_trainset = datasets.MNIST(root=\"./data\", train=True, download=True,\n",
" transform=transforms.Compose([\n",
" transforms.ToTensor(),\n",
" transforms.Normalize((0.1307,), (0.3081,))\n",
" ]))\n",
"\n",
"mnist_testset = datasets.MNIST(root=\"./data\", train=False, download=True,\n",
" transform=transforms.Compose([\n",
" transforms.ToTensor(),\n",
" transforms.Normalize((0.1307,), (0.3081,))\n",
" ]))"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "gkMoKQVc-oKS",
"colab_type": "code",
"colab": {}
},
"source": [
"train_loader = torch.utils.data.DataLoader(mnist_trainset,\n",
" batch_size=batch_size, shuffle=True, **kwargs)\n",
"\n",
"test_loader = torch.utils.data.DataLoader(mnist_testset,\n",
" batch_size=batch_size, shuffle=True, **kwargs)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "IjXRQ52I-17Z",
"colab_type": "text"
},
"source": [
"## Visualization of images"
]
},
{
"cell_type": "code",
"metadata": {
"id": "NB81qRMu-6vr",
"colab_type": "code",
"colab": {}
},
"source": [
"examples = enumerate(train_loader)\n",
"batch_idx, (example_data, example_targets) = next(examples)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "8M2XDWfz-76k",
"colab_type": "code",
"outputId": "73dc3cb5-d240-474a-8e23-7af785196caf",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 728
}
},
"source": [
"fig = plt.figure()\n",
"for i in range(6):\n",
" plt.subplot(2,3,i+1)\n",
" plt.tight_layout()\n",
" plt.imshow(example_data[i][0], interpolation='none')\n",
" plt.title(f\"Ground Truth : {example_targets[i]}\")"
],
"execution_count": 9,
"outputs": [
{
"output_type": "display_data",
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 1440x720 with 6 Axes>"
]
},
"metadata": {
"tags": [],
"needs_background": "light"
}
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "BT8BOx7ejP3o",
"colab_type": "text"
},
"source": [
"## Defining training and testing functions"
]
},
{
"cell_type": "code",
"metadata": {
"id": "L6_Zia8XjPKb",
"colab_type": "code",
"colab": {}
},
"source": [
"from tqdm import tqdm\n",
"\n",
"def train(model, device, train_loader, optimizer, epoch):\n",
" running_loss = 0.0\n",
" running_correct = 0\n",
"\n",
" model.train()\n",
" pbar = tqdm(train_loader)\n",
" for batch_idx, (data, target) in enumerate(pbar):\n",
" data, target = data.to(device), target.to(device)\n",
" optimizer.zero_grad()\n",
" output = model(data)\n",
" loss = F.nll_loss(output, target)\n",
" _, preds = torch.max(output.data, 1)\n",
" loss.backward()\n",
" optimizer.step()\n",
"\n",
" #calculate training running loss\n",
" running_loss += loss.item()\n",
" running_correct += (preds == target).sum().item()\n",
" pbar.set_description(desc= f'loss={loss.item()} batch_id={batch_idx}')\n",
"\n",
" print(\"\\n\")\n",
" print(f\"Epoch {epoch} train loss: {running_loss/len(mnist_trainset):.3f} train acc: {running_correct/len(mnist_trainset):.3f}\")\n",
"\n",
"def test(model, device, test_loader):\n",
" model.eval()\n",
" test_loss = 0\n",
" correct = 0\n",
" with torch.no_grad():\n",
" for data, target in test_loader:\n",
" data, target = data.to(device), target.to(device)\n",
" output = model(data)\n",
" test_loss += F.nll_loss(output, target, reduction='sum').item() # sum up batch loss\n",
" pred = output.argmax(dim=1, keepdim=True) # get the index of the max log-probability\n",
" correct += pred.eq(target.view_as(pred)).sum().item()\n",
"\n",
" test_loss /= len(test_loader.dataset)\n",
"\n",
" print('\\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.3f}%)\\n'.format(\n",
" test_loss, correct, len(test_loader.dataset),\n",
" 100. * correct / len(test_loader.dataset)))"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "KIsxjleoivtO",
"colab_type": "text"
},
"source": [
"## Building the model"
]
},
{
"cell_type": "code",
"metadata": {
"id": "ToQ0qtQSCzOT",
"colab_type": "code",
"colab": {}
},
"source": [
"class Net(nn.Module):\n",
" def __init__(self):\n",
" super(Net, self).__init__()\n",
"\n",
" self.drop = nn.Dropout2d(0.1)\n",
"\n",
" self.conv1 = nn.Conv2d(1, 16, 3, padding=1) #(-1,28,28,3)>(-1,3,3,3,16)>(-1,28,28,16)\n",
" self.batchnorm1 = nn.BatchNorm2d(16) #(-1,28,28,16)\n",
" self.conv2 = nn.Conv2d(16, 16, 3, padding=1) #(-1,28,28,16)>(-1,3,3,16,16)>(-1,28,28,16)\n",
" self.batchnorm2 = nn.BatchNorm2d(16) #(-1,28,28,16)\n",
" \n",
" self.pool1 = nn.MaxPool2d(2, 2) #(-1,14,14,16)\n",
" \n",
" self.conv3 = nn.Conv2d(16, 16, 3, padding=1) #(-1,14,14,16)>(-1,3,3,16,16)>(-1,14,14,16)\n",
" self.batchnorm3 = nn.BatchNorm2d(16) #(-1,14,14,16)\n",
" self.conv4 = nn.Conv2d(16, 16, 3, padding=1) #(-1,14,14,16)>(-1,3,3,16,16)>(-1,14,14,16)\n",
" self.batchnorm4 = nn.BatchNorm2d(16) #(-1,14,14,16)\n",
" \n",
" self.pool2 = nn.MaxPool2d(2, 2) #(-1,7,7,16)\n",
" \n",
" self.conv5 = nn.Conv2d(16, 16, 3, padding=1) #(-1,7,7,16)>(-1,3,3,16,16)>(-1,7,7,16)\n",
" self.batchnorm5 = nn.BatchNorm2d(16) \n",
" self.conv6 = nn.Conv2d(16, 16, 3, padding=1) #(-1,7,7,16)>(-1,3,3,16,16)>(-1,7,7,16)\n",
" self.batchnorm6 = nn.BatchNorm2d(16)\n",
" self.conv7 = nn.Conv2d(16, 10, 3) #(-1,7,7,16)>(-1,3,3,16,10)>(-1,5,5,10)\n",
" \n",
" self.avgpool = nn.AvgPool2d(5)\n",
"\n",
" \n",
" def forward(self, x):\n",
" x = F.relu(self.conv1(x))\n",
" x = self.drop(x)\n",
" x = self.batchnorm1(x)\n",
" x = F.relu(self.conv2(x))\n",
" x = self.drop(x)\n",
" x = self.batchnorm2(x)\n",
" \n",
" x = self.pool1(x)\n",
" \n",
" x = F.relu(self.conv3(x))\n",
" x = self.drop(x)\n",
" x = self.batchnorm3(x)\n",
" x = F.relu(self.conv4(x))\n",
" x = self.drop(x)\n",
" x = self.batchnorm4(x)\n",
" \n",
" x = self.pool2(x)\n",
" \n",
" x = F.relu(self.conv5(x))\n",
" x = self.drop(x)\n",
" x = self.batchnorm5(x)\n",
"\n",
" x = F.relu(self.conv6(x))\n",
" x = self.drop(x)\n",
" x = self.batchnorm6(x)\n",
" \n",
" x = self.conv7(x)\n",
" x = self.avgpool(x)\n",
" x = x.view(-1, 10)\n",
" return F.log_softmax(x)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "_QVewjwMZsxp",
"colab_type": "code",
"outputId": "c3d8ca41-4911-4933-c669-42113bd8270a",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 676
}
},
"source": [
"model5 = Net().to(device)\n",
"summary(model5, input_size=(1, 28, 28))"
],
"execution_count": 16,
"outputs": [
{
"output_type": "stream",
"text": [
"----------------------------------------------------------------\n",
" Layer (type) Output Shape Param #\n",
"================================================================\n",
" Conv2d-1 [-1, 16, 28, 28] 160\n",
" Dropout2d-2 [-1, 16, 28, 28] 0\n",
" BatchNorm2d-3 [-1, 16, 28, 28] 32\n",
" Conv2d-4 [-1, 16, 28, 28] 2,320\n",
" Dropout2d-5 [-1, 16, 28, 28] 0\n",
" BatchNorm2d-6 [-1, 16, 28, 28] 32\n",
" MaxPool2d-7 [-1, 16, 14, 14] 0\n",
" Conv2d-8 [-1, 16, 14, 14] 2,320\n",
" Dropout2d-9 [-1, 16, 14, 14] 0\n",
" BatchNorm2d-10 [-1, 16, 14, 14] 32\n",
" Conv2d-11 [-1, 16, 14, 14] 2,320\n",
" Dropout2d-12 [-1, 16, 14, 14] 0\n",
" BatchNorm2d-13 [-1, 16, 14, 14] 32\n",
" MaxPool2d-14 [-1, 16, 7, 7] 0\n",
" Conv2d-15 [-1, 16, 7, 7] 2,320\n",
" Dropout2d-16 [-1, 16, 7, 7] 0\n",
" BatchNorm2d-17 [-1, 16, 7, 7] 32\n",
" Conv2d-18 [-1, 16, 7, 7] 2,320\n",
" Dropout2d-19 [-1, 16, 7, 7] 0\n",
" BatchNorm2d-20 [-1, 16, 7, 7] 32\n",
" Conv2d-21 [-1, 10, 5, 5] 1,450\n",
" AvgPool2d-22 [-1, 10, 1, 1] 0\n",
"================================================================\n",
"Total params: 13,402\n",
"Trainable params: 13,402\n",
"Non-trainable params: 0\n",
"----------------------------------------------------------------\n",
"Input size (MB): 0.00\n",
"Forward/backward pass size (MB): 0.79\n",
"Params size (MB): 0.05\n",
"Estimated Total Size (MB): 0.84\n",
"----------------------------------------------------------------\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:60: UserWarning: Implicit dimension choice for log_softmax has been deprecated. Change the call to include dim=X as an argument.\n"
],
"name": "stderr"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "_p2cV0exZtZ1",
"colab_type": "code",
"outputId": "0bfd0e07-bdfe-40ed-ada1-c820ac3fab4e",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 1000
}
},
"source": [
"# optimizer = optim.SGD(model5.parameters(), lr=lr, momentum=momentum)\n",
"optimizer = optim.Adam(model5.parameters(), lr=0.001)#, momentum=momentum)\n",
"\n",
"\n",
"for epoch in range(1, num_epochs+1):\n",
" train(model5, device, train_loader, optimizer, epoch)\n",
" test(model5, device, test_loader)"
],
"execution_count": 17,
"outputs": [
{
"output_type": "stream",
"text": [
" 0%| | 0/469 [00:00<?, ?it/s]/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:60: UserWarning: Implicit dimension choice for log_softmax has been deprecated. Change the call to include dim=X as an argument.\n",
"loss=0.1616697460412979 batch_id=468: 100%|██████████| 469/469 [00:13<00:00, 34.63it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 1 train loss: 0.005 train acc: 0.804\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n",
" 0%| | 0/469 [00:00<?, ?it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.1028, Accuracy: 9719/10000 (97.190%)\n",
"\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"loss=0.13534857332706451 batch_id=468: 100%|██████████| 469/469 [00:13<00:00, 36.00it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 2 train loss: 0.001 train acc: 0.947\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n",
" 0%| | 0/469 [00:00<?, ?it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.0564, Accuracy: 9826/10000 (98.260%)\n",
"\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"loss=0.154523566365242 batch_id=468: 100%|██████████| 469/469 [00:13<00:00, 35.73it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 3 train loss: 0.001 train acc: 0.960\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n",
" 0%| | 0/469 [00:00<?, ?it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.0481, Accuracy: 9863/10000 (98.630%)\n",
"\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"loss=0.051796767860651016 batch_id=468: 100%|██████████| 469/469 [00:13<00:00, 35.49it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 4 train loss: 0.001 train acc: 0.968\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n",
" 0%| | 0/469 [00:00<?, ?it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.0365, Accuracy: 9892/10000 (98.920%)\n",
"\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"loss=0.09049244970083237 batch_id=468: 100%|██████████| 469/469 [00:13<00:00, 35.40it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 5 train loss: 0.001 train acc: 0.973\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n",
" 0%| | 0/469 [00:00<?, ?it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.0310, Accuracy: 9912/10000 (99.120%)\n",
"\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"loss=0.05884885787963867 batch_id=468: 100%|██████████| 469/469 [00:13<00:00, 36.04it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 6 train loss: 0.001 train acc: 0.975\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n",
" 0%| | 0/469 [00:00<?, ?it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.0286, Accuracy: 9913/10000 (99.130%)\n",
"\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"loss=0.03546054661273956 batch_id=468: 100%|██████████| 469/469 [00:13<00:00, 35.88it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 7 train loss: 0.001 train acc: 0.977\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n",
" 0%| | 0/469 [00:00<?, ?it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.0286, Accuracy: 9902/10000 (99.020%)\n",
"\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"loss=0.03192787244915962 batch_id=468: 100%|██████████| 469/469 [00:12<00:00, 36.20it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 8 train loss: 0.001 train acc: 0.979\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n",
" 0%| | 0/469 [00:00<?, ?it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.0257, Accuracy: 9917/10000 (99.170%)\n",
"\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"loss=0.05475388094782829 batch_id=468: 100%|██████████| 469/469 [00:13<00:00, 35.38it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 9 train loss: 0.001 train acc: 0.979\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n",
" 0%| | 0/469 [00:00<?, ?it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.0241, Accuracy: 9931/10000 (99.310%)\n",
"\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"loss=0.0360184907913208 batch_id=468: 100%|██████████| 469/469 [00:12<00:00, 36.42it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 10 train loss: 0.000 train acc: 0.981\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n",
" 0%| | 0/469 [00:00<?, ?it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.0232, Accuracy: 9933/10000 (99.330%)\n",
"\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"loss=0.060868944972753525 batch_id=468: 100%|██████████| 469/469 [00:13<00:00, 35.28it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 11 train loss: 0.000 train acc: 0.981\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n",
" 0%| | 0/469 [00:00<?, ?it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.0251, Accuracy: 9924/10000 (99.240%)\n",
"\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"loss=0.012177616357803345 batch_id=468: 100%|██████████| 469/469 [00:13<00:00, 35.92it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 12 train loss: 0.000 train acc: 0.983\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n",
" 0%| | 0/469 [00:00<?, ?it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.0252, Accuracy: 9929/10000 (99.290%)\n",
"\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"loss=0.025731412693858147 batch_id=468: 100%|██████████| 469/469 [00:13<00:00, 35.57it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 13 train loss: 0.000 train acc: 0.984\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n",
" 0%| | 0/469 [00:00<?, ?it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.0235, Accuracy: 9930/10000 (99.300%)\n",
"\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"loss=0.1300484985113144 batch_id=468: 100%|██████████| 469/469 [00:13<00:00, 34.99it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 14 train loss: 0.000 train acc: 0.983\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n",
" 0%| | 0/469 [00:00<?, ?it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.0215, Accuracy: 9932/10000 (99.320%)\n",
"\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"loss=0.014920040965080261 batch_id=468: 100%|██████████| 469/469 [00:13<00:00, 35.38it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 15 train loss: 0.000 train acc: 0.985\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n",
" 0%| | 0/469 [00:00<?, ?it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.0220, Accuracy: 9928/10000 (99.280%)\n",
"\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"loss=0.0299172755330801 batch_id=468: 100%|██████████| 469/469 [00:13<00:00, 34.85it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 16 train loss: 0.000 train acc: 0.987\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n",
" 0%| | 0/469 [00:00<?, ?it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.0227, Accuracy: 9938/10000 (99.380%)\n",
"\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"loss=0.018389130011200905 batch_id=468: 100%|██████████| 469/469 [00:12<00:00, 36.08it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 17 train loss: 0.000 train acc: 0.986\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n",
" 0%| | 0/469 [00:00<?, ?it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.0202, Accuracy: 9936/10000 (99.360%)\n",
"\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"loss=0.12532515823841095 batch_id=468: 100%|██████████| 469/469 [00:13<00:00, 35.49it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 18 train loss: 0.000 train acc: 0.986\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n",
" 0%| | 0/469 [00:00<?, ?it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.0212, Accuracy: 9938/10000 (99.380%)\n",
"\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"loss=0.03086220659315586 batch_id=468: 100%|██████████| 469/469 [00:13<00:00, 36.03it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 19 train loss: 0.000 train acc: 0.986\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n",
" 0%| | 0/469 [00:00<?, ?it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.0198, Accuracy: 9946/10000 (99.460%)\n",
"\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"loss=0.014667436480522156 batch_id=468: 100%|██████████| 469/469 [00:13<00:00, 35.00it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"\n",
"Epoch 20 train loss: 0.000 train acc: 0.986\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"\n",
"Test set: Average loss: 0.0208, Accuracy: 9938/10000 (99.380%)\n",
"\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "0mBzSj7mcMnq",
"colab_type": "code",
"colab": {}
},
"source": [
""
],
"execution_count": 0,
"outputs": []
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment