{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# <center> 🔢 MNIST | Pytorch 🔥 CNN Tuto </center>\n\n> The goal of this quick notebook is to build a CNN with PyTorch. \nThe aim won't be to have the best accuracy, but to create a CNN from scratch on this toy dataset.","metadata":{}},{"cell_type":"code","source":"# Libraries\nimport numpy as np\nimport pandas as pd\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport matplotlib.pyplot as plt\nimport plotly.graph_objects as go\nfrom torchvision import transforms as T\nfrom torch.utils.data import Dataset\nfrom torch.utils.data import DataLoader, random_split\nfrom torch import optim\nfrom tqdm.notebook import tqdm as tqdm","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-05-10T13:49:36.222587Z","iopub.execute_input":"2023-05-10T13:49:36.223353Z","iopub.status.idle":"2023-05-10T13:49:42.051766Z","shell.execute_reply.started":"2023-05-10T13:49:36.223319Z","shell.execute_reply":"2023-05-10T13:49:42.050724Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We'll use GPU (faster for CNN training), so we set the device directly here.","metadata":{}},{"cell_type":"code","source":"# Device\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")","metadata":{"execution":{"iopub.status.busy":"2023-05-10T13:49:42.057352Z","iopub.execute_input":"2023-05-10T13:49:42.059965Z","iopub.status.idle":"2023-05-10T13:49:42.141731Z","shell.execute_reply.started":"2023-05-10T13:49:42.059924Z","shell.execute_reply":"2023-05-10T13:49:42.140248Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# MNIST Dataset\n\nCoding `Dataset` class instance for out MNIST dataset. \n\nWe'll use the `ToTensor()` transformation in order to convert our numpy arrays to tensor. It also converts the image dimension to C x H x W (in pytorch the input channel should be first).","metadata":{}},{"cell_type":"code","source":"# Dataset class for MNIST\nclass MNIST_Dataset(Dataset):\n    \n    def __init__(self, train=True, transform=T.ToTensor()):\n        if train:\n            self.data = pd.read_csv('/kaggle/input/digit-recognizer/train.csv')\n            self.y = self.data['label']\n            self.data = self.data.drop(['label'], axis=1)\n        else:\n            self.data = pd.read_csv('/kaggle/input/digit-recognizer/test.csv')\n            self.y = None\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.data)\n\n    def __getitem__(self, index):\n        img = np.array(self.data.iloc[index], dtype=np.float32) # float32 in order to be converted to float with ToTensor() instead of double\n        img = img.reshape(28, 28, 1)\n        img = img / 255 # Normalization\n        if self.transform:\n            img = self.transform(img)\n            \n        if self.y is not None:\n            return (img, self.y[index]) # (X, Y)\n        else:\n            return img # Only X","metadata":{"execution":{"iopub.status.busy":"2023-05-10T13:49:42.144242Z","iopub.execute_input":"2023-05-10T13:49:42.144589Z","iopub.status.idle":"2023-05-10T13:49:42.160198Z","shell.execute_reply.started":"2023-05-10T13:49:42.144550Z","shell.execute_reply":"2023-05-10T13:49:42.159049Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We'll take 10% of the training data as validation set.","metadata":{}},{"cell_type":"code","source":"# Splitting X_train into traning and validation sets\nfull_train_set = MNIST_Dataset(train=True)\nval_split = 2e-1\nlen_val_set = int(len(full_train_set)*val_split)\nlen_train_set = len(full_train_set) - len_val_set \ntrain_dataset, val_dataset = random_split(full_train_set, (len_train_set, len_val_set))\n\n# Test set\ntest_dataset = MNIST_Dataset(train=False)\n\n# Details\nprint(f'Total nb of train imgs: {len(train_dataset)}')\nprint(f\"Total nb of validation imgs: {len(val_dataset)}\")\nprint(f\"Total nb of test imgs: {len(test_dataset)}\")","metadata":{"execution":{"iopub.status.busy":"2023-05-10T13:49:42.163055Z","iopub.execute_input":"2023-05-10T13:49:42.163888Z","iopub.status.idle":"2023-05-10T13:49:50.204592Z","shell.execute_reply.started":"2023-05-10T13:49:42.163854Z","shell.execute_reply":"2023-05-10T13:49:50.203530Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The datasets are created, let's plot an image at random in the trainset","metadata":{}},{"cell_type":"code","source":"# Showing an img from train set at random\nfig, ax = plt.subplots(1, 1, figsize=(8,4))\nidx = np.random.choice(np.arange(len(train_dataset)))\nimg, label = train_dataset[idx]\nax.set(title=f'Index {idx}: Label {label}')\nax.imshow(img.squeeze(),cmap = 'gray');","metadata":{"execution":{"iopub.status.busy":"2023-05-10T13:49:50.205814Z","iopub.execute_input":"2023-05-10T13:49:50.206365Z","iopub.status.idle":"2023-05-10T13:49:50.609453Z","shell.execute_reply.started":"2023-05-10T13:49:50.206331Z","shell.execute_reply":"2023-05-10T13:49:50.608341Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# CNN\n\nBelow a schema of the CNN we're going to create.\n\n![CNN_example_model.png](attachment:bc5f7d72-5ec8-4a3f-8ed0-80aeb8218361.png)\n\nMade with [this website](https://alexlenail.me/NN-SVG/LeNet.html).","metadata":{},"attachments":{"bc5f7d72-5ec8-4a3f-8ed0-80aeb8218361.png":{"image/png":"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BoqpkolLdCpevLgTnRRmp20MAhCAAARSkwBiU2reF3oFAQhAoEgQ0Ata165d7fPPP7c2bdpYpUqV3LYEoeHDh9sxxxwT5HD99ddbv379TOc0a9E333zjtkeMGGFHHHFEsJw2JEpdeOGFTsDq27evHXnkkbbffvvZypUr7aeffrJ7773Xpk+fbq+99pp16tQpeO2CBQusffv27qXm+OOPtyVLlti0adNce+PGjbN69eoFy+ZlI9b15aVNymQ2AXnNLFy40Bo3bmzly5fP7MGm8OjC5V/yCb4jCeApPJx8dy0ZgpPvpLzGJDrp97P+Fkh0qlKlij/NGgIQgAAEUoQAYlOK3Ai6AQEIQKAoEvjXv/5lr776qo0dO9batWvnEOglQtvbtm1zLxR6oR40aJBdccUV9vjjj1vPnj3dt9krVqxwwtC6devst99+M5//ZOPGjda6dWuXWPaVV15xHgb6VlwiU5kyZZzopIbuvPNOe/jhh+3PP/+0Zs2aubZPOeUU5wUlTyifmFYv9vvss49JfHrvvfdcubz+E+v68tou5ZJDIF5eehKYevfubR9++KH9/vvvwcG1bNnSLrvsMrvuuuusdOnSweORNl5//XUXihQq4kYqm5fjsa4vL20ms4zPv+RD5CR8y3tJIpP//ZPM/iW67WQKThqrftd7byeFR0t0UqgdBgEIQAACqUEAsSk17gO9gAAEIFDkCKxatcr23HNP69Onj919991Zxq+X2PPOO88mTpzovJYOOOAAq169uunlplixYsGyCr3TOXkoyUNKJg+ooUOH2pw5c1yI3ZAhQ5xAtX79enf+1FNPtR9//NG6detmX331lWnWI73ES5AqVaqUE6BuvfVWV9b/c9ttt7mQPAlbu3fvtu3bt1uJEiXc4stoLbHB16MwvrzUF3o92+lLIF5eep999pmdf/75LhxLPycHHXSQ82qaO3euCynVs6mQ05EjR1rz5s0jAnzjjTfcz4iEqaeffjpiubyeiHV9eW030eUyOf9SLFjmV3CaM3qkVZ71hz3U6x73uzcWfVAd+n2vLyo0o533dlIYNAYBCEAAAskjQKBz8tjTMgQgAIEiTeCPP/5w42/btm0ODj5cTWFv8iySqHTOOedkEZp0kTyY9E22XnhkCqtQqF3//v2d0PTss89ajx497B//+If98MMP9tZbb9kHH3xgCm9T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cPJAJO7K02nJkiVB0alKlSr+NGsIQAACaUUAsSmtbhedhQAEIAABCEAAArEjEC7/kvde2nPPPWPXEDVBIB8EirLgJEwbN24MejvtscceLreTQu0wCEAAAulEALEpne4WfYUABCAAAQhAAAKFJODzL/kQuerVqwdD5Mi/VEi4XB4zAkVdcPIg58yZ47ydNKNd06ZNnfCkpPwYBCAAgVQngNiU6neI/kEAAhCAAAQgAIFCEsief8l7L9WtW9dKly5dyNq5HALxIYDg9DfXlStXOtFp1qxZ1rhxYyc61ahR4+8CbEEAAhBIMQKITSl2Q+gOBCAAAQhAAAIQiAWBcPmXvMgUi/qpAwKJIIDglJWycqkpr5NEJwnFSiaupVixYlkLsgcBCEAgyQQQm5J8A2geAhCAAAQgAAEIxIKA8i/50Dity5QpY15cIv9SLAhTR7IIIDiFJ79o0SInPC1fvjwoOlWuXDl8YY5CAAIQSDABxKYEA6c5CEAAAhCAAAQgECsCW7duDc4epxdP8i/Fiiz1pBoBBKfId2T9+vVBbyf9DpCnU7169SJfwBkIQAACCSCA2JQAyDQRHwK7du1yLsTlypVziU1xH44PZ2qFAAQgAIHUIkD+pdS6H/QmcQQQnHJn7UPsFG4n0UlJxcnLljs3SkAAArEngNgUe6bUmI3A3LlzbeDAgdanTx8rVapUtrNmml3j22+/dUuFChXskEMOsaOOOipHOX9gzJgx9thjj9k333xj+iZHptlzjj32WHvggQesdevWvmiWtaaR1bXTpk1zoQX77befdejQwUqWLJmlXPadcePGuW+Nu3btmv1Unvd//vln19+FCxe6P/zt27d362gVqL8vv/yy/eMf/7BmzZpFK8o5CEAAAhDIcALKv+RD5PQSqcTePkQuw4fO8CCQhQCCUxYcEXf0O0N5nTSbnRedCKeNiIsTEIBAHAggNsUBKlVmJdC7d2+79957nagkL6RQmzFjhrVp08aJRkcccYT7o7hs2TK76KKLbPDgwVa8ePFg8Q0bNtgtt9xizz77rN1xxx128skn2wEHHGDycJo+fbr169fPXn31Vbv//vutV69eweu08f3339sZZ5xhCxYssOOPP961N2nSJDv44IPtgw8+cB/as1zwv50///zTWrRoYS1btjT1Nb+mvvXs2dP+85//uG+W9tprL5swYYJr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CCRZgLApyUeXfUMAAQQQQAABBBBAAAEEEEAAAQRiFiBsihmczSGAAAIIIIAAAggggAACCCCAAAJJFiBsSvLRZd8QQAABBBBAAAEEEEAAAQQQQACBmAUIm2IGZ3MIIIAAAggggAACCCCAAAIIIIBAkgUIm5J8dNk3BBBAAAEEEEAAAQQQQAABBBBAIGYBwqaYwdkcAggggAACCCCAAAIIIIAAAgggkGQBwqYkH132DQEEEEAAAQQQQAABBBBAAAEEEIhZgLApZnA2hwACCCCAAAIIIIAAAggggAACCCRZgLApyUeXfUMAAQQQQAABBBBAAAEEEEAAAQRiFiBsihmczSGAAAIIIIAAAggggAACCCCAAAJJFiBsSsDR3bJli82ZM8c2btyYgL1hFxBAAIH8Ak1NTTZv3jxbuXKlHThwIP9MjEUAAQQQQAABBBBAAIEOFyBs6vBD0LYCbNu2zT7/+c9bv379bODAgXbsscfakCFDbNiwYXbzzTfbnj172rbiDlzqe9/7nn3kIx8pWQnOOecc++EPf1iy9bGilgk8+OCDduSRR9qkSZNs3759RRe65ppr/Lxf/vKXi85XjomhnCpr9Pb2t7/dPvnJT9pTTz1Vjs1mrPPSSy+1n/3sZxnjeJIpsH//frvttttswoQJ1rt3bzv66KNtzJgx1qVLF/viF79YlSE7f+syjzHPDgqEv0n87Wz+FVHq91DzW2SOShH4zGc+k/GZHf38Do9nzpxpOk/W82effbZSit6icqxevdqXe8aMGS2an5kQQACBShboWsmFo2z5BfTL/llnnWXr16+3b3zjG3baaadZ37597f/+7/9s6tSp9qlPfcr+9re/2e23326dOnXKv5IKHKuaWcuWLWtTyfSFfd26dXb99denl1+8eLGvAZEewYNYBLZv324LFizw23r88cftvPPOy7td1VL57ne/66etXbs27zzlHBnKee2119rQoUP9pnbt2mWrVq2yO++802655Ra76aab/PupXOV47bXXbNOmTeVafdWvV68RhcZPPvmkffzjH7fzzz/f6uvr7bnnnjO9tm688UZ7+OGHfTDYv3//qtlf/tZVzaGKtaDhb5I2yt/O4vTteQ8VXzNTK11ANVv12XD11VcXLKo+0/VDhc5Fdu7cWXC+QhPUYuDyyy+3n/70pz74CfN97GMf8+c073nPe8Ko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"}}},{"cell_type":"code","source":"# Our CNN\nclass CNN(nn.Module):\n    \n    def __init__(self):\n        super(CNN, self).__init__()\n        self.conv1 = nn.Conv2d(1, 10, kernel_size=5)\n        self.conv2 = nn.Conv2d(10, 20, kernel_size=5)\n        self.conv2_drop = nn.Dropout2d(p=0.2)\n        self.maxpool2d = nn.MaxPool2d(kernel_size=2)\n        self.fc1 = nn.Linear(320, 50)\n        self.fc2 = nn.Linear(50, 10)\n        \n    def forward(self, x):\n        x = F.relu(self.maxpool2d(self.conv1(x)))\n        x = F.relu(self.maxpool2d(self.conv2_drop(self.conv2(x))))\n        x = x.view(-1, 320)\n        x = F.relu(self.fc1(x))\n        x = F.dropout(x, p=0.2, training=self.training)\n        x = self.fc2(x)\n        \n        return F.log_softmax(x, dim=1)\n    \n# CNN instance\ncnn = CNN()\ncnn.to(device)\ncnn","metadata":{"execution":{"iopub.status.busy":"2023-05-10T13:53:28.772284Z","iopub.execute_input":"2023-05-10T13:53:28.772662Z","iopub.status.idle":"2023-05-10T13:53:28.788459Z","shell.execute_reply.started":"2023-05-10T13:53:28.772632Z","shell.execute_reply":"2023-05-10T13:53:28.787316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We can also have a summary from the `torchsummary` package. Let's install it and plot the model summary","metadata":{}},{"cell_type":"code","source":"%%capture\n!pip install torchsummary","metadata":{"execution":{"iopub.status.busy":"2023-05-10T13:49:53.858296Z","iopub.execute_input":"2023-05-10T13:49:53.858743Z","iopub.status.idle":"2023-05-10T13:50:10.083943Z","shell.execute_reply.started":"2023-05-10T13:49:53.858708Z","shell.execute_reply":"2023-05-10T13:50:10.082613Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torchsummary import summary\nsummary(cnn, input_size=(1, 28, 28))","metadata":{"execution":{"iopub.status.busy":"2023-05-10T13:50:10.085524Z","iopub.execute_input":"2023-05-10T13:50:10.085892Z","iopub.status.idle":"2023-05-10T13:50:16.277698Z","shell.execute_reply.started":"2023-05-10T13:50:10.085853Z","shell.execute_reply":"2023-05-10T13:50:16.275828Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training\n\nFor training we'll use the negative log likelihood loss `NLLLoss()`. \n\nIn our CNN, we return the log_softmax of the last layer, which actually gives log-probabilities output. Then applying `NLLLoss()` to this output is the same as using the `CrossEntropyLoss()` (if we want to use `CrossEntropyLoss()`, we can return directly the last layer without the `log_softmax()`.\n\nWe won't do any hypermarameter optimization in this notebook. But [Optuna](https://optuna.org/) is a really good library for this.","metadata":{}},{"cell_type":"markdown","source":"## Data loader\n\nThe `batch_size` is fixed.","metadata":{}},{"cell_type":"code","source":"# Creating batches generator\nbatch_size = 64\ntrain_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)\nval_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=True)\n\n# First Batch\ndataiter = iter(train_loader)\nimgs, labels = next(dataiter)\n\nprint('Shape of loading one batch: {}'.format(imgs.shape))\nprint('Total nb of batches created in Train loader: {}'.format(len(train_loader)))\nprint('Total nb of batches created in Valid loader: {}'.format(len(val_loader)))","metadata":{"execution":{"iopub.status.busy":"2023-05-10T13:53:30.553988Z","iopub.execute_input":"2023-05-10T13:53:30.555256Z","iopub.status.idle":"2023-05-10T13:53:30.576734Z","shell.execute_reply.started":"2023-05-10T13:53:30.555215Z","shell.execute_reply":"2023-05-10T13:53:30.575725Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Optim parameters\ncriterion = nn.NLLLoss()\n# log_softmax in output activation + nn.NLLLoss() =  nn.CrossEntropyLoss() !\noptimizer = optim.AdamW(cnn.parameters(), lr=1e-2)","metadata":{"execution":{"iopub.status.busy":"2023-05-10T13:53:31.707886Z","iopub.execute_input":"2023-05-10T13:53:31.708563Z","iopub.status.idle":"2023-05-10T13:53:31.714979Z","shell.execute_reply.started":"2023-05-10T13:53:31.708528Z","shell.execute_reply":"2023-05-10T13:53:31.713925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Training and evalutation loop","metadata":{}},{"cell_type":"code","source":"# Fonction used in order to compute the accuracy for each batch\ndef multiclass_accuracy(y_pred, y_true):\n    top_pred, y_pred_class = y_pred.topk(1, dim = 1)\n    equals = (y_pred_class == y_true.view(*y_pred_class.shape))\n    return torch.mean(equals.type(torch.FloatTensor))","metadata":{"execution":{"iopub.status.busy":"2023-05-10T13:53:32.630234Z","iopub.execute_input":"2023-05-10T13:53:32.630581Z","iopub.status.idle":"2023-05-10T13:53:32.638469Z","shell.execute_reply.started":"2023-05-10T13:53:32.630553Z","shell.execute_reply":"2023-05-10T13:53:32.637589Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We'll train the model for 15 epochs.","metadata":{}},{"cell_type":"code","source":"# Training loop\n\n# Number of epochs\nepochs = 15\n\ntrain_losses = []\ntrain_accs = []\nval_losses = []\nval_accs = []\n\nfor i in tqdm(range(epochs), 'Epochs'):\n\n    train_loss = 0.\n    train_acc = 0.\n    val_loss = 0.\n    val_acc = 0.\n\n    # Train on each batch\n    cnn.train()\n    for X_batch, label_batch in train_loader:\n        X_batch, label_batch = X_batch.to(device), label_batch.to(device)\n        logpreds = cnn(X_batch)\n\n        loss = criterion(logpreds, label_batch)\n        optimizer.zero_grad()\n        loss.backward() # dw, db\n        optimizer.step() # w = w - lr*dw\n        train_loss += loss.item()\n\n        preds = torch.exp(logpreds)\n        train_acc += multiclass_accuracy(preds, label_batch)\n\n    # Evaluation for each batch\n    cnn.eval() # Dropout, Batch Norm\n    for X_batch, label_batch in val_loader:\n        X_batch, label_batch = X_batch.to(device), label_batch.to(device)\n        logpreds = cnn(X_batch)\n\n        loss = criterion(logpreds, label_batch)\n        val_loss += loss.item()\n\n        preds = torch.exp(logpreds)\n        val_acc += multiclass_accuracy(preds, label_batch)\n\n    # Aggregate the loss for the current epoch\n    avg_train_loss = train_loss/len(train_loader)\n    avg_train_acc = train_acc/len(train_loader)\n    avg_val_loss = val_loss/len(val_loader)\n    avg_val_acc = val_acc/len(val_loader)\n\n    train_losses.append(avg_train_loss)\n    train_accs.append(avg_train_acc)\n    val_losses.append(avg_val_loss)\n    val_accs.append(avg_val_acc)","metadata":{"execution":{"iopub.status.busy":"2023-05-10T13:53:33.610471Z","iopub.execute_input":"2023-05-10T13:53:33.610826Z","iopub.status.idle":"2023-05-10T13:54:59.663192Z","shell.execute_reply.started":"2023-05-10T13:53:33.610797Z","shell.execute_reply":"2023-05-10T13:54:59.662006Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plot train and validation losses\nfig = go.Figure()\ntrain_losses = pd.Series(train_losses)\nval_losses = pd.Series(val_losses)\nfig.add_trace(go.Scatter(x=train_losses.index, y=train_losses, name=\"Train Loss\"))\nfig.add_trace(go.Scatter(x=val_losses.index, y=val_losses, name=\"Val Loss\"))\nfig.update_layout(title=dict(text=\"Train and Validation Loss\", x=0.5), xaxis=dict(title=\"Epochs\"), yaxis=dict(title=\"Loss\"))","metadata":{"execution":{"iopub.status.busy":"2023-05-10T13:56:21.905116Z","iopub.execute_input":"2023-05-10T13:56:21.906175Z","iopub.status.idle":"2023-05-10T13:56:21.926614Z","shell.execute_reply.started":"2023-05-10T13:56:21.906130Z","shell.execute_reply":"2023-05-10T13:56:21.925373Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plot train and validation accuracy\nfig = go.Figure()\ntrain_accs = pd.Series(train_accs)\nval_accs = pd.Series(val_accs)\nfig.add_trace(go.Scatter(x=train_accs.index, y=train_accs, name=\"Train Accuracy\"))\nfig.add_trace(go.Scatter(x=val_accs.index, y=val_accs, name=\"Val Accuracy\"))\nfig.update_layout(title=dict(text=\"Train and Validation Accuracy\", x=0.5), xaxis=dict(title=\"Epochs\"), yaxis=dict(title=\"Accuracy (%)\"))","metadata":{"execution":{"iopub.status.busy":"2023-05-10T13:56:23.507252Z","iopub.execute_input":"2023-05-10T13:56:23.507610Z","iopub.status.idle":"2023-05-10T13:56:23.542457Z","shell.execute_reply.started":"2023-05-10T13:56:23.507580Z","shell.execute_reply":"2023-05-10T13:56:23.541532Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We can see the the validation loss (accuracy) never increases (decreases), so we can assume there is no overfit (we used only 15 epochs so it makes sens.)","metadata":{}},{"cell_type":"markdown","source":"# Test set predictions\n\nThen let's predict on the test set.","metadata":{}},{"cell_type":"code","source":"# Test set predictions\ncnn.eval() # Dropout, Batch Norm\ntest = next(iter(DataLoader(test_dataset, batch_size=len(test_dataset), shuffle=False))).to(device).detach()\nlogpreds = cnn(test)\npreds = torch.exp(logpreds) # Probabilities \n_, y_pred = preds.topk(1, dim = 1)\ny_pred = pd.DataFrame({'ImageId': np.arange(1, len(test_dataset)+1), 'Label': y_pred.cpu().numpy().squeeze()})\ny_pred.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-05-10T13:56:41.967078Z","iopub.execute_input":"2023-05-10T13:56:41.967617Z","iopub.status.idle":"2023-05-10T13:56:44.629245Z","shell.execute_reply.started":"2023-05-10T13:56:41.967575Z","shell.execute_reply":"2023-05-10T13:56:44.628302Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Conclusion\n\nThe CNN is quite simple, and can the overall process can be improved (hyper-parameter optimization, model more complex...). \n","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}