{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import cv2\n", "from PIL import Image\n", "# the previous import is to process my own images\n", "import torch\n", "import torch.nn as nn\n", "import torchvision.transforms as transforms\n", "import torchvision.datasets as datasets" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "mean_gray = 0.1307\n", "stddev_gray = 0.3081\n", "\n", "# input[channel] = (input[channel]-meaan[channel]) / std[channel]\n", "\n", "transforms_ori = transforms.Compose([transforms.ToTensor(),\n", " transforms.Normalize((mean_gray,),(stddev_gray,))])\n", "\n", "train_dataset = datasets.MNIST(root='./data', \n", " train=True, \n", " transform=transforms_ori, \n", " download=True)\n", "\n", "test_dataset = datasets.MNIST(root='./data', \n", " train=False, \n", " transform=transforms_ori)\n", "\n", "# The next code is to transform the image\n", "transforms_photo = transforms.Compose([transforms.Resize((28,28)),\n", " transforms.ToTensor(),\n", " transforms.Normalize((mean_gray,),(stddev_gray,))])\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "random_img = train_dataset[20][0].numpy() * stddev_gray + mean_gray\n", "plt.imshow(random_img.reshape(28,28), cmap='gray')" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4\n" ] } ], "source": [ "print(train_dataset[20][1])" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "batch_size = 100\n", "\n", "train_load = torch.utils.data.DataLoader(dataset=train_dataset,\n", " batch_size=batch_size,\n", " shuffle=True)\n", "\n", "test_load = torch.utils.data.DataLoader(dataset=test_dataset,\n", " batch_size=batch_size,\n", " shuffle=True)\n" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "100" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(test_load)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "class CNN(nn.Module):\n", " def __init__(self):\n", " super(CNN,self).__init__()\n", " # Same padding means that input_size = output_size\n", " # same_padding = (filter_size - 1) / 2\n", " self.cnn1 = nn.Conv2d(in_channels=1, out_channels=8, kernel_size=(3,3), stride=1, padding=1)\n", " # The output from this layer has size:\n", " # [(input_size - filter_size + 2*(padding)) / stride] + 1\n", " self.batchnorm1 = nn.BatchNorm2d(8)\n", " self.relu = nn.ReLU()\n", " self.maxpool = nn.MaxPool2d(kernel_size=(2,2))\n", " # Pooling output size is 28/2 = 14 (downsampling)\n", " # Same padding size is (5 - 1)/2 = 2\n", " self.cnn2 = nn.Conv2d(in_channels=8, out_channels=32, kernel_size=(5,5), stride=1, padding=2)\n", " self.batchnorm2 = nn.BatchNorm2d(32)\n", " # Pooling output size is 14/2 = 7 (downsampling)\n", " # We have to flatten the output channels 32*7*7 = 1568\n", " self.fc1 = nn.Linear(1568,600)\n", " self.dropout = nn.Dropout(p=0.5)\n", " self.fc2 = nn.Linear(600,10)\n", " \n", " def forward(self,x):\n", " out = self.cnn1(x)\n", " out = self.batchnorm1(out)\n", " out = self.relu(out)\n", " out = self.maxpool(out)\n", " out = self.cnn2(out)\n", " out = self.batchnorm2(out)\n", " out = self.relu(out)\n", " out = self.maxpool(out)\n", " # we have to flatten the 32 feature maps, output of our last maxpool (100, 1568)\n", " out = out.view(-1, 1568) # <- setting the number of rows to -1 is important, because \n", " out = self.fc1(out) # when we try to predict we would require to use a size 100 (batch size)\n", " out = self.relu(out) # tensor but -1 infers the size.\n", " out = self.dropout(out)\n", " out = self.fc2(out)\n", " \n", " return out\n", " " ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "model = CNN()\n", "\n", "CUDA = torch.cuda.is_available()\n", "\n", "if CUDA:\n", " model = model.cuda()\n", " \n", "loss_fn = nn.CrossEntropyLoss()\n", "optimizer = torch.optim.Adam(model.parameters(), lr=0.01)\n" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "print(CUDA)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "For one iteration this is what happens:\n", "Input shape: torch.Size([100, 1, 28, 28])\n", "Labels shape: torch.Size([100])\n", "Output shape: torch.Size([100, 10])\n", "Predicted shape: torch.Size([100, 1, 28, 28])\n", "Predicted tensor: \n", "tensor([9, 4, 9, 4, 0, 7, 3, 7, 8, 4, 0, 0, 4, 9, 9, 8, 4, 0, 6, 4, 9, 0, 3, 8,\n", " 8, 8, 0, 0, 8, 9, 3, 8, 4, 0, 4, 8, 9, 0, 4, 4, 0, 9, 0, 9, 9, 7, 4, 4,\n", " 8, 0, 0, 8, 8, 0, 0, 4, 9, 9, 9, 4, 8, 4, 0, 4, 0, 8, 0, 0, 4, 8, 4, 4,\n", " 7, 8, 5, 4, 8, 9, 9, 8, 7, 8, 0, 9, 0, 4, 0, 9, 9, 8, 5, 0, 4, 9, 4, 7,\n", " 9, 4, 4, 9], device='cuda:0')\n" ] } ], "source": [ "# Understand what is happening\n", "iteration = 0\n", "correct = 0\n", "\n", "for i,(inputs, labels) in enumerate(train_load):\n", " \n", " if CUDA:\n", " inputs = inputs.cuda()\n", " labels = labels.cuda()\n", " \n", " print('For one iteration this is what happens:')\n", " print('Input shape: ', inputs.shape)\n", " print('Labels shape: ', labels.shape)\n", " output = model(inputs)\n", " print('Output shape: ', output.shape)\n", " _, predicted = torch.max(output, dim=1)\n", " print('Predicted shape: ', inputs.shape)\n", " print('Predicted tensor: ')\n", " print(predicted)\n", " correct += (predicted==labels).sum()\n", " break\n", " " ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/10, Training loss: 0.574, Training accuracy: 0.840, Testing loss: 3.446, Testing accuracy: 0.974\n", "Epoch 2/10, Training loss: 0.151, Training accuracy: 0.956, Testing loss: 0.907, Testing accuracy: 0.984\n", "Epoch 3/10, Training loss: 0.105, Training accuracy: 0.971, Testing loss: 0.629, Testing accuracy: 0.987\n", "Epoch 4/10, Training loss: 0.085, Training accuracy: 0.975, Testing loss: 0.511, Testing accuracy: 0.989\n", "Epoch 5/10, Training loss: 0.080, Training accuracy: 0.978, Testing loss: 0.477, Testing accuracy: 0.988\n", "Epoch 6/10, Training loss: 0.068, Training accuracy: 0.981, Testing loss: 0.407, Testing accuracy: 0.990\n", "Epoch 7/10, Training loss: 0.064, Training accuracy: 0.982, Testing loss: 0.385, Testing accuracy: 0.990\n", "Epoch 8/10, Training loss: 0.062, Training accuracy: 0.982, Testing loss: 0.369, Testing accuracy: 0.989\n", "Epoch 9/10, Training loss: 0.058, Training accuracy: 0.983, Testing loss: 0.346, Testing accuracy: 0.986\n", "Epoch 10/10, Training loss: 0.055, Training accuracy: 0.984, Testing loss: 0.331, Testing accuracy: 0.988\n" ] } ], "source": [ "# Training of the CNN\n", "num_epochs = 10\n", "train_loss = list()\n", "train_accuracy = list()\n", "test_loss = list()\n", "test_accuracy = list()\n", "\n", "\n", "for epoch in range(num_epochs):\n", " correct = 0\n", " iterations = 0\n", " iter_loss = 0.0\n", " \n", " # When batch normalization and dropout are used\n", " # we have to specify our model that we are training\n", " model.train()\n", " \n", " for i,(inputs, labels) in enumerate(train_load):\n", " \n", " if CUDA:\n", " inputs = inputs.cuda()\n", " labels = labels.cuda()\n", " \n", " outputs = model(inputs)\n", " loss = loss_fn(outputs,labels)\n", " iter_loss += loss.item()\n", " \n", " optimizer.zero_grad()\n", " loss.backward()\n", " optimizer.step()\n", " \n", " _, predicted = torch.max(outputs, dim=1)\n", " correct += (predicted==labels).sum().item()\n", " iterations += 1\n", " \n", " train_loss.append(iter_loss/iterations)\n", " train_accuracy.append(correct/len(train_dataset))\n", " \n", " # Testing phase\n", " testing_loss = 0.0\n", " correct = 0\n", " iterations = 0\n", " \n", " model.eval()\n", " \n", " for i,(inputs, labels) in enumerate(test_load):\n", " \n", " if CUDA:\n", " inputs = inputs.cuda()\n", " labels = labels.cuda()\n", " \n", " outputs = model(inputs)\n", " loss = loss_fn(outputs,labels)\n", " testing_loss += loss.item()\n", " \n", " _, predicted = torch.max(outputs, dim=1)\n", " correct += (predicted==labels).sum().item()\n", " iterations += 1\n", " \n", " test_loss.append(iter_loss/iterations)\n", " test_accuracy.append(correct/len(test_dataset))\n", " \n", " print('Epoch {}/{}, Training loss: {:.3f}, Training accuracy: {:.3f}, Testing loss: {:.3f}, Testing accuracy: {:.3f}'.format(\n", " epoch+1,num_epochs,train_loss[-1],train_accuracy[-1],test_loss[-1],test_accuracy[-1]))\n", "\n", "\n", " " ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# Plotting the loss\n", "\n", "f = plt.figure(figsize=(10,10))\n", "plt.plot(train_loss, label='Training loss')\n", "plt.plot(test_loss, label='Testing loss')\n", "plt.legend()\n", "plt.show()\n" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "image/png": "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+10KcqiqqkptbW0qL898hZiSDVmsWQgAyIbe3l7V1dWpvb1dZuZ3OcgB55z6+/vV29urjo6OjF9XspcLw31eyOokZAEAFmF8fFzNzc0ErCJmZmpubj7t0cqSDVndkajKA6bVy6r9LgUAUOAIWMVvIX/HJRuyeiJRndlUo2CgZH8EAIAC19/fr/PPP1/nn3++Vq5cqdWrV09vx2Kxk7529+7d+sQnPnHKP+OSSy7JVrklp6TnZNHpHQBQyJqbm/XEE09Ikj73uc8pFArpxhtvnD4+OTmpYHD+j/quri51dXWd8s94+OGHs1PsEkokEgoE/O+BWZLDOMmkU7ifHlkAgOJzzTXX6KMf/aguvvhifepTn9LOnTv12te+VhdccIEuueQSvfDCC5Kkhx56SO985zsleQHt2muv1WWXXabOzk799V//9fT3C4VC0+dfdtlles973qOzzz5bV111lZxzkqQdO3bo7LPP1oUXXqhPfOIT0983XU9Pj97whjdoy5Yt2rJly6zw9sUvflHnnnuuNm/erJtuukmStG/fPr3lLW/R5s2btWXLFr344ouzapakG264QXfeeackqb29XX/4h3+oLVu26Pvf/75uv/12XXTRRdq8ebPe/e53a3TUW6/48OHDuuKKK7R582Zt3rxZDz/8sG6++WZ95Stfmf6+n/nMZ/TVr3510X8XJTmSdejYmGKTSdo3AACy6k//9Rk9e2goq99z06p6/clvnnNar+nt7dXDDz+sQCCgoaEh/fznP1cwGNT999+vP/qjP9I//dM/Hfea559/Xg8++KCGh4e1ceNGfexjHzuuXcHjjz+uZ555RqtWrdLrXvc6/eIXv1BXV5euv/56/exnP1NHR4e2b98+b03Lly/Xfffdp6qqKu3du1fbt2/X7t279eMf/1g/+tGP9Mgjj6impkYDAwOSpKuuuko33XSTrrjiCo2PjyuZTOrAgQMnfd/Nzc167LHHJHmXUj/ykY9Ikj772c/qG9/4hj7+8Y/rE5/4hC699FL98Ic/VCKR0MjIiFatWqUrr7xSv/d7v6dkMqm7775bO3fuPK2f+XxKMmRNt29oJmQBAIrPb//2b09fLjt27Jiuvvpq7d27V2ameDw+72t+4zd+Q5WVlaqsrNTy5ct1+PBhtbW1zTpn69at0/vOP/989fT0KBQKqbOzc7q1wfbt23Xb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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# Plotting the accuracy\n", "\n", "f = plt.figure(figsize=(10,10))\n", "plt.plot(train_accuracy, label='Training accuracy')\n", "plt.plot(test_accuracy, label='Testing accuracy')\n", "plt.legend()\n", "plt.show()\n" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Prediction is: 1\n", "Actual label is: 1\n" ] } ], "source": [ "img = test_dataset[31][0].resize_((1,1,28,28))\n", "label = test_dataset[31][1]\n", "\n", "model.eval()\n", "\n", "if CUDA:\n", " model = model.cuda()\n", " img = img.cuda()\n", " \n", "output = model(img)\n", "_, predicted = torch.max(output, dim=1)\n", "print('Prediction is: {}'.format(predicted.item()))\n", "print('Actual label is: {}'.format(label))\n" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "random_img = test_dataset[31][0].numpy() * stddev_gray + mean_gray\n", "plt.imshow(random_img.reshape(28,28), cmap='gray')" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "def predict(img_name,model,show_image=False):\n", " image = cv2.imread(img_name,0)\n", " ret, thresholded = cv2.threshold(image,127,255,cv2.THRESH_BINARY)\n", " img = 255 - thresholded\n", " if show_image == True:\n", " cv2.imshow('Original',img)\n", " cv2.waitKey(0)\n", " cv2.destroyAllWindows()\n", " \n", " img = Image.fromarray(img)\n", " img = transforms_photo(img)\n", " img = img.view(1,1,28,28)\n", " #img = Variable(img)\n", " \n", " model.eval()\n", " \n", " if CUDA:\n", " model = model.cuda()\n", " img = img.cuda()\n", " \n", " output = model(img)\n", " print(output)\n", " print(output.data)\n", " _, predicted = torch.max(output,1)\n", " return predicted.item()\n", " " ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[-5.4035, 2.6434, 8.6153, -3.0462, -7.2718, -7.2775, -1.7709, 0.8279,\n", " -4.8467, -8.3950]], device='cuda:0', grad_fn=)\n", "tensor([[-5.4035, 2.6434, 8.6153, -3.0462, -7.2718, -7.2775, -1.7709, 0.8279,\n", " -4.8467, -8.3950]], device='cuda:0')\n", "the predicted label is 2\n" ] } ], "source": [ "pred = predict('photo.jpg',model)\n", "print('the predicted label is {}'.format(pred))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "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.7" } }, "nbformat": 4, "nbformat_minor": 4 }