{"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,"isSourceIdPinned":false}],"dockerImageVersionId":31328,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nfrom tqdm import tqdm\nimport cv2\n\nfrom sklearn.linear_model import Ridge\nfrom sklearn.model_selection import KFold\nfrom sklearn.preprocessing import StandardScaler\n\nimport tensorflow as tf\nimport tensorflow_hub as hub\n\n# ===============================\n# PATHS\n# ===============================\nBASE_PATH = \"/kaggle/input/competitions/csiro-biomass\"\n\nTRAIN_CSV_PATH = os.path.join(BASE_PATH, \"train.csv\")\nTEST_CSV_PATH  = os.path.join(BASE_PATH, \"test.csv\")\n\nEFFICIENTNET_PATH = \"/kaggle/input/models/tensorflow/efficientnet/tensorflow2/b3-feature-vector/1\"\n\nIMG_SIZE = 300\nN_FOLDS = 5\n\n# ===============================\n# LOAD DATA\n# ===============================\ntrain_df = pd.read_csv(TRAIN_CSV_PATH)\ntest_df  = pd.read_csv(TEST_CSV_PATH)\n\n# ===============================\n# PIVOT\n# ===============================\ntrain_wide_df = train_df.pivot(\n    index='image_path',\n    columns='target_name',\n    values='target'\n).reset_index()\n\nTARGET_COLS = [c for c in train_wide_df.columns if c != 'image_path']\n\n# ===============================\n# LOAD MODEL (SAFE)\n# ===============================\nif os.path.exists(EFFICIENTNET_PATH):\n    hub_layer = hub.load(EFFICIENTNET_PATH)\n    print(\"✅ EfficientNet loaded\")\nelse:\n    hub_layer = None\n    print(\"⚠️ EfficientNet NOT found → fallback mode\")\n\n# ===============================\n# SAFE IMAGE LOADER\n# ===============================\ndef load_image(path):\n    try:\n        path = os.path.join(BASE_PATH, str(path).split(\"/\")[-1])\n\n        if not os.path.exists(path):\n            return np.zeros((IMG_SIZE, IMG_SIZE, 3), dtype=np.uint8)\n\n        img = cv2.imread(path)\n        if img is None:\n            return np.zeros((IMG_SIZE, IMG_SIZE, 3), dtype=np.uint8)\n\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))\n        return img\n\n    except:\n        return np.zeros((IMG_SIZE, IMG_SIZE, 3), dtype=np.uint8)\n\n# ===============================\n# SAFE FEATURE EXTRACTOR\n# ===============================\ndef extract_features(img):\n    try:\n        if hub_layer is None:\n            return np.zeros(1536)\n\n        x = img.astype(np.float32) / 255.0\n        x = np.expand_dims(x, axis=0)\n        x = tf.constant(x)\n\n        features = hub_layer(x, training=False)\n        return features.numpy().flatten()\n\n    except:\n        return np.zeros(1536)\n\n# ===============================\n# TRAIN FEATURES\n# ===============================\ntrain_features = []\ntrain_labels = []\n\nfor _, row in tqdm(train_wide_df.iterrows(), total=len(train_wide_df)):\n    img = load_image(row['image_path'])\n    feat = extract_features(img)\n\n    train_features.append(feat)\n    train_labels.append(row[TARGET_COLS].values.astype(np.float32))\n\nX_train = np.array(train_features)\ny_train = np.array(train_labels)\n\n# ===============================\n# TEST FEATURES\n# ===============================\nunique_paths = test_df['image_path'].unique()\n\ntest_features = []\n\nfor p in tqdm(unique_paths):\n    img = load_image(p)\n    feat = extract_features(img)\n    test_features.append(feat)\n\nX_test = np.array(test_features)\n\n# ===============================\n# SCALE\n# ===============================\nscaler = StandardScaler()\nX_train = scaler.fit_transform(X_train + 1e-6)\nX_test  = scaler.transform(X_test + 1e-6)\n\n# ===============================\n# MODEL (RIDGE)\n# ===============================\nkf = KFold(n_splits=N_FOLDS, shuffle=True, random_state=42)\n\ntest_preds = np.zeros((X_test.shape[0], len(TARGET_COLS)))\n\nfor t_idx, target in enumerate(TARGET_COLS):\n    y_t = y_train[:, t_idx]\n    fold_preds = np.zeros((N_FOLDS, X_test.shape[0]))\n\n    for fold, (tr_idx, val_idx) in enumerate(kf.split(X_train)):\n        model = Ridge(alpha=1.0)\n        model.fit(X_train[tr_idx], y_t[tr_idx])\n\n        fold_preds[fold] = model.predict(X_test)\n\n    test_preds[:, t_idx] = fold_preds.mean(axis=0)\n\n# ===============================\n# SUBMISSION\n# ===============================\ntest_preds = np.clip(test_preds, 0, None)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-04-10T17:56:53.416426Z","iopub.execute_input":"2026-04-10T17:56:53.416705Z","iopub.status.idle":"2026-04-10T17:57:33.171086Z","shell.execute_reply.started":"2026-04-10T17:56:53.416664Z","shell.execute_reply":"2026-04-10T17:57:33.170197Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pred_df = pd.DataFrame(test_preds, columns=TARGET_COLS)\npred_df[\"image_path\"] = unique_paths\n\npred_long = pred_df.melt(\n    id_vars=[\"image_path\"],\n    value_vars=TARGET_COLS,\n    var_name=\"target_name\",\n    value_name=\"target\"\n)\n\nsubmission = pd.merge(\n    test_df[[\"sample_id\", \"image_path\", \"target_name\"]],\n    pred_long,\n    on=[\"image_path\", \"target_name\"],\n    how=\"left\"\n)\n\nsubmission[\"target\"] = submission[\"target\"].fillna(0)\n\nsubmission = submission[[\"sample_id\", \"target\"]]\n\nsubmission.to_csv(\"/kaggle/working/submission.csv\", index=False)\n\nprint(\"✅ Submission created successfully!\")\nprint(submission.head())\nprint(\"Shape:\", submission.shape)\nprint(\"Files:\", os.listdir(\"/kaggle/working\"))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-04-10T17:57:33.175654Z","iopub.execute_input":"2026-04-10T17:57:33.176791Z","iopub.status.idle":"2026-04-10T17:57:33.251448Z","shell.execute_reply.started":"2026-04-10T17:57:33.176741Z","shell.execute_reply":"2026-04-10T17:57:33.249877Z"}},"outputs":[],"execution_count":null}]}