{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":3004,"databundleVersionId":861823,"sourceType":"competition"}],"dockerImageVersionId":30786,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# Import necessary libraries\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\nfrom torch.utils.data import DataLoader, TensorDataset\n\n# Load and preprocess the data\ndata = pd.read_csv('/kaggle/input/digit-recognizer/train.csv')\n\n# Separate features and labels\nX = data.iloc[:, 1:].values  # pixel values\nY = data.iloc[:, 0].values   # labels (0-9)\n\n# Normalize pixel values to be between 0 and 1\nX = X / 255.0\n\n# Convert data to torch tensors\nX = torch.tensor(X, dtype=torch.float32)\nY = torch.tensor(Y, dtype=torch.long)\n\n# Split into training and development sets\nX_train, X_dev, Y_train, Y_dev = train_test_split(X, Y, test_size=0.2, random_state=42)\n\n# Create DataLoader for batching\ntrain_data = TensorDataset(X_train, Y_train)\ntrain_loader = DataLoader(train_data, batch_size=32, shuffle=True)\n\ndev_data = TensorDataset(X_dev, Y_dev)\ndev_loader = DataLoader(dev_data, batch_size=32, shuffle=False)","metadata":{"_uuid":"1c312e4d-af06-4ebc-90ae-957cd8fe7488","_cell_guid":"15415dd8-c617-4457-abd8-476744f7c198","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-10-19T14:44:58.767779Z","iopub.execute_input":"2024-10-19T14:44:58.768370Z","iopub.status.idle":"2024-10-19T14:45:03.106620Z","shell.execute_reply.started":"2024-10-19T14:44:58.768327Z","shell.execute_reply":"2024-10-19T14:45:03.105148Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Shallow Neural Network \nclass SNN(nn.Module):\n    def __init__(self):\n        super(SNN, self).__init__()\n        self.fc1 = nn.Linear(784, 10)\n        self.fc2 = nn.Linear(10, 10)\n\n    def forward(self, x):\n        x = F.relu(self.fc1(x))\n        x = self.fc2(x)\n        return x\n\n# Convolutional Neural Network\nclass CNN(nn.Module):\n    def __init__(self):\n        super(CNN, self).__init__()\n        self.conv1 = nn.Conv2d(in_channels=1, out_channels=15, kernel_size=3, stride=2)\n        self.conv2 = nn.Conv2d(in_channels=15, out_channels=15, kernel_size=3, stride=2)\n        self.conv3 = nn.Conv2d(in_channels=15, out_channels=15, kernel_size=3, stride=2)\n        # Digit pictures dimensions 28*28\n        # After Layer 1 : dimension = (28-3)/2 + 1 = 13\n        # After Layer 2 : dimension = (13-3)/2 + 1 = 6\n        # After Layer 3 : dimension = (6-3)/2 + 1 =~ 2\n        self.fc1 = nn.Linear(15 * 2 * 2, 10)\n\n    def forward(self, x):\n        x = x.view(x.size(0), 1, 28, 28)\n        x = F.relu(self.conv1(x))\n        x = F.relu(self.conv2(x))\n        x = F.relu(self.conv3(x))      \n        # Flatten and apply the fully connected layer\n        x = x.view(x.size(0), -1)\n        x = self.fc1(x)\n        \n        return x\n\n# Training function with tracking loss per epoch and accuracy on dev set\ndef train_model(model, criterion, optimizer, train_loader, dev_loader, epochs=10):\n    losses = []\n    accuracies = []\n    \n    for epoch in range(epochs):\n        running_loss = 0.0\n        model.train()\n        \n        # Training loop\n        for i, (inputs, labels) in enumerate(train_loader):\n            optimizer.zero_grad()\n\n            # Forward pass\n            outputs = model(inputs)\n            loss = criterion(outputs, labels)\n\n            # Backward pass and optimize\n            loss.backward()\n            optimizer.step()\n\n            running_loss += loss.item()\n\n        # Calculate average loss for the epoch\n        epoch_loss = running_loss / len(train_loader)\n        losses.append(epoch_loss)\n\n        # Evaluate on the dev set\n        model.eval()\n        correct = 0\n        total = 0\n        with torch.no_grad():\n            for inputs, labels in dev_loader:\n                outputs = model(inputs)\n                _, predicted = torch.max(outputs, 1)\n                total += labels.size(0)\n                correct += (predicted == labels).sum().item()\n\n        accuracy = 100 * correct / total\n        accuracies.append(accuracy)\n        \n        print(f'Epoch [{epoch+1}/{epochs}], Loss: {epoch_loss:.4f}, Dev Accuracy: {accuracy:.2f}%')\n    \n    return model, losses, accuracies","metadata":{"_uuid":"c17edd13-d6b3-4cdb-a011-300981ec4380","_cell_guid":"f8827da9-2b2c-4bb8-9ec2-130e3ee4036c","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-10-19T14:45:03.109403Z","iopub.execute_input":"2024-10-19T14:45:03.109888Z","iopub.status.idle":"2024-10-19T14:45:03.132595Z","shell.execute_reply.started":"2024-10-19T14:45:03.109840Z","shell.execute_reply":"2024-10-19T14:45:03.131154Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Initialize both models\nsnn_model = SNN()\ncnn_model = CNN()\n\n# Define loss function and optimizers\ncriterion = nn.CrossEntropyLoss()\nsnn_optimizer = optim.Adam(snn_model.parameters(), lr=0.001)\ncnn_optimizer = optim.Adam(cnn_model.parameters(), lr=0.001)\n\n# Train the SNN model and track both losses and dev accuracies\nprint(\"Training SNN...\")\nsnn_model, snn_losses, snn_accuracies = train_model(snn_model, criterion, snn_optimizer, train_loader, dev_loader, epochs=10)\n\n# Train the CNN model and track both losses and dev accuracies\nprint(\"Training CNN...\")\ncnn_model, cnn_losses, cnn_accuracies = train_model(cnn_model, criterion, cnn_optimizer, train_loader, dev_loader, epochs=10)\n\n# Plotting training loss comparison between SNN and CNN\nplt.figure(figsize=(10, 5))\nplt.plot(range(1, 11), snn_losses, label=\"SNN Loss\", marker='o')\nplt.plot(range(1, 11), cnn_losses, label=\"CNN Loss\", marker='x')\nplt.title(\"Training Loss per Epoch (SNN vs CNN)\")\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Loss\")\nplt.legend()\nplt.show()\n\n# Plotting development accuracy comparison between SNN and CNN\nplt.figure(figsize=(10, 5))\nplt.plot(range(1, 11), snn_accuracies, label=\"SNN Dev Accuracy\", marker='o')\nplt.plot(range(1, 11), cnn_accuracies, label=\"CNN Dev Accuracy\", marker='x')\nplt.title(\"Dev Set Accuracy per Epoch (SNN vs CNN)\")\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Accuracy (%)\")\nplt.legend()\nplt.show()\n\n# Evaluation function to compare accuracies (this could be for the test set or dev set)\ndef evaluate_model(model, data_loader):\n    correct = 0\n    total = 0\n    with torch.no_grad():\n        for inputs, labels in data_loader:\n            outputs = model(inputs)\n            _, predicted = torch.max(outputs, 1)\n            total += labels.size(0)\n            correct += (predicted == labels).sum().item()\n\n    return 100 * correct / total\n\n# Evaluate both models on the dev set\nsnn_dev_accuracy = evaluate_model(snn_model, dev_loader)\ncnn_dev_accuracy = evaluate_model(cnn_model, dev_loader)\n\n# Print final dev accuracy results\nprint(f'Final SNN Dev Accuracy: {snn_dev_accuracy:.2f}%')\nprint(f'Final CNN Dev Accuracy: {cnn_dev_accuracy:.2f}%')","metadata":{"_uuid":"c17edd13-d6b3-4cdb-a011-300981ec4380","_cell_guid":"f8827da9-2b2c-4bb8-9ec2-130e3ee4036c","trusted":true,"collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-10-19T14:45:03.134379Z","iopub.execute_input":"2024-10-19T14:45:03.135081Z","iopub.status.idle":"2024-10-19T14:46:27.945927Z","shell.execute_reply.started":"2024-10-19T14:45:03.135019Z","shell.execute_reply":"2024-10-19T14:46:27.944503Z"}},"outputs":[],"execution_count":null}]}