{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":13836,"databundleVersionId":1718836,"sourceType":"competition"},{"sourceId":1834160,"sourceType":"datasetVersion","datasetId":333968},{"sourceId":8531466,"sourceType":"datasetVersion","datasetId":5095387}],"dockerImageVersionId":30699,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optim\nimport torch\nimport torchvision\nimport torchvision.transforms as transforms\nimport torchvision.transforms.functional as TF\nimport pandas as pd\nimport cv2\nfrom torch.utils.data import Dataset, DataLoader\nfrom sklearn.model_selection import train_test_split\nfrom torch.optim.lr_scheduler import StepLR\nimport matplotlib.pyplot as plt\nimport os\nimport numpy as np\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-05-31T14:21:22.798135Z","iopub.execute_input":"2024-05-31T14:21:22.799046Z","iopub.status.idle":"2024-05-31T14:21:29.623854Z","shell.execute_reply.started":"2024-05-31T14:21:22.799007Z","shell.execute_reply":"2024-05-31T14:21:29.623028Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1","metadata":{}},{"cell_type":"markdown","source":"Предобработка данных.","metadata":{}},{"cell_type":"code","source":"device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")","metadata":{"execution":{"iopub.status.busy":"2024-05-31T14:21:29.625804Z","iopub.execute_input":"2024-05-31T14:21:29.626601Z","iopub.status.idle":"2024-05-31T14:21:29.652680Z","shell.execute_reply.started":"2024-05-31T14:21:29.626568Z","shell.execute_reply":"2024-05-31T14:21:29.651754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CNNDataset(Dataset):\n    def __init__(self, data, folder):\n        self.folder = folder\n        self.data = data\n    \n    def __len__(self):\n        return len(self.data)\n    \n    def __getitem__(self, idx):\n        img_name = self.data.iloc[idx, 0]\n        image = cv2.imread(self.folder+img_name) / 255\n        image = torch.from_numpy(image).to(torch.float).permute(2, 0, 1)\n        label = self.data.iloc[idx, 1]\n        \n        mean = [0.485, 0.456, 0.406]\n        std = [0.229, 0.224, 0.225]\n\n        normalize = transforms.Normalize(mean=mean, std=std)\n        image = normalize(image)\n\n        return image, label\n","metadata":{"execution":{"iopub.status.busy":"2024-05-31T14:21:29.653767Z","iopub.execute_input":"2024-05-31T14:21:29.654002Z","iopub.status.idle":"2024-05-31T14:21:29.675054Z","shell.execute_reply.started":"2024-05-31T14:21:29.653981Z","shell.execute_reply":"2024-05-31T14:21:29.674254Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = 4\ntrain_csv = '/kaggle/input/cassava-leaf-disease-classification/train.csv'\ntrain_folder = '/kaggle/input/cassava-leaf-disease-classification/train_images/'\n\ndf = pd.read_csv(train_csv)\nn_train = int(len(df.index) * 0.8)\nn_test = len(df.index) - n_train\ntrain, test = train_test_split(df[:10000], test_size=0.2)\n# train = pd.DataFrame(train)\n# test = pd.DataFrame(test)\ntrain_set = CNNDataset(train, train_folder)\ntest_set = CNNDataset(test, train_folder)\ntrainloader = torch.utils.data.DataLoader(train_set, batch_size=batch_size,\n                                          shuffle=True, num_workers=2)\ntestloader = torch.utils.data.DataLoader(test_set, batch_size=batch_size,\n                                         shuffle=False, num_workers=2)\n\nclasses = (\n    \"Cassava Bacterial Blight (CBB)\",\n    \"Cassava Brown Streak Disease (CBSD)\",\n    \"Cassava Green Mottle (CGM)\",\n    \"Cassava Mosaic Disease (CMD)\",\n    \"Healthy\"\n)","metadata":{"execution":{"iopub.status.busy":"2024-05-31T14:21:29.677040Z","iopub.execute_input":"2024-05-31T14:21:29.677461Z","iopub.status.idle":"2024-05-31T14:21:29.725128Z","shell.execute_reply.started":"2024-05-31T14:21:29.677430Z","shell.execute_reply":"2024-05-31T14:21:29.724314Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train(model, dataloader, optimizer, sheduler=None):\n    losses = []\n    criterion = nn.CrossEntropyLoss()\n    \n    for epoch in range(3):  # loop over the dataset multiple times\n\n        running_loss = 0.0\n        for i, data in enumerate(dataloader, 0):\n            # get the inputs; data is a list of [inputs, labels]\n            inputs, labels = data\n            inputs = inputs\n\n            # zero the parameter gradients\n            optimizer.zero_grad()\n\n            # forward + backward + optimize\n            outputs = model(inputs.to(device))\n            loss = criterion(outputs, labels.to(device))\n            loss.backward()\n            if sheduler is None:\n                optimizer.step()\n            else:\n                sheduler.step()\n\n            running_loss += loss.item()\n            if i % 100 == 99:\n                mean_loss = running_loss / 100\n#                 print(f'[{epoch + 1}, {i + 1:5d}] loss: {running_loss / 1000:.3f}')\n                losses.append(mean_loss)\n                running_loss = 0.0\n\n    print('Finished Training')\n    return losses","metadata":{"execution":{"iopub.status.busy":"2024-05-31T14:21:35.243755Z","iopub.execute_input":"2024-05-31T14:21:35.244557Z","iopub.status.idle":"2024-05-31T14:21:35.253134Z","shell.execute_reply.started":"2024-05-31T14:21:35.244519Z","shell.execute_reply":"2024-05-31T14:21:35.252158Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def test(model, dataloader):\n    correct = 0\n    total = 0\n    # since we're not training, we don't need to calculate the gradients for our outputs\n    with torch.no_grad():\n        for data in dataloader:\n            images, labels = data\n            images = images.to(device)\n            labels = labels.to(device)\n            # calculate outputs by running images through the network\n            outputs = model(images)\n            # the class with the highest energy is what we choose as prediction\n            _, predicted = torch.max(outputs.data, 1)\n            total += labels.size(0)\n            correct += (predicted == labels).sum().item()\n    \n    accuracy = 100 * correct // total\n    return accuracy","metadata":{"execution":{"iopub.status.busy":"2024-05-31T16:29:35.432845Z","iopub.execute_input":"2024-05-31T16:29:35.433737Z","iopub.status.idle":"2024-05-31T16:29:35.440684Z","shell.execute_reply.started":"2024-05-31T16:29:35.433694Z","shell.execute_reply":"2024-05-31T16:29:35.439786Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Custom + SGD","metadata":{}},{"cell_type":"code","source":"class CNN(nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.conv1 = nn.Conv2d(3, 32, 5)\n        self.pool = nn.MaxPool2d(2, 2)\n        self.conv2 = nn.Conv2d(32, 64, 5)\n        self.conv3 = nn.Conv2d(64, 128, 5)\n        self.fc1 = nn.Linear(872448, 120)\n        self.fc2 = nn.Linear(120, 84)\n        self.fc3 = nn.Linear(84, 5)\n\n    def forward(self, x):\n        x = self.pool(F.relu(self.conv1(x)))\n        x = self.pool(F.relu(self.conv2(x)))\n        x = self.pool(F.relu(self.conv3(x)))\n        x = torch.flatten(x, 1)\n        x = F.relu(self.fc1(x))\n        x = F.relu(self.fc2(x))\n        x = self.fc3(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2024-05-31T14:21:38.988971Z","iopub.execute_input":"2024-05-31T14:21:38.989346Z","iopub.status.idle":"2024-05-31T14:21:38.998143Z","shell.execute_reply.started":"2024-05-31T14:21:38.989312Z","shell.execute_reply":"2024-05-31T14:21:38.997202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"leaf_CNN_sgd = CNN().to(device)\nsgd = optim.SGD(leaf_CNN_sgd.parameters(), lr=0.001, momentum=0.9)\n\nlosses1 = train(leaf_CNN_sgd, trainloader, sgd)\naccuracy1 = test(leaf_CNN_sgd, testloader)\n\nplt.plot(losses1)\nplt.show()\nprint(f'Accuracy test: {accuracy1}%')","metadata":{"execution":{"iopub.status.busy":"2024-05-31T14:21:41.108866Z","iopub.execute_input":"2024-05-31T14:21:41.109550Z","iopub.status.idle":"2024-05-31T14:33:20.646369Z","shell.execute_reply.started":"2024-05-31T14:21:41.109516Z","shell.execute_reply":"2024-05-31T14:33:20.645358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"accuracy_train1 = test(leaf_CNN_sgd, trainloader)\nprint(f'Accuracy train: {accuracy_train1}%')","metadata":{"execution":{"iopub.status.busy":"2024-05-31T16:29:35.442627Z","iopub.execute_input":"2024-05-31T16:29:35.442880Z","iopub.status.idle":"2024-05-31T16:31:34.152390Z","shell.execute_reply.started":"2024-05-31T16:29:35.442858Z","shell.execute_reply":"2024-05-31T16:31:34.151128Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Custom + RMSprop","metadata":{}},{"cell_type":"code","source":"leaf_CNN_rms = CNN().to(device)\nrms = optim.RMSprop(leaf_CNN_rms.parameters(), lr=0.001, momentum=0.9)\n\nlosses2 = train(leaf_CNN_rms, trainloader, rms)\naccuracy2 = test(leaf_CNN_rms, testloader)\n\nplt.plot(losses2)\nplt.show()\nprint(f'Accuracy test: {accuracy2}%')","metadata":{"execution":{"iopub.status.busy":"2024-05-31T14:38:02.928883Z","iopub.execute_input":"2024-05-31T14:38:02.929910Z","iopub.status.idle":"2024-05-31T14:50:22.919743Z","shell.execute_reply.started":"2024-05-31T14:38:02.929868Z","shell.execute_reply":"2024-05-31T14:50:22.918648Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"accuracy_train2 = test(leaf_CNN_rms, trainloader)\nprint(f'Accuracy train: {accuracy_train2}%')","metadata":{"execution":{"iopub.status.busy":"2024-05-31T16:31:34.154001Z","iopub.execute_input":"2024-05-31T16:31:34.154409Z","iopub.status.idle":"2024-05-31T16:33:31.686769Z","shell.execute_reply.started":"2024-05-31T16:31:34.154372Z","shell.execute_reply":"2024-05-31T16:33:31.685647Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Custom + Adam","metadata":{}},{"cell_type":"code","source":"leaf_CNN_adam = CNN().to(device)\nadam = optim.Adam(leaf_CNN_adam.parameters())\n\nlosses3 = train(leaf_CNN_adam, trainloader, adam)\naccuracy3 = test(leaf_CNN_adam, testloader)\n\nplt.plot(losses3)\nplt.show()\nprint(f'Accuracy test: {accuracy3}%')","metadata":{"execution":{"iopub.status.busy":"2024-05-31T15:21:19.259261Z","iopub.execute_input":"2024-05-31T15:21:19.259666Z","iopub.status.idle":"2024-05-31T15:33:42.281674Z","shell.execute_reply.started":"2024-05-31T15:21:19.259634Z","shell.execute_reply":"2024-05-31T15:33:42.280647Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"accuracy_train3 = test(leaf_CNN_adam, trainloader)\nprint(f'Accuracy train: {accuracy_train3}%')","metadata":{"execution":{"iopub.status.busy":"2024-05-31T16:33:31.688277Z","iopub.execute_input":"2024-05-31T16:33:31.688653Z","iopub.status.idle":"2024-05-31T16:35:28.654033Z","shell.execute_reply.started":"2024-05-31T16:33:31.688622Z","shell.execute_reply":"2024-05-31T16:35:28.652823Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Custom + Adam + Sheduler","metadata":{}},{"cell_type":"code","source":"leaf_CNN_adam_shed = CNN().to(device)\nadam = optim.Adam(leaf_CNN_adam_shed.parameters())\nsheduler = StepLR(adam, step_size=10)\n\nlosses4 = train(leaf_CNN_adam_shed, trainloader, adam, sheduler)\naccuracy4 = test(leaf_CNN_adam_shed, testloader)\n\nplt.plot(losses4)\nplt.show()\nprint(f'Accuracy test: {accuracy4}%')","metadata":{"execution":{"iopub.status.busy":"2024-05-31T16:09:23.643956Z","iopub.execute_input":"2024-05-31T16:09:23.644471Z","iopub.status.idle":"2024-05-31T16:20:17.648651Z","shell.execute_reply.started":"2024-05-31T16:09:23.644429Z","shell.execute_reply":"2024-05-31T16:20:17.647580Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"accuracy_train4 = test(leaf_CNN_adam_shed, trainloader)\nprint(f'Accuracy train: {accuracy_train4}%')","metadata":{"execution":{"iopub.status.busy":"2024-05-31T16:27:37.521327Z","iopub.execute_input":"2024-05-31T16:27:37.522188Z","iopub.status.idle":"2024-05-31T16:29:35.431123Z","shell.execute_reply.started":"2024-05-31T16:27:37.522147Z","shell.execute_reply":"2024-05-31T16:29:35.429925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Модель ResNet","metadata":{}},{"cell_type":"code","source":"resnet = torchvision.models.resnet18(pretrained=True)\nresnet.fc = nn.Linear(resnet.fc.in_features, 5)\nresnet.to(device)\n\nadam = optim.Adam(resnet.parameters())\n\nlosses5 = train(resnet, trainloader, adam)\naccuracy5 = test(resnet, testloader)\n\nplt.plot(losses5)\nplt.show()\nprint(f'Accuracy test: {accuracy5}%')","metadata":{"execution":{"iopub.status.busy":"2024-05-31T15:59:16.046009Z","iopub.execute_input":"2024-05-31T15:59:16.046395Z","iopub.status.idle":"2024-05-31T16:07:26.313459Z","shell.execute_reply.started":"2024-05-31T15:59:16.046361Z","shell.execute_reply":"2024-05-31T16:07:26.312378Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"accuracy_train5 = test(leaf_CNN_rms, trainloader)\nprint(f'Accuracy train: {accuracy_train5}%')","metadata":{"execution":{"iopub.status.busy":"2024-05-31T16:20:17.650611Z","iopub.execute_input":"2024-05-31T16:20:17.650906Z","iopub.status.idle":"2024-05-31T16:22:15.842422Z","shell.execute_reply.started":"2024-05-31T16:20:17.650879Z","shell.execute_reply":"2024-05-31T16:22:15.841314Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Активации внутренних слоев","metadata":{}},{"cell_type":"code","source":"activations = {}\ndef get_activation(name):\n    def hook(model, input, output):\n        activations[name] = output.detach()\n    return hook\n\ndef plot_activations(layer, num_cols=4, num_activations=16):\n    num_kernels = layer.shape[1]\n    fig, axes = plt.subplots(nrows=(num_activations + num_cols - 1) // num_cols, ncols=num_cols, figsize=(12, 12))\n    for i, ax in enumerate(axes.flat):\n        if i < num_kernels:\n            ax.imshow(layer[0, i].cpu().numpy(), cmap='twilight')\n            ax.axis('off')\n    plt.tight_layout()\n    plt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-05-31T16:22:40.142483Z","iopub.execute_input":"2024-05-31T16:22:40.142893Z","iopub.status.idle":"2024-05-31T16:22:40.150988Z","shell.execute_reply.started":"2024-05-31T16:22:40.142860Z","shell.execute_reply":"2024-05-31T16:22:40.149876Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Активации для первого сверточного слоя.","metadata":{}},{"cell_type":"code","source":"# Register hooks\nleaf_CNN_adam.conv1.register_forward_hook(get_activation('conv1'))\nleaf_CNN_adam.conv2.register_forward_hook(get_activation('conv2'))\nleaf_CNN_adam.conv3.register_forward_hook(get_activation('conv3'))\n\nwith torch.no_grad():\n    output = leaf_CNN_adam(images.to(device))\n\nplot_activations(activations['conv1'], num_cols=4, num_activations=16)","metadata":{"execution":{"iopub.status.busy":"2024-05-31T16:22:43.011495Z","iopub.execute_input":"2024-05-31T16:22:43.012195Z","iopub.status.idle":"2024-05-31T16:22:44.944958Z","shell.execute_reply.started":"2024-05-31T16:22:43.012165Z","shell.execute_reply":"2024-05-31T16:22:44.943575Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Отображение результатов.","metadata":{}},{"cell_type":"code","source":"results = pd.DataFrame({'Model': ['Custom + SGD', 'Custom + RMSprop', 'Custiom + Adam', 'Custom + Adam + Sheduler', 'Resnet + Adam'], 'Test accuracy': [accuracy1, accuracy2, accuracy3, accuracy4, accuracy5], 'Train accuracy': [accuracy_train1, accuracy_train2, accuracy_train3, accuracy_train4, accuracy_train5]})\nresults","metadata":{"execution":{"iopub.status.busy":"2024-05-31T16:35:28.655589Z","iopub.execute_input":"2024-05-31T16:35:28.655915Z","iopub.status.idle":"2024-05-31T16:35:28.669120Z","shell.execute_reply.started":"2024-05-31T16:35:28.655883Z","shell.execute_reply":"2024-05-31T16:35:28.667987Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2. Семантическая сегментация","metadata":{}},{"cell_type":"markdown","source":"Использованы модели из библиотеки SMP.","metadata":{}},{"cell_type":"code","source":"!pip install segmentation_models_pytorch\nimport segmentation_models_pytorch as smp\nfrom segmentation_models_pytorch import utils\nimport ssl\nimport os\nos.environ['CUDA_VISIBLE_DEVICES'] = '0'\n\n\nssl._create_default_https_context = ssl._create_stdlib_context","metadata":{"execution":{"iopub.status.busy":"2024-05-31T09:30:53.386823Z","iopub.execute_input":"2024-05-31T09:30:53.387353Z","iopub.status.idle":"2024-05-31T09:31:15.537275Z","shell.execute_reply.started":"2024-05-31T09:30:53.387312Z","shell.execute_reply":"2024-05-31T09:31:15.536232Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class SegmentationDataset(Dataset):\n    def __init__(self, data, label_colors, image_folder, mask_folder, extra_transform=None):\n        self.image_folder = image_folder\n        self.mask_folder = mask_folder\n        self.data = data\n        self.labels_dict = dict(zip([tuple(c) for c in label_colors], range(len(label_colors))))\n        self.class_values = list(range(len(label_colors)))\n        self.extra_transform = extra_transform\n        \n    def __len__(self):\n        return len(self.data)\n    \n    def __getitem__(self, idx):\n        img_name = self.data.iloc[idx, 0]\n        image = cv2.imread(self.image_folder+img_name+'.jpg')\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) / 255\n        image = torch.from_numpy(image).to(torch.float).permute(2, 0, 1)\n        \n        mask = cv2.imread(self.mask_folder+img_name+'.png')\n        mask = cv2.cvtColor(mask, cv2.COLOR_BGR2RGB)\n        mask = torch.from_numpy(mask).permute(2, 0, 1)\n        \n        image, mask = self.transform(image, mask)\n                \n        # Извлечение меток пикселей\n        mask = mask.permute(1, 2, 0)\n        mask = np.vectorize(lambda pix: self.labels_dict[tuple(pix)], signature='(3)->()')(mask)\n        masks = np.array([mask == v for v in self.class_values], dtype=float)\n#         masks = np.stack(mask, axis=-1)\n        \n        return image, masks\n    \n    def transform(self, image, mask):\n        # Нормализация\n        mean = [0.485, 0.456, 0.406]\n        std = [0.229, 0.224, 0.225]\n        normalize = transforms.Normalize(mean=mean, std=std)\n        image = normalize(image)\n                \n        # Сжатие\n        resize_transform = torchvision.transforms.Resize(1024, interpolation=TF.InterpolationMode.NEAREST)\n        image = resize_transform(image)\n        mask = resize_transform(mask)\n                \n        return image, mask\n","metadata":{"execution":{"iopub.status.busy":"2024-05-31T09:31:15.538456Z","iopub.execute_input":"2024-05-31T09:31:15.538733Z","iopub.status.idle":"2024-05-31T09:31:15.552054Z","shell.execute_reply.started":"2024-05-31T09:31:15.538699Z","shell.execute_reply":"2024-05-31T09:31:15.551214Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = 2\nimages_folder = '/kaggle/input/semantic-drone-dataset/dataset/semantic_drone_dataset/original_images/'\nmasks_folder = '/kaggle/input/semantic-drone-dataset/RGB_color_image_masks/RGB_color_image_masks/'\n\nlabels_df = pd.read_csv('/kaggle/input/semantic-drone-dataset/class_dict_seg.csv')\nclasses = labels_df['name'].values\nlabel_colors = labels_df.iloc[:, 1:4].to_numpy()\n\ntrain_images_names = os.listdir(images_folder)\ntrain_images_names = [name.split(sep='.')[0] for name in train_images_names]\ndf = pd.DataFrame(train_images_names, columns=['name'])\n\nn_train = int(len(df.index) * 0.8)\nn_test = len(df.index) - n_train\ntrain, test = train_test_split(df, test_size=0.2)\ntrain_set = SegmentationDataset(train, label_colors, images_folder, masks_folder)\ntest_set = SegmentationDataset(test, label_colors, images_folder, masks_folder)\ntrainloader = torch.utils.data.DataLoader(train_set, batch_size=batch_size,\n                                          shuffle=True, num_workers=2)\ntestloader = torch.utils.data.DataLoader(test_set, batch_size=batch_size,\n                                         shuffle=False, num_workers=2)","metadata":{"execution":{"iopub.status.busy":"2024-05-31T09:31:26.598913Z","iopub.execute_input":"2024-05-31T09:31:26.599286Z","iopub.status.idle":"2024-05-31T09:31:26.665558Z","shell.execute_reply.started":"2024-05-31T09:31:26.599235Z","shell.execute_reply":"2024-05-31T09:31:26.664525Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ENCODER = 'se_resnext50_32x4d'\nENCODER_WEIGHTS = 'imagenet'\nACTIVATION = 'softmax2d'\n\nmodel_fpn = smp.FPN(\n    encoder_name=ENCODER, \n    encoder_weights=ENCODER_WEIGHTS, \n    classes=len(classes), \n    activation=ACTIVATION,\n)\n","metadata":{"execution":{"iopub.status.busy":"2024-05-31T03:09:51.137038Z","iopub.execute_input":"2024-05-31T03:09:51.137411Z","iopub.status.idle":"2024-05-31T03:15:03.700041Z","shell.execute_reply.started":"2024-05-31T03:09:51.137381Z","shell.execute_reply":"2024-05-31T03:15:03.699078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_to_color_dict = dict(zip(range(len(classes)), label_colors))","metadata":{"execution":{"iopub.status.busy":"2024-05-31T11:44:26.448769Z","iopub.execute_input":"2024-05-31T11:44:26.449116Z","iopub.status.idle":"2024-05-31T11:44:26.453922Z","shell.execute_reply.started":"2024-05-31T11:44:26.449089Z","shell.execute_reply":"2024-05-31T11:44:26.452850Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DEVICE = 'cuda'","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"loss = utils.losses.DiceLoss()\nmetrics = [\n    smp.utils.metrics.IoU(threshold=0.5),\n]\n\noptimizer = torch.optim.Adam([ \n    dict(params=model_fpn.parameters(), lr=0.0001),\n])\n\ntrain_epoch = smp.utils.train.TrainEpoch(\n    model_fpn, \n    loss=loss, \n    metrics=metrics, \n    optimizer=optimizer,\n    device=DEVICE,\n    verbose=True,\n)","metadata":{"execution":{"iopub.status.busy":"2024-05-31T03:15:03.708371Z","iopub.execute_input":"2024-05-31T03:15:03.708672Z","iopub.status.idle":"2024-05-31T03:15:03.933973Z","shell.execute_reply.started":"2024-05-31T03:15:03.708646Z","shell.execute_reply":"2024-05-31T03:15:03.933214Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"max_score = 0\n\nfor i in range(0, 3):\n    \n    print('\\nEpoch: {}'.format(i))\n    train_logs = train_epoch.run(trainloader)\n    \n    torch.save(model_fpn, './best_seg_model.pth')\n    print('Model saved!')\n        \n    if i == 2:\n        optimizer.param_groups[0]['lr'] = 1e-5\n        print('Decrease decoder learning rate to 1e-5!')\n","metadata":{"execution":{"iopub.status.busy":"2024-05-31T03:15:03.935571Z","iopub.execute_input":"2024-05-31T03:15:03.935831Z","iopub.status.idle":"2024-05-31T04:49:17.448457Z","shell.execute_reply.started":"2024-05-31T03:15:03.935809Z","shell.execute_reply":"2024-05-31T04:49:17.447255Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_fpn = torch.load('/kaggle/input/fpn-v1/best_fpn.pth', map_location=DEVICE)\n\ntrain_set = SegmentationDataset(train, label_colors, images_folder, masks_folder)\ntest_set = SegmentationDataset(test, label_colors, images_folder, masks_folder)\ntrainloader = torch.utils.data.DataLoader(train_set, batch_size=batch_size,\n                                          shuffle=True, num_workers=2)\ntestloader = torch.utils.data.DataLoader(test_set, batch_size=batch_size,\n                                         shuffle=False, num_workers=2)","metadata":{"execution":{"iopub.status.busy":"2024-05-28T16:11:13.431205Z","iopub.execute_input":"2024-05-28T16:11:13.432031Z","iopub.status.idle":"2024-05-28T16:11:14.369090Z","shell.execute_reply.started":"2024-05-28T16:11:13.431983Z","shell.execute_reply":"2024-05-28T16:11:14.367598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def visualize(**images):\n    n = len(images)\n    plt.figure(figsize=(16, 5))\n    for i, (name, image) in enumerate(images.items()):\n        plt.subplot(1, n, i + 1)\n        plt.xticks([])\n        plt.yticks([])\n        plt.title(' '.join(name.split('_')).title())\n        plt.imshow(image)\n    plt.show()\n\ninv_normalize = transforms.Normalize(\n    mean=[-0.485/0.229, -0.456/0.224, -0.406/0.225],\n    std=[1/0.229, 1/0.224, 1/0.255]\n)\n\ndef masks_to_image(masks, colors):\n    _, h, w = masks.shape\n    image = np.zeros((h, w, 3), dtype=int)\n    for i in range(len(colors)):\n        for x in range(h):\n            for y in range(w):\n                if masks[i][x][y] == 1:\n                    image[x, y, :] = colors[i]\n    return image","metadata":{"execution":{"iopub.status.busy":"2024-05-31T11:46:19.704812Z","iopub.execute_input":"2024-05-31T11:46:19.705190Z","iopub.status.idle":"2024-05-31T11:46:19.715204Z","shell.execute_reply.started":"2024-05-31T11:46:19.705160Z","shell.execute_reply":"2024-05-31T11:46:19.714296Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(5):\n    n = np.random.choice(len(test_set))\n    \n    image, gt_mask = test_set[n]\n    image = inv_normalize(image)\n    x_tensor = image.to(DEVICE).unsqueeze(0)\n    pr_mask = model_fpn.predict(x_tensor)\n    pr_mask = pr_mask.squeeze().cpu().numpy().round()\n    \n    visualize(\n        image=image.permute(1,2,0),\n        ground_truth_mask=masks_to_image(gt_mask, label_colors),\n        predicted_mask=masks_to_image(pr_mask, label_colors)\n    )\n","metadata":{"execution":{"iopub.status.busy":"2024-05-31T04:56:22.740791Z","iopub.execute_input":"2024-05-31T04:56:22.741169Z","iopub.status.idle":"2024-05-31T05:11:23.613355Z","shell.execute_reply.started":"2024-05-31T04:56:22.741140Z","shell.execute_reply":"2024-05-31T05:11:23.612412Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Хорошо.","metadata":{}},{"cell_type":"markdown","source":"## Unet++","metadata":{}},{"cell_type":"code","source":"ENCODER = 'se_resnext50_32x4d'\nENCODER_WEIGHTS = 'imagenet'\nACTIVATION = 'softmax2d'\n\nmodel_unet = smp.UnetPlusPlus(\n    encoder_name=ENCODER, \n    encoder_weights=ENCODER_WEIGHTS, \n    classes=len(classes), \n)\n","metadata":{"execution":{"iopub.status.busy":"2024-05-31T09:35:22.462729Z","iopub.execute_input":"2024-05-31T09:35:22.463604Z","iopub.status.idle":"2024-05-31T09:40:34.410792Z","shell.execute_reply.started":"2024-05-31T09:35:22.463570Z","shell.execute_reply":"2024-05-31T09:40:34.410004Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = 1\ntrain_set = SegmentationDataset(train, label_colors, images_folder, masks_folder)\ntest_set = SegmentationDataset(test, label_colors, images_folder, masks_folder)\ntrainloader = torch.utils.data.DataLoader(train_set, batch_size=batch_size,\n                                          shuffle=True, num_workers=2)\ntestloader = torch.utils.data.DataLoader(test_set, batch_size=batch_size,\n                                         shuffle=False, num_workers=2)","metadata":{"execution":{"iopub.status.busy":"2024-05-31T09:48:54.628902Z","iopub.execute_input":"2024-05-31T09:48:54.629532Z","iopub.status.idle":"2024-05-31T09:48:54.635300Z","shell.execute_reply.started":"2024-05-31T09:48:54.629498Z","shell.execute_reply":"2024-05-31T09:48:54.634366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"loss = utils.losses.DiceLoss()\nmetrics = [\n    smp.utils.metrics.IoU(threshold=0.5),\n]\n\noptimizer = torch.optim.Adam([ \n    dict(params=model_unet.parameters(), lr=0.0001),\n])\n\ntrain_epoch = smp.utils.train.TrainEpoch(\n    model_unet, \n    loss=loss, \n    metrics=metrics, \n    optimizer=optimizer,\n    device=DEVICE,\n    verbose=True,\n)","metadata":{"execution":{"iopub.status.busy":"2024-05-31T09:48:57.997047Z","iopub.execute_input":"2024-05-31T09:48:57.997407Z","iopub.status.idle":"2024-05-31T09:48:58.246595Z","shell.execute_reply.started":"2024-05-31T09:48:57.997379Z","shell.execute_reply":"2024-05-31T09:48:58.245635Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"max_score = 0\nlogs = []\n\nfor i in range(0, 3):\n    \n    print('\\nEpoch: {}'.format(i))\n    train_logs = train_epoch.run(trainloader)\n    logs.append(train_logs)\n    \n    torch.save(model_unet, './best_seg_model.pth')\n    print('Model saved!')\n        \n    if i == 1:\n        optimizer.param_groups[0]['lr'] = 1e-5\n        print('Decrease decoder learning rate to 1e-5!')\n","metadata":{"execution":{"iopub.status.busy":"2024-05-31T09:49:02.462207Z","iopub.execute_input":"2024-05-31T09:49:02.462951Z","iopub.status.idle":"2024-05-31T11:23:55.720561Z","shell.execute_reply.started":"2024-05-31T09:49:02.462918Z","shell.execute_reply":"2024-05-31T11:23:55.719368Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot([log['dice_loss'] for log in logs])\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-05-31T12:04:13.977616Z","iopub.execute_input":"2024-05-31T12:04:13.978590Z","iopub.status.idle":"2024-05-31T12:04:14.224692Z","shell.execute_reply.started":"2024-05-31T12:04:13.978555Z","shell.execute_reply":"2024-05-31T12:04:14.223758Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(5):\n    n = np.random.choice(len(test_set))\n    \n    image, gt_mask = test_set[n]\n    image = inv_normalize(image)\n    x_tensor = image.to(DEVICE).unsqueeze(0)\n    pr_mask = model_unet.predict(x_tensor)\n    pr_mask = pr_mask.squeeze().cpu().numpy().round()\n    \n    visualize(\n        image=image.permute(1,2,0),\n        ground_truth_mask=masks_to_image(gt_mask, label_colors),\n        predicted_mask=masks_to_image(pr_mask, label_colors)\n    )\n","metadata":{"execution":{"iopub.status.busy":"2024-05-31T11:46:27.082481Z","iopub.execute_input":"2024-05-31T11:46:27.083346Z","iopub.status.idle":"2024-05-31T12:01:43.923096Z","shell.execute_reply.started":"2024-05-31T11:46:27.083304Z","shell.execute_reply":"2024-05-31T12:01:43.922187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Плохо.","metadata":{}}]}