{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"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":"2023-06-14T13:01:02.093592Z","iopub.execute_input":"2023-06-14T13:01:02.094115Z","iopub.status.idle":"2023-06-14T13:01:05.382735Z","shell.execute_reply.started":"2023-06-14T13:01:02.094065Z","shell.execute_reply":"2023-06-14T13:01:05.381558Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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 = 16 # 32\n    use_amp = True\n\n    seed = 42\n    num_workers=2","metadata":{"execution":{"iopub.status.busy":"2023-06-14T13:01:05.385490Z","iopub.execute_input":"2023-06-14T13:01:05.386091Z","iopub.status.idle":"2023-06-14T13:01:05.397292Z","shell.execute_reply.started":"2023-06-14T13:01:05.386049Z","shell.execute_reply":"2023-06-14T13:01:05.396045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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-06-14T13:01:05.399248Z","iopub.execute_input":"2023-06-14T13:01:05.399735Z","iopub.status.idle":"2023-06-14T13:01:05.415104Z","shell.execute_reply.started":"2023-06-14T13:01:05.399694Z","shell.execute_reply":"2023-06-14T13:01:05.413989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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-06-14T13:01:05.418557Z","iopub.execute_input":"2023-06-14T13:01:05.419049Z","iopub.status.idle":"2023-06-14T13:01:09.963334Z","shell.execute_reply.started":"2023-06-14T13:01:05.419010Z","shell.execute_reply":"2023-06-14T13:01:09.962160Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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-06-14T13:01:09.964903Z","iopub.execute_input":"2023-06-14T13:01:09.968204Z","iopub.status.idle":"2023-06-14T13:01:09.978201Z","shell.execute_reply.started":"2023-06-14T13:01:09.968159Z","shell.execute_reply":"2023-06-14T13:01:09.976824Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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-06-14T13:01:09.979620Z","iopub.execute_input":"2023-06-14T13:01:09.981944Z","iopub.status.idle":"2023-06-14T13:01:09.991525Z","shell.execute_reply.started":"2023-06-14T13:01:09.981901Z","shell.execute_reply":"2023-06-14T13:01:09.990414Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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-06-14T13:01:09.993202Z","iopub.execute_input":"2023-06-14T13:01:09.993734Z","iopub.status.idle":"2023-06-14T13:01:10.007135Z","shell.execute_reply.started":"2023-06-14T13:01:09.993690Z","shell.execute_reply":"2023-06-14T13:01:10.005921Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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, 1024, 2048], 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-06-14T13:01:10.009120Z","iopub.execute_input":"2023-06-14T13:01:10.009571Z","iopub.status.idle":"2023-06-14T13:01:10.033086Z","shell.execute_reply.started":"2023-06-14T13:01:10.009531Z","shell.execute_reply":"2023-06-14T13:01:10.031951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def TTA_models(x:tc.Tensor,model_list):\n    model = model_list[0]\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    \n    model = model_list[1]\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-06-14T13:01:10.034732Z","iopub.execute_input":"2023-06-14T13:01:10.035551Z","iopub.status.idle":"2023-06-14T13:01:10.049688Z","shell.execute_reply.started":"2023-06-14T13:01:10.035510Z","shell.execute_reply":"2023-06-14T13:01:10.048513Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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-06-14T13:01:10.054603Z","iopub.execute_input":"2023-06-14T13:01:10.054903Z","iopub.status.idle":"2023-06-14T13:01:10.066229Z","shell.execute_reply.started":"2023-06-14T13:01:10.054874Z","shell.execute_reply":"2023-06-14T13:01:10.064948Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"in_submission=get_folder_size(\"/kaggle/input/vesuvius-challenge-ink-detection/test\")!=6732244267\nIS_DEBUG = False\nmode = 'train' if IS_DEBUG else 'test'","metadata":{"execution":{"iopub.status.busy":"2023-06-14T13:01:10.067952Z","iopub.execute_input":"2023-06-14T13:01:10.068400Z","iopub.status.idle":"2023-06-14T13:01:10.096009Z","shell.execute_reply.started":"2023-06-14T13:01:10.068343Z","shell.execute_reply":"2023-06-14T13:01:10.095085Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h1 style=\"color: #6cb4e4;  text-align: center;  padding: 0.25em;  \n           border-top: solid 2.5px #16d60f;  \n           border-bottom: solid 2.5px #16d60f; \n           background: repeating-linear-gradient(-45deg, #000603, #000603 3px,#000603 3px, #000603 7px);\n           height:45px;\">\n<b>Model</b>\n</h1> ","metadata":{}},{"cell_type":"markdown","source":"```\nEpoch 86/200  Mem : 7.39GB  LR : 7.03E-05  Loss: 0.0910: 100%|██████████| 178/178 [01:15<00:00,  2.35it/s]\nVal Loss: 0.1858: 100%|██████████| 37/37 [00:12<00:00,  3.08it/s]\n\nThreshold : 0.20\tFBeta : 0.554708\nThreshold : 0.25\tFBeta : 0.579477\nThreshold : 0.30\tFBeta : 0.599039\nThreshold : 0.35\tFBeta : 0.613585\nThreshold : 0.40\tFBeta : 0.626378\nThreshold : 0.45\tFBeta : 0.636743\nThreshold : 0.50\tFBeta : 0.644397\nThreshold : 0.55\tFBeta : 0.649481\nThreshold : 0.60\tFBeta : 0.649233\nThreshold : 0.65\tFBeta : 0.645716\nThreshold : 0.70\tFBeta : 0.639150\nThreshold : 0.75\tFBeta : 0.626562\nThreshold : 0.80\tFBeta : 0.607574\n-->Improve:0.649481\n```","metadata":{}},{"cell_type":"markdown","source":"```\n\nEpoch 65/100  Mem : 7.39GB  LR : 3.29E-05  Loss: 0.1010: 100%|██████████| 178/178 [01:18<00:00,  2.27it/s]\nVal Loss: 0.2192: 100%|██████████| 37/37 [00:13<00:00,  2.69it/s]\n\nThreshold : 0.20    FBeta : 0.597576\nThreshold : 0.25    FBeta : 0.611320\nThreshold : 0.30    FBeta : 0.620045\nThreshold : 0.35    FBeta : 0.624579\nThreshold : 0.40    FBeta : 0.626842\nThreshold : 0.45    FBeta : 0.626182\nThreshold : 0.50    FBeta : 0.622581\nThreshold : 0.55    FBeta : 0.615768\nThreshold : 0.60    FBeta : 0.604203\nThreshold : 0.65    FBeta : 0.588721\nThreshold : 0.70    FBeta : 0.569466\nThreshold : 0.75    FBeta : 0.544499\nThreshold : 0.80    FBeta : 0.508851\n-->Improve:0.626842\n\n```","metadata":{}},{"cell_type":"markdown","source":"```\nBC-200-TRAIN-3dresnet-d34x256-x2048-RotFlip-s22-e200-LossTversky-test1\n\nEpoch 113/200  Mem : 7.43GB  LR : 4.74E-05  Loss: 0.1566: 100%|██████████| 168/168 [01:14<00:00,  2.27it/s]\nVal Loss: 0.4495: 100%|██████████| 47/47 [00:15<00:00,  3.02it/s]\n\nThreshold : 0.20    FBeta : 0.591502\nThreshold : 0.25    FBeta : 0.594632\nThreshold : 0.30    FBeta : 0.597220\nThreshold : 0.35    FBeta : 0.599432\nThreshold : 0.40    FBeta : 0.601498\nThreshold : 0.45    FBeta : 0.603379\nThreshold : 0.50    FBeta : 0.605112\nThreshold : 0.55    FBeta : 0.606648\nThreshold : 0.60    FBeta : 0.608080\nThreshold : 0.65    FBeta : 0.609384\nThreshold : 0.70    FBeta : 0.610375\nThreshold : 0.75    FBeta : 0.611493\nThreshold : 0.80    FBeta : 0.611834\n-->Improve:0.611834\n```","metadata":{}},{"cell_type":"markdown","source":"```\nFF-100-TRAIN-T3-3dresnet-d34x256-x2048-RotFlip-e200-LossTversky\nEpoch 90/200  Mem : 7.39GB  LR : 6.71E-05  Loss: 0.1820: 100%|██████████| 178/178 [02:50<00:00,  1.04it/s]\nVal Loss: 0.3181: 100%|██████████| 37/37 [00:25<00:00,  1.43it/s]\n\nThreshold : 0.20    FBeta : 0.639846\nThreshold : 0.25    FBeta : 0.643685\nThreshold : 0.30    FBeta : 0.645757\nThreshold : 0.35    FBeta : 0.646962\nThreshold : 0.40    FBeta : 0.647508\nThreshold : 0.45    FBeta : 0.647574\nThreshold : 0.50    FBeta : 0.647057\nThreshold : 0.55    FBeta : 0.646660\nThreshold : 0.60    FBeta : 0.646050\nThreshold : 0.65    FBeta : 0.645026\nThreshold : 0.70    FBeta : 0.643004\nThreshold : 0.75    FBeta : 0.639998\nThreshold : 0.80    FBeta : 0.635312\n[INFO]MaxScore:0.629994\n------>Improve:0.647574\n```","metadata":{}},{"cell_type":"markdown","source":"```\nGG-102-TRAIN-T3-3dresnet-d34x256-x2048-RotFlip-e200-LossTversky-DaFix-s92\nEpoch 115/200  Mem : 7.39GB  LR : 4.56E-05  Loss: 0.1484: 100%|██████████| 178/178 [02:53<00:00,  1.03it/s]\nVal Loss: 0.3397: 100%|██████████| 37/37 [00:26<00:00,  1.41it/s]\n\nThreshold : 0.20    FBeta : 0.656393\nThreshold : 0.25    FBeta : 0.657261\nThreshold : 0.30    FBeta : 0.657196\nThreshold : 0.35    FBeta : 0.657263\nThreshold : 0.40    FBeta : 0.657166\nThreshold : 0.45    FBeta : 0.656964\nThreshold : 0.50    FBeta : 0.656173\nThreshold : 0.55    FBeta : 0.655041\nThreshold : 0.60    FBeta : 0.653327\nThreshold : 0.65    FBeta : 0.650844\nThreshold : 0.70    FBeta : 0.646967\nThreshold : 0.75    FBeta : 0.641680\nThreshold : 0.80    FBeta : 0.632986\n[INFO]MaxScore:0.652666\n------>Improve:0.657263\n```","metadata":{}},{"cell_type":"markdown","source":"```\nBB-2222-TRAIN-3dresnet-d34x256-x2048-RotFlip-test1-s22-chAug-e400\nEpoch 117/400  Mem : 7.45GB  LR : 8.91E-05  Loss: 0.0770: 100%|██████████| 168/168 [02:55<00:00,  1.04s/it]\nVal Loss: 0.3162: 100%|██████████| 47/47 [00:32<00:00,  1.47it/s]\n\nThreshold : 0.20\tFBeta : 0.566085\nThreshold : 0.25\tFBeta : 0.576871\nThreshold : 0.30\tFBeta : 0.586326\nThreshold : 0.35\tFBeta : 0.592845\nThreshold : 0.40\tFBeta : 0.596841\nThreshold : 0.45\tFBeta : 0.598708\nThreshold : 0.50\tFBeta : 0.599209\nThreshold : 0.55\tFBeta : 0.598963\nThreshold : 0.60\tFBeta : 0.596706\nThreshold : 0.65\tFBeta : 0.593113\nThreshold : 0.70\tFBeta : 0.587141\nThreshold : 0.75\tFBeta : 0.577682\nThreshold : 0.80\tFBeta : 0.563702\nThreshold : 0.85\tFBeta : 0.542897\nThreshold : 0.90\tFBeta : 0.505858\nThreshold : 0.95\tFBeta : 0.427728\nThreshold : 1.00\tFBeta : 0.000000\n-->Improve:0.599209\n```","metadata":{}},{"cell_type":"code","source":"TH = 0.45\nif mode == 'test':\n    fragment_ids = sorted(os.listdir(CFG.comp_dataset_path + mode))\nelse:\n    fragment_ids = [3]\n\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nmodel = build_model(CFG)\nmodel.load_state_dict(tc.load(\"/kaggle/input/vesuvius-train-bb-2222-20230606035149/resnet18_3d_seg_epoch_117.pt\", map_location=device))\nmodel = nn.DataParallel(model, device_ids=[0, 1])\nmodel = model.cuda()#.eval()\nmodel.training","metadata":{"execution":{"iopub.status.busy":"2023-06-14T13:01:10.098403Z","iopub.execute_input":"2023-06-14T13:01:10.099064Z","iopub.status.idle":"2023-06-14T13:01:15.953796Z","shell.execute_reply.started":"2023-06-14T13:01:10.099024Z","shell.execute_reply":"2023-06-14T13:01:15.952741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nmodel_2 = build_model(CFG)\nmodel_2.load_state_dict(tc.load(\"/kaggle/input/vesuvius-train-gg-102-20230614125223/resnet18_3d_seg_epoch_115.pt\", map_location=device))\nmodel_2 = nn.DataParallel(model_2, device_ids=[0, 1])\nmodel_2 = model_2.cuda()#.eval()\nmodel_2.training","metadata":{"execution":{"iopub.status.busy":"2023-06-14T13:01:15.955367Z","iopub.execute_input":"2023-06-14T13:01:15.955854Z","iopub.status.idle":"2023-06-14T13:01:20.685838Z","shell.execute_reply.started":"2023-06-14T13:01:15.955810Z","shell.execute_reply":"2023-06-14T13:01:20.684465Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## main","metadata":{}},{"cell_type":"code","source":"DENOIZE_ITER=700","metadata":{"execution":{"iopub.status.busy":"2023-06-14T13:01:20.691223Z","iopub.execute_input":"2023-06-14T13:01:20.693876Z","iopub.status.idle":"2023-06-14T13:01:20.711046Z","shell.execute_reply.started":"2023-06-14T13:01:20.693835Z","shell.execute_reply":"2023-06-14T13:01:20.708840Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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            a_preds=TTA(images,model)\n            b_preds=TTA(images,model_2)\n#             print(\"XXX\",((y_preds+b_preds)/2).shape)\n            y_preds = ((a_preds+b_preds)/2)\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=DENOIZE_ITER)\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-06-14T13:01:20.718721Z","iopub.execute_input":"2023-06-14T13:01:20.719103Z","iopub.status.idle":"2023-06-14T13:03:59.786346Z","shell.execute_reply.started":"2023-06-14T13:01:20.719063Z","shell.execute_reply":"2023-06-14T13:03:59.784578Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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-06-14T13:03:59.788076Z","iopub.status.idle":"2023-06-14T13:03:59.788642Z","shell.execute_reply.started":"2023-06-14T13:03:59.788343Z","shell.execute_reply":"2023-06-14T13:03:59.788387Z"},"trusted":true},"execution_count":null,"outputs":[]}]}