{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":112509,"databundleVersionId":14254895,"sourceType":"competition"}],"dockerImageVersionId":31192,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport os\nfrom PIL import Image\nfrom tqdm import tqdm\n\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\n\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.metrics import r2_score\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T16:57:01.933940Z","iopub.execute_input":"2025-11-24T16:57:01.934273Z","iopub.status.idle":"2025-11-24T16:57:01.939164Z","shell.execute_reply.started":"2025-11-24T16:57:01.934246Z","shell.execute_reply":"2025-11-24T16:57:01.938487Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df = pd.read_csv('/kaggle/input/csiro-biomass/train.csv')\ntest_df = pd.read_csv('/kaggle/input/csiro-biomass/test.csv')\n\nle_target = LabelEncoder()\ntrain_df['target_name_enc'] = le_target.fit_transform(train_df['target_name'])\ntest_df['target_name_enc'] = le_target.transform(test_df['target_name'])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T16:57:01.940334Z","iopub.execute_input":"2025-11-24T16:57:01.940584Z","iopub.status.idle":"2025-11-24T16:57:01.970109Z","shell.execute_reply.started":"2025-11-24T16:57:01.940563Z","shell.execute_reply":"2025-11-24T16:57:01.969227Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class BiomassDataset(Dataset):\n    def __init__(self, df, img_base_path, transform=None, train=True):\n        self.df = df\n        self.img_base_path = img_base_path\n        self.transform = transform\n        self.train = train\n        \n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, idx):\n        row = self.df.iloc[idx]\n        img_path = os.path.join(self.img_base_path, row['image_path'])\n        image = Image.open(img_path).convert('RGB')\n        if self.transform:\n            image = self.transform(image)\n        \n        if self.train:\n            target = torch.tensor(row['target'], dtype=torch.float32)\n            return image, target\n        else:\n            return image\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T16:57:01.970791Z","iopub.execute_input":"2025-11-24T16:57:01.970974Z","iopub.status.idle":"2025-11-24T16:57:01.977193Z","shell.execute_reply.started":"2025-11-24T16:57:01.970959Z","shell.execute_reply":"2025-11-24T16:57:01.976308Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"transform = transforms.Compose([\n    transforms.RandomResizedCrop(224, scale=(0.8, 1.0)),\n    transforms.RandomHorizontalFlip(),\n    transforms.RandomVerticalFlip(),\n    transforms.RandomRotation(15),\n    transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2),\n    transforms.ToTensor(),\n    transforms.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])\n])\n\n\n\ntrain_dataset = BiomassDataset(train_df, '/kaggle/input/csiro-biomass', transform=transform, train=True)\ntrain_loader = DataLoader(\n    train_dataset, \n    batch_size=32, \n    shuffle=True,\n    num_workers=4,  # try 2-4 for Kaggle kernels\n    pin_memory=True\n)\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T16:57:01.978871Z","iopub.execute_input":"2025-11-24T16:57:01.979149Z","iopub.status.idle":"2025-11-24T16:57:01.995790Z","shell.execute_reply.started":"2025-11-24T16:57:01.979132Z","shell.execute_reply":"2025-11-24T16:57:01.995191Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class SimpleCNN(nn.Module):\n    def __init__(self):\n        super().__init__()\n\n        def block(in_c, out_c):\n            return nn.Sequential(\n                nn.Conv2d(in_c, out_c, 3, padding=1),\n                nn.BatchNorm2d(out_c),\n                nn.ReLU(),\n                nn.Conv2d(out_c, out_c, 3, padding=1),\n                nn.BatchNorm2d(out_c),\n                nn.ReLU(),\n                nn.MaxPool2d(2)\n            )\n\n        self.features = nn.Sequential(\n            block(3, 32),\n            block(32, 64),\n            block(64, 128),\n            block(128, 256),\n            block(256, 512),\n            nn.AdaptiveAvgPool2d((1,1)),\n            nn.Dropout(0.4)\n        )\n\n        self.fc = nn.Linear(512, 1)\n\n    def forward(self, x):\n        x = self.features(x)\n        x = x.view(x.size(0), -1)\n        return self.fc(x).squeeze(1)\n\n\ndevice = 'cuda' if torch.cuda.is_available() else 'cpu'\nmodel = SimpleCNN().to(device)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T16:57:01.996609Z","iopub.execute_input":"2025-11-24T16:57:01.996791Z","iopub.status.idle":"2025-11-24T16:57:02.061580Z","shell.execute_reply.started":"2025-11-24T16:57:01.996776Z","shell.execute_reply":"2025-11-24T16:57:02.060935Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"criterion = nn.SmoothL1Loss()\noptimizer = torch.optim.AdamW(model.parameters(), lr=1e-3, weight_decay=1e-4)\nscheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', patience=3, factor=0.5)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T16:57:02.062425Z","iopub.execute_input":"2025-11-24T16:57:02.062683Z","iopub.status.idle":"2025-11-24T16:57:02.068017Z","shell.execute_reply.started":"2025-11-24T16:57:02.062661Z","shell.execute_reply":"2025-11-24T16:57:02.067218Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"epochs = 30\nfor epoch in range(epochs):\n    model.train()\n    running_loss = 0\n    for images, targets in tqdm(train_loader, desc=f\"Epoch {epoch+1}\"):\n        images, targets = images.to(device), targets.to(device)\n        \n        optimizer.zero_grad()\n        outputs = model(images)\n        loss = criterion(outputs, targets)\n        loss.backward()\n        torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=5)\n        optimizer.step()\n        \n        running_loss += loss.item() * images.size(0)\n    \n    epoch_loss = running_loss / len(train_dataset)\n    scheduler.step(epoch_loss)\n    \n    print(f\"Epoch {epoch+1}/{epochs}, Loss: {epoch_loss:.4f}\")\n    for param_group in optimizer.param_groups:\n        print(f\"Current LR: {param_group['lr']}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T16:57:02.068760Z","iopub.execute_input":"2025-11-24T16:57:02.068940Z","iopub.status.idle":"2025-11-24T17:01:00.116156Z","shell.execute_reply.started":"2025-11-24T16:57:02.068926Z","shell.execute_reply":"2025-11-24T17:01:00.115127Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_dataset = BiomassDataset(test_df, '/kaggle/input/csiro-biomass', transform=transform, train=False)\ntest_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)\n\nmodel.eval()\npreds = []\nwith torch.no_grad():\n    for images in test_loader:\n        images = images.to(device)\n        outputs = model(images)\n        preds.extend(outputs.cpu().numpy())\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T17:01:00.118493Z","iopub.execute_input":"2025-11-24T17:01:00.118778Z","iopub.status.idle":"2025-11-24T17:01:00.506641Z","shell.execute_reply.started":"2025-11-24T17:01:00.118748Z","shell.execute_reply":"2025-11-24T17:01:00.505939Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission = pd.DataFrame({\n    'sample_id': test_df['sample_id'],\n    'target': preds\n})\nsubmission.to_csv('submission.csv', index=False)\nprint(\"Submission file created: submission.csv\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-24T17:01:00.507391Z","iopub.execute_input":"2025-11-24T17:01:00.507613Z","iopub.status.idle":"2025-11-24T17:01:00.519855Z","shell.execute_reply.started":"2025-11-24T17:01:00.507584Z","shell.execute_reply":"2025-11-24T17:01:00.518733Z"}},"outputs":[],"execution_count":null}]}