{"cells":[{"metadata":{},"cell_type":"markdown","source":"Imports:"},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install albumentations","execution_count":4,"outputs":[{"output_type":"stream","text":"Collecting albumentations\n\u001b[33m  Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError('<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f241910e7b8>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution',)': /simple/albumentations/\u001b[0m\n^C\n","name":"stdout"}]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import torch\nimport torchvision\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optim\nimport torchvision.transforms as transforms\nimport albumentations\nfrom albumentations import torch as AT\nimport torchvision.models as models\nimport cv2\n\nfrom torch.utils.data import Dataset\nfrom torch.autograd import Variable\nfrom typing import Optional\nfrom typing import Tuple\nfrom typing import List\nfrom PIL import Image\nimport pandas as pd\nimport numpy as np\nimport math\nimport random\n\nimport time\nimport datetime\nimport IPython.display as display\nfrom IPython.display import clear_output\n\nimport matplotlib.pyplot as plt\nimport matplotlib.animation as animation\nfrom matplotlib import style\nimport pylab as pl\n\nfrom google.colab import files","execution_count":3,"outputs":[{"output_type":"error","ename":"ModuleNotFoundError","evalue":"No module named 'albumentations'","traceback":["\u001b[0;31m---------------------------------------------------------------------------\u001b[0m","\u001b[0;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)","\u001b[0;32m<ipython-input-3-10e77c7b0333>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moptim\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0moptim\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      6\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mtorchvision\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtransforms\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mtransforms\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 7\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0malbumentations\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      8\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0malbumentations\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mtorch\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mAT\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      9\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mtorchvision\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmodels\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mmodels\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n","\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'albumentations'"]}]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nDATA_FOLDER = \"../input\"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Hiperparameters**"},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"LR = 0.1\nBATCH_SIZE = 256\nTEST_BATCH_SIZE = 512\nWEIGHT_DECAY = 0.0005\n\nCLASSES = ['Cancer', 'No cancer']\n  \nDEVICE = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Data loading and preparation**\n\n\n---\n\nData split:\n\n\n*   train: 97% of total: 1/1; 219k of train_dataset, 51,5k of test_dataset\n*   valid: 1% of total: 2,5k of test_dataset\n*   test: 1% of total: 2,5k of test_dataset"},{"metadata":{"trusted":true},"cell_type":"code","source":"def to_float_tensor(tensor):\n    if not torch.is_tensor(tensor):\n        tensor = torch.FloatTensor(tensor)\n    else:\n        tensor = tensor.type(torch.FloatTensor)\n    return tensor.cuda()\n\nclass MainDataset(Dataset):\n    def __init__(self,\n                 x_dataset: Dataset,\n                 y_dataset: Dataset,):\n        self.x_dataset = x_dataset\n        self.y_dataset = y_dataset\n\n    def __len__(self) -> int:\n        return self.x_dataset.__len__()\n\n    def __getitem__(self, index: int) -> Tuple:\n        x = self.x_dataset[index]\n        y = self.y_dataset[index]\n        return x, y\n\n\nclass ImageDataset(Dataset):\n    def __init__(self, paths_to_imgs: List,\n                 transformer: Optional = None):\n        self.paths_to_imgs = paths_to_imgs\n        self.transformer = transformer\n\n    def __len__(self) -> int:\n        return len(self.paths_to_imgs)\n\n    def __getitem__(self, index: int) -> Image.Image:\n        img = cv2.imread(self.paths_to_imgs[index])\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        if self.transformer is not None:\n            img = self.transformer(image=img)\n        return img['image']\n\n\nclass LabelDataset(Dataset):\n    def __init__(self, labels: List):\n        self.labels = labels\n\n    def __len__(self) -> int:\n        return len(self.labels)\n\n    def __getitem__(self, index: int) -> int:\n        return self.labels[index]\n\n\nclass IdDataset(Dataset):\n    def __init__(self, ids: List):\n        self.ids = ids\n\n    def __len__(self) -> str:\n        return len(self.ids)\n\n    def __getitem__(self, index: int) -> str:\n        return self.ids[index]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Randomly divide kaggle dataframes into train/valid/test sets:"},{"metadata":{"trusted":true},"cell_type":"code","source":"kaggle_train_data = pd.read_csv(f\"{DATA_FOLDER}/train_labels.csv\")\n\nvalid_data = kaggle_train_data.sample(n=2500, random_state=113)\nkaggle_train_data = kaggle_train_data.drop(valid_data.index.values)\n\ntest_data = kaggle_train_data.sample(n=2500, random_state=113)\nkaggle_train_data = kaggle_train_data.drop(test_data.index.values)\n\ntrain_data = kaggle_train_data","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Define data augmentation and transformations for train and test loaders:"},{"metadata":{"trusted":true},"cell_type":"code","source":"transformers = {\n    'train': albumentations.Compose([\n    albumentations.CenterCrop(IMAGE_SIZE, IMAGE_SIZE),\n    albumentations.RandomRotate90(p=0.5),\n    albumentations.Transpose(p=0.5),\n    albumentations.Flip(p=0.5),\n    albumentations.OneOf([\n        albumentations.CLAHE(clip_limit=2), albumentations.IAASharpen(), albumentations.IAAEmboss(), \n        albumentations.RandomBrightness(), albumentations.RandomContrast(),\n        albumentations.JpegCompression(), albumentations.Blur(), albumentations.GaussNoise()], p=0.5), \n    albumentations.HueSaturationValue(p=0.5), \n    albumentations.ShiftScaleRotate(shift_limit=0.15, scale_limit=0.15, rotate_limit=45, p=0.5),\n    albumentations.Normalize(),\n    AT.ToTensor()\n    ]),\n    'test': albumentations.Compose([\n    albumentations.CenterCrop(IMAGE_SIZE, IMAGE_SIZE),\n    albumentations.Normalize(),\n    AT.ToTensor()\n    ])\n}","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Build data loaders:"},{"metadata":{"trusted":true},"cell_type":"code","source":"\ntrain_labels = pd.read_csv(f\"{DATA_FOLDER}/train_data.csv\")['label'].values.reshape(-1, 1)\nvalid_labels = pd.read_csv(f\"{DATA_FOLDER}/valid_data.csv\")['label'].values.reshape(-1, 1)\ntest_labels = pd.read_csv(f\"{DATA_FOLDER}/test_data.csv\")['label'].values.reshape(-1, 1)\nsubmission_labels = pd.read_csv(f\"{DATA_FOLDER}/sample_submission.csv\")['label'].values.reshape(-1, 1)\n\ntrain_ids = pd.read_csv(f\"{DATA_FOLDER}/train_data.csv\")['id'].values.reshape(-1, 1)\nvalid_ids = pd.read_csv(f\"{DATA_FOLDER}/valid_data.csv\")['id'].values.reshape(-1, 1)\ntest_ids = pd.read_csv(f\"{DATA_FOLDER}/test_data.csv\")['id'].values.reshape(-1, 1)\nsubmission_ids = pd.read_csv(f\"{DATA_FOLDER}/sample_submission.csv\")['id'].values.reshape(-1, 1)\n\ntrain_images = [f\"{DATA_FOLDER}/train/{f[0]}.tif\" for f in train_ids]\nvalid_images = [f\"{DATA_FOLDER}/train/{f[0]}.tif\" for f in valid_ids]\ntest_images = [f\"{DATA_FOLDER}/train/{f[0]}.tif\" for f in test_ids]\nsubmission_images = [f\"{DATA_FOLDER}/test/{f[0]}.tif\" for f in submission_ids]\n\ntrain_labels_dataset = LabelDataset(train_labels)\nvalid_labels_dataset = LabelDataset(valid_labels)\ntest_labels_dataset = LabelDataset(test_labels)\nsubmission_labels_dataset = LabelDataset(submission_labels)\n\ntrain_images_dataset = ImageDataset(train_images, transformers['train'])\nvalid_images_dataset = ImageDataset(valid_images, transformers['test'])\ntest_images_dataset = ImageDataset(test_images, transformers['test'])\nsubmission_images_dataset = ImageDataset(submission_images, transformers['test'])\n\ntrain_dataset = MainDataset(train_images_dataset, train_labels_dataset)\nvalid_dataset = MainDataset(valid_images_dataset, valid_labels_dataset)\ntest_dataset = MainDataset(test_images_dataset, test_labels_dataset)\nsubmission_dataset = MainDataset(submission_images_dataset, submission_labels_dataset)\n\ntrain_loader = torch.utils.data.DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True, num_workers=2)\nvalid_loader = torch.utils.data.DataLoader(valid_dataset, batch_size=TEST_BATCH_SIZE, shuffle=False, num_workers=2)\ntest_loader = torch.utils.data.DataLoader(test_dataset, batch_size=TEST_BATCH_SIZE, shuffle=False, num_workers=2)\nsubmission_loader = torch.utils.data.DataLoader(submission_dataset, batch_size=TEST_BATCH_SIZE, shuffle=False, num_workers=2)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Display some images from train dataset:"},{"metadata":{"trusted":true},"cell_type":"code","source":"fig = plt.figure(figsize=(20, 4))\nfor idx, img in enumerate(np.random.choice(train_images, 10)):\n    ax = fig.add_subplot(2, 5, idx+1, xticks=[], yticks=[])\n    im = Image.open(img)\n    plt.imshow(im)\n    lab = train_labels[np.where(train_ids == img.split('/')[-1].split('.')[0])][0]\n    ax.set_title(f'Label: {CLASSES[lab]}')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Display some images from test dataset:"},{"metadata":{"trusted":true},"cell_type":"code","source":"fig = plt.figure(figsize=(20, 4))\nfor idx, img in enumerate(np.random.choice(test_images, 10)):\n    ax = fig.add_subplot(2, 5, idx+1, xticks=[], yticks=[])\n    im = Image.open(img)\n    plt.imshow(im)\n    lab = test_labels[np.where(test_ids == img.split('/')[-1].split('.')[0])][0]\n    ax.set_title(f'Label: {CLASSES[lab]}')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Plot positive/negative labels balance in train/valid/test datasets:"},{"metadata":{"trusted":true},"cell_type":"code","source":"def positive_labels(data_loader, samples_num=None):\n    if samples_num is None:\n        return sum([torch.sum(labels).item() for i, (images, labels) in enumerate(data_loader, 0)])\n    else:\n        positive_sum = 0\n        for i, (images, labels) in enumerate(train_loader, 0):\n            positive_sum += torch.sum(labels).item()\n            if i > samples_num:\n              break\n        return positive_sum\n\ndef total_labels(data_loader):\n    return len(data_loader) * data_loader.batch_size\n  \nif SHOW_POSITIVES:\n    valid_positives = positive_labels(valid_loader)\n    test_positives = positive_labels(test_loader)\n    train_positives = positive_labels(train_loader, 30)\n\n    valid_total = total_labels(valid_loader)\n    test_total = total_labels(test_loader)\n    train_total = train_loader.batch_size * 30\n\n    print('Positives:total')\n    print(f'Valid dataset: {valid_positives}:{valid_total}')\n    print(f'Test dataset: {test_positives}:{test_total}')\n    print(f'Train dataset: {train_positives}:{train_total}')\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Live plotting tools setup for bias/variance monitoring:"},{"metadata":{"trusted":true},"cell_type":"code","source":"def set_x_max(x1, x2):\n    x_max = 200\n    if x1.size != 0:\n        x_max = max(x1[-1] + 100, x_max)\n    if x2.size != 0:\n        x_max = max(x2[-1] + 100, x_max)\n    return x_max\n        \n\ndef init_plot(title, x1, y1, x2, y2):\n    clear_output()\n    plt.style.use('seaborn-whitegrid')\n    plt.xlabel('Mini-batch', fontsize=15)\n    plt.ylabel('Cost', fontsize=15)\n    plt.xlim(0, set_x_max(x1, x2))\n    plt.ylim(0, 1)\n    plt.scatter(x1, y1, label='Train', marker='o', color='blue')\n    plt.scatter(x2, y2, label='Validation', marker='o', color='red')\n    plt.legend()\n    fig = plt.gcf()\n    fig.suptitle(title, fontsize=30)\n    fig.set_size_inches(20,10)\n    display(fig)\n\n\ndef update_plot(x1, y1, x2, y2):\n    plt.xlim(0, set_x_max(x1, x2))\n    plt.scatter(x1, y1, label='Costs', marker='o', color='blue')\n    plt.scatter(x2, y2, label='Errors', marker='o', color='red')\n    clear_output(wait=True)\n    display(plt.gcf())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Testing methods:"},{"metadata":{"trusted":true},"cell_type":"code","source":"def test_error(model, data_loader):\n    correct = 0\n    total = 0\n    with torch.no_grad():\n        for (inputs, labels) in data_loader:\n            inputs, labels = to_float_tensor(inputs), to_float_tensor(labels)\n            outputs = model(inputs)\n            predicted = torch.round(torch.sigmoid(outputs))\n            total += labels.size(0)\n            correct += (predicted == labels).sum().item()\n        return 1 - correct / total\n\ndef test_cost(model, data_loader):\n    running_loss = 0.0\n    mini_batches = 0\n    with torch.no_grad():\n        for (inputs, labels) in data_loader:\n            inputs, labels = to_float_tensor(inputs), to_float_tensor(labels)\n            outputs = model(inputs)\n            loss = criterion(outputs, labels)\n            running_loss += loss.item()\n            mini_batches += 1\n        return running_loss / mini_batches\n\ndef outputs_for(model, data_loader, ids):\n    loader_len = len(data_loader)\n    result = {'id': np.array([]), 'label': np.array([]), 'output': np.array([])}\n    print_interval = 100\n    with torch.no_grad():\n        for i, (inputs, labels) in enumerate(data_loader, 0):\n            inputs = to_float_tensor(inputs)\n            result['label'] = np.append(result['label'], labels.data.cpu().numpy().reshape(-1))\n            result['output'] = np.append(result['output'], torch.sigmoid(model(inputs)).data.cpu().numpy().reshape(-1))\n            if i % print_interval == print_interval - 1:\n                print(f'{datetime.datetime.now().replace(microsecond=0)} mini-batch: {(i + 1):3d}/{loader_len}')\n    result['id'] = ids.reshape(-1)\n    return result\n\ndef calculate_roc(test_result, step):\n    roc = {'x': np.array([]), 'y': np.array([])}\n    for threshold in np.arange(0, 1 + step, step):\n        roc['x'] = np.append(roc['x'], threshold)\n        predictions = test_result['output'] >= threshold\n        results = [prediction == label for prediction, label in zip(predictions, test_result['label'])]\n        roc['y'] = np.append(roc['y'], np.sum(results) / len(results))\n    return roc\n\ndef draw_roc(roc):\n    plt.plot(roc['x'], roc['y'], color='black', linewidth='3')\n    plt.xlim(0, 1)\n    plt.ylim(0, 1)\n    plt.show()\n\ndef calculate_auroc(roc):\n    return np.sum([(roc['x'][i + 1] - roc['x'][i])*(roc['y'][i] + 0.5 * (roc['y'][i + 1] - roc['y'][i])) for i in range(len(roc['x']) - 1)])\n\ndef eval_submission(submission, threshold):\n    result = {'id': submission['id'], 'label': []}\n    result['label'] = (submission['output'] >= threshold).astype(int)\n    return result\n    ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Training method:"},{"metadata":{"trusted":true},"cell_type":"code","source":"learning_start_time = time.time()\ntrain_costs = (np.array([]), np.array([]))\nvalid_costs = (np.array([]), np.array([]))\nepoch = 0\nbatch_num = 0\navg_train_loss = 0.7","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%pylab inline\n\ndef train_model(model):\n    global train_costs, valid_costs\n    init_plot('Training model ' + str(TRAINED_MODEL), train_costs[0], train_costs[1], valid_costs[0], valid_costs[1])\n    print(f'{datetime.datetime.now().replace(microsecond=0)} Started learning')\n\n    global learning_start_time\n    global batch_num\n    global avg_train_loss\n    global epoch\n\n    for i in range(EPOCHS):\n        running_loss = 0.0\n        start_time = time.time()\n        dataset_len = len(train_loader.dataset)\n\n        for i, (inputs, labels) in enumerate(train_loader, 0):\n            inputs, labels = to_float_tensor(inputs), to_float_tensor(labels)\n\n            optimizer.zero_grad()\n            outputs = model(inputs)\n            loss = criterion(outputs, labels)\n            loss.backward()\n            optimizer.step()\n\n            running_loss += loss.item()\n            print_interval = 150\n            valid_interval = 400\n            if i % print_interval == print_interval - 1:\n                avg_train_loss = avg_train_loss * 0.7 + (running_loss / print_interval) * 0.3\n                running_loss = 0.0\n                train_costs = (np.append(train_costs[0], batch_num),\n                               np.append(train_costs[1], avg_train_loss))\n                update_plot(train_costs[0], train_costs[1], valid_costs[0], valid_costs[1])\n                print(f'[{datetime.datetime.now().replace(microsecond=0)} epoch: {epoch + 1}, mini-batch: {(i + 1):3d}/{math.ceil(dataset_len / BATCH_SIZE)}] loss: {avg_train_loss:.3f} in: {time.time() - start_time:.0f} s')\n                start_time = time.time()\n            if i % valid_interval == valid_interval - 1:\n                valid_cost = test_cost(model, valid_loader)\n                valid_costs = (np.append(valid_costs[0], batch_num),\n                               np.append(valid_costs[1], valid_cost))\n                update_plot(train_costs[0], train_costs[1], valid_costs[0], valid_costs[1])\n                print(f\"{datetime.datetime.now().replace(microsecond=0)} Loss on validation dataset: {valid_cost:1.3f}\")\n                print(f\"{datetime.datetime.now().replace(microsecond=0)} Total learning time: {((time.time() - learning_start_time) / 60):3.1f} min\")\n                start_time = time.time()\n            batch_num += 1\n        epoch += 1","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Define single BottleNeck ResNet unit:"},{"metadata":{"trusted":true},"cell_type":"code","source":"class ResUnit(nn.Module):\n\n    def __init__(self, inplanes, outplanes):\n        super(ResUnit, self).__init__()\n        self.inplanes = inplanes\n        self.outplanes = outplanes\n        self.downsample = nn.Conv2d(inplanes, outplanes, 1)\n        self.conv = nn.Sequential(\n            nn.Conv2d(inplanes, int(outplanes / 4), 1),\n            nn.BatchNorm2d(int(outplanes / 4)),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(int(outplanes / 4), int(outplanes / 4), 3, padding=1),\n            nn.BatchNorm2d(int(outplanes / 4)),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(int(outplanes / 4), outplanes, 1),\n            nn.BatchNorm2d(outplanes)\n        )\n        self.relu = nn.ReLU(inplace=True)\n\n    def forward(self, x):\n        residual = x\n        x = self.conv(x)\n        if self.inplanes != self.outplanes:\n            residual = self.downsample(residual)\n        x += residual\n        return self.relu(x)\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Define ResNet model:"},{"metadata":{"trusted":true},"cell_type":"code","source":"class ResNet(nn.Module):\n\n    def __init__(self):\n        super(ResNet, self).__init__()\n        # 68 x 68\n        self.conv1 = nn.Sequential(\n            nn.Conv2d(3, 64, 5),\n            nn.ReLU(inplace=True)\n        )\n        # 32 x 32\n        self.conv2 = nn.Sequential(\n            ResUnit(64, 256),\n            ResUnit(256, 256),\n            ResUnit(256, 256)\n        )\n        # 16 x 16\n        self.conv3 = nn.Sequential(\n            ResUnit(256, 512),\n            ResUnit(512, 512),\n            ResUnit(512, 512),\n            ResUnit(512, 512)\n        )\n        # 8 x 8\n        self.conv4 = nn.Sequential(\n            ResUnit(512, 1024),\n            ResUnit(1024, 1024),\n            ResUnit(1024, 1024),\n            ResUnit(1024, 1024),\n            ResUnit(1024, 1024),\n            ResUnit(1024, 1024)\n        )\n        # 4 x 4\n        self.conv5 = nn.Sequential(\n            ResUnit(1024, 2048),\n            ResUnit(2048, 2048),\n            ResUnit(2048, 2048)\n        )\n        self.max_pool = nn.MaxPool2d(2, 2)\n        self.avg_pool = nn.AvgPool2d(4, 1)\n        # 2048\n        self.fc = nn.Linear(2048, 1)\n\n    def forward(self, x):\n        x = self.conv1(x)\n        x = self.max_pool(x)\n        x = self.conv2(x)\n        x = self.max_pool(x)\n        x = self.conv3(x)\n        x = self.max_pool(x)\n        x = self.conv4(x)\n        x = self.max_pool(x)\n        x = self.conv5(x)\n        x = self.avg_pool(x)\n        x = x.view(x.size(0), -1)\n        x = self.fc(x)\n        return x\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model1 = ResNet()\nmodel1 = model1.cuda()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"criterion = nn.BCEWithLogitsLoss()\noptimizer = optim.SGD(model1.parameters(), lr=LR, weight_decay=WEIGHT_DECAY)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Train model:"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_model(model1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Test model on valid dataset:"},{"metadata":{"trusted":true},"cell_type":"code","source":"error = test_error(model1, valid_loader)  \nprint(f\"Error on valid dataseti: {(error * 100):2.2f}%\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Test model on test dataset:"},{"metadata":{"trusted":true},"cell_type":"code","source":"error = test_error(model1, test_loader)  \nprint(f\"Error on test dataset: {(error * 100):2.2f}%\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Draw ROC:"},{"metadata":{"trusted":true},"cell_type":"code","source":"outputs_test = outputs_for(model1, train_loader, test_ids)\nroc = calculate_roc(outputs_test, 0.001)\nauroc = calculate_auroc(roc)\nargmax = np.argmax(roc['y'])\nclear_output(wait=True)\ndraw_roc(roc)\nprint(f'AUROC: {auroc:.3f}')\nprint(f\"Max of ROC: {roc['y'][argmax]:.3f} for threshold: {roc['x'][argmax]}\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Create and save submission for prepared model:"},{"metadata":{"trusted":true},"cell_type":"code","source":"submission = outputs_for(model1, submission_loader, submission_ids)\nsubmission_result = eval_submission(submission, 0.5)\npd.DataFrame.from_dict(submission_result).to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}