{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceType":"competition","sourceId":112509,"databundleVersionId":14254895}],"dockerImageVersionId":31328,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\ndf = pd.read_csv(\"/kaggle/input/competitions/csiro-biomass/train.csv\")\ndf","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-24T00:10:52.161344Z","iopub.execute_input":"2026-03-24T00:10:52.161828Z","iopub.status.idle":"2026-03-24T00:10:52.194114Z","shell.execute_reply.started":"2026-03-24T00:10:52.161763Z","shell.execute_reply":"2026-03-24T00:10:52.193107Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Make sure you KEEP the path column when assigning names\ndf.columns = [\n    \"sample_id\",\n    \"path\",\n    \"Sampling_Date\",\n    \"State\",\n    \"Species\",\n    \"Pre_GSHH_NDVI\",\n    \"Height_Ave_cm\",\n    \"target_name\",\n    \"target\"\n]\n\n# Drop ID if you want\ndf = df.drop(columns=[\"sample_id\"])\n\n# Pivot correctly\npivot_df = df.pivot_table(\n    index=\"path\",\n    columns=\"target_name\",\n    values=\"target\"\n)\n\npivot_df = pivot_df.reset_index()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-24T00:10:52.195754Z","iopub.execute_input":"2026-03-24T00:10:52.196197Z","iopub.status.idle":"2026-03-24T00:10:52.215387Z","shell.execute_reply.started":"2026-03-24T00:10:52.196164Z","shell.execute_reply":"2026-03-24T00:10:52.214439Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pivot_df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-24T00:10:52.216572Z","iopub.execute_input":"2026-03-24T00:10:52.216917Z","iopub.status.idle":"2026-03-24T00:10:52.235063Z","shell.execute_reply.started":"2026-03-24T00:10:52.216886Z","shell.execute_reply":"2026-03-24T00:10:52.233983Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from torch.utils.data import Dataset , DataLoader\nfrom PIL import Image\nimport torch\nimport torchvision.transforms as transforms","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-24T00:10:52.237283Z","iopub.execute_input":"2026-03-24T00:10:52.237542Z","iopub.status.idle":"2026-03-24T00:10:52.249884Z","shell.execute_reply.started":"2026-03-24T00:10:52.237513Z","shell.execute_reply":"2026-03-24T00:10:52.248888Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class GrassDataset(Dataset):\n    def __init__(self, dataframe, root_dir=\"\", transform=None):\n        self.df = dataframe\n        self.root_dir = root_dir\n        self.transform = transform\n        \n        self.paths = self.df[\"path\"].values\n        self.labels = self.df.drop(columns=[\"path\"]).values.astype(\"float32\")\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        # Add root here\n        img_path = self.root_dir + self.paths[idx]\n\n        image = Image.open(img_path).convert(\"RGB\")\n\n        if self.transform:\n            image = self.transform(image)\n\n        label = torch.tensor(self.labels[idx])\n\n        return image, label","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-24T00:10:52.251533Z","iopub.execute_input":"2026-03-24T00:10:52.251947Z","iopub.status.idle":"2026-03-24T00:10:52.261267Z","shell.execute_reply.started":"2026-03-24T00:10:52.251898Z","shell.execute_reply":"2026-03-24T00:10:52.260432Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"transform = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.ToTensor(),  # converts to [0,1] tensor\n])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-24T00:10:52.262972Z","iopub.execute_input":"2026-03-24T00:10:52.263333Z","iopub.status.idle":"2026-03-24T00:10:52.279228Z","shell.execute_reply.started":"2026-03-24T00:10:52.263292Z","shell.execute_reply":"2026-03-24T00:10:52.277929Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dataset = GrassDataset(\n    pivot_df,\n    root_dir=\"/kaggle/input/competitions/csiro-biomass/\",\n    transform=transform\n)\n\ndataloader = DataLoader(\n    dataset,\n    batch_size=32,\n    shuffle=True,\n    num_workers=2\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-24T00:10:52.280903Z","iopub.execute_input":"2026-03-24T00:10:52.281568Z","iopub.status.idle":"2026-03-24T00:10:52.298919Z","shell.execute_reply.started":"2026-03-24T00:10:52.281503Z","shell.execute_reply":"2026-03-24T00:10:52.297760Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"images, labels = next(iter(dataloader))\n\nprint(images.shape)  # (32, 3, 224, 224)\nprint(labels.shape)  # (32, 5)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-24T00:10:52.300107Z","iopub.execute_input":"2026-03-24T00:10:52.300514Z","iopub.status.idle":"2026-03-24T00:10:56.775010Z","shell.execute_reply.started":"2026-03-24T00:10:52.300470Z","shell.execute_reply":"2026-03-24T00:10:56.773833Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nclass ImageClassifier(nn.Module):\n    def __init__(self, num_classes):\n        super(ImageClassifier, self).__init__()\n\n        self.conv = nn.Sequential(\n            nn.Conv2d(3, 32, 3, padding=1),   # input: RGB\n            nn.ReLU(),\n            nn.MaxPool2d(2,2),\n\n            nn.Conv2d(32, 64, 3, padding=1),\n            nn.ReLU(),\n            nn.MaxPool2d(2,2)\n        )\n\n        self.fc = nn.Sequential(\n            nn.Linear(64 * 56 * 56, 256),     # assumes 224×224 images\n            nn.ReLU(),\n            nn.Linear(256, num_classes)        # logits\n        )\n\n    def forward(self, x):\n        x = self.conv(x)\n        x = x.view(x.size(0), -1)  # flatten\n        x = self.fc(x)\n        return F.softmax(x, dim=1)  # return percentages\n\nmodel = ImageClassifier(num_classes=5)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-24T00:10:56.777222Z","iopub.execute_input":"2026-03-24T00:10:56.777620Z","iopub.status.idle":"2026-03-24T00:10:57.218945Z","shell.execute_reply.started":"2026-03-24T00:10:56.777578Z","shell.execute_reply":"2026-03-24T00:10:57.217524Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"criterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n\nfor imgs, labels in dataloader:\n    optimizer.zero_grad()\n\n    logits = model(imgs)        # raw scores\n    loss = criterion(logits, labels)\n\n    loss.backward()\n    optimizer.step()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-24T00:10:57.222412Z","iopub.execute_input":"2026-03-24T00:10:57.222809Z","iopub.status.idle":"2026-03-24T00:12:04.249121Z","shell.execute_reply.started":"2026-03-24T00:10:57.222774Z","shell.execute_reply":"2026-03-24T00:12:04.248057Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from PIL import Image\nimg_path = \"/kaggle/input/competitions/csiro-biomass/test/ID1001187975.jpg\"\n\nimg = Image.open(img_path).convert(\"RGB\")\nimport torchvision.transforms as transforms\n\ntransform = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.ToTensor()\n])\n\ntensor_img = transform(img).unsqueeze(0)   # shape: [1, 3, 224, 224]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-24T00:12:04.250923Z","iopub.execute_input":"2026-03-24T00:12:04.251244Z","iopub.status.idle":"2026-03-24T00:12:04.325848Z","shell.execute_reply.started":"2026-03-24T00:12:04.251205Z","shell.execute_reply":"2026-03-24T00:12:04.324766Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\nimport pandas as pd\nimport torch\nfrom PIL import Image\nimport torchvision.transforms as transforms\n\nsample_id = \"ID1001187975\"\ntarget_names = [\n    \"Dry_Clover_g\",\n    \"Dry_Dead_g\",\n    \"Dry_Green_g\",\n    \"Dry_Total_g\",\n    \"GDM_g\"\n]\n\n# Load image\nimg = Image.open(img_path).convert(\"RGB\")\n\ntransform = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.ToTensor()\n])\n\ntensor_img = transform(img).unsqueeze(0)\n\n# Predict\nmodel.eval()\nwith torch.no_grad():\n    probs = model(tensor_img).squeeze().tolist()\n\n# Prepare CSV rows\nrows = []\nfor name, value in zip(target_names, probs):\n    rows.append({\n        \"sample_id\": f\"{sample_id}__{name}\",\n        \"target\": value\n    })\n\ndf = pd.DataFrame(rows)\ndf.to_csv(\"prediction_output.csv\", index=False)\n\nprint(\"Saved prediction_output.csv\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-24T00:13:02.216931Z","iopub.execute_input":"2026-03-24T00:13:02.217831Z","iopub.status.idle":"2026-03-24T00:13:02.318749Z","shell.execute_reply.started":"2026-03-24T00:13:02.217791Z","shell.execute_reply":"2026-03-24T00:13:02.317752Z"}},"outputs":[],"execution_count":null}]}