{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":112509,"databundleVersionId":14254895,"sourceType":"competition"}],"dockerImageVersionId":31236,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-12-26T16:22:20.082361Z","iopub.execute_input":"2025-12-26T16:22:20.082604Z","iopub.status.idle":"2025-12-26T16:22:21.454846Z","shell.execute_reply.started":"2025-12-26T16:22:20.082579Z","shell.execute_reply":"2025-12-26T16:22:21.453812Z"},"collapsed":true,"jupyter":{"outputs_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"TRAIN = True\n\nimport os\n\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\n%matplotlib inline\n\nfrom sklearn.model_selection import KFold, GroupKFold, StratifiedGroupKFold\n\nfrom PIL import Image\nfrom tqdm.auto import tqdm\ntqdm.pandas()\n\nDATA_ROOT = '/kaggle/input/csiro-biomass'\n\ntrain_df = pd.read_csv(f\"{DATA_ROOT}/train.csv\")\ntrain_df.head(10)\n\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-26T16:22:26.684869Z","iopub.execute_input":"2025-12-26T16:22:26.685183Z","iopub.status.idle":"2025-12-26T16:22:27.774568Z","shell.execute_reply.started":"2025-12-26T16:22:26.685156Z","shell.execute_reply":"2025-12-26T16:22:27.773689Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\ntrain_df[\"image_id\"] = train_df[\"sample_id\"].apply(\n    lambda x: x.split(\"_\")[0]\n)\ntrain_wide = train_df.pivot(\n    index=\"image_id\",\n    columns=\"target_name\",\n    values=\"target\"\n).reset_index()\n\ntrain_wide.head()\n# print(len(train_wide))\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-26T16:22:33.494809Z","iopub.execute_input":"2025-12-26T16:22:33.495164Z","iopub.status.idle":"2025-12-26T16:22:33.530986Z","shell.execute_reply.started":"2025-12-26T16:22:33.495134Z","shell.execute_reply":"2025-12-26T16:22:33.530325Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset,DataLoader\nfrom torchvision import transforms, models\nfrom PIL import Image\n\ntrain_tfms = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.RandomHorizontalFlip(),\n    transforms.ToTensor(),\n                      # normalisation can be done\n])\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(\"Using device:\", device)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-26T16:23:14.405371Z","iopub.execute_input":"2025-12-26T16:23:14.406155Z","iopub.status.idle":"2025-12-26T16:23:21.597686Z","shell.execute_reply.started":"2025-12-26T16:23:14.406124Z","shell.execute_reply":"2025-12-26T16:23:21.596884Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class BiomassDataset(Dataset):\n    def __init__(self,df,img_dir,transform=None):\n        self.df = df\n        self.img_dir = img_dir\n        self.transform = transform\n\n        self.targets = [\n            \"Dry_Green_g\",\n            \"Dry_Dead_g\",\n            \"Dry_Clover_g\",\n            \"GDM_g\",\n            \"Dry_Total_g\"\n        ]\n        print(df[self.targets].dtypes)\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self,idx):\n        row = self.df.iloc[idx]\n        img_path = f\"{self.img_dir}/{row.image_id}.jpg\"\n        image = Image.open(img_path).convert(\"RGB\")\n\n        if self.transform:\n            image = self.transform(image)\n\n        y = torch.from_numpy(\n        row[self.targets].values.astype(np.float32)\n    )\n\n        return image,y","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-26T16:23:37.979636Z","iopub.execute_input":"2025-12-26T16:23:37.979972Z","iopub.status.idle":"2025-12-26T16:23:37.986534Z","shell.execute_reply.started":"2025-12-26T16:23:37.979947Z","shell.execute_reply":"2025-12-26T16:23:37.985746Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_dataset = BiomassDataset(train_wide,\n                               img_dir = f\"{DATA_ROOT}/train\",\n                               transform=train_tfms\n)\ntrain_loader = DataLoader(train_dataset,\n                         batch_size=16,\n                         shuffle=True,\n                         num_workers=1\n                         )\nprint(train_loader)\nfor images, targets in train_loader:\n    print(images.shape)   # [B, 3, H, W]\n    print(targets.shape)  # [B, 5","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-26T16:23:42.456316Z","iopub.execute_input":"2025-12-26T16:23:42.457150Z","iopub.status.idle":"2025-12-26T16:23:48.529708Z","shell.execute_reply.started":"2025-12-26T16:23:42.457121Z","shell.execute_reply":"2025-12-26T16:23:48.528297Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = models.resnet50(weights=\"IMAGENET1K_V1\")\nmodel.fc = nn.Sequential(\n    nn.Linear(model.fc.in_features, 5),\n    nn.ReLU()\n)\nmodel = model.cuda()\ncriterion = nn.MSELoss()\noptimizer = torch.optim.AdamW(model.parameters(),lr=1e-4)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-26T16:23:53.146731Z","iopub.execute_input":"2025-12-26T16:23:53.147107Z","iopub.status.idle":"2025-12-26T16:23:54.422496Z","shell.execute_reply.started":"2025-12-26T16:23:53.147076Z","shell.execute_reply":"2025-12-26T16:23:54.421897Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for epoch in range(20):\n    model.train()\n    running_loss = 0\n    for images,targets in train_loader:\n        images = images.to(device)\n        targets = targets.to(device)\n\n        preds = model(images)\n        loss = criterion(preds,targets)\n\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        running_loss += loss.item()\n    print(f\"Epoch {epoch+1} | Loss: {running_loss/len(train_loader):.4f}\")    \n        ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-26T16:23:55.577147Z","iopub.execute_input":"2025-12-26T16:23:55.577682Z","iopub.status.idle":"2025-12-26T16:30:38.578115Z","shell.execute_reply.started":"2025-12-26T16:23:55.577656Z","shell.execute_reply":"2025-12-26T16:30:38.577111Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.eval()\nimg_path = \"/kaggle/input/csiro-biomass/test/ID1001187975.jpg\"\nimg_id = \"ID1001187975\"\nimage = Image.open(img_path).convert(\"RGB\")\nimage = train_tfms(image)\nprint(image.size())\nimage = image.unsqueeze(0)\nimage = image.to(device)\nwith torch.no_grad():\n    prediction = model(image)\nprediction    ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-26T16:33:28.333725Z","iopub.execute_input":"2025-12-26T16:33:28.334006Z","iopub.status.idle":"2025-12-26T16:33:28.728345Z","shell.execute_reply.started":"2025-12-26T16:33:28.333983Z","shell.execute_reply":"2025-12-26T16:33:28.727773Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"preds = prediction.cpu().numpy().flatten()\npreds","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-26T16:33:49.569117Z","iopub.execute_input":"2025-12-26T16:33:49.569840Z","iopub.status.idle":"2025-12-26T16:33:49.576266Z","shell.execute_reply.started":"2025-12-26T16:33:49.569810Z","shell.execute_reply":"2025-12-26T16:33:49.575426Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"targets = [\n    \"Dry_Clover_g\",\n    \"Dry_Dead_g\",\n    \"Dry_Green_g\",\n    \"Dry_Total_g\",\n    \"GDM_g\"\n]\n\nsubmission_rows = []\n\nfor name, value in zip(targets, preds):\n    submission_rows.append({\n        \"sample_id\": f\"{img_id}__{name}\",\n        \"target\": float(value)\n    })\n\nsubmission = pd.DataFrame(submission_rows)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-26T16:33:53.879809Z","iopub.execute_input":"2025-12-26T16:33:53.880262Z","iopub.status.idle":"2025-12-26T16:33:53.888306Z","shell.execute_reply.started":"2025-12-26T16:33:53.880227Z","shell.execute_reply":"2025-12-26T16:33:53.887529Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission.to_csv(\"submission.csv\", index=False)\nsubmission\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-26T16:33:56.549216Z","iopub.execute_input":"2025-12-26T16:33:56.550031Z","iopub.status.idle":"2025-12-26T16:33:56.565116Z","shell.execute_reply.started":"2025-12-26T16:33:56.549981Z","shell.execute_reply":"2025-12-26T16:33:56.564427Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}