{"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":14216039,"sourceType":"datasetVersion","datasetId":9068172},{"sourceId":4537,"sourceType":"modelInstanceVersion","modelInstanceId":3329,"modelId":986},{"sourceId":729204,"sourceType":"modelInstanceVersion","modelInstanceId":555348,"modelId":567908}],"dockerImageVersionId":31193,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"#This notebook is forked from  https://www.kaggle.com/code/carsoncheng/csiro-dinov2-dense-features-lb-0-66\n\n#!pip install transformers==4.57.1\n\nimport pandas as pd\nimport numpy as np\nimport torch\nimport torchvision\nimport os\nfrom torchvision.datasets import ImageFolder\nfrom torch.utils.data import DataLoader, Subset, Dataset\nimport torchvision.transforms as transforms\nimport torch.optim as optim\nfrom PIL import Image\nfrom torch.optim.lr_scheduler import StepLR\nimport torch.nn.functional as F\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]\nimport gc\nimport random\n\ngc.collect()\ninfer =1","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-01-24T19:53:35.848421Z","iopub.execute_input":"2026-01-24T19:53:35.848619Z","iopub.status.idle":"2026-01-24T19:53:44.525075Z","shell.execute_reply.started":"2026-01-24T19:53:35.848602Z","shell.execute_reply":"2026-01-24T19:53:44.524407Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#DINO\n#!pip install protobuf==3.20.3\nimport torch.nn as nn\nif infer == 1:\n    from transformers import Dinov2Model\n    model = Dinov2Model.from_pretrained('/kaggle/input/dinov2/pytorch/giant/1')\n    model.head = nn.Identity()\n    model = model.cuda()\n    gc.collect()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-24T19:53:44.526242Z","iopub.execute_input":"2026-01-24T19:53:44.526562Z","iopub.status.idle":"2026-01-24T19:53:44.530783Z","shell.execute_reply.started":"2026-01-24T19:53:44.526544Z","shell.execute_reply":"2026-01-24T19:53:44.530162Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#DATAPIPE EXTRACT\nimport torchvision.transforms as transforms\nimport pandas as pd\nfrom PIL import Image\nfrom tqdm import tqdm\n\nmapping = {\"Dry_Clover_g\": 0, \"Dry_Dead_g\": 1, \"Dry_Green_g\": 2, \"Dry_Total_g\": 3, \"GDM_g\": 4}\n\ntransform = transforms.Compose([transforms.ToTensor(), transforms.Resize((224, 224)), transforms.Normalize(mean, std)])\ntrain_df = pd.read_csv(\"/kaggle/input/csiro-biomass/train.csv\")\naugmentation_transforms = [\n    transforms.Compose([transforms.ToTensor(), transforms.Resize((224, 224)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(3)]),  # Original\n    transforms.Compose([transforms.RandomHorizontalFlip(p=1.0), transforms.ToTensor(), transforms.Resize((224, 224)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(3)]),  # Horizontal flip\n    transforms.Compose([transforms.RandomVerticalFlip(p=1.0), transforms.ToTensor(), transforms.Resize((224, 224)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(5)]),  # Vertical flip\n    transforms.Compose([transforms.RandomHorizontalFlip(p=1.0), transforms.RandomVerticalFlip(p=1.0), transforms.ToTensor(), transforms.Resize((224, 224)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(5)]),  # Both flips\n    transforms.Compose([transforms.RandomRotation(degrees=25), transforms.ToTensor(), transforms.Resize((224, 224)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(5)]),  # 90 degree rotation\n    transforms.Compose([transforms.RandomRotation(degrees=35), transforms.ToTensor(), transforms.Resize((224, 224)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(3)]),  # 270 degree rotation\n]\nroot = \"/kaggle/input/csiro-biomass/\"\n\naugmentation_transforms1 = [\n    transforms.Compose([transforms.ToTensor(), transforms.Resize((224*2, 224*2)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(3)]),  # Original\n    transforms.Compose([transforms.RandomHorizontalFlip(p=1.0), transforms.ToTensor(), transforms.Resize((224*2, 224*2)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(3)]),  # Horizontal flip\n    transforms.Compose([transforms.RandomVerticalFlip(p=1.0), transforms.ToTensor(), transforms.Resize((224*2, 224*2)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(5)]),  # Vertical flip\n    transforms.Compose([transforms.RandomHorizontalFlip(p=1.0), transforms.RandomVerticalFlip(p=1.0), transforms.ToTensor(), transforms.Resize((224*2, 224*2)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(5)]),  # Both flips\n    transforms.Compose([transforms.RandomRotation(degrees=25), transforms.ToTensor(), transforms.Resize((224*2, 224*2)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(5)]),  # 90 degree rotation\n    transforms.Compose([transforms.RandomRotation(degrees=35), transforms.ToTensor(), transforms.Resize((224*2, 224*2)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(3)]),  # 270 degree rotation\n]\n\n\ntest_embeds = {}\ndef get_feats(train_df, augmentation_transforms):\n    test_embeds = {}\n    sample_ids = []\n    counter = 0\n    for i in tqdm(range(len(train_df))):\n        entry = train_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.split(\"_\")[0] not in sample_ids:\n            image_embeddings = []\n            for aug in augmentation_transforms:\n                img = Image.open(file_path)\n                x = aug(img).unsqueeze(0)\n                with torch.inference_mode():\n                    x = x.cuda()\n                    image_embeddings.append(torch.cat([model(x).last_hidden_state[:,1:,:].cpu()[0]]).unsqueeze(0))\n                    counter += 1\n            #print(image_embeddings[0].shape, sample_id)\n            test_embeds[sample_id.split(\"_\")[0]] = torch.stack(image_embeddings, dim=0)\n            #print(torch.stack(image_embeddings, dim=0).shape)\n            sample_ids.append(sample_id.split(\"_\")[0])        \n        if counter % 100 == 0:\n            print(f\"{counter} batches processed.\")\n    return test_embeds\n\n\n#test_embeds = get_feats(train_df, augmentation_transforms1)\n\n        \ndef get_labels(group_name):\n    labels = [[i[1]['sample_id'].split('_')[0], i[1]['target']] \n                      for \n                      i \n                      in \n                      train_df[train_df['target_name']==group_name].iterrows()]\n    return labels\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-24T19:53:44.531416Z","iopub.execute_input":"2026-01-24T19:53:44.531684Z","iopub.status.idle":"2026-01-24T19:53:44.567197Z","shell.execute_reply.started":"2026-01-24T19:53:44.531661Z","shell.execute_reply":"2026-01-24T19:53:44.566724Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"The main gain of this model is sourced from dataset samples generation procedure in DatasetTRN. Dataset sampleas are stochastically generated from two independent samples ","metadata":{}},{"cell_type":"code","source":"#DATAPIPE PACK\n\nclass DatasetTRN(Dataset):\n    def __init__(self, data, labels, tran_num, decomp):\n        self.data = data\n        self.labels =labels\n        self.tran_num = tran_num\n        self.decomp = decomp\n        self.shape = list(self.data[self.labels[1][0]][0].shape)[1:]\n        self.masks  = []\n        for i in range (self.decomp):\n            self.masks.append(list(range(i, self.shape[0], self.decomp)))\n\n    def __len__(self):\n        return len(self.labels)*self.tran_num * self.decomp \n\n    def __getitem__(self, idx):\n        mask_num = idx%self.decomp\n        mask_extracted = self.masks[mask_num]\n        idx_without_decomp = idx//self.decomp\n        tran_num = idx_without_decomp % self.tran_num\n        idx_without_decomp_wihtout_tran_num = idx_without_decomp // self.tran_num\n        data_idx = idx_without_decomp_wihtout_tran_num % (len(self.labels)/5)\n        cat_idx = int( idx_without_decomp_wihtout_tran_num // (len(self.labels)/5) )\n        label = np.zeros((2,5))\n        label[0,cat_idx] = weights[labels[cat_idx]]\n        label[1,cat_idx] = self.labels[idx_without_decomp_wihtout_tran_num][1]\n        sample = self.data[self.labels[idx_without_decomp_wihtout_tran_num][0]][tran_num][:,mask_extracted,:]\n        return sample, torch.from_numpy(label)#.unsqueeze(dim=0)\n\n\nclass HullDatasetTST(Dataset):\n    def __init__(self, data, labels, tran_num, decomp): #decomp - each sample is decomposed to N=decomp subsamples, it should be a power of 2, i.e. 2,4,8, etc.\n        self.data = data\n        self.labels =labels\n        self.tran_num = tran_num\n        self.decomp = decomp\n        self.shape = list(self.data[self.labels[1][0]][0].shape)[1:]\n        self.masks  = []\n        for i in range (self.decomp):\n            self.masks.append(list(range(i, self.shape[0], self.decomp)))\n\n    def __len__(self):\n        return len(self.labels)*10\n\n    def __getitem__(self, idx):\n        label = np.zeros((2,5))\n        sample_chunks = []\n\n        idx = random.randint(0, len(self.labels) - 1)\n        mask_num = random.randint(0, self.decomp - 1)\n        mask_extracted = self.masks[mask_num]\n        tran_num = random.randint(0, self.tran_num - 1)\n        data_idx = idx % (len(self.labels)/5)\n        cat_idx = int( idx // (len(self.labels)/5) )\n        \n        label = np.zeros((2,5))\n        label[0,cat_idx] =  weights[labels[cat_idx]] \n        label[1,cat_idx] = self.labels[idx][1] / self.decomp\n        \n        sample_chunks.append( self.data[self.labels[idx][0]][tran_num][:,mask_extracted,:])\n        \n        for i in range(1, self.decomp):\n            data_idx =  random.randint(0, len(self.labels)/5 - 1)\n            idx = data_idx + int(cat_idx*(len(self.labels)/5))\n            mask_num = random.randint(0, self.decomp - 1)\n            mask_extracted = self.masks[mask_num]\n            tran_num = random.randint(0, self.tran_num - 1)\n\n            label[1,cat_idx] = label[1,cat_idx] + self.labels[idx][1] / self.decomp\n            sample_chunks.append( self.data[self.labels[idx][0]][tran_num][:,mask_extracted,:])\n        return torch.cat(sample_chunks, dim=-2), torch.from_numpy(label)#.unsqueeze(dim=0)\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-24T19:55:25.399806Z","iopub.execute_input":"2026-01-24T19:55:25.400017Z","iopub.status.idle":"2026-01-24T19:55:25.420004Z","shell.execute_reply.started":"2026-01-24T19:55:25.400002Z","shell.execute_reply":"2026-01-24T19:55:25.419175Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#NN-used OBJECTS\nimport torch.nn as nn\n\n#weighted r^2:\ndef r_two(y_pred, y_true, weights=None):\n    if weights==None:\n        weights = torch.ones(list(y_pred.size()))\n    print(f'check {sum(y_true*weights)}')\n    y_true_w = torch.sum(y_true * weights) / torch.sum(weights)\n    ss_res = torch.sum(weights * torch.pow(y_true - y_pred,2))\n    ss_tot = torch.sum(weights * torch.pow(y_true - y_true_w,2))\n    print(f'check {ss_res}')\n    print(f'check {ss_tot}')\n    rez = 1 - (ss_res / ss_tot).item()\n    return rez, y_true_w.item()\n    \n\nclass Net(nn.Module):\n    def __init__(self, drip):\n        super(Net, self).__init__()\n        self.dropout1 = nn.Dropout(drip)\n        self.dropout2 = nn.Dropout(drip/2)\n        self.fc1 = nn.Linear(1536, 16)\n        self.fc2 = nn.Linear(1536, 5)\n        self.fc3 = nn.Linear(16, 5)\n        self.carfour = []\n        for i in range(5):\n            self.carfour.append(nn.Linear(16, 1))\n\n    def forward(self, x_in):\n        x = self.fc1(x_in)\n        x = F.sigmoid(x)\n        x = self.dropout1(x)\n        x = self.fc3 (x)\n        x = F.leaky_relu(x)\n        x = torch.mean(x, dim=(1, 2)) \n        return x\n\n\n\ndef r2_like_loss(y_pred, y_true):\n    y_true_w = torch.mean(y_true ) \n    ss_res = torch.sum( torch.pow(y_true - y_pred,2))\n    ss_tot = torch.sum(torch.pow(y_true - y_true_w,2))\n    rez = 1 - (ss_res / (0 + ss_tot))\n    return -rez\n\n\ndef r2_like_loss1(y_pred, y_true, y_true_w):\n    y_true[:,0,:] =torch.pow(y_true[:,0,:], 0.5)\n    y_pred = torch.sum( y_true[:,0,:] * y_pred, dim=-1 )\n    y_true_w = torch.sum( y_true[:,0,:] * y_true_w, dim=-1 )\n    y_true = torch.sum( y_true[:,0,:] * y_true[:,1,:], dim=-1 )\n    \n    ss_res = torch.sum( torch.pow(y_true - y_pred,2))\n    ss_tot = torch.sum(torch.pow(y_true - y_true_w,2))\n    rez = 1 - (ss_res / (0 + ss_tot))\n    return -rez","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def train( model,loss_f, device, train_loader, optimizer, epoch, y_true_w):\n    model.train()\n    test_loss = 0\n    correct = 0\n    for batch_idx, (data, target) in enumerate(train_loader):\n        data, target = data.to(device), target.to(device)\n        optimizer.zero_grad()\n        output = model(data)\n        loss = loss_f(output, target, y_true_w)\n        loss.backward()\n        optimizer.step()\n        if batch_idx % 500 == 0:\n            print('Train Epoch: {} [{}/{} ({:.0f}%)]\\tLoss: {:.6f}'.format(\n                epoch, batch_idx * len(data), len(train_loader.dataset),\n                100. * batch_idx / len(train_loader), loss.item()))\n\ndef test(model, device, test_loader, y_true_w):\n    model.eval()\n    test_loss = 0\n    correct = 0\n    p_all = None\n    t_all = None\n    with torch.no_grad():\n        for data, target in test_loader:\n            data, target = data.to(device), target.to(device)\n            output = model(data)\n            pred = output.round(decimals=9)  \n            if p_all == None:\n                p_all = pred\n                t_all = target\n            else:\n                p_all = torch.cat((p_all,pred))\n                t_all = torch.cat((t_all,target))\n    rez = r2_like_loss1(p_all, t_all, y_true_w).item()\n    print('\\nTest set: R2: {}\\n'.format(\n        rez))\n    return rez\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-24T19:55:25.445149Z","iopub.execute_input":"2026-01-24T19:55:25.445433Z","iopub.status.idle":"2026-01-24T19:55:25.461475Z","shell.execute_reply.started":"2026-01-24T19:55:25.445406Z","shell.execute_reply":"2026-01-24T19:55:25.460723Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"device = torch.device(\"cuda\")\nsplit = 0.2\nborder = int(split*len(test_embeds))\ny_train = []\ny_test = []\n\nif infer ==0:\n    for i in (\"Dry_Clover_g\", \"Dry_Dead_g\", \"Dry_Green_g\", \"Dry_Total_g\", \"GDM_g\"):\n        labls = get_labels(i)\n        y_train_l = labls[:-border]\n        y_test_l = labls[-border:]\n        y_train += y_train_l \n        y_test += y_test_l\n    \n        \n    x_train = dict(list(test_embeds.items())[:-border])\n    x_test = dict(list(test_embeds.items())[-border:])\n    #del test_embeds\n    gc.collect()\n    y_true_w_train = np.sum([j[1]*weights[labels[i//(len(y_train)/5)]] \n                             for i,j in enumerate(y_train)]) / np.sum([weights[labels[i//(len(y_train)/5)]] \n                                                                     for i,j in enumerate(y_train)])\n    y_true_w_test = np.sum([j[1]*weights[labels[i//(len(y_test)/5)]] \n                             for i,j in enumerate(y_test)]) / np.sum([weights[labels[i//(len(y_test)/5)]] \n                                                                     for i,j in enumerate(y_test)])\n    tran_num = len(augmentation_transforms)\n    dataset1 = DatasetTRN(x_train,y_train,tran_num,4)\n    del x_train\n    dataset2 = DatasetTST(x_test,y_test,tran_num,1)\n    del x_test\n    gc.collect()\n    train_loader = DataLoader(dataset1, batch_size=32, shuffle=True, num_workers=0)\n    gc.collect()\n    test_loader = DataLoader(dataset2, batch_size=32, #len(dataset2), \n                             shuffle=False, num_workers=0)\n    \n    model_ch = Net(0.3).to(device)\n    optimizer = optim.Adadelta(model_ch.parameters(), lr=1)\n    scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(\n    optimizer, mode=\"min\", patience=3\n)\n    best_val_acc = 0.0\n    for epoch in range(1, 50 + 1):\n            train( model_ch,\n                  #F.mse_loss, \n                  r2_like_loss1, \n                  device, train_loader, optimizer, epoch, y_true_w_train)\n            gc.collect()\n            val_loss  = test(model_ch, device,test_loader, y_true_w_test)\n            if val_loss  < best_val_acc:\n                best_val_acc = val_loss\n                torch.save(model_ch.state_dict(), \"best_model.pth\")\n            scheduler.step(val_loss)\n\n\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-24T20:12:33.629610Z","iopub.execute_input":"2026-01-24T20:12:33.629868Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if infer==1:\n    model_ch = Net(0.46).to(device)\n    checkpoint = torch.load(\"/kaggle/input/csmix/pytorch/default/1/best_model (4).pth\", map_location=\"cuda\")\n    model_ch.load_state_dict(checkpoint)\n    model_ch.eval()\n            ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-24T19:55:27.077832Z","iopub.status.idle":"2026-01-24T19:55:27.078035Z","shell.execute_reply.started":"2026-01-24T19:55:27.077938Z","shell.execute_reply":"2026-01-24T19:55:27.077947Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if infer==1:\n    submission = pd.DataFrame(columns = ['sample_id','target'])\n    \n    y_train = []\n    y_test = []\n\n    mapping = {\"Dry_Clover_g\": 0, \"Dry_Dead_g\": 1, \"Dry_Green_g\": 2, \"Dry_Total_g\": 3, \"GDM_g\": 4}\n\n    \n   \n    transform = transforms.Compose([transforms.ToTensor(), transforms.Resize((224, 224)), transforms.Normalize(mean, std)])\n    train_df = pd.read_csv(\"/kaggle/input/csiro-biomass/test.csv\")\n    augmentation_transforms = [\n        transforms.Compose([transforms.ToTensor(), transforms.Resize((224, 224)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(3)]),  # Original\n        transforms.Compose([transforms.RandomHorizontalFlip(p=1.0), transforms.ToTensor(), transforms.Resize((224, 224)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(3)]),  # Horizontal flip\n        transforms.Compose([transforms.RandomVerticalFlip(p=1.0), transforms.ToTensor(), transforms.Resize((224, 224)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(5)]),  # Vertical flip\n        transforms.Compose([transforms.RandomHorizontalFlip(p=1.0), transforms.RandomVerticalFlip(p=1.0), transforms.ToTensor(), transforms.Resize((224, 224)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(5)]),  # Both flips\n        transforms.Compose([transforms.RandomRotation(degrees=25), transforms.ToTensor(), transforms.Resize((224, 224)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(5)]),  # 90 degree rotation\n        transforms.Compose([transforms.RandomRotation(degrees=35), transforms.ToTensor(), transforms.Resize((224, 224)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(3)]),  # 270 degree rotation\n    ]\n    root = \"/kaggle/input/csiro-biomass/\"\n    \n    augmentation_transforms1 = [\n        transforms.Compose([transforms.ToTensor(), transforms.Resize((224*2, 224*2)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(3)]),  # Original\n        transforms.Compose([transforms.RandomHorizontalFlip(p=1.0), transforms.ToTensor(), transforms.Resize((224*2, 224*2)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(3)]),  # Horizontal flip\n        transforms.Compose([transforms.RandomVerticalFlip(p=1.0), transforms.ToTensor(), transforms.Resize((224*2, 224*2)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(5)]),  # Vertical flip\n        transforms.Compose([transforms.RandomHorizontalFlip(p=1.0), transforms.RandomVerticalFlip(p=1.0), transforms.ToTensor(), transforms.Resize((224*2, 224*2)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(5)]),  # Both flips\n        transforms.Compose([transforms.RandomRotation(degrees=25), transforms.ToTensor(), transforms.Resize((224*2, 224*2)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(5)]),  # 90 degree rotation\n        transforms.Compose([transforms.RandomRotation(degrees=35), transforms.ToTensor(), transforms.Resize((224*2, 224*2)), transforms.Normalize(mean, std), torchvision.transforms.GaussianBlur(3)]),  # 270 degree rotation\n    ]\n\n    \n    with torch.inference_mode():\n      for i in set(train_df['image_path']):\n        sampl = train_df.loc[train_df['image_path']==i].iloc[0:1]\n        x_train = get_feats(sampl, augmentation_transforms1)\n        for key in x_train:\n            gc.collect()\n            avgd_preds = sum(model_ch(x_train[key].cuda()).detach().cpu().numpy())/6\n            for i,j in enumerate((\"Dry_Clover_g\", \"Dry_Dead_g\", \"Dry_Green_g\", \"Dry_Total_g\", \"GDM_g\")):\n                sample_id = key +'__'+ j\n                target = avgd_preds[i]\n                submission = pd.concat([pd.DataFrame([[sample_id,target]], columns=submission.columns), submission], ignore_index=True)\n  \n    \n    \n  \n    \n    \n    \n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-24T19:55:27.079526Z","iopub.status.idle":"2026-01-24T19:55:27.079854Z","shell.execute_reply.started":"2026-01-24T19:55:27.079697Z","shell.execute_reply":"2026-01-24T19:55:27.079711Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%cd /kaggle/working\nsubmission.to_csv('submission.csv', index=False)\nsubmission","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-24T19:55:27.080828Z","iopub.status.idle":"2026-01-24T19:55:27.081041Z","shell.execute_reply.started":"2026-01-24T19:55:27.080937Z","shell.execute_reply":"2026-01-24T19:55:27.080947Z"}},"outputs":[],"execution_count":null}]}