{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Pytorch CNN  CIFAR10 Classification","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"# 1. Import Libraries","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install py7zr","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom time import time\n\nimport torch\nfrom torch import optim\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.data import DataLoader\nimport torchvision\nfrom torchvision import datasets\nimport torchvision.transforms as transforms\nfrom torch.utils.data import random_split\nfrom PIL import Image\n\nfrom py7zr import unpack_7zarchive\nimport shutil\nshutil.register_unpack_format('7zip', ['.7z'], unpack_7zarchive)\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    print(dirname)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 2. Load and Preprocess Images","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"shutil.unpack_archive('/kaggle/input/cifar-10/train.7z', '/kaggle/working')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_dir = os.listdir(\"/kaggle/working/train\")\ntrain_dir_len = len(train_dir)\nprint(\".\\\\train:\\t\",train_dir_len)\nprint(\"files:\\t\\t\",train_dir[:3])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas as pd\ntrain_labels = pd.read_csv('/kaggle/input/cifar-10/trainLabels.csv',dtype=str)\ntrain_images = pd.DataFrame(columns = ['id','label','path'],dtype=str)\ntest_labels = pd.read_csv('/kaggle/input/cifar-10/sampleSubmission.csv')\ntrain_labels.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"path_base = '/kaggle/working/train/'\n\nfor index in range(0,train_dir_len):\n    path = path_base + str(index+1)+'.png'\n    if os.path.exists(path):\n        train_images = train_images.append([{ 'id': str(train_labels['id'].iloc[index]),'path': path, 'label':train_labels['label'].iloc[index]}])\n        \ntrain_images.head(2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display_groupby = train_images.groupby(['label']).count()\ndisplay_groupby.head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class_names = ['airplane','automobile','bird','cat','deer','dog','frog','horse','ship','truck']\nfor name in  class_names:\n    index = class_names.index(name)\n    train_images.loc[train_images.label==name,'label'] = str(index)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_images.head(2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class MyDataset(torch.utils.data.Dataset):\n    def __init__(self, dataframe):\n        self.dataframe = dataframe\n\n    def __len__(self):\n        return len(self.dataframe)\n\n    def __getitem__(self, index):\n        row = self.dataframe.iloc[index]\n        return (\n            transforms.functional.to_tensor(Image.open(row[\"path\"])),\n            int(row[\"label\"]),\n        )\n\ndataset = MyDataset(train_images)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"BATCH_SIZE = 64\nNUM_WORKERS = 0\nVALIDATION_SIZE = 0.2\nnum = len(dataset)\nsplit = round(num*VALIDATION_SIZE)\n\ntrain_dataset, val_dataset = random_split(dataset, [num-split, split])\n\ntrain_loader = DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True, num_workers=NUM_WORKERS)\nval_loader = DataLoader(val_dataset, batch_size=BATCH_SIZE, shuffle=True, num_workers=NUM_WORKERS)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def imshow(img):\n    # convert from Tensor image\n    plt.imshow(np.transpose(img, (1, 2, 0)))  \n    \n# Show Image Dataloader\ntrain_dataiter = iter(train_loader)\nimages, labels = train_dataiter.next()\nimages = images.numpy()\nfig = plt.figure(figsize=(25, 4))\n\n# Display 20 images\nfor idx in np.arange(20):\n    ax = fig.add_subplot(2, 20/2, idx+1, xticks=[], yticks=[])\n    imshow(images[idx])\n    ax.set_title([labels[idx]])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 3. Build CNN Model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch.nn as nn\nimport torch.nn.functional as F\n\nclass Net(nn.Module):\n    def __init__(self):\n        super(Net, self).__init__()\n        self.conv1 = nn.Conv2d(3, 6, 5)\n        self.conv2 = nn.Conv2d(6, 16, 5)\n        self.pool = nn.MaxPool2d(kernel_size=(2,2), stride=2)\n        self.fc1 = nn.Linear(16 * 5 * 5, 120)\n        self.fc2 = nn.Linear(120, 84)\n        self.fc3 = nn.Linear(84, 10)\n        self.dropout = nn.Dropout(0.2)\n        \n    def forward(self, input):\n        x = self.pool(F.relu(self.conv1(input)))\n        x = self.pool(F.relu(self.conv2(x)))\n        x = x.view(-1, 16 * 5 * 5)\n        x = F.relu(self.fc1(x))\n        x = self.dropout(x)\n        x = F.relu(self.fc2(x))\n        x = self.dropout(x)\n        x = self.fc3(x)\n        return x","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 4. Train Model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nprint(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = Net()\nmodel.to(device)\n\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)\n\nn_epochs = 100\ntime0 = time()\n\ntrain_loss_list = []\nval_loss_list = []\n\n\nif torch.cuda.is_available():\n    for epoch in range(n_epochs):\n        train_loss = 0.0\n        val_loss = 0.0\n\n        for images, labels in train_loader:\n            optimizer.zero_grad()\n            \n            output = model(images.to(device))\n            loss = criterion(output, labels.to(device))\n            loss.backward()\n            optimizer.step()\n            \n            train_loss += loss.item()\n\n        for images, labels in val_loader:\n            output = model(images.to(device))\n            loss = criterion(output, labels.to(device))\n            \n            val_loss += loss.item()\n\n        train_loss = train_loss\n        val_loss = val_loss\n        train_loss_list.append(train_loss)\n        val_loss_list.append(val_loss)\n        \n        print('Epoch: {} \\tTraining loss: {:.6f} \\tValidation loss: {:.6f}'.format(\n            epoch+1,\n            train_loss,\n            val_loss\n        ))\n    \nprint(\"\\nTraining Time (in minutes) =\",(time()-time0)/60)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(range(100),train_loss_list)\nplt.plot(range(100),val_loss_list)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 5. Test and Evaluation","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"to_pil = torchvision.transforms.ToPILImage()\n\nimages, labels = next(iter(val_loader))\n\nimg = images[1].view(1, 3, 32, 32).to(device)\nwith torch.no_grad():\n    logps = model(img)\n\nps = torch.exp(logps)\nprobab = list(ps.cpu().numpy()[0])\n\nprint(probab)\nindex_predict = probab.index(max(probab))\nprint(index_predict, class_names[index_predict])\nprint(labels[1])\n\nimg = to_pil(images[1])\nplt.imshow(img)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"correct_count, all_count = 0, 0\nfor images,labels in val_loader:\n    for i in range(len(labels)):\n        img = images[i].view(1, 3, 32, 32).to(device)\n        with torch.no_grad():\n            logps = model(img)\n\n        ps = torch.exp(logps)\n        probab = list(ps.cpu().numpy()[0])\n        pred_label = probab.index(max(probab))\n        true_label = labels.numpy()[i]\n        if(true_label == pred_label):\n          correct_count += 1\n        all_count += 1\n\nprint(\"Number Of Images Tested =\", all_count)\nprint(\"\\nModel Accuracy =\", (correct_count/all_count))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}