{"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":"gpu","dataSources":[{"sourceId":112509,"databundleVersionId":14254895,"sourceType":"competition"}],"dockerImageVersionId":31234,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nfrom PIL import Image\nfrom pathlib import Path\n\n\nimport tensorflow as tf\nfrom tqdm.auto import tqdm\n\n\nsns.set_style(\"whitegrid\")\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:16:56.329284Z","iopub.execute_input":"2026-01-29T16:16:56.329636Z","iopub.status.idle":"2026-01-29T16:16:56.334901Z","shell.execute_reply.started":"2026-01-29T16:16:56.329609Z","shell.execute_reply":"2026-01-29T16:16:56.334030Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"BASE_PATH = \"/kaggle/input/csiro-biomass/\"\ntrain = BASE_PATH + \"train.csv\"\ntest  = BASE_PATH + \"test.csv\"\n\ndf_train = pd.read_csv(train)\ndf_test = pd.read_csv(test)\n\ndisplay(df_train)\ndisplay(df_test)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:16:56.336132Z","iopub.execute_input":"2026-01-29T16:16:56.336542Z","iopub.status.idle":"2026-01-29T16:16:56.380904Z","shell.execute_reply.started":"2026-01-29T16:16:56.336518Z","shell.execute_reply":"2026-01-29T16:16:56.380290Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train.info()\n\nna = df_train.isna().mean().sort_values(ascending=False)\ndisplay(na[na>0])\n\ndup = df_train.duplicated(subset=[\"sample_id\",\"target_name\"]).sum()\nprint(\"Duplicate sample_id-target_name rows:\", dup)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:16:56.381865Z","iopub.execute_input":"2026-01-29T16:16:56.382097Z","iopub.status.idle":"2026-01-29T16:16:56.397600Z","shell.execute_reply.started":"2026-01-29T16:16:56.382076Z","shell.execute_reply":"2026-01-29T16:16:56.396704Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(10,5))\nsns.countplot(data=df_train, x=\"target_name\", order=df_train[\"target_name\"].value_counts().index)\nplt.xticks(rotation=20)\nplt.title(\"Training rows per target_name\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:16:56.399196Z","iopub.execute_input":"2026-01-29T16:16:56.400025Z","iopub.status.idle":"2026-01-29T16:16:56.554696Z","shell.execute_reply.started":"2026-01-29T16:16:56.399990Z","shell.execute_reply":"2026-01-29T16:16:56.553994Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"g = sns.FacetGrid(df_train, col=\"target_name\", col_wrap=3, sharex=False, sharey=False, height=3.2)\ng.map_dataframe(sns.histplot, x=\"target\", bins=40)\ng.set_titles(\"{col_name}\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:16:56.556116Z","iopub.execute_input":"2026-01-29T16:16:56.556388Z","iopub.status.idle":"2026-01-29T16:16:57.634703Z","shell.execute_reply.started":"2026-01-29T16:16:56.556359Z","shell.execute_reply":"2026-01-29T16:16:57.633762Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"wide = df_train.pivot_table(index=\"sample_id\", columns=\"target_name\", values=\"target\", aggfunc=\"mean\")\nwide.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:16:57.635650Z","iopub.execute_input":"2026-01-29T16:16:57.635937Z","iopub.status.idle":"2026-01-29T16:16:57.655248Z","shell.execute_reply.started":"2026-01-29T16:16:57.635906Z","shell.execute_reply":"2026-01-29T16:16:57.654470Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(6,5))\nsns.heatmap(wide.corr(), annot=True, fmt=\".2f\", cmap=\"coolwarm\", vmin=-1, vmax=1)\nplt.title(\"Correlation between biomass targets\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:16:57.656869Z","iopub.execute_input":"2026-01-29T16:16:57.657105Z","iopub.status.idle":"2026-01-29T16:16:57.863338Z","shell.execute_reply.started":"2026-01-29T16:16:57.657085Z","shell.execute_reply":"2026-01-29T16:16:57.862391Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"num_cols = [\"Pre_GSHH_NDVI\", \"Height_Ave_cm\"]\ndf_train[num_cols].describe()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:16:57.864555Z","iopub.execute_input":"2026-01-29T16:16:57.864937Z","iopub.status.idle":"2026-01-29T16:16:57.879169Z","shell.execute_reply.started":"2026-01-29T16:16:57.864898Z","shell.execute_reply":"2026-01-29T16:16:57.878424Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fig, axes = plt.subplots(1,2, figsize=(12,4))\nsns.histplot(df_train[\"Pre_GSHH_NDVI\"], bins=40, ax=axes[0])\naxes[0].set_title(\"NDVI distribution\")\nsns.histplot(df_train[\"Height_Ave_cm\"], bins=40, ax=axes[1])\naxes[1].set_title(\"Height distribution\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:16:57.880880Z","iopub.execute_input":"2026-01-29T16:16:57.881123Z","iopub.status.idle":"2026-01-29T16:16:58.228903Z","shell.execute_reply.started":"2026-01-29T16:16:57.881101Z","shell.execute_reply":"2026-01-29T16:16:58.228092Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"tmp = df_train[df_train[\"target_name\"]==\"Dry_Total_g\"].copy()\n\nplt.figure(figsize=(6,4))\nsns.scatterplot(data=tmp, x=\"Pre_GSHH_NDVI\", y=\"target\", alpha=0.25)\nplt.title(\"Dry_Total_g vs NDVI\")\nplt.show()\n\nplt.figure(figsize=(6,4))\nsns.scatterplot(data=tmp, x=\"Height_Ave_cm\", y=\"target\", alpha=0.25)\nplt.title(\"Dry_Total_g vs Height\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:16:58.229808Z","iopub.execute_input":"2026-01-29T16:16:58.230088Z","iopub.status.idle":"2026-01-29T16:16:58.544480Z","shell.execute_reply.started":"2026-01-29T16:16:58.230053Z","shell.execute_reply":"2026-01-29T16:16:58.543666Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sns.scatterplot(data=df_train, x='Height_Ave_cm', y='target', hue='target_name')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:16:58.545491Z","iopub.execute_input":"2026-01-29T16:16:58.545819Z","iopub.status.idle":"2026-01-29T16:16:58.893815Z","shell.execute_reply.started":"2026-01-29T16:16:58.545784Z","shell.execute_reply":"2026-01-29T16:16:58.892962Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sns.scatterplot(data=df_train, x='Pre_GSHH_NDVI', y='target', hue='target_name')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:16:58.894714Z","iopub.execute_input":"2026-01-29T16:16:58.894980Z","iopub.status.idle":"2026-01-29T16:16:59.212216Z","shell.execute_reply.started":"2026-01-29T16:16:58.894957Z","shell.execute_reply":"2026-01-29T16:16:59.211401Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(8,4))\nsns.countplot(data=df_train, y=\"State\", order=df_train[\"State\"].value_counts().index)\nplt.title(\"Samples per State\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:16:59.215233Z","iopub.execute_input":"2026-01-29T16:16:59.215651Z","iopub.status.idle":"2026-01-29T16:16:59.341068Z","shell.execute_reply.started":"2026-01-29T16:16:59.215626Z","shell.execute_reply":"2026-01-29T16:16:59.340368Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"top_species = df_train[\"Species\"].value_counts().head(15)\nplt.figure(figsize=(8,5))\nsns.barplot(x=top_species.values, y=top_species.index)\nplt.title(\"Top 15 Species mixes\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:16:59.342128Z","iopub.execute_input":"2026-01-29T16:16:59.342505Z","iopub.status.idle":"2026-01-29T16:16:59.567115Z","shell.execute_reply.started":"2026-01-29T16:16:59.342458Z","shell.execute_reply":"2026-01-29T16:16:59.566379Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train[\"Sampling_Date\"] = pd.to_datetime(df_train[\"Sampling_Date\"])\ntmp = df_train.groupby(df_train[\"Sampling_Date\"].dt.to_period(\"M\")).size()\ntmp.index = tmp.index.astype(str)\n\nplt.figure(figsize=(10,4))\ntmp.plot(kind=\"bar\")\nplt.title(\"Samples by month\")\nplt.xticks(rotation=45)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:16:59.568220Z","iopub.execute_input":"2026-01-29T16:16:59.569231Z","iopub.status.idle":"2026-01-29T16:16:59.733502Z","shell.execute_reply.started":"2026-01-29T16:16:59.569204Z","shell.execute_reply":"2026-01-29T16:16:59.732619Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_rows = df_train.sample(1)\n\nfull_path = BASE_PATH + sample_rows['image_path'].iloc[0]\n\nfull_path\n\nimg = Image.open(full_path)\nplt.imshow(img)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:16:59.734694Z","iopub.execute_input":"2026-01-29T16:16:59.735424Z","iopub.status.idle":"2026-01-29T16:17:00.130101Z","shell.execute_reply.started":"2026-01-29T16:16:59.735383Z","shell.execute_reply":"2026-01-29T16:17:00.129273Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_rows = df_train.sample(5)\n\nplt.figure(figsize=(20, 5))\n\nfor i, (idx, row) in enumerate(sample_rows.iterrows()):\n    full_path = os.path.join(BASE_PATH, row[\"image_path\"])\n\n    img = Image.open(full_path)\n\n    plt.subplot(1, 5, i + 1)\n    plt.imshow(img)\n    plt.title(\n        \"\\n\".join([\n            f\"sample_id: {row['sample_id']}\",\n            f\"image_path: {row['image_path']}\",\n            f\"Sampling_Date: {row['Sampling_Date']}  State: {row['State']}\",\n            f\"Species: {row['Species']}\",\n            f\"Pre_GSHH_NDVI: {row['Pre_GSHH_NDVI']}\",\n            f\"Height_Ave_cm: {row['Height_Ave_cm']} cm\",\n            f\"target_name: {row['target_name']}\",\n            f\"target: {row['target']:.1f} g\",\n        ]),\n        loc=\"left\",\n        fontsize=8\n    )\n    plt.axis(\"off\")\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:17:00.131412Z","iopub.execute_input":"2026-01-29T16:17:00.131823Z","iopub.status.idle":"2026-01-29T16:17:01.202530Z","shell.execute_reply.started":"2026-01-29T16:17:00.131780Z","shell.execute_reply":"2026-01-29T16:17:01.201652Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **Model Training** \nDinal Hasantha","metadata":{}},{"cell_type":"markdown","source":"# **1st Atempt**","metadata":{}},{"cell_type":"code","source":"print(tf.config.list_physical_devices('GPU'))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:17:01.203718Z","iopub.execute_input":"2026-01-29T16:17:01.204474Z","iopub.status.idle":"2026-01-29T16:17:01.209034Z","shell.execute_reply.started":"2026-01-29T16:17:01.204447Z","shell.execute_reply":"2026-01-29T16:17:01.208219Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"target_by_name = df_train.groupby('target_name')['target'].mean().reset_index()\ntarget_by_name","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:17:01.210075Z","iopub.execute_input":"2026-01-29T16:17:01.210387Z","iopub.status.idle":"2026-01-29T16:17:01.228596Z","shell.execute_reply.started":"2026-01-29T16:17:01.210359Z","shell.execute_reply":"2026-01-29T16:17:01.227757Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_submission = df_test.merge(\n    target_by_name,\n    on='target_name',\n    how='left'\n) [[\"sample_id\",\"target\"]]\n\ndf_submission","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:17:01.229598Z","iopub.execute_input":"2026-01-29T16:17:01.229991Z","iopub.status.idle":"2026-01-29T16:17:01.240064Z","shell.execute_reply.started":"2026-01-29T16:17:01.229960Z","shell.execute_reply":"2026-01-29T16:17:01.239176Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_submission.to_csv('submission.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:17:01.241082Z","iopub.execute_input":"2026-01-29T16:17:01.241334Z","iopub.status.idle":"2026-01-29T16:17:01.252876Z","shell.execute_reply.started":"2026-01-29T16:17:01.241281Z","shell.execute_reply":"2026-01-29T16:17:01.252175Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **2nd atempt using CNN**","metadata":{}},{"cell_type":"markdown","source":"Dataset preperation","metadata":{}},{"cell_type":"code","source":"IMG_SIZE = (224, 224)\n\ndef load_image(path, y):\n    x = tf.io.read_file(path)\n    x = tf.io.decode_jpeg(x, channels=3)\n    x = tf.image.resize(x, IMG_SIZE)\n    x = tf.image.convert_image_dtype(x, tf.float32)\n    return x, y\n\ndef make_dataset(df, shuffle=True, batch_size=32):\n    paths = df[\"image_path\"].apply(lambda p: os.path.join(BASE_PATH, p)).values\n    targets = df[\"target\"].values.astype(\"float32\")\n    \n    ds = tf.data.Dataset.from_tensor_slices((paths, targets))\n    ds = ds.map(load_image, num_parallel_calls=tf.data.AUTOTUNE)\n    \n    if shuffle:\n        ds = ds.shuffle(2048)\n    \n    ds = ds.batch(batch_size).prefetch(tf.data.AUTOTUNE)\n    return ds\n\ntrain_df = df_train[:int(0.8 * len(df_train))]\nval_df = df_train[int(0.8 * len(df_train)):]\n\ntrain_ds = make_dataset(train_df, shuffle=True)\nval_ds = make_dataset(val_df, shuffle=False)\n\nprint(\"✅ Datasets ready!\")\nprint(f\"Train batches: {len(train_ds)}\")\nprint(f\"Val batches: {len(val_ds)}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:17:01.253890Z","iopub.execute_input":"2026-01-29T16:17:01.254239Z","iopub.status.idle":"2026-01-29T16:17:01.305362Z","shell.execute_reply.started":"2026-01-29T16:17:01.254216Z","shell.execute_reply":"2026-01-29T16:17:01.304580Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Model Code","metadata":{}},{"cell_type":"code","source":"class RegrCNN(tf.keras.Model):\n    def __init__(self):\n        super().__init__()\n        self.conv1 = tf.keras.layers.Conv2D(32, 3, padding=\"same\", activation=\"relu\")\n        self.pool1 = tf.keras.layers.MaxPool2D()\n        self.conv2 = tf.keras.layers.Conv2D(64, 3, padding=\"same\", activation=\"relu\")\n        self.pool2 = tf.keras.layers.MaxPool2D()\n        self.conv3 = tf.keras.layers.Conv2D(128, 3, padding=\"same\", activation=\"relu\")\n        self.gap = tf.keras.layers.GlobalAveragePooling2D()\n        self.drop = tf.keras.layers.Dropout(0.2)\n        self.out = tf.keras.layers.Dense(1)\n\n    def call(self, x, training=False):\n        x = self.pool1(self.conv1(x))\n        x = self.pool2(self.conv2(x))\n        x = self.conv3(x)\n        x = self.gap(x)\n        x = self.drop(x, training=training)\n        return self.out(x)\n\nmodel = RegrCNN()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:17:01.306219Z","iopub.execute_input":"2026-01-29T16:17:01.306469Z","iopub.status.idle":"2026-01-29T16:17:01.323193Z","shell.execute_reply.started":"2026-01-29T16:17:01.306445Z","shell.execute_reply":"2026-01-29T16:17:01.322572Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Visualization","metadata":{}},{"cell_type":"code","source":"def plot_training_history(history):\n    \"\"\"Safe plot: works with or without validation data\"\"\"\n    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\n    \n    # Loss plot\n    ax1.plot(history.history['loss'], label='Training Loss', linewidth=2, color='blue')\n    if 'val_loss' in history.history:\n        ax1.plot(history.history['val_loss'], label='Validation Loss', linewidth=2, color='orange')\n    ax1.set_title('Model Loss (MSE)')\n    ax1.set_xlabel('Epoch')\n    ax1.set_ylabel('Loss')\n    ax1.legend()\n    ax1.grid(True, alpha=0.3)\n    \n    # MAE plot\n    ax2.plot(history.history['mae'], label='Training MAE', linewidth=2, color='blue')\n    if 'val_mae' in history.history:\n        ax2.plot(history.history['val_mae'], label='Validation MAE', linewidth=2, color='orange')\n    ax2.set_title('Model MAE (grams)')\n    ax2.set_xlabel('Epoch')\n    ax2.set_ylabel('MAE')\n    ax2.legend()\n    ax2.grid(True, alpha=0.3)\n    \n    plt.tight_layout()\n    plt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:35:53.981005Z","iopub.execute_input":"2026-01-29T16:35:53.981839Z","iopub.status.idle":"2026-01-29T16:35:54.679228Z","shell.execute_reply.started":"2026-01-29T16:35:53.981803Z","shell.execute_reply":"2026-01-29T16:35:54.678398Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Training","metadata":{}},{"cell_type":"code","source":"model.compile(optimizer=\"adam\", loss=\"mse\", metrics=[\"mae\"])\n\nhistory = model.fit(\n    train_ds,\n    epochs=20,\n    steps_per_epoch=len(train_ds),\n    validation_data=val_ds,\n    validation_steps=len(val_ds),\n)\n\nplot_training_history(history)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:17:01.324215Z","iopub.execute_input":"2026-01-29T16:17:01.324520Z","iopub.status.idle":"2026-01-29T16:28:01.119997Z","shell.execute_reply.started":"2026-01-29T16:17:01.324468Z","shell.execute_reply":"2026-01-29T16:28:01.118921Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"History keys:\", list(history.history.keys()))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:36:17.026056Z","iopub.execute_input":"2026-01-29T16:36:17.026610Z","iopub.status.idle":"2026-01-29T16:36:17.030845Z","shell.execute_reply.started":"2026-01-29T16:36:17.026582Z","shell.execute_reply":"2026-01-29T16:36:17.029978Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Training with Visualization","metadata":{}},{"cell_type":"markdown","source":"Saveing Model","metadata":{}},{"cell_type":"code","source":"model.save(\"/kaggle/working/regr_cnn.keras\")\nmodel.save(\"/kaggle/working/regr_cnn.h5\")\n\nprint(\"Saved to /kaggle/working/\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:36:20.103365Z","iopub.execute_input":"2026-01-29T16:36:20.103913Z","iopub.status.idle":"2026-01-29T16:36:20.178854Z","shell.execute_reply.started":"2026-01-29T16:36:20.103886Z","shell.execute_reply":"2026-01-29T16:36:20.178157Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Get an Output using Model","metadata":{}},{"cell_type":"code","source":"test_paths = df_test[\"image_path\"].apply(lambda p: os.path.join(BASE_PATH, p)).values\n\ndef load_test_image(path):\n    x = tf.io.read_file(path)\n    x = tf.io.decode_jpeg(x, channels=3)\n    x = tf.image.resize(x, IMG_SIZE)\n    x = tf.image.convert_image_dtype(x, tf.float32)\n    return x\n\ntest_ds = tf.data.Dataset.from_tensor_slices(test_paths)\ntest_ds = test_ds.map(load_test_image, num_parallel_calls=tf.data.AUTOTUNE)\ntest_ds = test_ds.batch(32).prefetch(tf.data.AUTOTUNE)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:36:26.354877Z","iopub.execute_input":"2026-01-29T16:36:26.355205Z","iopub.status.idle":"2026-01-29T16:36:26.408795Z","shell.execute_reply.started":"2026-01-29T16:36:26.355176Z","shell.execute_reply":"2026-01-29T16:36:26.408114Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"preds = model.predict(test_ds)\npreds = preds.squeeze()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:36:29.151155Z","iopub.execute_input":"2026-01-29T16:36:29.151768Z","iopub.status.idle":"2026-01-29T16:36:29.610675Z","shell.execute_reply.started":"2026-01-29T16:36:29.151739Z","shell.execute_reply":"2026-01-29T16:36:29.609835Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission = pd.DataFrame({\n    \"sample_id\": df_test[\"sample_id\"],\n    \"target\": preds.astype(\"float32\"),\n})\n\nsubmission.to_csv(\"submission.csv\", index=False)\nprint(\"Saved submission.csv with\", len(submission), \"rows\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-29T16:36:44.834754Z","iopub.execute_input":"2026-01-29T16:36:44.835383Z","iopub.status.idle":"2026-01-29T16:36:44.841561Z","shell.execute_reply.started":"2026-01-29T16:36:44.835353Z","shell.execute_reply":"2026-01-29T16:36:44.840717Z"}},"outputs":[],"execution_count":null}]}