{"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":"gpu","dataSources":[{"sourceId":112509,"databundleVersionId":14254895,"sourceType":"competition"},{"sourceId":4534,"sourceType":"modelInstanceVersion","modelInstanceId":3326,"modelId":986},{"sourceId":4537,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":3329,"modelId":986}],"dockerImageVersionId":31154,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport torch\nimport torchvision\nimport os\nimport torchvision.transforms as transforms\nfrom torchvision.datasets import ImageFolder\nfrom torch.utils.data import DataLoader, Subset, Dataset\nfrom PIL import Image\n!cp -r \"/kaggle/input/rsna-models/facebookresearch_dinov2_main (1)/root/.cache/torch/hub/facebookresearch_dinov2_main\" /kaggle/working/dinov2\nmean = [0.485, 0.456, 0.406]\nstd = [0.229, 0.224, 0.225]","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-10-31T23:23:43.976224Z","iopub.execute_input":"2025-10-31T23:23:43.976452Z","iopub.status.idle":"2025-10-31T23:23:53.551528Z","shell.execute_reply.started":"2025-10-31T23:23:43.976435Z","shell.execute_reply":"2025-10-31T23:23:53.550688Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from transformers import AutoImageProcessor, AutoModel\nprocessor = AutoImageProcessor.from_pretrained('/kaggle/input/dinov2/pytorch/giant/1')\nmodel = AutoModel.from_pretrained('/kaggle/input/dinov2/pytorch/giant/1')\nmodel = model.cuda()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-31T23:28:37.651789Z","iopub.execute_input":"2025-10-31T23:28:37.652445Z","iopub.status.idle":"2025-10-31T23:28:37.981983Z","shell.execute_reply.started":"2025-10-31T23:28:37.652416Z","shell.execute_reply":"2025-10-31T23:28:37.981174Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"embeds = []\ntargets = [[] for i in range(5)]\ncounter = 0\nimport torchvision.transforms as transforms\nimport pandas as pd\nfrom PIL import Image\n#transform = transforms.Compose([transforms.ToTensor(), transforms.Resize((224, 224)), transforms.Normalize(mean, std)])\ntrain_df = pd.read_csv(\"/kaggle/input/csiro-biomass/train.csv\")\nroot = \"/kaggle/input/csiro-biomass/\"\nfor i in range(len(train_df)):\n    entry = train_df.iloc[i]\n    file_path = root + entry['image_path']\n    y = torch.tensor([[entry['target']]])\n    targets[i % 5].append(y)\n    if i % 5 == 0:\n        img = Image.open(file_path)\n        x = torch.tensor(processor(img).pixel_values)\n        with torch.no_grad():\n            x = x.cuda()\n            embeds.append(model(x).pooler_output.cpu())\n            counter += 1\n            if counter % 100 == 0:\n                print(f\"{counter} batches processed.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-31T23:29:41.427812Z","iopub.execute_input":"2025-10-31T23:29:41.428071Z","iopub.status.idle":"2025-10-31T23:30:21.040074Z","shell.execute_reply.started":"2025-10-31T23:29:41.42805Z","shell.execute_reply":"2025-10-31T23:30:21.039269Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import random\nimport numpy as np\nfrom sklearn.linear_model import Lasso\nfrom sklearn.metrics import r2_score\n\n# Create indices and shuffle once\nlst = list(range(len(embeds)))\nrandom.seed(42)\nrandom.shuffle(lst)\n\n# Create multiple random 80/20 splits\nn_splits = 5\nsplits = []\n\nfor i in range(n_splits):\n    # Reshuffle for each split while maintaining same splits across targets\n    temp_lst = lst.copy()\n    random.seed(42 + i)  # Different seed for each split\n    random.shuffle(temp_lst)\n    \n    split_point = int(len(temp_lst) * 0.8)\n    train_idxs = temp_lst[:split_point]\n    val_idxs = temp_lst[split_point:]\n    splits.append((train_idxs, val_idxs))\n\n# Convert embeds to numpy array once for efficiency\nembeds_np = np.array(torch.cat(embeds))\nregressors = [[None for i in range(5)] for j in range(5)]\n# Now iterate through each target\nfor i in range(5):\n    print(f\"\\n=== Target {i+1} ===\")\n    targets_np = np.array(torch.cat(targets[i]))\n    \n    split_scores = []\n    \n    for split_idx, (train_idxs, val_idxs) in enumerate(splits):\n        print(f\"Fold {split_idx+1}:\")\n        X_train, y_train = embeds_np[train_idxs], targets_np[train_idxs]\n        X_val, y_val = embeds_np[val_idxs], targets_np[val_idxs]\n        reg = Lasso()\n        reg.fit(X_train, y_train)\n        train_preds = reg.predict(X_train)\n        train_preds[train_preds < 0.0] = 0.0\n        train_r2 = r2_score(y_train, train_preds)\n        val_preds = reg.predict(X_val)\n        val_preds[val_preds < 0.0] = 0.0\n        val_r2 = r2_score(y_val, val_preds)\n        print(f\"  Train R²: {train_r2:.4f}\")\n        print(f\"  Val R²: {val_r2:.4f}\")\n        split_scores.append((train_r2, val_r2))\n        regressors[i][split_idx] = reg\n    \n    # Print summary for this target\n    avg_train_r2 = np.mean([score[0] for score in split_scores])\n    avg_val_r2 = np.mean([score[1] for score in split_scores])\n    print(f\"\\nTarget {i+1} Average:\")\n    print(f\"  Avg Train R²: {avg_train_r2:.4f}\")\n    print(f\"  Avg Val R²: {avg_val_r2:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-31T23:32:17.170053Z","iopub.execute_input":"2025-10-31T23:32:17.170566Z","iopub.status.idle":"2025-10-31T23:32:17.550037Z","shell.execute_reply.started":"2025-10-31T23:32:17.170543Z","shell.execute_reply":"2025-10-31T23:32:17.549375Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"mapping = {\"Dry_Clover_g\": 0, \"Dry_Dead_g\": 1, \"Dry_Green_g\": 2, \"Dry_Total_g\": 3, \"GDM_g\": 4}","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-31T23:33:16.375885Z","iopub.execute_input":"2025-10-31T23:33:16.376146Z","iopub.status.idle":"2025-10-31T23:33:16.380014Z","shell.execute_reply.started":"2025-10-31T23:33:16.376126Z","shell.execute_reply":"2025-10-31T23:33:16.379139Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_embeds = {}\ncounter = 0\nimport torchvision.transforms as transforms\nimport pandas as pd\nfrom PIL import Image\ntransform = transforms.Compose([transforms.ToTensor(), transforms.Resize((224, 224)), transforms.Normalize(mean, std)])\ntest_df = pd.read_csv(\"/kaggle/input/csiro-biomass/test.csv\")\nroot = \"/kaggle/input/csiro-biomass/\"\nsample_ids = []\nfor i in range(len(test_df)):\n    entry = test_df.iloc[i]\n    file_path = root + entry['image_path']\n    sample_id = entry['sample_id']\n    #y = torch.tensor([[entry['target']]])\n    if sample_id not in sample_ids:\n        img = Image.open(file_path)\n        x = torch.tensor(processor(img).pixel_values)\n        with torch.no_grad():\n            x = x.cuda()\n            test_embeds[sample_id.split(\"_\")[0]] = model(x).pooler_output.cpu()\n            counter += 1\n        sample_ids.append(sample_id)\n    if counter % 100 == 0:\n        print(f\"{counter} batches processed.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-31T23:32:54.567805Z","iopub.execute_input":"2025-10-31T23:32:54.568072Z","iopub.status.idle":"2025-10-31T23:32:55.251035Z","shell.execute_reply.started":"2025-10-31T23:32:54.568053Z","shell.execute_reply":"2025-10-31T23:32:55.250277Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predictions = []\nsample_ids = []\ntest_df = pd.read_csv(\"/kaggle/input/csiro-biomass/test.csv\")\nfor i in range(len(test_df)):\n    try:\n        entry = test_df.iloc[i]\n        X = np.array(test_embeds[entry['sample_id'].split(\"__\")[0]])\n        sample_ids.append(entry['sample_id'])\n        models = regressors[mapping[entry['sample_id'].split(\"__\")[1]]]\n        prediction = 0.0\n        for item in models:\n            single_pred = item.predict(X)\n            if single_pred < 0.0:\n                single_pred = 0.0\n            prediction += single_pred\n        prediction = prediction / 5\n        predictions.append(float(prediction))\n    except Exception as e:\n        predictions.append(0.0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-31T23:33:17.845Z","iopub.execute_input":"2025-10-31T23:33:17.845278Z","iopub.status.idle":"2025-10-31T23:33:17.858066Z","shell.execute_reply.started":"2025-10-31T23:33:17.845249Z","shell.execute_reply":"2025-10-31T23:33:17.85718Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%cd /kaggle/working\nsubmission = pd.DataFrame({\n    'sample_id': sample_ids,\n    'target': predictions\n})\n\nsubmission.to_csv('submission.csv', index=False)\nsubmission","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-31T23:33:19.973063Z","iopub.execute_input":"2025-10-31T23:33:19.973883Z","iopub.status.idle":"2025-10-31T23:33:19.986563Z","shell.execute_reply.started":"2025-10-31T23:33:19.973848Z","shell.execute_reply":"2025-10-31T23:33:19.985838Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"##### acknowledgement - https://www.kaggle.com/code/carsoncheng/dinov2-lasso-baseline-lb-0-54","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}