{"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":101330,"databundleVersionId":12350302,"sourceType":"competition"}],"dockerImageVersionId":31040,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np \nimport pandas as pd \nfrom PIL import Image\nfrom torch.utils.data import Dataset\nfrom torchvision import transforms\nimport torchvision.models as models\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nimport os\n\n#no transfer learning\n#limit model\n#only black and white","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-05-17T22:43:37.567010Z","iopub.execute_input":"2025-05-17T22:43:37.567678Z","execution_failed":"2025-05-17T22:46:42.316Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"x\")","metadata":{"trusted":true,"execution":{"execution_failed":"2025-05-17T22:46:42.316Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class ImageCSVDataset(Dataset):\n    def __init__(self, csv_file, root_dir, transform=None, label_map=None, is_test=False):\n        self.df = pd.read_csv(csv_file)\n        self.root_dir = root_dir  \n        self.transform = transform\n        self.label_map = label_map\n        self.is_test = is_test\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        row = self.df.iloc[idx]\n        rel_path = self.df.iloc[idx]['path']  \n        img_path = os.path.join(self.root_dir, rel_path)\n        \n        image = Image.open(img_path).convert('RGB')\n        \n        \n        if self.transform:\n            image = self.transform(image)\n\n        if self.is_test:\n            image_id = int(row['ID'])\n            print(image_id)\n            return image, image_id  # useful for mapping back to submission\n        else:\n            label = self.label_map.get(row.get(\"biome_type\", -1), -1)\n            return image, label if label != -1 else row['path']\n\n\n\ntrain_df = pd.read_csv(\"/kaggle/input/acm-ai-hack/train.csv\")\n\n\ntransform = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406],\n                         std=[0.229, 0.224, 0.225]),\n    transforms.Grayscale(num_output_channels=1)\n])\n\nclass_names = sorted(train_df['biome_type'].unique())\nprint(f\"Number of classes: {len(class_names)}\")\nlabel2idx = {label: idx for idx, label in enumerate(class_names)}\n\ntrain_dataset = ImageCSVDataset(\n    csv_file=\"/kaggle/input/acm-ai-hack/train.csv\",\n    root_dir=\"/kaggle/input/acm-ai-hack/train/\",\n    transform=transform,\n    label_map=label2idx\n   \n)","metadata":{"trusted":true,"execution":{"execution_failed":"2025-05-17T22:46:42.317Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_dataset = ImageCSVDataset(\n    csv_file=\"/kaggle/input/acm-ai-hack/train.csv\",\n    root_dir=\"/kaggle/input/acm-ai-hack/train/\",\n    transform=transform,\n    label_map=label2idx\n   \n)","metadata":{"trusted":true,"execution":{"execution_failed":"2025-05-17T22:46:42.317Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport torchvision.transforms.functional as F\nexample_img, example_label = train_dataset[1]\n\n# Print out the shape and label\nprint(f\"Image shape: {example_img.shape}\")  # Should be [1, 224, 224] if grayscale\nprint(f\"Label: {example_label}\")\n# Convert back to PIL image for display\nimg_pil = F.to_pil_image(example_img)\n\nplt.imshow(img_pil, cmap='gray')  # use cmap='gray' since image is grayscale\n# Create a reverse map: label index to class name\nidx2label = {v: k for k, v in label2idx.items()}\n\n# Get the original label name\nlabel_name = idx2label.get(example_label, \"Unknown\")\nplt.title(f\"Label: {example_label}, {label_name}\")\n\nplt.axis('off')\nplt.show()","metadata":{"trusted":true,"execution":{"execution_failed":"2025-05-17T22:46:42.317Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch.nn.functional as F\nclass SimpleCNN(nn.Module):\n    def __init__(self, num_classes):\n        super(SimpleCNN, self).__init__()\n        ''''Hint: this is where you define your convolution, pool, and feed forward linears. You can use \n        nn.Conv2d, which takes the number of channels, output channels, kernel, and padding,and similarly, the MaxPool2d and nn.Linear functions\n        Once we've performed out convolutions, we can input them into our linear layers. Note that by the end of our layers, our goal\n        is to map our[1, 224, 224] input into a [10x1] vector outputting the probabilities for each class'''\n        self.conv1 = nn.Conv2d(in_channels=1, out_channels=64, kernel_size=3, padding=1)\n        self.conv2 = nn.Conv2d(64, 128, 3, padding=1)\n\n        self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)\n\n        self.conv3 = nn.Conv2d(128, 256, kernel_size=3, padding=1)\n        self.conv4 = nn.Conv2d(256, 256, kernel_size=3, padding=1)\n        self.pool2 = nn.MaxPool2d(2, 2)  # 56x56\n\n        self.conv5 = nn.Conv2d(256, 512, kernel_size=3, padding=1)\n        self.conv6 = nn.Conv2d(512, 512, kernel_size=3, padding=1)\n        self.pool3 = nn.MaxPool2d(2, 2)  # 28x28\n\n        # self.fc1 = nn.Linear(32 * 56 * 56, 128)  # For 224x224 input images\n        # self.fc2 = nn.Linear(128, num_classes)\n\n        self.fc1 = nn.Linear(512 * 28 * 28, 1024)\n        self.dropout = nn.Dropout(0.5)\n        self.fc2 = nn.Linear(1024, num_classes)\n\n        #resnet\n\n    # def forward(self, x):\n    #     x = self.pool(nn.functional.relu(self.conv1(x)))  # -> [batch, 16, 112, 112]\n    #     x = self.pool(nn.functional.relu(self.conv2(x)))  # -> [batch, 32, 56, 56]\n    #     x = self.pool(nn.functional.relu(self.conv3(x))) \n    #     x = self.pool(nn.functional.relu(self.conv4(x))) \n    #     x = self.pool(nn.functional.relu(self.conv5(x)))\n    #     x = self.pool(nn.functional.relu(self.conv6(x)))\n\n    #     x = x.view(-1, 512 * 28 * 28)           # Flatten\n    #     x = nn.functional.relu(self.fc1(x))\n    #     #add?\n    #     x=self.dropout(x)\n    #     x = self.fc2(x)\n    #     return x\n\n\n    def forward(self, x):\n        # Block 1\n        x = F.relu(self.conv1(x))\n        x = F.relu(self.conv2(x)) #error here\n        x = self.pool1(x)          # shape: (B, 32, 112, 112)\n\n        # Block 2\n        x = F.relu(self.conv3(x))\n        x = F.relu(self.conv4(x))\n        x = self.pool2(x)          # shape: (B, 128, 56, 56)\n\n        # Block 3\n        x = F.relu(self.conv5(x))\n        x = F.relu(self.conv6(x))\n        x = self.pool3(x)          # shape: (B, 512, 28, 28)\n\n        # Flatten & fully-connected\n        x = x.view(x.size(0), -1)  # (B, 512·28·28)\n        x = F.relu(self.fc1(x))\n        x = self.dropout(x)\n        return self.fc2(x)\n\n","metadata":{"trusted":true,"execution":{"execution_failed":"2025-05-17T22:46:42.317Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nfrom torch.utils.data import random_split\nimport torch\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\n\nnum_classes = len(label2idx)\nmodel = SimpleCNN(num_classes).to(device)\n\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=0.001)","metadata":{"trusted":true,"execution":{"execution_failed":"2025-05-17T22:46:42.317Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nfrom torch.utils.data import random_split\nimport torch\n\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\ntrain_size = int(0.8 * len(train_dataset))\nval_size = len(train_dataset) - train_size\n\ntrain_dataset, val_dataset = random_split(train_dataset, [train_size, val_size])\n\ndef train_one_epoch(model, dataloader):\n    model.train()\n    total_loss = 0\n\n    for batch in dataloader:\n        imgs, labels = batch  \n        imgs = imgs.to(device)\n        labels = labels.to(device)\n\n        optimizer.zero_grad()\n        outputs = model(imgs)\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimizer.step()\n\n        total_loss += loss.item()\n\n    return total_loss / len(dataloader)\n\n\ndef evaluate(model, dataloader):\n    model.eval()\n    correct, total = 0, 0\n\n    with torch.no_grad():\n        for batch in dataloader:\n            imgs, labels = batch  \n            imgs = imgs.to(device)\n            labels = labels.to(device)\n            outputs = model(imgs)\n            _, preds = torch.max(outputs, 1)\n            correct += (preds == labels).sum().item()\n            total += labels.size(0)\n\n    return correct/total","metadata":{"trusted":true,"execution":{"execution_failed":"2025-05-17T22:46:42.317Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tqdm.auto import tqdm\nfrom torch.utils.data import DataLoader\n\ntrain_loader = DataLoader(train_dataset, batch_size=32, shuffle=True, num_workers=2)\nval_loader = DataLoader(val_dataset, batch_size=32, shuffle=False, num_workers=2)\n\nEPOCHS = 1\n\nfor epoch in tqdm(range(EPOCHS)):\n    train_loss = train_one_epoch(model, train_loader)\n    val_acc = evaluate(model, val_loader)\n    print(f\"Epoch {epoch+1}: Train Loss = {train_loss:.4f}, Val Acc = {val_acc:.2%}\")","metadata":{"trusted":true,"execution":{"execution_failed":"2025-05-17T22:46:42.317Z"}},"outputs":[],"execution_count":null}]}