{"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 torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport numpy as np\nimport glob\nimport PIL.Image as Image\nimport torch.utils.data as data\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:06:23.802433Z","iopub.execute_input":"2023-05-27T10:06:23.802772Z","iopub.status.idle":"2023-05-27T10:06:26.884742Z","shell.execute_reply.started":"2023-05-27T10:06:23.802745Z","shell.execute_reply":"2023-05-27T10:06:26.883225Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pip install patchify","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:06:26.886484Z","iopub.execute_input":"2023-05-27T10:06:26.887042Z","iopub.status.idle":"2023-05-27T10:06:37.725841Z","shell.execute_reply.started":"2023-05-27T10:06:26.887012Z","shell.execute_reply":"2023-05-27T10:06:37.724755Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport PIL.Image as Image\nfrom tifffile import tifffile\nfrom patchify import patchify\nfrom tqdm import tqdm\nimport gc\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:06:37.72738Z","iopub.execute_input":"2023-05-27T10:06:37.7277Z","iopub.status.idle":"2023-05-27T10:06:37.896154Z","shell.execute_reply.started":"2023-05-27T10:06:37.727674Z","shell.execute_reply":"2023-05-27T10:06:37.895473Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path_surface = lambda mode,fragment_id,i: f\"/kaggle/input/vesuvius-challenge-ink-detection/{mode}/{fragment_id}/surface_volume/{i:02}.tif\"\npath_mask = lambda mode,fragment_id : f'/kaggle/input/vesuvius-challenge-ink-detection/{mode}/{fragment_id}/mask.png'\npath_label = lambda mode,fragment_id :f'/kaggle/input/vesuvius-challenge-ink-detection/{mode}/{fragment_id}/inklabels.png'","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:06:37.897123Z","iopub.execute_input":"2023-05-27T10:06:37.89854Z","iopub.status.idle":"2023-05-27T10:06:37.904563Z","shell.execute_reply.started":"2023-05-27T10:06:37.898509Z","shell.execute_reply":"2023-05-27T10:06:37.903134Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CFG:\n    size = 224\n    va = 224\n    valid_frag = 1\n    in_chans = 6","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:06:37.908058Z","iopub.execute_input":"2023-05-27T10:06:37.908345Z","iopub.status.idle":"2023-05-27T10:06:37.918411Z","shell.execute_reply.started":"2023-05-27T10:06:37.908323Z","shell.execute_reply":"2023-05-27T10:06:37.917064Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def return_patch_details(fragment_id,size=224,mode = 'train'):\n\n    dic = {'fragment':[],'xmin':[],'ymin':[],'size':[]}\n    \n    mask = np.array(Image.open(path_mask('train',fragment_id)))\n    \n    patched_mask = patchify(mask,(size,size),step = size)\n\n    for j in tqdm(range(patched_mask.shape[0])):\n        for k in range(patched_mask.shape[1]): \n            mask_p = patched_mask[j,k,:,:]\n            if np.count_nonzero(mask_p)==size*size or mode == 'valid':    \n                dic['fragment'].append(fragment_id)\n                dic['ymin'].append(j*size)\n                dic['xmin'].append(k*size)\n                dic['size'].append(size)\n                    \n    df = pd.DataFrame(dic)\n    return df","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:06:37.920395Z","iopub.execute_input":"2023-05-27T10:06:37.920842Z","iopub.status.idle":"2023-05-27T10:06:37.932927Z","shell.execute_reply.started":"2023-05-27T10:06:37.920808Z","shell.execute_reply":"2023-05-27T10:06:37.931563Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def return_image_mask_patch(fragment_id,mode):\n    \n    in_chans = CFG.in_chans\n    size = CFG.size\n    valid_frag = CFG.valid_frag\n    \n    df = return_patch_details(fragment_id,size=size,mode=mode)\n    images = []\n\n    mid = 65 // 2\n    start = mid - in_chans // 2\n    end = mid + in_chans // 2\n    \n    label_ = np.array(Image.open(path_label('train',fragment_id)))\n    pad0 = 0\n    pad1 = 0\n    \n    if mode == 'valid':\n        pad0 = (size - label_.shape[0] % size)\n        pad1 = (size - label_.shape[1] % size)\n         \n    for i in tqdm(range(start,end)):\n        image = tifffile.imread(path_surface('train',fragment_id,i)).astype('float16')\n        image = np.pad(image, [(0, pad0), (0, pad1)], constant_values=0)\n        images.append(image)\n        \n    images = np.stack(images, axis=2).astype('float32')\n    label_ = np.pad(label_, [(0, pad0), (0, pad1)], constant_values=0)\n    \n    image = []\n    label = []\n    xyxy = []\n    size = df.iloc[0,3]\n    for j in range(df.shape[0]):\n        xmin = df.iloc[j,1]\n        ymin = df.iloc[j,2]\n        img = images[ymin:ymin+size,xmin:xmin+size,:]\n        lab = np.expand_dims(label_[ymin:ymin+size,xmin:xmin+size],0)\n        image.append(img)\n        label.append(lab)\n        xyxy.append([xmin,ymin,xmin+size,ymin+size])\n        \n    label = list(np.array(label).astype('float32')/255)\n    return image, label, xyxy","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:06:37.934879Z","iopub.execute_input":"2023-05-27T10:06:37.935705Z","iopub.status.idle":"2023-05-27T10:06:37.949744Z","shell.execute_reply.started":"2023-05-27T10:06:37.935668Z","shell.execute_reply":"2023-05-27T10:06:37.948191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_train_valid_dataset():\n    \n    in_chans = CFG.in_chans\n    size = CFG.size\n    valid_frag = CFG.valid_frag    \n    \n    train_images = []\n    train_label = []\n\n    valid_images = []\n    valid_label = []\n    \n\n    for fragment_id in range(1, 4):\n        \n        if fragment_id == valid_frag:\n            mode = 'valid'\n        else:\n            mode = 'train'\n        image, label, _ = return_image_mask_patch(fragment_id,mode = mode)\n        \n        if fragment_id == valid_frag:\n            valid_images += image\n            valid_label += label\n            valid_xyxy = _\n        else:\n            train_images += image\n            train_label += label\n\n    return train_images, train_label, valid_images, valid_label, valid_xyxy","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:06:37.950948Z","iopub.execute_input":"2023-05-27T10:06:37.951221Z","iopub.status.idle":"2023-05-27T10:06:37.965679Z","shell.execute_reply.started":"2023-05-27T10:06:37.951199Z","shell.execute_reply":"2023-05-27T10:06:37.96474Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"train_images, train_masks, valid_images, valid_masks, valid_xyxys = get_train_valid_dataset()","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:06:37.966837Z","iopub.execute_input":"2023-05-27T10:06:37.967192Z","iopub.status.idle":"2023-05-27T10:07:16.945588Z","shell.execute_reply.started":"2023-05-27T10:06:37.967162Z","shell.execute_reply":"2023-05-27T10:07:16.944056Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_xyxys = np.stack(valid_xyxys)","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:07:16.947503Z","iopub.execute_input":"2023-05-27T10:07:16.947904Z","iopub.status.idle":"2023-05-27T10:07:16.955863Z","shell.execute_reply.started":"2023-05-27T10:07:16.947869Z","shell.execute_reply":"2023-05-27T10:07:16.954306Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(train_images)","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:07:16.958053Z","iopub.execute_input":"2023-05-27T10:07:16.958439Z","iopub.status.idle":"2023-05-27T10:07:16.982797Z","shell.execute_reply.started":"2023-05-27T10:07:16.958408Z","shell.execute_reply":"2023-05-27T10:07:16.981358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i,image in enumerate(train_images):\n    plt.imshow(image[:, :, 0], cmap='gray')\n    plt.show()\n    '''\n    plt.imshow(image[:, :, 1], cmap='gray')\n    plt.show()\n    plt.imshow(image[:, :, 2], cmap='gray')\n    plt.show()\n    plt.imshow(image[:, :, 3], cmap='gray')\n    plt.show()\n    plt.imshow(image[:, :, 4], cmap='gray')\n    plt.show()\n    plt.imshow(image[:, :, 5], cmap='gray')\n    plt.show()\n    '''\n    if i == 0:\n        break\n\ntrain_masks[1].shape","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:07:16.984406Z","iopub.execute_input":"2023-05-27T10:07:16.984841Z","iopub.status.idle":"2023-05-27T10:07:17.235055Z","shell.execute_reply.started":"2023-05-27T10:07:16.984807Z","shell.execute_reply":"2023-05-27T10:07:17.234249Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_images[1].shape","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:07:17.236571Z","iopub.execute_input":"2023-05-27T10:07:17.237203Z","iopub.status.idle":"2023-05-27T10:07:17.243623Z","shell.execute_reply.started":"2023-05-27T10:07:17.237171Z","shell.execute_reply":"2023-05-27T10:07:17.242572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i,image in enumerate(train_masks):\n    plt.imshow(image[0,:, :], cmap='gray')\n    plt.show()\n    '''\n    plt.imshow(image[:, :, 1], cmap='gray')\n    plt.show()\n    plt.imshow(image[:, :, 2], cmap='gray')\n    plt.show()\n    plt.imshow(image[:, :, 3], cmap='gray')\n    plt.show()\n    plt.imshow(image[:, :, 4], cmap='gray')\n    plt.show()\n    plt.imshow(image[:, :, 5], cmap='gray')\n    plt.show()\n    '''\n    if i == 10:\n        break","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:07:17.247795Z","iopub.execute_input":"2023-05-27T10:07:17.248134Z","iopub.status.idle":"2023-05-27T10:07:19.197196Z","shell.execute_reply.started":"2023-05-27T10:07:17.248107Z","shell.execute_reply":"2023-05-27T10:07:19.195925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from matplotlib.patches import Rectangle\npath = path_mask('train',1)\nimg = np.array(Image.open(path))\nplt.imshow(img,cmap='gray')\ndf = return_patch_details(1,size=256,mode='train')\nfor i in range(df.shape[0]):\n    x = df.iloc[i,1]\n    y = df.iloc[i,2]\n    plt.gca().add_patch(Rectangle((x,y),256,256,\n                    edgecolor='red',\n                    facecolor='none',\n                    lw=1))\n    \nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:07:19.198435Z","iopub.execute_input":"2023-05-27T10:07:19.1987Z","iopub.status.idle":"2023-05-27T10:07:21.209696Z","shell.execute_reply.started":"2023-05-27T10:07:19.198679Z","shell.execute_reply":"2023-05-27T10:07:21.208354Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_images[0].shape","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:07:21.211006Z","iopub.execute_input":"2023-05-27T10:07:21.211334Z","iopub.status.idle":"2023-05-27T10:07:21.215925Z","shell.execute_reply.started":"2023-05-27T10:07:21.211301Z","shell.execute_reply":"2023-05-27T10:07:21.215384Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\n\n# Create the output folder if it doesn't exist\nif not os.path.exists('output'):\n    os.makedirs('output')","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:07:21.216989Z","iopub.execute_input":"2023-05-27T10:07:21.217301Z","iopub.status.idle":"2023-05-27T10:07:21.22933Z","shell.execute_reply.started":"2023-05-27T10:07:21.217275Z","shell.execute_reply":"2023-05-27T10:07:21.228346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Save train_images\nnp.save('output/train_images.npy', train_images)\n\n# Save train_masks\nnp.save('output/train_masks.npy', train_masks)\n\n# Save valid_images\nnp.save('output/valid_images.npy', valid_images)\n\n# Save valid_masks\nnp.save('output/valid_masks.npy', valid_masks)\n\n# Save valid_xyxys\nnp.save('output/valid_xyxys.npy', valid_xyxys)","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:07:21.230716Z","iopub.execute_input":"2023-05-27T10:07:21.231014Z","iopub.status.idle":"2023-05-27T10:07:25.204539Z","shell.execute_reply.started":"2023-05-27T10:07:21.23099Z","shell.execute_reply":"2023-05-27T10:07:25.203301Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DATA_DIR_1 = '/kaggle/input/vesuvius-challenge-ink-detection/train/1/'\nDATA_DIR_2 = '/kaggle/input/vesuvius-challenge-ink-detection/train/2/'\nDATA_DIR_3 = '/kaggle/input/vesuvius-challenge-ink-detection/train/3/'\n\nBUFFER = 30  # Buffer size in x and y direction\nZ_START = 20 # First slice in the z direction to use\nZ_DIM = 25  # Number of slices in the z direction\nTRAINING_STEPS = 30000\nLEARNING_RATE = 0.03\nBATCH_SIZE = 32\nSAVE_PATH = './model1.pth'\nDEVICE = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:07:25.206668Z","iopub.execute_input":"2023-05-27T10:07:25.207483Z","iopub.status.idle":"2023-05-27T10:07:25.213927Z","shell.execute_reply.started":"2023-05-27T10:07:25.207442Z","shell.execute_reply":"2023-05-27T10:07:25.213111Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class SubvolumeDataset(data.Dataset):\n    def __init__(self, image_stack, label, pixels):\n        self.image_stack = image_stack\n        self.label = label\n        self.pixels = pixels\n    def __len__(self):\n        return len(self.pixels)\n    def __getitem__(self, index):\n        y, x = self.pixels[index]\n        subvolume = self.image_stack\n        inklabel = self.label[0]\n        return subvolume, inklabel\n\nclass TestDataset(data.Dataset):\n    def __init__(self, image_stack, pixels):\n        self.image_stack = image_stack\n        self.pixels = pixels\n    def __len__(self):\n        return len(self.pixels)\n    def __getitem__(self, index):\n        y, x = self.pixels[index]\n        subvolume = self.image_stack[:, y-BUFFER:y+BUFFER+1, x-BUFFER:x+BUFFER+1].view(Z_DIM, BUFFER*2+1, BUFFER*2+1)\n        return subvolume\n\nclass ResBlock(nn.Module):\n    def __init__(self, in_channels, out_channels):\n        super(ResBlock, self).__init__()\n        \n        self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1, bias=False)\n        self.bn1 = nn.BatchNorm2d(out_channels)\n        self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1, bias=False)\n        self.bn2 = nn.BatchNorm2d(out_channels)\n        self.activation = nn.SiLU(inplace=True)\n        \n        if in_channels != out_channels:\n            self.shortcut = nn.Sequential(\n                nn.Conv2d(in_channels, out_channels, kernel_size=1, bias=False),\n                nn.BatchNorm2d(out_channels)\n            )\n        else:\n            self.shortcut = nn.Identity()\n        \n    def forward(self, x):\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.activation(out)\n        \n        out = self.conv2(out)\n        out = self.bn2(out)\n        out += self.shortcut(x)\n        out = self.activation(out)\n        return out","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:24:13.516915Z","iopub.execute_input":"2023-05-27T10:24:13.517329Z","iopub.status.idle":"2023-05-27T10:24:13.53256Z","shell.execute_reply.started":"2023-05-27T10:24:13.5173Z","shell.execute_reply":"2023-05-27T10:24:13.531445Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class ResNet(nn.Module):\n    def __init__(self, in_channels=6, num_classes=1):\n        super(ResNet, self).__init__()\n        \n        self.conv = nn.Conv2d(in_channels, 64, kernel_size=7, stride=2, padding=3, bias=False)\n        self.bn = nn.BatchNorm2d(64)\n        self.activation = nn.SiLU(inplace=True)\n        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n        \n        self.layer1 = nn.Sequential(\n            ResBlock(64, 64),\n            ResBlock(64, 64)\n        )\n        self.layer2 = nn.Sequential(\n            ResBlock(64, 128),\n            ResBlock(128, 128)\n        )\n        self.layer3 = nn.Sequential(\n            ResBlock(128, 256),\n            ResBlock(256, 256)\n        )\n        self.layer4 = nn.Sequential(\n            ResBlock(256, 512),\n            ResBlock(512, 512)\n        )\n        \n        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))\n        self.fc = nn.Linear(512, num_classes)\n        \n    def forward(self, x):\n        out = self.conv(x)\n        out = self.bn(out)\n        out = self.activation(out)\n        out = self.maxpool(out)\n        \n        out = self.layer1(out)\n        out = self.layer2(out)\n        out = self.layer3(out)\n        out = self.layer4(out)\n        \n        out = self.avgpool(out)\n        out = torch.flatten(out, 1)\n        out = torch.sigmoid(self.fc(out))\n        \n        return out\n    \nmodel = ResNet().to(DEVICE)","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:07:26.03535Z","iopub.execute_input":"2023-05-27T10:07:26.036134Z","iopub.status.idle":"2023-05-27T10:07:27.175726Z","shell.execute_reply.started":"2023-05-27T10:07:26.036101Z","shell.execute_reply":"2023-05-27T10:07:27.174755Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.set_printoptions(threshold=100000)","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:07:27.17705Z","iopub.execute_input":"2023-05-27T10:07:27.177416Z","iopub.status.idle":"2023-05-27T10:07:29.771518Z","shell.execute_reply.started":"2023-05-27T10:07:27.177384Z","shell.execute_reply":"2023-05-27T10:07:29.7703Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"N = 224 * 224\n\n# 生成坐标数组\npixels_outside_rect = np.zeros((N, 2))\n\n# 填充坐标数组\nfor i in range(N):\n    pixels_outside_rect[i, 0] = i // 224  # x坐标\n    pixels_outside_rect[i, 1] = i % 224   # y坐标","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:07:29.773212Z","iopub.execute_input":"2023-05-27T10:07:29.773776Z","iopub.status.idle":"2023-05-27T10:07:30.806889Z","shell.execute_reply.started":"2023-05-27T10:07:29.773742Z","shell.execute_reply":"2023-05-27T10:07:30.805768Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ntrain_dataset = SubvolumeDataset(train_images, train_masks, pixels_outside_rect)\ntrain_loader = data.DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True)","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:24:20.439102Z","iopub.execute_input":"2023-05-27T10:24:20.439488Z","iopub.status.idle":"2023-05-27T10:24:20.446394Z","shell.execute_reply.started":"2023-05-27T10:24:20.439461Z","shell.execute_reply":"2023-05-27T10:24:20.444773Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_sample = train_dataset[0]\nprint(type(data_sample[0]))\nprint(len(data_sample[0]))\nprint(data_sample[0][0].shape)\nprint(type(data_sample[1]))\nprint(len(data_sample[1]))\nprint(data_sample[1][0].shape)","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:24:34.659924Z","iopub.execute_input":"2023-05-27T10:24:34.66033Z","iopub.status.idle":"2023-05-27T10:24:34.666658Z","shell.execute_reply.started":"2023-05-27T10:24:34.660301Z","shell.execute_reply":"2023-05-27T10:24:34.665618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"criterion = nn.BCELoss()\noptimizer = optim.SGD(model.parameters(), lr=LEARNING_RATE)\nscheduler = torch.optim.lr_scheduler.OneCycleLR(optimizer, max_lr=LEARNING_RATE, total_steps=TRAINING_STEPS)\nmodel.train()\nrunning_loss = 0.0\n\n# 有訓練好的weight 用這邊把他載入\n'''\nPATH = '/kaggle/input/weight-1'\nmodel.load_state_dict(torch.load(PATH))\n\n'''\n# 訓練的時後把他解開\nfor i, (subvolumes, inklabels) in tqdm(enumerate(train_loader), total=TRAINING_STEPS):\n    if i >= TRAINING_STEPS:\n        break\n    optimizer.zero_grad()\n    outputs = model(subvolumes.to(DEVICE))\n    loss = criterion(outputs, inklabels.to(DEVICE))\n    loss.backward()\n    optimizer.step()\n    scheduler.step()\n    running_loss += loss.item()\n    if i % 2000 == 2000-1:\n        print(\"Loss:\", running_loss / 2000)\n        running_loss = 0.0\n        \ntorch.save(model.state_dict(), SAVE_PATH) # 存模型\n\n\n# 訓練的時候把後面所有block都槓掉\n# 測試的時候載模型用\n'''\nPATH = '/kaggle/input/data-weight/model1.pth'\nmodel.load_state_dict(torch.load(PATH))\n'''\n","metadata":{"execution":{"iopub.status.busy":"2023-05-27T10:02:26.101613Z","iopub.execute_input":"2023-05-27T10:02:26.101992Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 訓練的時候把後面所有block都槓掉\n# 測試的時候載模型用\n'''\nimport gc\ndel image_stack, label, not_border_mask\ndel train_loader\ngc.collect()\n'''\n","metadata":{"execution":{"iopub.status.busy":"2023-05-27T09:59:55.08909Z","iopub.status.idle":"2023-05-27T09:59:55.089385Z","shell.execute_reply.started":"2023-05-27T09:59:55.089243Z","shell.execute_reply":"2023-05-27T09:59:55.089258Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 訓練的時候把後面所有block都槓掉\n# 測試的時候載模型用\n'''\nimport time\ntest_data_path = \"/kaggle/input/vesuvius-challenge-ink-detection/test/a/\"\nmask = np.array(Image.open(test_data_path+\"mask.png\").convert('1'))\nimages = [np.array(Image.open(filename), dtype=np.float32)/65535.0 for filename in tqdm(sorted(glob.glob(test_data_path+\"surface_volume/*.tif\"))[Z_START:Z_START+Z_DIM])]\nimage_stack = torch.stack([torch.from_numpy(image) for image in images], dim=0).to(DEVICE)\nnot_border = np.zeros(mask.shape, dtype=bool)\nnot_border[BUFFER:mask.shape[0]-BUFFER, BUFFER:mask.shape[1]-BUFFER] = True\nnot_border_mask = np.array(mask) * not_border\npixels_outside_rect = np.argwhere(not_border_mask)\n\neval_dataset = TestDataset(image_stack, pixels_outside_rect)\neval_loader = data.DataLoader(eval_dataset, batch_size=BATCH_SIZE, shuffle=False)\noutput = torch.zeros_like(torch.tensor(mask)).float()\nmodel.eval()\n\nstart_time = time.time()\nwith torch.no_grad():\n    for i, subvolumes in enumerate(tqdm(eval_loader)):\n        for j, value in enumerate(model(subvolumes.to(DEVICE))):\n            output[tuple(pixels_outside_rect[i*BATCH_SIZE+j])] = value\n            \nend_time = time.time()\nprint(\"inference time: {}min\".format((end_time-start_time)/60))\n        \n\nfig, (ax1, ax2) = plt.subplots(1, 2)\nax1.imshow(output.cpu(), cmap='gray')\nax2.imshow(label.cpu(), cmap='gray')\nplt.show()\n'''","metadata":{"execution":{"iopub.status.busy":"2023-05-27T09:59:55.090953Z","iopub.status.idle":"2023-05-27T09:59:55.091527Z","shell.execute_reply.started":"2023-05-27T09:59:55.091269Z","shell.execute_reply":"2023-05-27T09:59:55.091293Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 訓練的時候把後面所有block都槓掉\n# 測試的時候載模型用\n'''\ndef rle(output):\n    pixels = np.where(output.flatten().cpu() > 0.4, 1, 0).astype(np.uint8)\n    pixels[0] = 0\n    pixels[-1] = 0\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 2\n    runs[1::2] = runs[1::2] - runs[:-1:2]\n    return ' '.join(str(x) for x in runs)\nrle_output = rle(output)\n# This doesn't make too much sense, but let's just output in the required format\n# so notebook works as a submission. :-)\nprint(\"Id,Predicted\\na,\" + rle_output + \"\\nb,\" + rle_output, file=open('submission.csv', 'w'))\n'''\n","metadata":{"execution":{"iopub.status.busy":"2023-05-27T09:59:55.093085Z","iopub.status.idle":"2023-05-27T09:59:55.093556Z","shell.execute_reply.started":"2023-05-27T09:59:55.093328Z","shell.execute_reply":"2023-05-27T09:59:55.093349Z"},"trusted":true},"execution_count":null,"outputs":[]}]}