{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":3649,"databundleVersionId":46718,"sourceType":"competition"}],"dockerImageVersionId":31040,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# ✅ 1. Setup\n!pip install timm py7zr -q\n\nimport os\nimport time\nimport pandas as pd\nimport numpy as np\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import Dataset, DataLoader, random_split\nfrom torchvision import transforms, models\nfrom PIL import Image\nimport timm\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfrom sklearn.metrics import classification_report, confusion_matrix\n\n# ✅ 2. Extract Dataset\nimport py7zr\n\nos.makedirs(\"/kaggle/working/train\", exist_ok=True)\nos.makedirs(\"/kaggle/working/test\", exist_ok=True)\n\nwith py7zr.SevenZipFile(\"/kaggle/input/cifar-10/train.7z\", mode='r') as z:\n    z.extractall(path=\"/kaggle/working/train\")\n\nwith py7zr.SevenZipFile(\"/kaggle/input/cifar-10/test.7z\", mode='r') as z:\n    z.extractall(path=\"/kaggle/working/test\")\n\n# ✅ 3. Custom Dataset Class\n\nlabels_df = pd.read_csv(\"/kaggle/input/cifar-10/trainLabels.csv\")\ntrain_image_folder = \"/kaggle/working/train/train\"\n\ntransform = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.ToTensor(),\n    transforms.Normalize((0.5,), (0.5,))\n])\n\nclass CIFAR10CustomDataset(Dataset):\n    def __init__(self, dataframe, image_folder, transform=None):\n        self.dataframe = dataframe\n        self.image_folder = image_folder\n        self.transform = transform\n        self.classes = sorted(self.dataframe.label.unique())\n        self.class_to_idx = {cls: i for i, cls in enumerate(self.classes)}\n\n    def __len__(self):\n        return len(self.dataframe)\n\n    def __getitem__(self, idx):\n        img_name = self.dataframe.iloc[idx, 0]\n        label = self.class_to_idx[self.dataframe.iloc[idx, 1]]\n        img_path = os.path.join(self.image_folder, f\"{img_name}.png\")\n        image = Image.open(img_path).convert(\"RGB\")\n        if self.transform:\n            image = self.transform(image)\n        return image, label\n\n# ✅ 4. Data Splitting\nfull_dataset = CIFAR10CustomDataset(labels_df, train_image_folder, transform)\n\ntrain_len = int(0.7 * len(full_dataset))\nval_len = int(0.2 * len(full_dataset))\ntest_len = len(full_dataset) - train_len - val_len\n\ntrain_set, val_set, test_set = random_split(full_dataset, [train_len, val_len, test_len])\n\ntrain_loader = DataLoader(train_set, batch_size=64, shuffle=True)\nval_loader = DataLoader(val_set, batch_size=64)\ntest_loader = DataLoader(test_set, batch_size=64)\n\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\n# ✅ 5. Load and Modify Models\n\ndef get_model(model_name):\n    if model_name == 'alexnet':\n        model = models.alexnet(pretrained=True)\n        model.classifier[6] = nn.Linear(4096, 10)\n    elif model_name == 'vgg':\n        model = models.vgg16(pretrained=True)\n        model.classifier[6] = nn.Linear(4096, 10)\n    elif model_name == 'resnext':\n        model = models.resnext50_32x4d(pretrained=True)\n        model.fc = nn.Linear(model.fc.in_features, 10)\n    elif model_name == 'vit':\n        model = timm.create_model('vit_base_patch16_224', pretrained=True, num_classes=10)\n    return model.to(device)\n\n# ✅ 6. Training Function\n\ndef train_model(model, name, epochs=5):\n    criterion = nn.CrossEntropyLoss()\n    optimizer = optim.Adam(model.parameters(), lr=1e-4)\n\n    train_losses, val_losses = [], []\n\n    for epoch in range(epochs):\n        model.train()\n        total_loss = 0\n        for x, y in train_loader:\n            x, y = x.to(device), y.to(device)\n            optimizer.zero_grad()\n            outputs = model(x)\n            loss = criterion(outputs, y)\n            loss.backward()\n            optimizer.step()\n            total_loss += loss.item()\n        train_losses.append(total_loss / len(train_loader))\n\n        # Validation\n        model.eval()\n        val_loss = 0\n        correct = 0\n        total = 0\n        with torch.no_grad():\n            for x, y in val_loader:\n                x, y = x.to(device), y.to(device)\n                outputs = model(x)\n                loss = criterion(outputs, y)\n                val_loss += loss.item()\n                _, predicted = outputs.max(1)\n                total += y.size(0)\n                correct += predicted.eq(y).sum().item()\n        val_acc = correct / total\n        val_losses.append(val_loss / len(val_loader))\n        print(f\"{name.upper()} | Epoch {epoch+1}: Train Loss={train_losses[-1]:.4f}, Val Acc={val_acc:.4f}\")\n    \n    return train_losses, val_losses\n\n# ✅ 7. Evaluation Function\n\ndef evaluate_model(model, name):\n    model.eval()\n    y_true, y_pred = [], []\n    with torch.no_grad():\n        for x, y in test_loader:\n            x = x.to(device)\n            outputs = model(x)\n            _, preds = outputs.max(1)\n            y_true.extend(y.cpu().numpy())\n            y_pred.extend(preds.cpu().numpy())\n\n    print(f\"Classification Report for {name.upper()}\")\n    print(classification_report(y_true, y_pred, target_names=full_dataset.classes))\n\n    cm = confusion_matrix(y_true, y_pred)\n    plt.figure(figsize=(8,6))\n    sns.heatmap(cm, annot=True, fmt='d', xticklabels=full_dataset.classes, yticklabels=full_dataset.classes, cmap=\"Blues\")\n    plt.title(f\"Confusion Matrix - {name.upper()}\")\n    plt.xlabel(\"Predicted\")\n    plt.ylabel(\"True\")\n    plt.show()\n\n# ✅ 8. Train All Models & Compare\n\nresults = {}\nmodels_to_train = ['alexnet', 'vgg', 'resnext', 'vit']\n\nfor model_name in models_to_train:\n    print(f\"\\n----- Training {model_name.upper()} -----\")\n    model = get_model(model_name)\n    start = time.time()\n    train_losses, val_losses = train_model(model, model_name)\n    duration = time.time() - start\n\n    # Inference time\n    dummy = torch.randn(1, 3, 224, 224).to(device)\n    t0 = time.time()\n    for _ in range(10):\n        _ = model(dummy)\n    inference_time = (time.time() - t0) / 10\n\n    results[model_name] = {\n        \"model\": model,\n        \"train_loss\": train_losses,\n        \"val_loss\": val_losses,\n        \"train_time_sec\": round(duration, 2),\n        \"inference_time_ms\": round(inference_time * 1000, 2),\n        \"params_m\": round(sum(p.numel() for p in model.parameters()) / 1e6, 2)\n    }\n\n    evaluate_model(model, model_name)\n\n # ✅ 9. Visualization & Summary\n\ndf = pd.DataFrame({\n    name.upper(): {\n        'Train Time (s)': res['train_time_sec'],\n        'Inference Time (ms)': res['inference_time_ms'],\n        'Params (M)': res['params_m']\n    } for name, res in results.items()\n}).T\n\nprint(\"📊 Model Comparison Summary:\")\ndisplay(df)\n\ndf[['Train Time (s)', 'Inference Time (ms)']].plot(kind='bar', figsize=(10,5))\nplt.title(\"Model Training & Inference Time\")\nplt.ylabel(\"Time\")\nplt.grid(True)\nplt.show()","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}