{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":47317,"databundleVersionId":5799376,"sourceType":"competition"},{"sourceId":699609,"sourceType":"datasetVersion","datasetId":255887},{"sourceId":3492463,"sourceType":"datasetVersion","datasetId":2102244},{"sourceId":3492503,"sourceType":"datasetVersion","datasetId":2102274},{"sourceId":5634217,"sourceType":"datasetVersion","datasetId":3235533},{"sourceId":5713214,"sourceType":"datasetVersion","datasetId":3284273},{"sourceId":5728283,"sourceType":"datasetVersion","datasetId":3103325}],"dockerImageVersionId":30408,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Introduction\nThis notebook is based on \n1. [2.5d segmentaion baseline [training]](https://www.kaggle.com/code/tanakar/2-5d-segmentaion-baseline-training)\n2. [2.5d segmentaion baseline [inference]](https://www.kaggle.com/code/tanakar/2-5d-segmentaion-baseline-inference)\n3. [Vesuvius Challenge - 3D ResNet Training](https://www.kaggle.com/code/samfc10/vesuvius-challenge-3d-resnet-training)\n4. [Improving performance with L1/Hessian denoising](https://www.kaggle.com/code/brettolsen/improving-performance-with-l1-hessian-denoising)\n\nThank them for letting us learn more.(^w^)","metadata":{}},{"cell_type":"markdown","source":"Base parameter:\n1. ResNet34\n2. 1fold only!! (Use 2,3 to train and 1 to val)\n3. use 16 channels\n4. loss = 0.5 * BCELoss + 0.5 * DiceLoss\n\nthen get cv0.55 (^w^)\n","metadata":{}},{"cell_type":"code","source":"import os,cv2\nimport gc\nimport sys\nimport random\nfrom glob import glob\nimport numpy as np\nimport pandas as pd\nfrom tqdm import tqdm\nimport matplotlib.pyplot as plt\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.cuda import amp\nfrom torch.utils.data import Dataset, DataLoader\n\nsys.path.append(\"/kaggle/input/resnet3d\")\nfrom resnet3d import generate_model\nimport torch as tc","metadata":{"execution":{"iopub.status.busy":"2026-02-08T10:41:37.224057Z","iopub.execute_input":"2026-02-08T10:41:37.224447Z","iopub.status.idle":"2026-02-08T10:41:40.156262Z","shell.execute_reply.started":"2026-02-08T10:41:37.224415Z","shell.execute_reply":"2026-02-08T10:41:40.154915Z"},"trusted":true},"outputs":[],"execution_count":1},{"cell_type":"code","source":"class CFG:\n    # ============== comp exp name =============\n    comp_name = 'vesuvius'\n\n    # comp_dir_path = './'\n    comp_dir_path = '/kaggle/input/'\n    comp_folder_name = 'vesuvius-challenge-ink-detection'\n    # comp_dataset_path = f'{comp_dir_path}datasets/{comp_folder_name}/'\n    comp_dataset_path = f'{comp_dir_path}{comp_folder_name}/'\n    \n    exp_name = 'vesuvius_2d_slide_exp002'\n\n    # ============== pred target =============\n    target_size = 1\n\n    # ============== model cfg =============\n    model_name = 'Unet'\n    #backbone = 'efficientnet-b5'\n    #backbone = 'mit_b5'\n    backbone = 'resnet3d'\n    #backbone = 'resnext50_32x4d'\n    pretrained = True\n\n    in_chans = 16 # 65\n    load_chans=16\n    # ============== training cfg =============\n    prd_size=192\n    stride = prd_size // 8\n\n    batch_size = 24 # 32\n    use_amp = True\n\n    seed = 42\n    num_workers=2","metadata":{"execution":{"iopub.status.busy":"2023-05-18T05:05:37.813627Z","iopub.execute_input":"2023-05-18T05:05:37.814777Z","iopub.status.idle":"2023-05-18T05:05:37.82481Z","shell.execute_reply.started":"2023-05-18T05:05:37.814737Z","shell.execute_reply":"2023-05-18T05:05:37.823645Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## helper","metadata":{}},{"cell_type":"code","source":"# ref.: https://www.kaggle.com/stainsby/fast-tested-rle\ndef rle(img):\n    '''\n    img: numpy array, 1 - mask, 0 - background\n    Returns run length as string formated\n    '''\n    pixels = img.flatten()\n    # pixels = (pixels >= thr).astype(int)\n    \n    pixels = np.concatenate([[0], pixels, [0]])\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1\n    runs[1::2] -= runs[::2]\n    return ' '.join(str(x) for x in runs)\ndef normalization(x:tc.Tensor)->tc.Tensor:\n    \"\"\"input.shape=(batch,f1,f2,...)\"\"\"\n    #[batch,f1,f2]->dim[1,2]\n    dim=list(range(1,x.ndim))\n    mean=x.mean(dim=dim,keepdim=True)\n    std=x.std(dim=dim,keepdim=True)\n    return (x-mean)/(std+1e-9)\n\ndef get_folder_size(folder_path):\n    total_size = 0\n    for dirpath, dirnames, filenames in os.walk(folder_path):\n        for f in filenames:\n            fp = os.path.join(dirpath, f)\n            total_size += os.path.getsize(fp)\n    return total_size","metadata":{"execution":{"iopub.status.busy":"2023-05-18T05:05:37.826465Z","iopub.execute_input":"2023-05-18T05:05:37.827281Z","iopub.status.idle":"2023-05-18T05:05:37.841307Z","shell.execute_reply.started":"2023-05-18T05:05:37.827238Z","shell.execute_reply":"2023-05-18T05:05:37.840253Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## L1/Hessian denoising","metadata":{}},{"cell_type":"code","source":"import cupy as cp\nxp = cp\n\ndelta_lookup = {\n    \"xx\": xp.array([[1, -2, 1]], dtype=float),\n    \"yy\": xp.array([[1], [-2], [1]], dtype=float),\n    \"xy\": xp.array([[1, -1], [-1, 1]], dtype=float),\n}\n\ndef operate_derivative(img_shape, pair):\n    assert len(img_shape) == 2\n    delta = delta_lookup[pair]\n    fft = xp.fft.fftn(delta, img_shape)\n    return fft * xp.conj(fft)\n\ndef soft_threshold(vector, threshold):\n    return xp.sign(vector) * xp.maximum(xp.abs(vector) - threshold, 0)\n\ndef back_diff(input_image, dim):\n    assert dim in (0, 1)\n    r, n = xp.shape(input_image)\n    size = xp.array((r, n))\n    position = xp.zeros(2, dtype=int)\n    temp1 = xp.zeros((r+1, n+1), dtype=float)\n    temp2 = xp.zeros((r+1, n+1), dtype=float)\n    \n    temp1[position[0]:size[0], position[1]:size[1]] = input_image\n    temp2[position[0]:size[0], position[1]:size[1]] = input_image\n    \n    size[dim] += 1\n    position[dim] += 1\n    temp2[position[0]:size[0], position[1]:size[1]] = input_image\n    temp1 -= temp2\n    size[dim] -= 1\n    return temp1[0:size[0], 0:size[1]]\n\ndef forward_diff(input_image, dim):\n    assert dim in (0, 1)\n    r, n = xp.shape(input_image)\n    size = xp.array((r, n))\n    position = xp.zeros(2, dtype=int)\n    temp1 = xp.zeros((r+1, n+1), dtype=float)\n    temp2 = xp.zeros((r+1, n+1), dtype=float)\n        \n    size[dim] += 1\n    position[dim] += 1\n\n    temp1[position[0]:size[0], position[1]:size[1]] = input_image\n    temp2[position[0]:size[0], position[1]:size[1]] = input_image\n    \n    size[dim] -= 1\n    temp2[0:size[0], 0:size[1]] = input_image\n    temp1 -= temp2\n    size[dim] += 1\n    return -temp1[position[0]:size[0], position[1]:size[1]]\n\ndef iter_deriv(input_image, b, scale, mu, dim1, dim2):\n    g = back_diff(forward_diff(input_image, dim1), dim2)\n    d = soft_threshold(g + b, 1 / mu)\n    b = b + (g - d)\n    L = scale * back_diff(forward_diff(d - b, dim2), dim1)\n    return L, b\n\ndef iter_xx(*args):\n    return iter_deriv(*args, dim1=1, dim2=1)\n\ndef iter_yy(*args):\n    return iter_deriv(*args, dim1=0, dim2=0)\n\ndef iter_xy(*args):\n    return iter_deriv(*args, dim1=0, dim2=1)\n\ndef iter_sparse(input_image, bsparse, scale, mu):\n    d = soft_threshold(input_image + bsparse, 1 / mu)\n    bsparse = bsparse + (input_image - d)\n    Lsparse = scale * (d - bsparse)\n    return Lsparse, bsparse\n\ndef denoise_image(input_image, iter_num=100, fidelity=150, sparsity_scale=10, continuity_scale=0.5, mu=1):\n    image_size = xp.shape(input_image)\n    #print(\"Initialize denoising\")\n    norm_array = (\n        operate_derivative(image_size, \"xx\") + \n        operate_derivative(image_size, \"yy\") + \n        2 * operate_derivative(image_size, \"xy\")\n    )\n    norm_array += (fidelity / mu) + sparsity_scale ** 2\n    b_arrays = {\n        \"xx\": xp.zeros(image_size, dtype=float),\n        \"yy\": xp.zeros(image_size, dtype=float),\n        \"xy\": xp.zeros(image_size, dtype=float),\n        \"L1\": xp.zeros(image_size, dtype=float),\n    }\n    g_update = xp.multiply(fidelity / mu, input_image)\n    for i in tqdm(range(iter_num), total=iter_num):\n        #print(f\"Starting iteration {i+1}\")\n        g_update = xp.fft.fftn(g_update)\n        if i == 0:\n            g = xp.fft.ifftn(g_update / (fidelity / mu)).real\n        else:\n            g = xp.fft.ifftn(xp.divide(g_update, norm_array)).real\n        g_update = xp.multiply((fidelity / mu), input_image)\n        \n        #print(\"XX update\")\n        L, b_arrays[\"xx\"] = iter_xx(g, b_arrays[\"xx\"], continuity_scale, mu)\n        g_update += L\n        \n        #print(\"YY update\")\n        L, b_arrays[\"yy\"] = iter_yy(g, b_arrays[\"yy\"], continuity_scale, mu)\n        g_update += L\n        \n        #print(\"XY update\")\n        L, b_arrays[\"xy\"] = iter_xy(g, b_arrays[\"xy\"], 2 * continuity_scale, mu)\n        g_update += L\n        \n        #print(\"L1 update\")\n        L, b_arrays[\"L1\"] = iter_sparse(g, b_arrays[\"L1\"], sparsity_scale, mu)\n        g_update += L\n        \n    g_update = xp.fft.fftn(g_update)\n    g = xp.fft.ifftn(xp.divide(g_update, norm_array)).real\n    \n    g[g < 0] = 0\n    g -= g.min()\n    g /= g.max()\n    return g","metadata":{"execution":{"iopub.status.busy":"2023-05-18T05:05:37.845657Z","iopub.execute_input":"2023-05-18T05:05:37.846035Z","iopub.status.idle":"2023-05-18T05:05:37.883804Z","shell.execute_reply.started":"2023-05-18T05:05:37.846004Z","shell.execute_reply":"2023-05-18T05:05:37.882552Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## dataset","metadata":{}},{"cell_type":"code","source":"def read_image(fragment_id):\n    images = []\n\n    # idxs = range(65)\n    mid = 65 // 2\n    start = mid - CFG.in_chans // 2\n    end = mid + CFG.in_chans // 2\n    idxs = range(start, end)\n\n    for i in tqdm(idxs):\n        image = cv2.imread(CFG.comp_dataset_path + f\"{mode}/{fragment_id}/surface_volume/{i:02}.tif\", 0)\n\n        pad0 = (CFG.prd_size - image.shape[0] % CFG.prd_size)\n        pad1 = (CFG.prd_size - image.shape[1] % CFG.prd_size)\n\n        image = np.pad(image, [(0, pad0), (0, pad1)], constant_values=0)\n\n        images.append(image)\n    images = np.stack(images, axis=2)\n    \n    return images","metadata":{"execution":{"iopub.status.busy":"2023-05-18T05:05:37.96084Z","iopub.execute_input":"2023-05-18T05:05:37.961199Z","iopub.status.idle":"2023-05-18T05:05:37.969555Z","shell.execute_reply.started":"2023-05-18T05:05:37.961169Z","shell.execute_reply":"2023-05-18T05:05:37.96832Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class CustomDataset(Dataset):\n    def __init__(self, images, cfg,xys, labels=None):\n        self.images = images\n        self.cfg = cfg\n        self.labels = labels\n        self.xys=xys\n\n    def __len__(self):\n        # return len(self.xyxys)\n        return len(self.images)\n\n    def __getitem__(self, idx):\n        # x1, y1, x2, y2 = self.xyxys[idx]\n        image = self.images[idx]\n        image=tc.from_numpy(image).permute(2,0,1).to(tc.float32)/255\n        image = (image - 0.45)/0.225\n        return image,self.xys[idx]\n","metadata":{"execution":{"iopub.status.busy":"2023-05-18T05:05:37.972104Z","iopub.execute_input":"2023-05-18T05:05:37.972599Z","iopub.status.idle":"2023-05-18T05:05:37.982419Z","shell.execute_reply.started":"2023-05-18T05:05:37.972562Z","shell.execute_reply":"2023-05-18T05:05:37.981368Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def make_test_dataset(fragment_id):\n    test_images = read_image(fragment_id)\n    \n    x1_list = list(range(0, test_images.shape[1]-CFG.prd_size+1, CFG.stride))\n    y1_list = list(range(0, test_images.shape[0]-CFG.prd_size+1, CFG.stride))\n    \n    test_images_list = []\n    xyxys = []\n    for y1 in y1_list:\n        for x1 in x1_list:\n            y2 = y1 + CFG.prd_size\n            x2 = x1 + CFG.prd_size\n            if np.all(test_images[y1:y2, x1:x2]==0):\n                continue\n            test_images_list.append(test_images[y1:y2, x1:x2])\n            xyxys.append((x1, y1, x2, y2))\n    xyxys = np.stack(xyxys)\n            \n    test_dataset = CustomDataset(test_images_list, CFG,xys=xyxys)\n    \n    test_loader = DataLoader(test_dataset,\n                          batch_size=CFG.batch_size,\n                          shuffle=False,\n                          num_workers=CFG.num_workers, pin_memory=True, drop_last=False)\n    \n    return test_loader, xyxys","metadata":{"execution":{"iopub.status.busy":"2023-05-18T05:05:37.983869Z","iopub.execute_input":"2023-05-18T05:05:37.984974Z","iopub.status.idle":"2023-05-18T05:05:37.996389Z","shell.execute_reply.started":"2023-05-18T05:05:37.984894Z","shell.execute_reply":"2023-05-18T05:05:37.995129Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 3D ResNet","metadata":{}},{"cell_type":"code","source":"class Decoder(nn.Module):\n    def __init__(self, encoder_dims, upscale):\n        super().__init__()\n        self.convs = nn.ModuleList([\n            nn.Sequential(\n                nn.Conv2d(encoder_dims[i]+encoder_dims[i-1], encoder_dims[i-1], 3, 1, 1, bias=False),\n                nn.BatchNorm2d(encoder_dims[i-1]),\n                nn.ReLU(inplace=True)\n            ) for i in range(1, len(encoder_dims))])\n\n        self.logit = nn.Conv2d(encoder_dims[0], 1, 1, 1, 0)\n        self.up = nn.Upsample(scale_factor=upscale, mode=\"bilinear\")\n\n    def forward(self, feature_maps):\n        for i in range(len(feature_maps)-1, 0, -1):\n            f_up = F.interpolate(feature_maps[i], scale_factor=2, mode=\"bilinear\")\n            f = torch.cat([feature_maps[i-1], f_up], dim=1)\n            f_down = self.convs[i-1](f)\n            feature_maps[i-1] = f_down\n\n        x = self.logit(feature_maps[0])\n        mask = self.up(x)\n        return mask\n    \nclass SegModel(nn.Module):\n    def __init__(self,model_depth=34):\n        super().__init__()\n        self.encoder = generate_model(model_depth=model_depth, n_input_channels=1)\n        self.decoder = Decoder(encoder_dims=[64, 128, 256, 512], upscale=4)\n        \n    def forward(self, x):\n        if x.ndim==4:\n            x=x[:,None]\n        \n        feat_maps = self.encoder(x)\n        feat_maps_pooled = [torch.mean(f, dim=2) for f in feat_maps]\n        pred_mask = self.decoder(feat_maps_pooled)\n        return pred_mask\n        \nclass CustomModel(nn.Module):\n    def __init__(self, cfg=CFG, weight=None):\n        super().__init__()\n        self.cfg = cfg\n\n        if cfg.backbone==\"resnet3d\":\n            self.encoder=SegModel()\n        elif cfg.backbone[:3]!=\"mit\":\n            self.encoder = smp.Unet(\n                encoder_name=cfg.backbone, \n                encoder_weights=weight,\n                in_channels=cfg.in_chans,\n                classes=cfg.target_size,\n                activation=None,\n            )\n        else :\n            self.encoder = smp.Unet(\n                encoder_name=cfg.backbone, \n                encoder_weights=weight,\n                classes=cfg.target_size,\n                activation=None,\n            )\n            print(self.encoder.encoder.patch_embed1.proj)\n            out_channels=self.encoder.encoder.patch_embed1.proj.out_channels\n            self.encoder.encoder.patch_embed1.proj=nn.Conv2d(cfg.in_chans,out_channels,7,4,3)\n\n    def forward(self, images:torch.Tensor):\n        #image.shape=(b,C,H,W)\n        if images.ndim==4:\n            images=images[:,None]\n        images=normalization(images)\n        output = self.encoder(images)\n        return output\n\ndef build_model(cfg, weight=\"imagenet\"):\n    print('model_name', cfg.model_name)\n    print('backbone', cfg.backbone)\n\n    model = CustomModel(cfg, weight)\n    return model\n","metadata":{"execution":{"iopub.status.busy":"2023-05-18T05:05:37.998208Z","iopub.execute_input":"2023-05-18T05:05:37.99883Z","iopub.status.idle":"2023-05-18T05:05:38.197442Z","shell.execute_reply.started":"2023-05-18T05:05:37.998793Z","shell.execute_reply":"2023-05-18T05:05:38.196189Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def TTA(x:tc.Tensor,model:nn.Module):\n    #x.shape=(batch,c,h,w)\n    shape=x.shape\n    x=[x,*[tc.rot90(x,k=i,dims=(-2,-1)) for i in range(1,4)]]\n    x=tc.cat(x,dim=0)\n    x=model(x)\n    x=torch.sigmoid(x)\n    x=x.reshape(4,shape[0],*shape[2:])\n    x=[tc.rot90(x[i],k=-i,dims=(-2,-1)) for i in range(4)]\n    x=tc.stack(x,dim=0)\n    return x.mean(0)","metadata":{"execution":{"iopub.status.busy":"2023-05-18T05:05:38.20123Z","iopub.execute_input":"2023-05-18T05:05:38.202161Z","iopub.status.idle":"2023-05-18T05:05:38.213584Z","shell.execute_reply.started":"2023-05-18T05:05:38.202121Z","shell.execute_reply":"2023-05-18T05:05:38.212513Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#in_submission=get_folder_size(\"/kaggle/input/vesuvius-challenge-ink-detection/test\")!=6732244267\nin_submission=True\nIS_DEBUG = False\nmode = 'train' if IS_DEBUG else 'test'\nTH = 0.55\nif mode == 'test':\n    fragment_ids = sorted(os.listdir(CFG.comp_dataset_path + mode))\nelse:\n    fragment_ids = [3]\n\nmodel = build_model(CFG)\nmodel.load_state_dict(tc.load(\"/kaggle/input/3d-resnet-baseline-inference-model-data/resnet3d-34_3d_seg_epoch_14.pth\"))\nmodel = nn.DataParallel(model, device_ids=[0, 1])\nmodel = model.cuda()#.eval()\nmodel.training","metadata":{"execution":{"iopub.status.busy":"2023-05-18T05:05:38.215837Z","iopub.execute_input":"2023-05-18T05:05:38.216573Z","iopub.status.idle":"2023-05-18T05:05:42.03788Z","shell.execute_reply.started":"2023-05-18T05:05:38.216529Z","shell.execute_reply":"2023-05-18T05:05:42.036598Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## main","metadata":{}},{"cell_type":"code","source":"results = []\nfor fragment_id in fragment_ids:\n    if not in_submission:\n        break\n    test_loader, xyxys = make_test_dataset(fragment_id)\n    \n    binary_mask = cv2.imread(CFG.comp_dataset_path + f\"{mode}/{fragment_id}/mask.png\", 0)\n    binary_mask = (binary_mask / 255).astype(int)\n    \n    ori_h = binary_mask.shape[0]\n    ori_w = binary_mask.shape[1]\n\n    pad0 = (CFG.prd_size - binary_mask.shape[0] % CFG.prd_size)\n    pad1 = (CFG.prd_size - binary_mask.shape[1] % CFG.prd_size)\n\n    binary_mask = np.pad(binary_mask, [(0, pad0), (0, pad1)], constant_values=0)\n\n    mask_pred = np.zeros(binary_mask.shape)\n    mask_count = np.zeros(binary_mask.shape)\n    for step, (images,xys) in tqdm(enumerate(test_loader), total=len(test_loader)):\n        images = images.cuda()\n        batch_size = images.size(0)\n\n        with torch.no_grad():\n            y_preds=TTA(images,model)\n            \n        \n        for k, (x1, y1, x2, y2) in enumerate(xys):\n            mask_pred[y1:y2, x1:x2] += y_preds[k].squeeze(0).cpu().numpy()\n            mask_count[y1:y2, x1:x2] += 1\n        \n    print(f'mask_count_min: {mask_count.min()}')\n    mask_pred /= (mask_count+1e-7)\n\n    \n    fig, axes = plt.subplots(1, 4, figsize=(15, 8))\n    axes[0].imshow(mask_count)\n    axes[1].imshow(mask_pred.copy())\n    \n    mask_pred=xp.array(mask_pred)\n    mask_pred=denoise_image(mask_pred, iter_num=250)\n    mask_pred=mask_pred.get()\n    axes[2].imshow(mask_pred)\n    \n    mask_pred = mask_pred[:ori_h, :ori_w]\n    binary_mask = binary_mask[:ori_h, :ori_w]\n    \n    mask_pred = (mask_pred >= TH).astype(np.uint8)\n    mask_pred=mask_pred.astype(int)\n    mask_pred *= binary_mask\n    \n    axes[3].imshow(mask_pred)\n    plt.show()\n    \n    inklabels_rle = rle(mask_pred)\n    \n    results.append((fragment_id, inklabels_rle))\n    \n\n    del mask_pred, mask_count\n    del test_loader\n    \n    gc.collect()\n    torch.cuda.empty_cache()\n    plt.clf()\n    fig.clear()\n    plt.close(fig)","metadata":{"execution":{"iopub.status.busy":"2023-05-18T05:05:42.040711Z","iopub.execute_input":"2023-05-18T05:05:42.041465Z","iopub.status.idle":"2023-05-18T05:06:06.128361Z","shell.execute_reply.started":"2023-05-18T05:05:42.041423Z","shell.execute_reply":"2023-05-18T05:06:06.126683Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## submission","metadata":{}},{"cell_type":"code","source":"! cp /kaggle/input/vesuvius-challenge-ink-detection/sample_submission.csv submission.csv\nif in_submission:\n    sub = pd.DataFrame(results, columns=['Id', 'Predicted'])\n    #sub\n    sample_sub = pd.read_csv(CFG.comp_dataset_path + 'sample_submission.csv')\n    sample_sub = pd.merge(sample_sub[['Id']], sub, on='Id', how='left')\n    #sample_sub\n    sample_sub.to_csv(\"submission.csv\", index=False)\n    print(\"ok\")","metadata":{"execution":{"iopub.status.busy":"2023-05-18T05:06:08.4008Z","iopub.execute_input":"2023-05-18T05:06:08.40128Z","iopub.status.idle":"2023-05-18T05:06:09.64892Z","shell.execute_reply.started":"2023-05-18T05:06:08.401245Z","shell.execute_reply":"2023-05-18T05:06:09.647393Z"},"trusted":true},"outputs":[],"execution_count":null}]}