{"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"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":3004,"databundleVersionId":861823,"sourceType":"competition"}],"dockerImageVersionId":31089,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"from torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\nfrom torchsummary import summary\nimport torch.optim as optim\nimport torch.nn as nn\nimport pandas as pd\nimport numpy as np\nimport torch\nimport timm","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Custom dataset class for MNIST CSV files\nclass MNISTDataset(Dataset):\n    def __init__(self, dataframe, is_train=True, transform=None):\n        # Store training flag and transform\n        self.is_train = is_train\n        self.transform = transform\n\n        # Convert dataframe to numpy\n        data = dataframe.values\n\n        # Separate labels and images if training\n        if self.is_train:\n            self.labels = data[:, 0].astype(np.int64)\n            self.images = data[:, 1:].astype(np.float32).reshape(-1, 28, 28)\n        else:\n            self.labels = None\n            self.images = data.astype(np.float32).reshape(-1, 28, 28)\n\n    def __len__(self):\n        return len(self.images)\n\n    def __getitem__(self, idx):\n        image = self.images[idx]\n    \n        # Convert to tensor with a channel dimension\n        image = torch.tensor(image).unsqueeze(0)  # shape: (1, 28, 28)\n    \n        if self.transform:\n            image = self.transform(image)\n    \n        if self.is_train:\n            label = torch.tensor(self.labels[idx])\n            return image, label\n        else:\n            return image","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Model using timm\nclass Model(nn.Module):\n    def __init__(self, num_classes=10, pretrained=True):\n        super(Model, self).__init__()\n\n        # Load timm model\n        self.model = timm.create_model(\n            \"regnety_004\",\n            pretrained=pretrained,\n            in_chans=1,\n            num_classes=num_classes,\n            drop_rate=0.5,\n        )\n\n    def forward(self, x):\n        return self.model(x)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Training function\ndef train_model(model, train_loader, criterion, optimizer, device, epochs=20):\n    model.train()\n    for epoch in range(epochs):\n        total_loss = 0\n        for images, labels in train_loader:\n            images, labels = images.to(device), labels.to(device)\n\n            optimizer.zero_grad()\n            outputs = model(images)\n            loss = criterion(outputs, labels)\n            loss.backward()\n            optimizer.step()\n\n            total_loss += loss.item()\n\n        print(f\"Epoch [{epoch+1}/{epochs}], Loss: {total_loss/len(train_loader):.4f}\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Prediction function\ndef predict(model, test_loader, device):\n    model.eval()\n    predictions = []\n    with torch.no_grad():\n        for images in test_loader:\n            images = images.to(device)\n            outputs = model(images)\n            _, preds = torch.max(outputs, 1)\n            predictions.extend(preds.cpu().numpy())\n    return predictions","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Main function\ndef main():\n    # Load datasets\n    train_df = pd.read_csv(\"/kaggle/input/digit-recognizer/train.csv\")\n    test_df = pd.read_csv(\"/kaggle/input/digit-recognizer/test.csv\")\n\n    # Define transforms\n    train_transform = transforms.Compose([\n        # Random affine transformation (rotation, shift, shear, zoom)\n        transforms.RandomAffine(\n            degrees=20,\n            translate=(0.2, 0.2),\n            shear=15,\n            scale=(0.9, 1.1)\n        ),\n        transforms.ConvertImageDtype(torch.float32),\n        transforms.Normalize((0.5,), (0.5,))\n    ])\n    \n    test_transform = transforms.Compose([\n        transforms.ConvertImageDtype(torch.float32),\n        transforms.Normalize((0.5,), (0.5,))\n    ])\n\n    # Create dataset and dataloader\n    train_dataset = MNISTDataset(train_df, is_train=True, transform=train_transform)\n    test_dataset = MNISTDataset(test_df, is_train=False, transform=test_transform)\n\n    # ✅ Use num_workers=0 to avoid Windows pickling issue\n    train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True, num_workers=0)\n    test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False, num_workers=0)\n\n    # Set device\n    device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\n    # Initialize timm ResNet14t model\n    model = Model(num_classes=10, pretrained=True).to(device)\n\n    # ✅ Print model summary\n    summary(model, input_size=(1, 28, 28))\n\n    # Loss and optimizer\n    criterion = nn.CrossEntropyLoss()\n    optimizer = optim.AdamW(model.parameters(), lr=1e-4, weight_decay=1e-3)\n\n    # Train\n    train_model(model, train_loader, criterion, optimizer, device)\n\n    # Predict\n    predictions = predict(model, test_loader, device)\n\n    # Save submission file\n    submission = pd.DataFrame({\n        \"ImageId\": np.arange(1, len(predictions) + 1),\n        \"Label\": predictions\n    })\n    submission.to_csv(\"/kaggle/working/submission.csv\", index=False)\n    print(\"Saved submission.csv\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Run main\nif __name__ == \"__main__\":\n    main()","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null}]}