{"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"},{"sourceId":623326,"sourceType":"modelInstanceVersion","modelInstanceId":468976,"modelId":484837}],"dockerImageVersionId":31154,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset, DataLoader\nfrom PIL import Image\nimport torchvision.transforms as T\nimport os, random, numpy as np, pandas as pd, timm\nimport matplotlib.pyplot as plt","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-31T07:52:48.722985Z","iopub.execute_input":"2025-10-31T07:52:48.723368Z","iopub.status.idle":"2025-10-31T07:52:52.081808Z","shell.execute_reply.started":"2025-10-31T07:52:48.723337Z","shell.execute_reply":"2025-10-31T07:52:52.081184Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def seed_everything(seed=42):\n    random.seed(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed_all(seed)\n    os.environ[\"PYTHONHASHSEED\"] = str(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n\nseed_everything(42)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-31T07:52:57.072098Z","iopub.execute_input":"2025-10-31T07:52:57.072740Z","iopub.status.idle":"2025-10-31T07:52:57.078802Z","shell.execute_reply.started":"2025-10-31T07:52:57.072715Z","shell.execute_reply":"2025-10-31T07:52:57.078074Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class InferenceDataset(Dataset):\n    def __init__(self, df, base_path, transform=None):\n        self.df = df\n        self.base_path = base_path\n        self.transform = transform\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.base_path, row[\"image_path\"])\n        image = Image.open(img_path).convert(\"RGB\")\n        if self.transform:\n            image = self.transform(image)\n        return image","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-31T07:53:05.542548Z","iopub.execute_input":"2025-10-31T07:53:05.543183Z","iopub.status.idle":"2025-10-31T07:53:05.549806Z","shell.execute_reply.started":"2025-10-31T07:53:05.543154Z","shell.execute_reply":"2025-10-31T07:53:05.549048Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Model\nclass MultiRegressionModel(nn.Module):\n    def __init__(self, model_name=\"efficientnet_b2\", output_dim=5):\n        super().__init__()\n        self.model = timm.create_model(model_name, pretrained=False, num_classes=output_dim)\n\n    def forward(self, x):\n        return self.model(x)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-31T07:53:23.332995Z","iopub.execute_input":"2025-10-31T07:53:23.333485Z","iopub.status.idle":"2025-10-31T07:53:23.337587Z","shell.execute_reply.started":"2025-10-31T07:53:23.333463Z","shell.execute_reply":"2025-10-31T07:53:23.337024Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def tta_inference(model, images):\n    preds = model(images)\n    preds_lr = model(torch.flip(images, dims=[3]))\n    preds_ud = model(torch.flip(images, dims=[2]))\n    preds_lrud = model(torch.flip(images, dims=[2, 3]))\n    return (preds + preds_lr + preds_ud + preds_lrud) / 4.0","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-31T07:53:30.062489Z","iopub.execute_input":"2025-10-31T07:53:30.063050Z","iopub.status.idle":"2025-10-31T07:53:30.067165Z","shell.execute_reply.started":"2025-10-31T07:53:30.063013Z","shell.execute_reply":"2025-10-31T07:53:30.066556Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def run_inference(model_paths, test_csv, base_path=\"/kaggle/input/csiro-biomass\", batch_size=8):\n    test_df = pd.read_csv(test_csv)\n    test_df = test_df[[\"sample_id\", \"image_path\"]].drop_duplicates().reset_index(drop=True)\n    test_df[\"sample_id\"] = test_df[\"sample_id\"].astype(str)\n\n    transform = T.Compose([\n        T.Resize((512, 512)),\n        T.ToTensor(),\n        T.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n    ])\n\n    dataset = InferenceDataset(test_df, base_path, transform)\n    loader = DataLoader(dataset, batch_size=batch_size, shuffle=False, num_workers=2)\n\n    device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n    results = []\n\n    for fold, model_path in enumerate(model_paths):\n        model = MultiRegressionModel(\"efficientnet_b2\", 5)\n        model.load_state_dict(torch.load(model_path, map_location=device))\n        model.to(device).eval()\n\n        preds_all = []\n        with torch.no_grad():\n            for imgs in loader:\n                imgs = imgs.to(device)\n                preds = tta_inference(model, imgs)\n                preds_all.append(preds.cpu().numpy())\n        results.append(np.concatenate(preds_all))\n\n    preds_mean = np.mean(results, axis=0)\n    out_df = pd.DataFrame(preds_mean, columns=[\"Dry_Green_g\", \"Dry_Dead_g\", \"Dry_Clover_g\", \"GDM_g\", \"Dry_Total_g\"])\n    out_df[\"sample_id\"] = test_df[\"sample_id\"]\n\n    sub = out_df.melt(id_vars=\"sample_id\", var_name=\"target_name\", value_name=\"target\")\n    sub[\"sample_id\"] = sub[\"sample_id\"].astype(str) + \"__\" + sub[\"target_name\"]\n    sub[\"target\"] = sub[\"target\"].clip(0, 200)\n    sub = sub[[\"sample_id\", \"target\"]]\n    sub.to_csv(\"submission.csv\", index=False)\n    print(\"Saved submission.csv\")\n    return sub\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-31T07:53:38.522799Z","iopub.execute_input":"2025-10-31T07:53:38.523408Z","iopub.status.idle":"2025-10-31T07:53:38.531496Z","shell.execute_reply.started":"2025-10-31T07:53:38.523385Z","shell.execute_reply":"2025-10-31T07:53:38.530712Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def visualize_samples(df, base_path, n=3):\n    import os\n    from PIL import Image\n    import matplotlib.pyplot as plt\n\n    fig, axes = plt.subplots(1, n, figsize=(15, 5))\n    for i, ax in enumerate(axes):\n        img_path = df.iloc[i][\"image_path\"]\n        if img_path.startswith(\"test/\"):\n            path = os.path.join(\"/kaggle/input/csiro-biomass\", img_path)\n        else:\n            path = os.path.join(base_path, img_path)\n        img = Image.open(path)\n        ax.imshow(img)\n        ax.axis(\"off\")\n    plt.show()\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-31T07:54:52.542217Z","iopub.execute_input":"2025-10-31T07:54:52.542539Z","iopub.status.idle":"2025-10-31T07:54:52.548122Z","shell.execute_reply.started":"2025-10-31T07:54:52.542515Z","shell.execute_reply":"2025-10-31T07:54:52.547250Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if __name__ == \"__main__\":\n    model_paths = [\n        \"/kaggle/input/biomass-prediction/transformers/default/1/model_fold0.pth\",\n        \"/kaggle/input/biomass-prediction/transformers/default/1/model_fold1.pth\",\n        \"/kaggle/input/biomass-prediction/transformers/default/1/model_fold2.pth\"\n    ]\n    sub = run_inference(model_paths, \"/kaggle/input/csiro-biomass/test.csv\")\n    visualize_samples(pd.read_csv(\"/kaggle/input/csiro-biomass/test.csv\").head(3),\n                      \"/kaggle/input/csiro-biomass/test\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-31T07:54:55.422029Z","iopub.execute_input":"2025-10-31T07:54:55.422914Z","iopub.status.idle":"2025-10-31T07:54:59.108183Z","shell.execute_reply.started":"2025-10-31T07:54:55.422880Z","shell.execute_reply":"2025-10-31T07:54:59.107409Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}