{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":47317,"databundleVersionId":5799376,"sourceType":"competition"}],"dockerImageVersionId":30558,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport glob\nimport PIL.Image as Image\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as patches\nfrom tqdm import tqdm\nfrom ipywidgets import interact, fixed\n\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset, DataLoader\nimport torch.nn.functional as F\nimport cv2\nimport numpy as np \nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\n%matplotlib inline","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-12-02T00:37:05.690951Z","iopub.execute_input":"2023-12-02T00:37:05.691753Z","iopub.status.idle":"2023-12-02T00:37:07.745534Z","shell.execute_reply.started":"2023-12-02T00:37:05.691709Z","shell.execute_reply":"2023-12-02T00:37:07.744589Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nPREFIX = '/kaggle/input/vesuvius-challenge-ink-detection/train/1/'\nBUFFER = 30  # Buffer size in x and y direction\nZ_START = 27 # First slice in the z direction to use\nZ_DIM = 12  # Number of slices in the z direction\nTRAINING_STEPS = 30000\nLEARNING_RATE = 0.03\nBATCH_SIZE = 32\nDEVICE = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\nplt.imshow(Image.open(PREFIX+\"ir.png\"), cmap=\"gray\")","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:37:07.747517Z","iopub.execute_input":"2023-12-02T00:37:07.747997Z","iopub.status.idle":"2023-12-02T00:37:10.735028Z","shell.execute_reply.started":"2023-12-02T00:37:07.747962Z","shell.execute_reply":"2023-12-02T00:37:10.733999Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#!sudo apt install file -y\n#!file /kaggle/input/vesuvius-challenge-ink-detection/train/2/surface_volume/00.tif\n\n#Showes current OS information. \n##!cat /etc/os-release","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:37:10.736431Z","iopub.execute_input":"2023-12-02T00:37:10.737011Z","iopub.status.idle":"2023-12-02T00:37:10.741378Z","shell.execute_reply.started":"2023-12-02T00:37:10.736977Z","shell.execute_reply":"2023-12-02T00:37:10.740190Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"PREFIX = '/kaggle/input/vesuvius-challenge-ink-detection/train/1/'\nimages = [np.array(Image.open(filename), dtype=np.float32)/65535.0 for filename in tqdm(sorted(glob.glob(PREFIX+\"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)\nmask = np.array(Image.open(PREFIX+\"mask.png\").convert('1'))","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:37:10.743677Z","iopub.execute_input":"2023-12-02T00:37:10.743946Z","iopub.status.idle":"2023-12-02T00:37:44.601756Z","shell.execute_reply.started":"2023-12-02T00:37:10.743923Z","shell.execute_reply":"2023-12-02T00:37:44.600865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_stack.shape","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:37:44.603464Z","iopub.execute_input":"2023-12-02T00:37:44.603845Z","iopub.status.idle":"2023-12-02T00:37:44.610118Z","shell.execute_reply.started":"2023-12-02T00:37:44.603809Z","shell.execute_reply":"2023-12-02T00:37:44.609175Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"32 * 8181 * 6330 /8 / 10**6","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:37:44.611413Z","iopub.execute_input":"2023-12-02T00:37:44.611760Z","iopub.status.idle":"2023-12-02T00:37:44.628014Z","shell.execute_reply.started":"2023-12-02T00:37:44.611728Z","shell.execute_reply":"2023-12-02T00:37:44.627136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"PREFIX = '/kaggle/input/vesuvius-challenge-ink-detection/train/3/'\nimages_test = [np.array(Image.open(filename), dtype=np.float32)/65535.0 for filename in tqdm(sorted(glob.glob(PREFIX+\"surface_volume/*.tif\"))[Z_START:Z_START+Z_DIM])]\nimage_stack_test = torch.stack([torch.from_numpy(image) for image in images_test], dim=0).to(DEVICE)\nmask_test = np.array(Image.open(PREFIX+\"mask.png\").convert('1'))","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:37:44.629149Z","iopub.execute_input":"2023-12-02T00:37:44.629503Z","iopub.status.idle":"2023-12-02T00:38:05.823886Z","shell.execute_reply.started":"2023-12-02T00:37:44.629472Z","shell.execute_reply":"2023-12-02T00:38:05.822903Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.max(images_test)","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:38:05.825051Z","iopub.execute_input":"2023-12-02T00:38:05.825400Z","iopub.status.idle":"2023-12-02T00:38:06.649997Z","shell.execute_reply.started":"2023-12-02T00:38:05.825369Z","shell.execute_reply":"2023-12-02T00:38:06.649054Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(image_stack[1,:,:].cpu(), cmap=\"gray\")","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:38:06.651092Z","iopub.execute_input":"2023-12-02T00:38:06.651401Z","iopub.status.idle":"2023-12-02T00:38:09.339593Z","shell.execute_reply.started":"2023-12-02T00:38:06.651374Z","shell.execute_reply":"2023-12-02T00:38:09.338501Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_stack[1,:,:].shape","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:38:09.343140Z","iopub.execute_input":"2023-12-02T00:38:09.343501Z","iopub.status.idle":"2023-12-02T00:38:09.350325Z","shell.execute_reply.started":"2023-12-02T00:38:09.343472Z","shell.execute_reply":"2023-12-02T00:38:09.349314Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"200000","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:38:09.351323Z","iopub.execute_input":"2023-12-02T00:38:09.351621Z","iopub.status.idle":"2023-12-02T00:38:09.363151Z","shell.execute_reply.started":"2023-12-02T00:38:09.351590Z","shell.execute_reply":"2023-12-02T00:38:09.362117Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_stack[:, 2000,2000]","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:38:09.364347Z","iopub.execute_input":"2023-12-02T00:38:09.364649Z","iopub.status.idle":"2023-12-02T00:38:09.471534Z","shell.execute_reply.started":"2023-12-02T00:38:09.364625Z","shell.execute_reply":"2023-12-02T00:38:09.470515Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class MnistDataset(Dataset):\n\n    def __init__(self, image, mask, transform=None, tile_size = 29):\n        assert (image.shape[1] == mask.shape[0]) and (image.shape[2] == mask.shape[1]), \"Expect number of images to be the same as number of labels.\"\n        self.image = image\n        self.mask = mask\n\n        self.transform = transform\n        self.tile_size = tile_size # training size for each sample\n        _, self.image_row, self.image_col = image.shape\n        \n        self.num_tiles_row = self.image_row // self.tile_size\n        self.num_tiles_col = self.image_col // self.tile_size  \n        self.tile_size_half = tile_size // 2\n        #print(\"tile_size_half:\",self.tile_size_half)\n        \n\n    def __len__(self):\n        return self.num_tiles_row * self.num_tiles_col\n\n    def __getitem__(self, idx):\n        idx_col = (idx % self.num_tiles_col) * self.tile_size\n        idx_row = (idx // self.num_tiles_col) * self.tile_size\n\n        label = self.mask[idx_row+self.tile_size_half, idx_col+self.tile_size_half]\n        label = torch.as_tensor(float(label))\n        \n        \n        tile = self.image[:,\n                          idx_row: idx_row+self.tile_size_half*2+1,\n                         idx_col: idx_col+self.tile_size_half*2+1]\n        #print(\"idx:\",idx,\"  ;max:\",torch.max(tile), \" label:\",label)\n        #print(\"tile shape:\", tile.shape)\n        sample = {'image': tile, 'label': label}\n        \n        return sample","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:38:09.472823Z","iopub.execute_input":"2023-12-02T00:38:09.473203Z","iopub.status.idle":"2023-12-02T00:38:09.483559Z","shell.execute_reply.started":"2023-12-02T00:38:09.473165Z","shell.execute_reply":"2023-12-02T00:38:09.482607Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = MnistDataset(image_stack, mask)\n#text =  MnistDataset(image_stack_test, mask_test)","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:38:09.484895Z","iopub.execute_input":"2023-12-02T00:38:09.485170Z","iopub.status.idle":"2023-12-02T00:38:09.500551Z","shell.execute_reply.started":"2023-12-02T00:38:09.485139Z","shell.execute_reply":"2023-12-02T00:38:09.499691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#for i in range(300,400):\n#    train[i][\"label\"]","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:38:09.501668Z","iopub.execute_input":"2023-12-02T00:38:09.502281Z","iopub.status.idle":"2023-12-02T00:38:09.512067Z","shell.execute_reply.started":"2023-12-02T00:38:09.502249Z","shell.execute_reply":"2023-12-02T00:38:09.511145Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train[1000][\"label\"]","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:38:09.513223Z","iopub.execute_input":"2023-12-02T00:38:09.513765Z","iopub.status.idle":"2023-12-02T00:38:09.541182Z","shell.execute_reply.started":"2023-12-02T00:38:09.513740Z","shell.execute_reply":"2023-12-02T00:38:09.540266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"loader = DataLoader(train, batch_size=200, shuffle=False, num_workers=0)","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:38:09.542132Z","iopub.execute_input":"2023-12-02T00:38:09.542417Z","iopub.status.idle":"2023-12-02T00:38:09.547212Z","shell.execute_reply.started":"2023-12-02T00:38:09.542393Z","shell.execute_reply":"2023-12-02T00:38:09.546163Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for batch in loader:\n    sample_image_norm = batch['image']\n    sample_label_norm = batch['label']\n    break\nsample_image_norm.shape","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:38:09.548417Z","iopub.execute_input":"2023-12-02T00:38:09.549057Z","iopub.status.idle":"2023-12-02T00:38:09.582186Z","shell.execute_reply.started":"2023-12-02T00:38:09.549024Z","shell.execute_reply":"2023-12-02T00:38:09.581383Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Net(nn.Module):\n\n    def __init__(self):\n        super(Net, self).__init__()\n        \n        ## initial size : 28 x 28 x 1\n        self.conv1 = nn.Conv2d(12, 20, 4, 1)  # 26 x 26 x 20\n        self.pool1 = nn.MaxPool2d(2, 2) # 13 x 13 x 20\n        self.conv2 = nn.Conv2d(20, 30, 4, 1) # 10 x 10 x 30\n        self.pool2 = nn.MaxPool2d(2, 2) # 5 x 5 x 30\n        self.fc3 = nn.Linear(5 * 5 * 30, 80)\n        self.fc4 = nn.Linear(80, 1)\n\n    def forward(self, x):\n        #print(\"net input size: \", x.shape)\n        x = F.relu(self.conv1(x))\n        x = F.max_pool2d(x, (2, 2))\n        x = F.relu(self.conv2(x))\n        x = F.max_pool2d(x, (2, 2))\n        x = torch.flatten(x, 1) # flatten all dimensions except the batch dimension\n        x = self.fc3(x)# x = ...  # fc3\n        x = self.fc4(x)\n        x = torch.sigmoid(x)\n        #x = F.softmax(x, dim=1)\n        return x\nnet = Net()","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:38:09.583049Z","iopub.execute_input":"2023-12-02T00:38:09.583286Z","iopub.status.idle":"2023-12-02T00:38:09.593981Z","shell.execute_reply.started":"2023-12-02T00:38:09.583265Z","shell.execute_reply":"2023-12-02T00:38:09.593107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_loop(dataloader, model, loss_fn, optimizer):\n    size = len(dataloader.dataset)\n    train_loss = 0\n    correct = 0\n    #print(\"train dataloader dataset:\",len(dataloader.dataset))\n    \n    model.train()\n    model.to(DEVICE)\n    \n    for batch, sample in enumerate(dataloader):\n        \n        X = sample['image']\n        y = sample['label']\n        y = y.unsqueeze(1)\n        X, y = X.to(DEVICE), y.to(DEVICE)\n        \n        # Compute prediction and loss\n        pred = model(X)\n        \n        #print(\"pred shape:\",pred.shape)\n        #print(\"y shape:\", y.shape)\n        #print(\"pred: \",pred)\n        #print(\"y   : \", y)\n        \n        loss = loss_fn(pred, y)\n\n        # Backpropagation\n        \n        loss.backward()\n        optimizer.step()\n        optimizer.zero_grad()\n        \n\n        if batch % 100 == 0:\n            loss, current = loss.item(), (batch + 1) * len(X)\n            print(f\"loss: {loss:>7f}  [{current:>5d}/{size:>5d}]\")\n            \n        correct += ((pred > 0.5) == y).type(torch.float).sum().item()\n        train_loss += loss_fn(pred, y).item()\n        \n    accuracy =  correct / size    \n    train_loss /= len(dataloader)\n    print(f\"Train Error: \\n Accuracy: {(100*accuracy):>0.1f}%\\n\")\n    return train_loss\n            \n\n\n\ndef test_loop(dataloader, model, loss_fn):\n    # Set the model to evaluation mode - important for batch normalization and dropout layers\n    # Unnecessary in this situation but added for best practices\n    model.eval()\n    size = len(dataloader.dataset)\n    num_batches = len(dataloader)\n    test_loss, correct = 0, 0\n\n    # Evaluating the model with torch.no_grad() ensures that no gradients are computed during test mode\n    # also serves to reduce unnecessary gradient computations and memory usage for tensors with requires_grad=True\n    with torch.no_grad():\n        for sample in dataloader:\n            X = sample['image']\n            y = sample['label']\n            y = y.unsqueeze(1)\n            X, y = X.to(DEVICE), y.to(DEVICE)            \n            pred = model(X)\n            test_loss += loss_fn(pred, y).item()\n            \n            correct += ((pred > 0.5) == y).type(torch.float).sum().item()\n\n    test_loss /= num_batches\n    correct /= size\n    print(f\"Test Error: \\n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \\n\")\n    \n    return test_loss, correct","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:38:09.595175Z","iopub.execute_input":"2023-12-02T00:38:09.595456Z","iopub.status.idle":"2023-12-02T00:38:09.614373Z","shell.execute_reply.started":"2023-12-02T00:38:09.595434Z","shell.execute_reply":"2023-12-02T00:38:09.613524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#batch_size, lr, num_epochs = 512, 0.1, 20\nbatch_size, learning_rate, num_epochs = 512, 0.1, 10\n#loss = nn.CrossEntropyLoss()  # notice that reduction is NOT set to 'none'\nloss = nn.BCELoss()\n#trainer = torch.optim.SGD(net.parameters(), lr=lr)\n#trainer = torch.optim.Adam(net.parameters(), lr=lr)\noptimizer = torch.optim.SGD(net.parameters(), lr=learning_rate)","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:38:35.861782Z","iopub.execute_input":"2023-12-02T00:38:35.862122Z","iopub.status.idle":"2023-12-02T00:38:35.869846Z","shell.execute_reply.started":"2023-12-02T00:38:35.862097Z","shell.execute_reply":"2023-12-02T00:38:35.868818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ntrain = MnistDataset(image_stack, mask)\ntext = MnistDataset(image_stack_test, mask_test)\ntrain_loader_norm = DataLoader(train, batch_size=batch_size,  shuffle=True, num_workers=0)\n        ##loader =  DataLoader(train, batch_size=4, shuffle=False, num_workers=0)\nval_loader_norm = DataLoader(text, batch_size=batch_size, shuffle=True, num_workers=0)","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:38:43.452843Z","iopub.execute_input":"2023-12-02T00:38:43.453205Z","iopub.status.idle":"2023-12-02T00:38:43.459151Z","shell.execute_reply.started":"2023-12-02T00:38:43.453176Z","shell.execute_reply":"2023-12-02T00:38:43.458143Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ntrain_loss_all = []\ntest_loss_all = []\ntest_acc_all = []\nfor t in range(num_epochs):\n    print(f\"Epoch {t+1}\\n-------------------------------\")\n    train_loss = train_loop(train_loader_norm, net, loss, optimizer)\n    test_loss, test_acc = test_loop(val_loader_norm, net, loss)\n    \n    train_loss_all.append(train_loss)\n    test_loss_all.append(test_loss)\n    test_acc_all.append(test_acc)\n    \n    \nprint(\"Done!\")","metadata":{"execution":{"iopub.status.busy":"2023-12-02T00:39:09.838046Z","iopub.execute_input":"2023-12-02T00:39:09.838698Z","iopub.status.idle":"2023-12-02T00:39:53.009206Z","shell.execute_reply.started":"2023-12-02T00:39:09.838665Z","shell.execute_reply":"2023-12-02T00:39:53.008161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch['image'].shape","metadata":{"execution":{"iopub.status.busy":"2023-11-30T00:53:35.379571Z","iopub.execute_input":"2023-11-30T00:53:35.379871Z","iopub.status.idle":"2023-11-30T00:53:35.385755Z","shell.execute_reply.started":"2023-11-30T00:53:35.379843Z","shell.execute_reply":"2023-11-30T00:53:35.384840Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch['label']","metadata":{"execution":{"iopub.status.busy":"2023-11-30T00:53:35.387216Z","iopub.execute_input":"2023-11-30T00:53:35.387501Z","iopub.status.idle":"2023-11-30T00:53:35.399821Z","shell.execute_reply.started":"2023-11-30T00:53:35.387475Z","shell.execute_reply":"2023-11-30T00:53:35.398849Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch['label'].shape","metadata":{"execution":{"iopub.status.busy":"2023-11-04T13:33:45.356120Z","iopub.status.idle":"2023-11-04T13:33:45.356460Z","shell.execute_reply.started":"2023-11-04T13:33:45.356292Z","shell.execute_reply":"2023-11-04T13:33:45.356308Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}