{"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":"gpu","dataSources":[{"sourceId":20270,"databundleVersionId":1222630,"sourceType":"competition"},{"sourceId":1236170,"sourceType":"datasetVersion","datasetId":708434}],"dockerImageVersionId":30636,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Libraries we'll use","metadata":{}},{"cell_type":"code","source":"import numpy as np \nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom albumentations import Compose, Flip, CropAndPad, Transpose\nimport os","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-01-25T15:59:52.359857Z","iopub.execute_input":"2024-01-25T15:59:52.360686Z","iopub.status.idle":"2024-01-25T15:59:55.142707Z","shell.execute_reply.started":"2024-01-25T15:59:52.360651Z","shell.execute_reply":"2024-01-25T15:59:55.141899Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pd.read_csv('/kaggle/input/melanoma224/train.csv')\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2024-01-25T15:59:55.953081Z","iopub.execute_input":"2024-01-25T15:59:55.954091Z","iopub.status.idle":"2024-01-25T15:59:56.058442Z","shell.execute_reply.started":"2024-01-25T15:59:55.954056Z","shell.execute_reply":"2024-01-25T15:59:56.057504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Umbalanced dataset","metadata":{}},{"cell_type":"code","source":"print(train['target'].value_counts())\ntrain['target'].hist()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-01-25T15:59:58.740621Z","iopub.execute_input":"2024-01-25T15:59:58.741399Z","iopub.status.idle":"2024-01-25T15:59:59.098259Z","shell.execute_reply.started":"2024-01-25T15:59:58.741361Z","shell.execute_reply":"2024-01-25T15:59:59.097361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"mode:{train['age_approx'].mode()}\")\ntrain['age_approx'].hist()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:00:06.786362Z","iopub.execute_input":"2024-01-25T16:00:06.786801Z","iopub.status.idle":"2024-01-25T16:00:06.951415Z","shell.execute_reply.started":"2024-01-25T16:00:06.786767Z","shell.execute_reply":"2024-01-25T16:00:06.950184Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['age_approx'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:00:14.162264Z","iopub.execute_input":"2024-01-25T16:00:14.162968Z","iopub.status.idle":"2024-01-25T16:00:14.172214Z","shell.execute_reply.started":"2024-01-25T16:00:14.162934Z","shell.execute_reply":"2024-01-25T16:00:14.171238Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['age_approx'].hist(bins=len(train['age_approx'].unique()))\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:00:19.901294Z","iopub.execute_input":"2024-01-25T16:00:19.901664Z","iopub.status.idle":"2024-01-25T16:00:20.133054Z","shell.execute_reply.started":"2024-01-25T16:00:19.901635Z","shell.execute_reply":"2024-01-25T16:00:20.132152Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"imgs = os.listdir('/kaggle/input/melanoma224/jpeg224/train')\nimgs[:5]","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:00:27.749611Z","iopub.execute_input":"2024-01-25T16:00:27.749983Z","iopub.status.idle":"2024-01-25T16:00:28.262458Z","shell.execute_reply.started":"2024-01-25T16:00:27.749955Z","shell.execute_reply":"2024-01-25T16:00:28.261488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# One hot encoding for metadata","metadata":{}},{"cell_type":"code","source":"train.info()","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:00:46.325956Z","iopub.execute_input":"2024-01-25T16:00:46.326349Z","iopub.status.idle":"2024-01-25T16:00:46.361122Z","shell.execute_reply.started":"2024-01-25T16:00:46.326319Z","shell.execute_reply":"2024-01-25T16:00:46.360342Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.isna().sum()","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:00:52.790351Z","iopub.execute_input":"2024-01-25T16:00:52.791182Z","iopub.status.idle":"2024-01-25T16:00:52.817749Z","shell.execute_reply.started":"2024-01-25T16:00:52.791138Z","shell.execute_reply":"2024-01-25T16:00:52.816765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import OneHotEncoder\n\ncols = [\"sex\", \"age_approx\", \"anatom_site_general_challenge\"]\nselected_cols = train[cols]\noh_encoder = OneHotEncoder()\noh_encoded = oh_encoder.fit_transform(selected_cols)\ncategories = oh_encoder.categories_","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:00:59.668696Z","iopub.execute_input":"2024-01-25T16:00:59.669043Z","iopub.status.idle":"2024-01-25T16:00:59.705737Z","shell.execute_reply.started":"2024-01-25T16:00:59.669018Z","shell.execute_reply":"2024-01-25T16:00:59.704971Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"oh_encoder.transform([['female', 10.0, 'torso']]).toarray()","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:01:09.248162Z","iopub.execute_input":"2024-01-25T16:01:09.249198Z","iopub.status.idle":"2024-01-25T16:01:09.262359Z","shell.execute_reply.started":"2024-01-25T16:01:09.249153Z","shell.execute_reply":"2024-01-25T16:01:09.261316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"new_columns = oh_encoder.get_feature_names_out(cols)","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:01:17.166549Z","iopub.execute_input":"2024-01-25T16:01:17.166909Z","iopub.status.idle":"2024-01-25T16:01:17.171378Z","shell.execute_reply.started":"2024-01-25T16:01:17.166881Z","shell.execute_reply":"2024-01-25T16:01:17.170496Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_clean = pd.DataFrame(oh_encoded.toarray(), columns=new_columns)","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:01:22.723323Z","iopub.execute_input":"2024-01-25T16:01:22.724287Z","iopub.status.idle":"2024-01-25T16:01:22.739104Z","shell.execute_reply.started":"2024-01-25T16:01:22.724253Z","shell.execute_reply":"2024-01-25T16:01:22.738229Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_clean.isna().sum()","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:01:28.139008Z","iopub.execute_input":"2024-01-25T16:01:28.139977Z","iopub.status.idle":"2024-01-25T16:01:28.149621Z","shell.execute_reply.started":"2024-01-25T16:01:28.139940Z","shell.execute_reply":"2024-01-25T16:01:28.148654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Train set and validation set","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\n_, val = train_test_split(train, test_size=0.33, shuffle=True, random_state=42, stratify=train['target'])\n\"\"\"\nstratify hace que a la hora de hacer los dataset de train o validation no nos carguemos todos los valores que tienen 1 en uno de los dos datasets.\nya que hay muy pocos en comparacion con los de 0. entonces como que los distribuye en partes iguales\n\"\"\"\nval.shape","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:01:47.653295Z","iopub.execute_input":"2024-01-25T16:01:47.654011Z","iopub.status.idle":"2024-01-25T16:01:47.685298Z","shell.execute_reply.started":"2024-01-25T16:01:47.653979Z","shell.execute_reply":"2024-01-25T16:01:47.684460Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['target'].hist()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:01:56.244488Z","iopub.execute_input":"2024-01-25T16:01:56.245119Z","iopub.status.idle":"2024-01-25T16:01:56.486883Z","shell.execute_reply.started":"2024-01-25T16:01:56.245087Z","shell.execute_reply":"2024-01-25T16:01:56.485939Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val['target'].hist()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:02:04.052420Z","iopub.execute_input":"2024-01-25T16:02:04.053110Z","iopub.status.idle":"2024-01-25T16:02:04.281650Z","shell.execute_reply.started":"2024-01-25T16:02:04.053078Z","shell.execute_reply":"2024-01-25T16:02:04.280823Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# PyTorch baseline","metadata":{}},{"cell_type":"code","source":"import torch\nimport torchvision\nfrom skimage import io\nfrom fastprogress import master_bar, progress_bar\n\ntorch.__version__","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:02:24.447709Z","iopub.execute_input":"2024-01-25T16:02:24.448071Z","iopub.status.idle":"2024-01-25T16:02:27.984973Z","shell.execute_reply.started":"2024-01-25T16:02:24.448045Z","shell.execute_reply":"2024-01-25T16:02:27.984063Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val.head()","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:02:40.712320Z","iopub.execute_input":"2024-01-25T16:02:40.712883Z","iopub.status.idle":"2024-01-25T16:02:40.726333Z","shell.execute_reply.started":"2024-01-25T16:02:40.712854Z","shell.execute_reply":"2024-01-25T16:02:40.725467Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head()","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:02:53.357141Z","iopub.execute_input":"2024-01-25T16:02:53.358087Z","iopub.status.idle":"2024-01-25T16:02:53.370676Z","shell.execute_reply.started":"2024-01-25T16:02:53.358054Z","shell.execute_reply":"2024-01-25T16:02:53.369762Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['path'] = [f'/kaggle/input/melanoma224/jpeg224/train/{img}.jpg' for img in train['image_name']]\nval['path'] = [f'/kaggle/input/melanoma224/jpeg224/train/{img}.jpg' for img in val['image_name']]","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:03:00.403081Z","iopub.execute_input":"2024-01-25T16:03:00.403479Z","iopub.status.idle":"2024-01-25T16:03:00.426153Z","shell.execute_reply.started":"2024-01-25T16:03:00.403450Z","shell.execute_reply":"2024-01-25T16:03:00.425399Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Pytorch dataset","metadata":{}},{"cell_type":"code","source":"class Dataset(torch.utils.data.Dataset):\n    def __init__(self, images, meta, labels=None, train=True, cache=False, trans=None):\n        self.cache = cache\n        self.images = [self.load_img(img) for img in images] if cache else images\n        meta = oh_encoder.transform(meta).toarray()\n        self.meta = torch.tensor(meta).float()\n        self.train = train\n        self.trans = trans\n        if train: self.labels = [torch.tensor([label]).float() for label in labels]\n    \n    def __len__(self):\n        return len(self.images)\n    \n    def load_img(self, img):\n        return io.imread(img)\n    \n    def __getitem__(self, ix):    \n        img = self.images[ix] if self.cache else self.load_img(self.images[ix])\n        if self.trans:\n            img = self.trans(image=img)['image']\n        if self.train:\n            return torch.from_numpy(img), self.meta[ix], self.labels[ix]\n        return torch.from_numpy(img), self.meta[ix]\n\ntrans = Compose([\n    Flip(p=0.6), Transpose(), CropAndPad(p=0.2, percent=-0.1),\n])","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:03:19.320882Z","iopub.execute_input":"2024-01-25T16:03:19.321687Z","iopub.status.idle":"2024-01-25T16:03:19.331637Z","shell.execute_reply.started":"2024-01-25T16:03:19.321656Z","shell.execute_reply":"2024-01-25T16:03:19.330544Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset = {\n    'train': Dataset(train['path'], train[cols], train['target'], cache=True, trans=trans),\n    'val': Dataset(val['path'], val[cols], val['target'], cache=True, trans=trans),\n}","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:03:28.384402Z","iopub.execute_input":"2024-01-25T16:03:28.384785Z","iopub.status.idle":"2024-01-25T16:07:34.993607Z","shell.execute_reply.started":"2024-01-25T16:03:28.384758Z","shell.execute_reply":"2024-01-25T16:07:34.992763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Sample of the images","metadata":{}},{"cell_type":"code","source":"import random\n\nr, c = 3, 5\nfig = plt.figure(figsize=(2*c, 2*r))\nfor _r in range(r):\n    for _c in range(c):\n        plt.subplot(r, c, _r*c + _c + 1)\n        ix = random.randint(0, len(dataset['train']) - 1)\n        img, meta, label = dataset['train'][ix]\n        plt.imshow(img)\n        plt.title(label)\n        plt.axis('off')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:07:34.995061Z","iopub.execute_input":"2024-01-25T16:07:34.995371Z","iopub.status.idle":"2024-01-25T16:07:36.204978Z","shell.execute_reply.started":"2024-01-25T16:07:34.995345Z","shell.execute_reply":"2024-01-25T16:07:36.204010Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"meta","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:07:36.206111Z","iopub.execute_input":"2024-01-25T16:07:36.206427Z","iopub.status.idle":"2024-01-25T16:07:36.212870Z","shell.execute_reply.started":"2024-01-25T16:07:36.206401Z","shell.execute_reply":"2024-01-25T16:07:36.212008Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Building the model\n\npara trabajar con cnns en pytorch, debemos tener los canales como (batch_size, canales, alto, ancho).\n\npor eso hicimos la transformacion de (b, h, w, c) -> (b, c, h, w)\n","metadata":{}},{"cell_type":"code","source":"class NN(torch.nn.Module):\n    def __init__(self, inputs=29):\n        super().__init__()\n        # encoder de imagenes\n        resnet = torchvision.models.resnet101(weights=True)\n        for param in resnet.parameters():\n            param.requires_grad = False # no aplicar los gradientes\n        self.encoder = torch.nn.Sequential(*list(resnet.children())[:-1]) # conecta capas secuencialmente\n        \n        # encoder para metadata\n        self.meta_encoder = torch.nn.Sequential(\n            torch.nn.Linear(inputs, 100),\n            torch.nn.ReLU(inplace=True),\n            torch.nn.Linear(100, 3),\n            torch.nn.ReLU(inplace=True))\n        \n        # head. el head del backbone\n        self.head = torch.nn.Linear(2048+3, 1)\n        \n    def forward(self, x, y):\n        B, H, W, C = x.shape\n        x = (x / 255.).float().view(B, C, H, W)\n        x = self.encoder(x)\n        x = x.view(B, -1) # reshape\n        y = self.meta_encoder(y)\n        z = torch.cat([x, y], -1)\n        z = self.head(z)\n        \n        return z","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:07:36.214810Z","iopub.execute_input":"2024-01-25T16:07:36.215075Z","iopub.status.idle":"2024-01-25T16:07:36.225032Z","shell.execute_reply.started":"2024-01-25T16:07:36.215052Z","shell.execute_reply":"2024-01-25T16:07:36.224200Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Instantiate the model","metadata":{}},{"cell_type":"code","source":"BATCH_SIZE = 64\n\nmodel = NN()\n\noutput = model(torch.randn(BATCH_SIZE, 224, 224, 3), torch.randn(BATCH_SIZE, 29))\noutput.shape","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:07:36.226152Z","iopub.execute_input":"2024-01-25T16:07:36.226969Z","iopub.status.idle":"2024-01-25T16:07:50.207126Z","shell.execute_reply.started":"2024-01-25T16:07:36.226936Z","shell.execute_reply":"2024-01-25T16:07:50.206206Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Pytorch dataloader","metadata":{}},{"cell_type":"code","source":"dataloader = {\n    'train': torch.utils.data.DataLoader(dataset['train'], batch_size=BATCH_SIZE, shuffle=True),\n    'val': torch.utils.data.DataLoader(dataset['val'], batch_size=BATCH_SIZE),\n}","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:07:50.208579Z","iopub.execute_input":"2024-01-25T16:07:50.209200Z","iopub.status.idle":"2024-01-25T16:07:50.215199Z","shell.execute_reply.started":"2024-01-25T16:07:50.209161Z","shell.execute_reply":"2024-01-25T16:07:50.214247Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"imgs, meta, labels = next(iter(dataloader['train']))\n\nimgs.shape, meta.shape, labels.shape","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:07:50.216568Z","iopub.execute_input":"2024-01-25T16:07:50.216922Z","iopub.status.idle":"2024-01-25T16:07:50.261561Z","shell.execute_reply.started":"2024-01-25T16:07:50.216884Z","shell.execute_reply":"2024-01-25T16:07:50.260723Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Move the model to GPU","metadata":{}},{"cell_type":"code","source":"device = 'cuda' if torch.cuda.is_available() else 'cpu'\ndevice","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:07:50.262696Z","iopub.execute_input":"2024-01-25T16:07:50.263189Z","iopub.status.idle":"2024-01-25T16:07:50.292741Z","shell.execute_reply.started":"2024-01-25T16:07:50.263141Z","shell.execute_reply":"2024-01-25T16:07:50.291601Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## AUC error metric","metadata":{}},{"cell_type":"code","source":"from sklearn.metrics import roc_auc_score\n\ndef AUC(outputs, labels):\n    outputs = torch.sigmoid(outputs)\n    outputs = outputs.detach().cpu().numpy()\n    labels = labels.detach().cpu().numpy()\n    auc = roc_auc_score(labels, outputs)\n    return auc","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:07:50.294079Z","iopub.execute_input":"2024-01-25T16:07:50.295431Z","iopub.status.idle":"2024-01-25T16:07:50.304106Z","shell.execute_reply.started":"2024-01-25T16:07:50.295392Z","shell.execute_reply":"2024-01-25T16:07:50.303072Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training the model","metadata":{}},{"cell_type":"code","source":"model = NN()\noptimizer = torch.optim.Adam(model.parameters(), lr=0.01)\ncriterion = torch.nn.BCEWithLogitsLoss() # this loss apply sigmoid itself, and it's better mathematically\n\nepochs = 12\nvalidation_steps = 15\n\nmb = master_bar(range(1, epochs+1))\nbest_auc = 0\n\nmodel.to(device)\n\nfor epoch in mb:\n    train_loss = []\n    model.train() # training mode\n    for batch in progress_bar(dataloader['train'], parent=mb):\n        imgs, meta, labels = batch\n        imgs, meta, labels = imgs.to(device), meta.to(device), labels.to(device)\n        outputs = model(imgs, meta)\n        optimizer.zero_grad()\n        loss = criterion(outputs, labels)\n        #torch.cuda.empty_cache()\n        loss.backward()\n        optimizer.step() # apply the gradient\n        train_loss.append(loss.item())\n        mb.child.comment = f'loss: {np.mean(train_loss):.5f}'\n        \n    val_loss = []\n    model.eval() # evaluation mode\n    validation_step = 0\n    val_outputs = torch.tensor([])\n    val_targets = torch.tensor([])\n    with torch.no_grad():\n        for batch in progress_bar(dataloader['val'], parent=mb):\n            imgs, meta, labels = batch\n            imgs, meta, labels = imgs.to(device), meta.to(device), labels.to(device)\n            outputs = model(imgs, meta)\n            loss = criterion(outputs, labels)\n            val_loss.append(loss.item())\n            mb.child.comment = f'val_loss: {np.mean(val_loss):.5f}'\n            val_outputs = torch.cat([val_outputs, outputs.cpu()])\n            val_targets = torch.cat([val_targets, labels.cpu()])\n            validation_step += 1\n            if validation_step > validation_steps:\n                break\n                \n    auc = AUC(val_outputs, val_targets)\n    if auc > best_auc:\n        best_auc = auc\n        torch.save(model, 'model.pth') # saving the model\n        \n    mb.write(f'epoch: {epoch} | train_loss: {np.mean(train_loss):.5f} | epoch: {epoch} | val_loss: {np.mean(val_loss):.5f} | auc_loss: {auc:.5f}')","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:07:50.308273Z","iopub.execute_input":"2024-01-25T16:07:50.308611Z","iopub.status.idle":"2024-01-25T16:28:23.421119Z","shell.execute_reply.started":"2024-01-25T16:07:50.308541Z","shell.execute_reply":"2024-01-25T16:28:23.420145Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Let's see the performance with the testset","metadata":{}},{"cell_type":"code","source":"test = pd.read_csv('/kaggle/input/melanoma224/test.csv')\ntest['path'] = [f'/kaggle/input/melanoma224/jpeg224/test/{img}.jpg' for img in test['image_name']]\n\ntest.head()","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:28:23.422263Z","iopub.execute_input":"2024-01-25T16:28:23.422524Z","iopub.status.idle":"2024-01-25T16:28:23.468306Z","shell.execute_reply.started":"2024-01-25T16:28:23.422500Z","shell.execute_reply":"2024-01-25T16:28:23.467252Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dataset = Dataset(test['path'], test[cols], train=False)\ntest_dataloader = torch.utils.data.DataLoader(test_dataset, batch_size=200)","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:28:23.469629Z","iopub.execute_input":"2024-01-25T16:28:23.469979Z","iopub.status.idle":"2024-01-25T16:28:23.485133Z","shell.execute_reply.started":"2024-01-25T16:28:23.469944Z","shell.execute_reply":"2024-01-25T16:28:23.484380Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"imgs, meta = next(iter(test_dataloader))\nimgs.shape, meta.shape","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:28:23.488007Z","iopub.execute_input":"2024-01-25T16:28:23.488310Z","iopub.status.idle":"2024-01-25T16:28:24.983214Z","shell.execute_reply.started":"2024-01-25T16:28:23.488285Z","shell.execute_reply":"2024-01-25T16:28:24.982219Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Loading the model and testing","metadata":{}},{"cell_type":"code","source":"model_save = torch.load('/kaggle/working/model.pth')\nmodel_save.to(device)\nmodel_save.eval()\npreds = torch.tensor([]).to(device)\n\n# we dont need to calculate grads during testing\nwith torch.no_grad():\n    for imgs, meta in progress_bar(test_dataloader):\n        imgs, meta = imgs.to(device), meta.to(device)\n        outputs = model(imgs, meta)\n        outputs = torch.sigmoid(outputs)\n        preds = torch.cat([preds, outputs.view(-1)])","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:28:24.984368Z","iopub.execute_input":"2024-01-25T16:28:24.984660Z","iopub.status.idle":"2024-01-25T16:29:41.736980Z","shell.execute_reply.started":"2024-01-25T16:28:24.984636Z","shell.execute_reply":"2024-01-25T16:29:41.735995Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:29:41.738312Z","iopub.execute_input":"2024-01-25T16:29:41.738630Z","iopub.status.idle":"2024-01-25T16:29:42.220361Z","shell.execute_reply.started":"2024-01-25T16:29:41.738603Z","shell.execute_reply":"2024-01-25T16:29:42.219455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Convert the preds to dataframe","metadata":{}},{"cell_type":"code","source":"submission = pd.DataFrame({'image_name': test['image_name'].values, 'target': preds.cpu().numpy()})\nsubmission","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:29:42.221668Z","iopub.execute_input":"2024-01-25T16:29:42.222317Z","iopub.status.idle":"2024-01-25T16:29:42.234936Z","shell.execute_reply.started":"2024-01-25T16:29:42.222283Z","shell.execute_reply":"2024-01-25T16:29:42.234074Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Export to CSV","metadata":{}},{"cell_type":"code","source":"submission.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-01-25T16:29:42.235952Z","iopub.execute_input":"2024-01-25T16:29:42.236234Z","iopub.status.idle":"2024-01-25T16:29:42.282819Z","shell.execute_reply.started":"2024-01-25T16:29:42.236207Z","shell.execute_reply":"2024-01-25T16:29:42.282163Z"},"trusted":true},"execution_count":null,"outputs":[]}]}