{"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":31193,"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-11-08T20:09:44.689018Z","iopub.execute_input":"2025-11-08T20:09:44.689305Z","iopub.status.idle":"2025-11-08T20:09:47.121609Z","shell.execute_reply.started":"2025-11-08T20:09:44.689277Z","shell.execute_reply":"2025-11-08T20:09:47.120782Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install --upgrade protobuf\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-08T20:11:36.292338Z","iopub.execute_input":"2025-11-08T20:11:36.293112Z","iopub.status.idle":"2025-11-08T20:11:40.518799Z","shell.execute_reply.started":"2025-11-08T20:11:36.293086Z","shell.execute_reply":"2025-11-08T20:11:40.517639Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df = pd.read_csv(\"/kaggle/input/csiro-biomass/train.csv\")\ndf.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-08T20:23:43.5766Z","iopub.execute_input":"2025-11-08T20:23:43.577295Z","iopub.status.idle":"2025-11-08T20:23:43.596851Z","shell.execute_reply.started":"2025-11-08T20:23:43.577271Z","shell.execute_reply":"2025-11-08T20:23:43.59608Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.columns","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-08T20:25:12.130492Z","iopub.execute_input":"2025-11-08T20:25:12.130865Z","iopub.status.idle":"2025-11-08T20:25:12.136385Z","shell.execute_reply.started":"2025-11-08T20:25:12.130843Z","shell.execute_reply":"2025-11-08T20:25:12.135649Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Step 1: Import Libraries\n# ------------------------------\nimport os\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm\nimport cv2\nimport seaborn as sns\n\nimport tensorflow as tf\nfrom tensorflow.keras import layers, models\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import r2_score","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-08T20:37:04.930924Z","iopub.execute_input":"2025-11-08T20:37:04.931497Z","iopub.status.idle":"2025-11-08T20:37:04.935969Z","shell.execute_reply.started":"2025-11-08T20:37:04.931473Z","shell.execute_reply":"2025-11-08T20:37:04.935182Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n# ------------------------------\n# Step 2: Load train.csv + test.csv\n# ------------------------------\ntrain_csv_path = \"/kaggle/input/csiro-biomass/train.csv\"\ntest_csv_path = \"/kaggle/input/csiro-biomass/test.csv\"\n\ntrain_df = pd.read_csv(train_csv_path)\ntest_df = pd.read_csv(test_csv_path)\n\nprint(\"Train shape:\", train_df.shape)\nprint(\"Test shape:\", test_df.shape)\n\n# ------------------------------\n# Step 3: Dataset overview / statistics\n# ------------------------------\nprint(train_df.info())\nprint(train_df.describe())\n\n# ------------------------------\n# Step 4: Missing value check\n# ------------------------------\nprint(train_df.isnull().sum())\n\n# ------------------------------\n# Step 5: Target distribution visualization\n# ------------------------------\ntarget_cols = ['Dry_Green_g','Dry_Dead_g','Dry_Clover_g','GDM_g','Dry_Total_g']\n\n# Pivot to wide format for visualization\ntrain_wide = train_df.pivot(index='image_path', columns='target_name', values='target').reset_index()\n\nplt.figure(figsize=(12,6))\ntrain_wide[target_cols].hist(bins=30)\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-08T20:37:49.524205Z","iopub.execute_input":"2025-11-08T20:37:49.524785Z","iopub.status.idle":"2025-11-08T20:37:50.121644Z","shell.execute_reply.started":"2025-11-08T20:37:49.524762Z","shell.execute_reply":"2025-11-08T20:37:50.121057Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ------------------------------\n# Step 6: Sample images visualization\n# ------------------------------\ntrain_images_path = \"/kaggle/input/csiro-biomass/train\"\nsample_imgs = train_wide['image_path'].values[:5]\n\nplt.figure(figsize=(12,5))\nfor i, img_name in enumerate(sample_imgs):\n    img_path = os.path.join(train_images_path, os.path.basename(img_name))\n    img = cv2.imread(img_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    plt.subplot(1,5,i+1)\n    plt.imshow(img)\n    plt.axis('off')\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-08T20:38:19.243619Z","iopub.execute_input":"2025-11-08T20:38:19.244229Z","iopub.status.idle":"2025-11-08T20:38:20.381552Z","shell.execute_reply.started":"2025-11-08T20:38:19.244206Z","shell.execute_reply":"2025-11-08T20:38:20.380877Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ------------------------------\n# Step 7: Image preprocessing function\n# ------------------------------\nIMG_SIZE = 128\n\ndef preprocess_image(img_path, img_size=IMG_SIZE):\n    img = cv2.imread(img_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    img = cv2.resize(img,(img_size,img_size))\n    img = img / 255.0\n    return img\n\n# ------------------------------\n# Step 8: Load train images + labels\n# ------------------------------\n# Ensure numeric dtype\ntrain_wide[target_cols] = train_wide[target_cols].astype(float)\n\n# Full paths\ntrain_wide['full_path'] = train_wide['image_path'].apply(lambda x: os.path.join(train_images_path, os.path.basename(x)))\n\nimages = []\nlabels = []\n\nfor idx, row in tqdm(train_wide.iterrows(), total=len(train_wide)):\n    img_path = row['full_path']\n    if os.path.exists(img_path):\n        img = preprocess_image(img_path)\n        images.append(img)\n        labels.append(row[target_cols].values.astype(np.float32))\n\nimages = np.array(images, dtype=np.float32)\nlabels = np.array(labels, dtype=np.float32)\n\nprint(\"Images shape:\", images.shape)\nprint(\"Labels shape:\", labels.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-08T20:38:44.597143Z","iopub.execute_input":"2025-11-08T20:38:44.597959Z","iopub.status.idle":"2025-11-08T20:39:00.484515Z","shell.execute_reply.started":"2025-11-08T20:38:44.597935Z","shell.execute_reply":"2025-11-08T20:39:00.483725Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ------------------------------\n# Step 9: Train/validation split\n# ------------------------------\nX_train, X_val, y_train, y_val = train_test_split(images, labels, test_size=0.2, random_state=42)\nprint(\"Train:\", X_train.shape, y_train.shape)\nprint(\"Validation:\", X_val.shape, y_val.shape)\n\n# ------------------------------\n# Step 10: Data augmentation\n# ------------------------------\ntrain_datagen = ImageDataGenerator(\n    rotation_range=15,\n    horizontal_flip=True,\n    width_shift_range=0.1,\n    height_shift_range=0.1\n)\nval_datagen = ImageDataGenerator()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-08T20:39:50.892181Z","iopub.execute_input":"2025-11-08T20:39:50.892446Z","iopub.status.idle":"2025-11-08T20:39:50.913379Z","shell.execute_reply.started":"2025-11-08T20:39:50.89243Z","shell.execute_reply":"2025-11-08T20:39:50.912759Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ------------------------------\n# Step 11: Build simple CNN model\n# ------------------------------\ndef build_cnn_model(input_shape=(IMG_SIZE, IMG_SIZE, 3), num_targets=5):\n    model = models.Sequential([\n        layers.Conv2D(32,(3,3),activation='relu',input_shape=input_shape),\n        layers.MaxPooling2D(2,2),\n        layers.Conv2D(64,(3,3),activation='relu'),\n        layers.MaxPooling2D(2,2),\n        layers.Conv2D(128,(3,3),activation='relu'),\n        layers.MaxPooling2D(2,2),\n        layers.Flatten(),\n        layers.Dense(128, activation='relu'),\n        layers.Dense(num_targets, activation='linear')\n    ])\n    model.compile(optimizer='adam', loss='mse', metrics=['mae'])\n    return model\n\nmodel = build_cnn_model()\nmodel.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-08T20:40:07.230007Z","iopub.execute_input":"2025-11-08T20:40:07.230733Z","iopub.status.idle":"2025-11-08T20:40:07.286885Z","shell.execute_reply.started":"2025-11-08T20:40:07.230706Z","shell.execute_reply":"2025-11-08T20:40:07.286161Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ------------------------------\n# Step 12: Model training\n# ------------------------------\nhistory = model.fit(\n    train_datagen.flow(X_train, y_train, batch_size=16),\n    validation_data=val_datagen.flow(X_val, y_val),\n    epochs=20\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-08T20:40:22.564751Z","iopub.execute_input":"2025-11-08T20:40:22.565065Z","iopub.status.idle":"2025-11-08T20:40:50.205694Z","shell.execute_reply.started":"2025-11-08T20:40:22.565011Z","shell.execute_reply":"2025-11-08T20:40:50.204908Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ------------------------------\n# Step 13: Plot training history\n# ------------------------------\nplt.figure(figsize=(12,4))\nplt.subplot(1,2,1)\nplt.plot(history.history['loss'], label='train_loss')\nplt.plot(history.history['val_loss'], label='val_loss')\nplt.legend(); plt.title('Loss')\n\nplt.subplot(1,2,2)\nplt.plot(history.history['mae'], label='train_mae')\nplt.plot(history.history['val_mae'], label='val_mae')\nplt.legend(); plt.title('MAE')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-08T20:41:06.013618Z","iopub.execute_input":"2025-11-08T20:41:06.013883Z","iopub.status.idle":"2025-11-08T20:41:06.285638Z","shell.execute_reply.started":"2025-11-08T20:41:06.013866Z","shell.execute_reply":"2025-11-08T20:41:06.28509Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ------------------------------\n# Step 14: Validation evaluation (R²)\n# ------------------------------\ny_pred = model.predict(X_val)\nfor i, col in enumerate(target_cols):\n    r2 = r2_score(y_val[:,i], y_pred[:,i])\n    print(f\"R² score for {col}: {r2:.4f}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-08T20:41:37.470999Z","iopub.execute_input":"2025-11-08T20:41:37.47154Z","iopub.status.idle":"2025-11-08T20:41:38.101258Z","shell.execute_reply.started":"2025-11-08T20:41:37.471517Z","shell.execute_reply":"2025-11-08T20:41:38.10047Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ------------------------------\n# Step 15: Load test.csv + test images\n# ------------------------------\ntest_images_path = \"/kaggle/input/pasture-dataset/test\"\ntest_df['full_path'] = test_df['image_path'].apply(lambda x: os.path.join(test_images_path, os.path.basename(x)))\n\ntest_images = []\ntest_image_ids = []\n\nfor img_path in tqdm(test_df['full_path']):\n    if os.path.exists(img_path):\n        img = preprocess_image(img_path)\n        test_images.append(img)\n        test_image_ids.append(os.path.basename(img_path))\n\ntest_images = np.array(test_images, dtype=np.float32)\nprint(\"Test images shape:\", test_images.shape)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-08T20:42:04.377314Z","iopub.execute_input":"2025-11-08T20:42:04.377594Z","iopub.status.idle":"2025-11-08T20:42:04.387005Z","shell.execute_reply.started":"2025-11-08T20:42:04.377574Z","shell.execute_reply":"2025-11-08T20:42:04.386344Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ------------------------------\n# Step 17: Create submission CSV\n# ------------------------------\nsubmission = []\nfor idx, img_id in enumerate(test_image_ids):\n    for t_idx, target in enumerate(target_cols):\n        submission.append({\n            'sample_id': f\"{img_id}__{target}\",\n            'target': test_preds[idx, t_idx]\n        })\n\nsubmission_df = pd.DataFrame(submission)\nsubmission_df.to_csv(\"submission.csv\", index=False)\nprint(submission_df.head())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-08T20:42:54.377215Z","iopub.execute_input":"2025-11-08T20:42:54.377485Z","iopub.status.idle":"2025-11-08T20:42:54.391642Z","shell.execute_reply.started":"2025-11-08T20:42:54.377464Z","shell.execute_reply":"2025-11-08T20:42:54.391084Z"}},"outputs":[],"execution_count":null}]}