{"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","execution":{"iopub.status.busy":"2024-01-13T04:15:15.388372Z","iopub.execute_input":"2024-01-13T04:15:15.389282Z","iopub.status.idle":"2024-01-13T04:15:15.731965Z","shell.execute_reply.started":"2024-01-13T04:15:15.389237Z","shell.execute_reply":"2024-01-13T04:15:15.731078Z"},"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-13T04:15:15.734171Z","iopub.execute_input":"2024-01-13T04:15:15.734894Z","iopub.status.idle":"2024-01-13T04:15:17.477969Z","shell.execute_reply.started":"2024-01-13T04:15:15.734857Z","shell.execute_reply":"2024-01-13T04:15:17.477053Z"},"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-13T04:15:17.479230Z","iopub.execute_input":"2024-01-13T04:15:17.479721Z","iopub.status.idle":"2024-01-13T04:15:17.511557Z","shell.execute_reply.started":"2024-01-13T04:15:17.479686Z","shell.execute_reply":"2024-01-13T04:15:17.510526Z"},"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-13T04:15:17.512954Z","iopub.execute_input":"2024-01-13T04:15:17.513295Z","iopub.status.idle":"2024-01-13T04:15:17.526761Z","shell.execute_reply.started":"2024-01-13T04:15:17.513263Z","shell.execute_reply":"2024-01-13T04:15:17.526018Z"},"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-13T04:15:17.529193Z","iopub.execute_input":"2024-01-13T04:15:17.529457Z","iopub.status.idle":"2024-01-13T04:15:25.973619Z","shell.execute_reply.started":"2024-01-13T04:15:17.529434Z","shell.execute_reply":"2024-01-13T04:15:25.972402Z"},"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-13T04:15:25.974899Z","iopub.execute_input":"2024-01-13T04:15:25.975237Z","iopub.status.idle":"2024-01-13T04:15:25.987725Z","shell.execute_reply.started":"2024-01-13T04:15:25.975208Z","shell.execute_reply":"2024-01-13T04:15:25.986629Z"},"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-13T04:15:25.989017Z","iopub.execute_input":"2024-01-13T04:15:25.989324Z","iopub.status.idle":"2024-01-13T04:15:29.593537Z","shell.execute_reply.started":"2024-01-13T04:15:25.989298Z","shell.execute_reply":"2024-01-13T04:15:29.592811Z"},"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-13T04:15:29.594686Z","iopub.execute_input":"2024-01-13T04:15:29.594968Z","iopub.status.idle":"2024-01-13T04:15:30.136291Z","shell.execute_reply.started":"2024-01-13T04:15:29.594943Z","shell.execute_reply":"2024-01-13T04:15:30.134846Z"},"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-13T04:15:30.138387Z","iopub.execute_input":"2024-01-13T04:15:30.138954Z","iopub.status.idle":"2024-01-13T04:18:22.126178Z","shell.execute_reply.started":"2024-01-13T04:15:30.138893Z","shell.execute_reply":"2024-01-13T04:18:22.125239Z"},"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-13T04:18:22.127458Z","iopub.execute_input":"2024-01-13T04:18:22.128383Z","iopub.status.idle":"2024-01-13T04:18:22.470617Z","shell.execute_reply.started":"2024-01-13T04:18:22.128345Z","shell.execute_reply":"2024-01-13T04:18:22.468884Z"},"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-13T04:18:22.472399Z","iopub.execute_input":"2024-01-13T04:18:22.473174Z","iopub.status.idle":"2024-01-13T04:18:28.990194Z","shell.execute_reply.started":"2024-01-13T04:18:22.473124Z","shell.execute_reply":"2024-01-13T04:18:28.989225Z"},"trusted":true},"execution_count":null,"outputs":[]}]}