{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":16017,"databundleVersionId":708189,"sourceType":"competition"}],"dockerImageVersionId":30636,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Import libraries","metadata":{}},{"cell_type":"code","source":"%matplotlib inline\n\n# Importing necessary libraries and modules\nimport numpy as np # for numerical computing\nimport pandas as pd # for manipulation and analysis\nimport os # for interacting with the operating system \nimport matplotlib.pyplot as plt # for creating visualizations\nfrom PIL import Image # for working with images\n\nimport torch # for machine learning\nimport torch.nn as nn # for building neural networks in PyTorch\nimport torch.optim as optim # for optimizing neural networks in PyTorch\nimport torchvision # for computer vision tasks in PyTorch\nfrom torchvision import models, transforms # for loading and preprocessing image data\nimport torchvision.models as models # for using pre-trained models in PyTorch\nfrom torch.utils.data import DataLoader, Dataset # for working with datasets in PyTorch","metadata":{"execution":{"iopub.status.busy":"2024-01-13T05:59:05.808203Z","iopub.execute_input":"2024-01-13T05:59:05.808605Z","iopub.status.idle":"2024-01-13T05:59:05.817070Z","shell.execute_reply.started":"2024-01-13T05:59:05.808578Z","shell.execute_reply":"2024-01-13T05:59:05.816127Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Defining the paths for the training and testing data\nbase_dir = '../input/'\ntrain_csv = '../input/Kannada-MNIST/train.csv'\ntest_csv = '../input/Kannada-MNIST/test.csv'\n# Set the device which we will be using for the model\ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")","metadata":{"execution":{"iopub.status.busy":"2024-01-13T05:59:05.818724Z","iopub.execute_input":"2024-01-13T05:59:05.819038Z","iopub.status.idle":"2024-01-13T05:59:05.850790Z","shell.execute_reply.started":"2024-01-13T05:59:05.819000Z","shell.execute_reply":"2024-01-13T05:59:05.850096Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Define custom dataset class","metadata":{}},{"cell_type":"code","source":"# Defining a custom dataset class for loading and preprocessing image data\nclass manualDataset(Dataset):\n    def __init__(self, file_path, split='train', val_split=False):\n        df = pd.read_csv(file_path)\n       \n        self.split = split\n        self.val_split = val_split\n       \n        if self.split=='test' and val_split==False :\n            # test data\n            df = df.drop(columns=[\"id\"])\n            self.raw_files = df.values.reshape((-1,28,28)).astype(np.uint8)[:,:,:,None]\n            \n            self.labels = None\n        else:\n            # training data\n            self.raw_files = df.iloc[:,1:].values.reshape((-1,28,28)).astype(np.uint8)[:,:,:,None]\n            self.labels = torch.from_numpy(df.iloc[:,0].values)\n            print(self.raw_files.shape)\n        if(val_split):\n            self.raw_files = self.raw_files[:10]\n          \n       \n        # Defining the transformations to be applied to the images\n        self.train_transform = transforms.Compose([ transforms.ToPILImage(),transforms.RandomHorizontalFlip(), transforms.ToTensor()])\n        self.test_transform = transforms.Compose([ transforms.ToTensor()])\n          \n\n        \n    def __len__(self):\n        return len(self.raw_files)\n    \n    def __getitem__(self, idx):\n        # Reading in the image file\n        raw = self.raw_files[idx]\n      \n        \n        # Applying the appropriate transformation based on the split\n        if self.split == 'train' or self.val_split:\n            raw = self.train_transform(raw)\n            label = self.labels[idx]\n            return raw, label\n        elif self.split == 'test':\n            raw = self.test_transform(raw)\n            return raw","metadata":{"execution":{"iopub.status.busy":"2024-01-13T05:59:26.193070Z","iopub.execute_input":"2024-01-13T05:59:26.193986Z","iopub.status.idle":"2024-01-13T05:59:26.205134Z","shell.execute_reply.started":"2024-01-13T05:59:26.193953Z","shell.execute_reply":"2024-01-13T05:59:26.204001Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Creating instances of the manualDataset class for the training, testing, and validation datasets\ntrain_dataset = manualDataset(train_csv, split='train')\ntest_dataset = manualDataset(test_csv, split='test')\nval_dataset = manualDataset(train_csv, split='test', val_split=True)\n\n# Defining the batch sizes for the training and testing data\ntrain_batch_size = 32\ntest_batch_size = 1\n\n# Creating instances of the DataLoader class for the training, testing, and validation data\ntrain_loader = DataLoader(train_dataset, batch_size=train_batch_size, shuffle=True)\ntest_loader = DataLoader(test_dataset, batch_size=test_batch_size)\nval_loader = DataLoader(val_dataset, batch_size=test_batch_size)","metadata":{"execution":{"iopub.status.busy":"2024-01-13T05:59:35.898213Z","iopub.execute_input":"2024-01-13T05:59:35.899088Z","iopub.status.idle":"2024-01-13T05:59:43.943636Z","shell.execute_reply.started":"2024-01-13T05:59:35.899055Z","shell.execute_reply":"2024-01-13T05:59:43.942676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Creating a Convolutional Network¶","metadata":{}},{"cell_type":"code","source":"class CNN(nn.Module):    \n    def __init__(self):\n        super().__init__()\n        \n        # CNN layers\n        self.cnn = nn.Sequential(\n            nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1),  # Convolutional layer with 32 output channels\n            nn.BatchNorm2d(32),  # Batch normalization to normalize the outputs\n            nn.ReLU(inplace=True),  # ReLU activation function for introducing non-linearity\n            nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1),  # Another convolutional layer with 32 output channels\n            nn.BatchNorm2d(32),\n            nn.ReLU(inplace=True),\n            nn.MaxPool2d(kernel_size=2, stride=2),  # Max pooling layer to reduce the spatial dimensions\n            nn.Conv2d(32, 64, kernel_size=3, padding=1),  # Convolutional layer with 64 output channels\n            nn.BatchNorm2d(64),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(64, 64, kernel_size=3, padding=1),  # Another convolutional layer with 64 output channels\n            nn.BatchNorm2d(64),\n            nn.ReLU(inplace=True),\n            nn.MaxPool2d(kernel_size=2, stride=2)  # Max pooling layer to reduce the spatial dimensions\n        )\n        \n        # Fully connected layers\n        self.classifier = nn.Sequential(\n            nn.Dropout(p=0.5),  # Dropout layer to prevent overfitting\n            nn.Linear(64 * 7 * 7, 512),  # Fully connected layer with 512 output units\n            nn.BatchNorm1d(512),\n            nn.ReLU(inplace=True),\n            nn.Dropout(p=0.5),\n            nn.Linear(512, 512),  # Another fully connected layer with 512 output units\n            nn.BatchNorm1d(512),\n            nn.ReLU(inplace=True),\n            nn.Dropout(p=0.5),\n            nn.Linear(512, 10)  # Final fully connected layer with 10 output units (corresponding to classes)\n        )\n        \n    def forward(self, x):\n        x = self.cnn(x)  # Pass the input through the CNN layers\n        x = x.view(x.size(0), -1)  # Flatten the output for the fully connected layers\n        x = self.classifier(x)  # Pass the flattened output through the fully connected layers\n        \n        return x","metadata":{"execution":{"iopub.status.busy":"2024-01-13T05:59:54.269042Z","iopub.execute_input":"2024-01-13T05:59:54.269679Z","iopub.status.idle":"2024-01-13T05:59:54.280722Z","shell.execute_reply.started":"2024-01-13T05:59:54.269645Z","shell.execute_reply":"2024-01-13T05:59:54.279805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Visualizing Our Training Dataset","metadata":{}},{"cell_type":"code","source":"train_df = pd.read_csv(train_csv)\n#plt.rcParams['figure.figsize'] = (8, 5)\nplt.bar(train_df['label'].value_counts().index, train_df['label'].value_counts())\nplt.xticks(np.arange(10))\nplt.xlabel('Class', fontsize=16)\nplt.ylabel('Count', fontsize=16)\nplt.grid('on', axis='y')","metadata":{"execution":{"iopub.status.busy":"2024-01-13T06:00:08.432552Z","iopub.execute_input":"2024-01-13T06:00:08.433497Z","iopub.status.idle":"2024-01-13T06:00:12.082012Z","shell.execute_reply.started":"2024-01-13T06:00:08.433462Z","shell.execute_reply":"2024-01-13T06:00:12.081098Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"_,ax = plt.subplots(3,3,figsize=(6,6))\ntorch.manual_seed(81)\nvisualize_loader = DataLoader(train_dataset, batch_size=1,shuffle=True)\n\nfor i, (data,label) in enumerate(visualize_loader):\n    \n    \n    ax[i//3][i%3].imshow(data.cpu().squeeze())\n    ax[i//3][i%3].axis('off')\n    ax[i//3][i%3].set_title(f\"Label: {label.item()}\",y=-0.3)\n    if(i==8): break\nplt.subplots_adjust(hspace=0.5)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-01-13T06:00:18.483252Z","iopub.execute_input":"2024-01-13T06:00:18.484107Z","iopub.status.idle":"2024-01-13T06:00:18.915503Z","shell.execute_reply.started":"2024-01-13T06:00:18.484073Z","shell.execute_reply":"2024-01-13T06:00:18.914226Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model Setup & Training","metadata":{}},{"cell_type":"code","source":"model = CNN()\nmodel = model.to(device)\n# Defining the loss function and optimizer for training the model\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.SGD(params=model.parameters(), lr=0.001, momentum=0.9)\n\n# Defining the number of epochs to train the model\nepochs = 10\n\n# Setting the model to training mode\nmodel.train()\n\n# Training the model for the specified number of epochs\nfor epoch in range(epochs):\n    epoch_loss = 0\n    epoch_accuracy = 0\n    \n    # Iterating through the training data\n    for data, label in train_loader:\n        data = data.to(device)\n        label = label.to(device)\n        optimizer.zero_grad()\n        output = model(data)\n  \n     \n        loss = criterion(output, label)\n     \n      \n        \n        loss.backward()\n        optimizer.step()\n        \n        epoch_loss += (loss.item())/len(train_loader)\n        \n    print('Epoch : {},  train loss : {}'.format(epoch+1,epoch_loss))\n    \n    # Setting the model to evaluation mode\n    model.eval()\n    with torch.no_grad():\n        epoch_val_accuracy=0\n        epoch_val_loss =0\n        \n        # Iterating through the validation data\n        for data, label in val_loader:\n            data = data.to(device)\n            label = label.to(device)\n     \n            output = model(data)\n           \n\n            \n            val_output = model(data)\n            val_loss = criterion(val_output,label)\n            \n            epoch_val_loss += val_loss/ len(val_loader)\n            \n        print('Epoch : {} , val_loss : {}'.format(epoch+1,epoch_val_loss))","metadata":{"execution":{"iopub.status.busy":"2024-01-13T06:00:41.737132Z","iopub.execute_input":"2024-01-13T06:00:41.737593Z","iopub.status.idle":"2024-01-13T06:03:32.117667Z","shell.execute_reply.started":"2024-01-13T06:00:41.737561Z","shell.execute_reply":"2024-01-13T06:03:32.116696Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Visualizing Predictions","metadata":{}},{"cell_type":"code","source":"model.eval()\n_,ax = plt.subplots(3,3,figsize=(6,6))\nfor i, data in enumerate(test_loader):\n    \n \n    data = data.cuda()\n\n    output = model(data)\n    \n\n    pred = output.cpu().data.max(1, keepdim=True)[1]\n    \n    ax[i//3][i%3].imshow(data.cpu().squeeze())\n    ax[i//3][i%3].axis('off')\n    ax[i//3][i%3].set_title(f\"Prediction: {pred.item()}\",y=-0.3)\n    if(i==8): break\nplt.subplots_adjust(hspace=0.5)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-01-13T06:03:39.727239Z","iopub.execute_input":"2024-01-13T06:03:39.728612Z","iopub.status.idle":"2024-01-13T06:03:40.204070Z","shell.execute_reply.started":"2024-01-13T06:03:39.728567Z","shell.execute_reply":"2024-01-13T06:03:40.202874Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Submission","metadata":{}},{"cell_type":"code","source":"model.eval()\ntest_pred = torch.LongTensor()\n\nfor i, data in enumerate(test_loader):\n    \n    if torch.cuda.is_available():\n        data = data.cuda()\n\n    output = model(data)\n\n    pred = output.cpu().data.max(1, keepdim=True)[1]\n    test_pred = torch.cat((test_pred, pred), dim=0)\n    \nprint(test_pred.shape)\nsubmission_df = pd.read_csv(\"../input/Kannada-MNIST/sample_submission.csv\")\nsubmission_df['label'] = test_pred.numpy().squeeze()\nsubmission_df.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-01-13T06:03:43.294775Z","iopub.execute_input":"2024-01-13T06:03:43.295610Z","iopub.status.idle":"2024-01-13T06:03:49.922029Z","shell.execute_reply.started":"2024-01-13T06:03:43.295578Z","shell.execute_reply":"2024-01-13T06:03:49.921045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}