{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## Import Libraries","metadata":{}},{"cell_type":"code","source":"import warnings\nwarnings.filterwarnings(\"ignore\")","metadata":{"execution":{"iopub.status.busy":"2021-08-26T08:09:13.378830Z","iopub.execute_input":"2021-08-26T08:09:13.379197Z","iopub.status.idle":"2021-08-26T08:09:13.388257Z","shell.execute_reply.started":"2021-08-26T08:09:13.379145Z","shell.execute_reply":"2021-08-26T08:09:13.387443Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from glob import glob\nimport pandas as pd\nfrom pathlib import Path\nimport numpy as np\nfrom tqdm import tqdm\n\nimport matplotlib.pyplot as plt\nfrom PIL import Image\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import label_binarize\nfrom sklearn import metrics\n\nimport pytorch_lightning as pl\nfrom pytorch_lightning.callbacks import ModelCheckpoint\nfrom pytorch_lightning.callbacks.early_stopping import EarlyStopping\nfrom torchmetrics.functional import accuracy, auroc\nfrom torchmetrics.functional import mean_absolute_error, mean_squared_error\n\nimport torch\nimport torch.nn.functional as F\nfrom torch import nn\nfrom torch.utils.data import Dataset, DataLoader, random_split\n\nfrom torchvision import transforms\nfrom torchvision.datasets import ImageFolder","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-08-26T09:47:08.057221Z","iopub.execute_input":"2021-08-26T09:47:08.057565Z","iopub.status.idle":"2021-08-26T09:47:08.064341Z","shell.execute_reply.started":"2021-08-26T09:47:08.057526Z","shell.execute_reply":"2021-08-26T09:47:08.063370Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"RANDOM_STATE = 42\nNUM_CLASSES = 98\nMAX_HOURS = 90\nBATCH_SIZE = 128","metadata":{"execution":{"iopub.status.busy":"2021-08-26T08:09:17.326887Z","iopub.execute_input":"2021-08-26T08:09:17.327224Z","iopub.status.idle":"2021-08-26T08:09:17.331194Z","shell.execute_reply.started":"2021-08-26T08:09:17.327191Z","shell.execute_reply":"2021-08-26T08:09:17.330356Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Seed Everything**","metadata":{}},{"cell_type":"code","source":"pl.seed_everything(RANDOM_STATE)","metadata":{"execution":{"iopub.status.busy":"2021-08-26T08:09:19.166893Z","iopub.execute_input":"2021-08-26T08:09:19.167240Z","iopub.status.idle":"2021-08-26T08:09:19.179285Z","shell.execute_reply.started":"2021-08-26T08:09:19.167211Z","shell.execute_reply":"2021-08-26T08:09:19.178266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## DataModule","metadata":{}},{"cell_type":"code","source":"class CountBoxes(Dataset):\n    def __init__(self, df, transform=None):\n        super().__init__()\n        self.df = df\n        self.transform = transform\n        self.num_workers = 2\n\n    def __len__(self):\n        return self.df.shape[0]\n\n    def __getitem__(self, index):\n        img_id, label = self.df.iloc[index][\"image_id\"], self.df.iloc[index][\"count\"]\n        img_path = f\"../input/count-the-blue-boxes/train/train/{label}/{label}_{img_id}.png\"\n        image = Image.open(img_path)\n        image = image.convert(\"RGB\")\n        if self.transform is not None:\n            image = self.transform(image)\n        return image, label","metadata":{"execution":{"iopub.status.busy":"2021-08-26T08:09:20.960829Z","iopub.execute_input":"2021-08-26T08:09:20.961160Z","iopub.status.idle":"2021-08-26T08:09:20.968028Z","shell.execute_reply.started":"2021-08-26T08:09:20.961130Z","shell.execute_reply":"2021-08-26T08:09:20.966903Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CountBoxesDataModule(pl.LightningDataModule):\n    def __init__(self, path, batch_size=64, num_workers=4):\n        super().__init__()\n        self.path = Path(path)\n        self.batch_size = batch_size\n        self.num_workers = num_workers\n        self.transform = transforms.Compose(\n            [\n                transforms.Resize(size=(250, 500)),\n                transforms.ToTensor()\n            ]\n        )\n\n    def prepare_data(self):\n        df = pd.read_csv(self.path / \"train.csv\")\n        df = df.loc[df[\"count\"] < MAX_HOURS]\n        # making sure it's a stratified split\n        X_train, X_valid, y_train, y_valid = train_test_split(df[\"image_id\"], df[\"count\"], \n                                                              stratify=df[\"count\"], test_size=0.2)\n        train_df = pd.concat([X_train, y_train], axis=1)\n        valid_df = pd.concat([X_valid, y_valid], axis=1)\n        train_df.to_pickle(\"train_df.pkl\")\n        valid_df.to_pickle(\"valid_df.pkl\")\n\n    def setup(self):\n        self.train_df = pd.read_pickle(\"train_df.pkl\")\n        self.valid_df = pd.read_pickle(\"valid_df.pkl\")\n        self.train_transform = self.transform\n        self.valid_transform = self.transform\n\n    def train_dataloader(self):\n        train_dataset = CountBoxes(df=self.train_df, transform=self.train_transform)\n        return DataLoader(train_dataset, batch_size=self.batch_size, \n                          num_workers=self.num_workers, shuffle=True, pin_memory=True)\n\n    def val_dataloader(self):\n        valid_dataset = CountBoxes(df=self.valid_df, transform=self.valid_transform)\n        return DataLoader(valid_dataset, batch_size=self.batch_size, num_workers=self.num_workers,\n                          shuffle=False, pin_memory=True)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-08-26T08:09:21.845730Z","iopub.execute_input":"2021-08-26T08:09:21.846047Z","iopub.status.idle":"2021-08-26T08:09:21.856563Z","shell.execute_reply.started":"2021-08-26T08:09:21.846020Z","shell.execute_reply":"2021-08-26T08:09:21.855482Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"datamodule = CountBoxesDataModule(path=\"../input/count-the-blue-boxes/\", batch_size=BATCH_SIZE)\ndatamodule.prepare_data()\ndatamodule.setup()","metadata":{"execution":{"iopub.status.busy":"2021-08-26T08:09:22.804905Z","iopub.execute_input":"2021-08-26T08:09:22.805239Z","iopub.status.idle":"2021-08-26T08:09:23.203336Z","shell.execute_reply.started":"2021-08-26T08:09:22.805209Z","shell.execute_reply":"2021-08-26T08:09:23.202329Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Training DataLoader Samples**","metadata":{}},{"cell_type":"code","source":"train_dataloader = datamodule.train_dataloader()","metadata":{"execution":{"iopub.status.busy":"2021-08-26T08:09:25.089145Z","iopub.execute_input":"2021-08-26T08:09:25.089579Z","iopub.status.idle":"2021-08-26T08:09:25.093966Z","shell.execute_reply.started":"2021-08-26T08:09:25.089537Z","shell.execute_reply":"2021-08-26T08:09:25.092823Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images, labels = iter(train_dataloader).next()\nf, ax = plt.subplots(5, 5, figsize=(30, 30))\nfor i in range(5*5):\n    ax[i // 5, i % 5].imshow(images[i].permute(1, 2, 0))\n    ax[i // 5, i % 5].axis(\"off\")\n    ax[i // 5, i % 5].set_title(labels[i], fontdict={\"fontsize\": 20})\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-08-26T08:09:27.068931Z","iopub.execute_input":"2021-08-26T08:09:27.069265Z","iopub.status.idle":"2021-08-26T08:09:41.043761Z","shell.execute_reply.started":"2021-08-26T08:09:27.069233Z","shell.execute_reply":"2021-08-26T08:09:41.042391Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Validation DataLoader Plots**","metadata":{}},{"cell_type":"code","source":"valid_dataloader = datamodule.val_dataloader()","metadata":{"execution":{"iopub.status.busy":"2021-08-26T08:09:41.045355Z","iopub.execute_input":"2021-08-26T08:09:41.045845Z","iopub.status.idle":"2021-08-26T08:09:41.050133Z","shell.execute_reply.started":"2021-08-26T08:09:41.045807Z","shell.execute_reply":"2021-08-26T08:09:41.049332Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for data in valid_dataloader:\n    images, labels = data\n    f, ax = plt.subplots(5, 5, figsize=(30, 30))\n    for i in range(5*5):\n        ax[i // 5, i % 5].imshow(images[i].permute(1, 2, 0))\n        ax[i // 5, i % 5].axis(\"off\")\n        ax[i // 5, i % 5].set_title(labels[i], fontdict={\"fontsize\": 20})\n    plt.tight_layout()\n    plt.show()\n    break","metadata":{"execution":{"iopub.status.busy":"2021-08-26T08:09:41.051685Z","iopub.execute_input":"2021-08-26T08:09:41.052236Z","iopub.status.idle":"2021-08-26T08:09:52.503427Z","shell.execute_reply.started":"2021-08-26T08:09:41.052196Z","shell.execute_reply":"2021-08-26T08:09:52.502560Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model","metadata":{}},{"cell_type":"code","source":"class CountModel(pl.LightningModule):\n    def __init__(self, input_shape, num_classes, learning_rate=2e-4):\n        super().__init__()\n        \n        # log hyperparameters\n        self.save_hyperparameters()\n        self.num_classes = num_classes\n        self.learning_rate = learning_rate\n        \n        self.conv1 = nn.Conv2d(3, 16, 5, 1)\n        self.conv2 = nn.Conv2d(16, 32, 5, 1)\n        self.conv3 = nn.Conv2d(32, 64, 5, 1)\n        self.conv4 = nn.Conv2d(64, 128, 5, 1)\n\n        self.pool1 = torch.nn.MaxPool2d(2)\n        self.pool2 = torch.nn.MaxPool2d(2)\n        self.pool3 = torch.nn.MaxPool2d(2)\n        \n        n_sizes = self._get_conv_output(input_shape)\n\n        self.fc1 = nn.Linear(n_sizes, 512)\n        self.fc2 = nn.Linear(512, 256)\n        self.fc3 = nn.Linear(256, self.num_classes)\n\n    # returns the size of the output tensor going into Linear layer from the conv block\n    def _get_conv_output(self, shape):\n        batch_size = 1\n        input = torch.autograd.Variable(torch.rand(batch_size, *shape))\n\n        output_feat = self._forward_features(input) \n        n_size = output_feat.data.view(batch_size, -1).size(1)\n        return n_size\n        \n    # returns the feature tensor from the conv block\n    def _forward_features(self, x):\n        x = F.relu(self.conv1(x))\n        x = F.relu(self.pool1(x))\n        x = F.relu(self.conv2(x))\n        x = F.relu(self.pool2(x))\n        x = F.relu(self.conv3(x))\n        x = F.relu(self.pool3(x))\n        x = F.relu(self.conv4(x))\n        return x\n\n    # will be used during inference\n    def forward(self, x):\n        x = self._forward_features(x)\n        x = x.view(x.size(0), -1)    # Flatten in TF\n        x = F.relu(self.fc1(x))\n        x = F.relu(self.fc2(x))\n        x = F.log_softmax(self.fc3(x), dim=1)\n        return x\n\n    # logic for a single training step\n    def training_step(self, batch, batch_idx):\n        x, y = batch\n        logits = self(x)\n        loss = F.nll_loss(logits, y)\n        \n        # training metrics\n        preds = torch.argmax(logits, dim=1)\n        acc = accuracy(preds, y)\n        mae = mean_absolute_error(preds, y)\n        mse = mean_squared_error(preds, y)\n        self.log(\"train_loss\", loss, on_step=True, on_epoch=True, logger=True)\n        self.log(\"train_acc\", acc, on_step=True, on_epoch=True, logger=True)\n        self.log(\"train_mae\", mae, on_step=True, on_epoch=True, logger=True)\n        self.log(\"train_mse\", mse, on_step=True, on_epoch=True, logger=True)\n        return loss\n\n    # logic for a single validation step\n    def validation_step(self, batch, batch_idx):\n        x, y = batch\n        logits = self(x)\n        loss = F.nll_loss(logits, y)\n        \n        # training metrics\n        preds = torch.argmax(logits, dim=1)\n        acc = accuracy(preds, y)\n        mae = mean_absolute_error(preds, y)\n        mse = mean_squared_error(preds, y)\n        self.log(\"val_loss\", loss, on_step=True, on_epoch=True)\n        self.log(\"val_acc\", acc, on_step=True, on_epoch=True)\n        self.log(\"val_mae\", mae, on_step=True, on_epoch=True)\n        self.log(\"val_mse\", mse, on_step=True, on_epoch=True)\n        return loss\n\n\n    def configure_optimizers(self):\n        optimizer = torch.optim.Adam(self.parameters(), lr=self.learning_rate)\n        return optimizer","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-08-26T08:11:09.842387Z","iopub.execute_input":"2021-08-26T08:11:09.842744Z","iopub.status.idle":"2021-08-26T08:11:09.864872Z","shell.execute_reply.started":"2021-08-26T08:11:09.842713Z","shell.execute_reply":"2021-08-26T08:11:09.863995Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Callbacks","metadata":{}},{"cell_type":"code","source":"checkpoint_callback = ModelCheckpoint(\n    monitor=\"val_loss\",\n    filename=\"model-{epoch:02d}-{val_loss:.2f}\",\n    save_top_k=1,\n    mode=\"min\",\n)\n\nearly_stop_callback = EarlyStopping(monitor=\"val_loss\", patience=3, verbose=False, mode=\"min\")","metadata":{"execution":{"iopub.status.busy":"2021-08-26T08:10:38.982024Z","iopub.execute_input":"2021-08-26T08:10:38.982379Z","iopub.status.idle":"2021-08-26T08:10:38.990984Z","shell.execute_reply.started":"2021-08-26T08:10:38.982348Z","shell.execute_reply":"2021-08-26T08:10:38.990043Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Training","metadata":{}},{"cell_type":"code","source":"model = CountModel((3, 250, 500), NUM_CLASSES)\ntrainer = pl.Trainer(\n    max_epochs=3,\n    progress_bar_refresh_rate=5,\n    gpus=1,\n    callbacks=[checkpoint_callback, early_stop_callback]\n)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-08-26T08:11:12.508767Z","iopub.execute_input":"2021-08-26T08:11:12.509207Z","iopub.status.idle":"2021-08-26T08:11:13.120330Z","shell.execute_reply.started":"2021-08-26T08:11:12.509167Z","shell.execute_reply":"2021-08-26T08:11:13.119446Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainer.fit(model, datamodule)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-08-26T08:11:14.632395Z","iopub.execute_input":"2021-08-26T08:11:14.632766Z","iopub.status.idle":"2021-08-26T09:30:38.938274Z","shell.execute_reply.started":"2021-08-26T08:11:14.632736Z","shell.execute_reply":"2021-08-26T09:30:38.937255Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Load the best model\nModel with lowest validation loss","metadata":{}},{"cell_type":"code","source":"print(f\"Best Model: {checkpoint_callback.best_model_path}\")\ninference_model = CountModel.load_from_checkpoint(checkpoint_callback.best_model_path)","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:30:38.940349Z","iopub.execute_input":"2021-08-26T09:30:38.940767Z","iopub.status.idle":"2021-08-26T09:30:39.851865Z","shell.execute_reply.started":"2021-08-26T09:30:38.940725Z","shell.execute_reply":"2021-08-26T09:30:39.850944Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"inference_model = inference_model.to(\"cuda\")\ninference_model.eval()\ninference_model.freeze()","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:30:39.853580Z","iopub.execute_input":"2021-08-26T09:30:39.853919Z","iopub.status.idle":"2021-08-26T09:30:39.907079Z","shell.execute_reply.started":"2021-08-26T09:30:39.853888Z","shell.execute_reply":"2021-08-26T09:30:39.906168Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Inference","metadata":{}},{"cell_type":"code","source":"def get_predictions(dataloader):\n    y_preds, y_actuals = [], []\n    for imgs, labels in tqdm(dataloader):\n        logits = inference_model(imgs.to(\"cuda\"))\n        preds = torch.argmax(logits, dim=1)\n        y_actuals.extend(labels.numpy().tolist())\n        y_preds.extend(preds.cpu().detach().numpy().tolist())\n    return y_preds, y_actuals","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:30:39.908643Z","iopub.execute_input":"2021-08-26T09:30:39.909019Z","iopub.status.idle":"2021-08-26T09:30:39.915329Z","shell.execute_reply.started":"2021-08-26T09:30:39.908980Z","shell.execute_reply":"2021-08-26T09:30:39.914345Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_roc_auc_score(y_true, y_pred):\n    classes = np.unique(np.array(y_true))\n    y_true = label_binarize(y_true, classes=classes)\n    y_pred = label_binarize(y_pred, classes=classes)\n    print(y_true.shape ,y_pred.shape)\n    return metrics.roc_auc_score(y_true, y_pred, average=\"macro\", multi_class=\"ovr\")","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:50:44.165958Z","iopub.execute_input":"2021-08-26T09:50:44.166300Z","iopub.status.idle":"2021-08-26T09:50:44.172306Z","shell.execute_reply.started":"2021-08-26T09:50:44.166266Z","shell.execute_reply":"2021-08-26T09:50:44.170505Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def print_metrics(stage, y_true, y_pred):\n    auc = get_roc_auc_score(y_true, y_pred)\n    acc = metrics.accuracy_score(y_true, y_pred)\n    mae = metrics.mean_absolute_error(y_true, y_pred)\n    mse = metrics.mean_squared_error(y_true, y_pred)\n    print(f\"{stage} ROC-AUC Score: {auc:.2f}\")\n    print(f\"{stage} Accuracy: {acc:.2f}\")\n    print(f\"{stage} Mean Absolute Error: {mae:.2f}\")\n    print(f\"{stage} Mean Squared Error: {mse:.2f}\")","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:50:46.529025Z","iopub.execute_input":"2021-08-26T09:50:46.529351Z","iopub.status.idle":"2021-08-26T09:50:46.534390Z","shell.execute_reply.started":"2021-08-26T09:50:46.529320Z","shell.execute_reply":"2021-08-26T09:50:46.533593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_dataloader = datamodule.val_dataloader()\ntrain_dataloader = datamodule.train_dataloader()","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:41:59.253983Z","iopub.execute_input":"2021-08-26T09:41:59.254322Z","iopub.status.idle":"2021-08-26T09:41:59.258621Z","shell.execute_reply.started":"2021-08-26T09:41:59.254291Z","shell.execute_reply":"2021-08-26T09:41:59.257452Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_pred, valid_act = get_predictions(valid_dataloader)","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-08-26T09:42:00.413720Z","iopub.execute_input":"2021-08-26T09:42:00.414048Z","iopub.status.idle":"2021-08-26T09:46:52.842875Z","shell.execute_reply.started":"2021-08-26T09:42:00.414019Z","shell.execute_reply":"2021-08-26T09:46:52.841836Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print_metrics(\"Validation\", valid_pred, valid_act)","metadata":{"execution":{"iopub.status.busy":"2021-08-26T09:50:59.211155Z","iopub.execute_input":"2021-08-26T09:50:59.211594Z","iopub.status.idle":"2021-08-26T09:50:59.727165Z","shell.execute_reply.started":"2021-08-26T09:50:59.211554Z","shell.execute_reply":"2021-08-26T09:50:59.726106Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code occasionally throws multiprocessing-related errors which here is atleast non-fatal","metadata":{}},{"cell_type":"code","source":"train_pred, train_act = get_predictions(train_dataloader)","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-08-26T09:51:09.276180Z","iopub.execute_input":"2021-08-26T09:51:09.276526Z","iopub.status.idle":"2021-08-26T10:10:50.211945Z","shell.execute_reply.started":"2021-08-26T09:51:09.276494Z","shell.execute_reply":"2021-08-26T10:10:50.210565Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print_metrics(\"Training\", train_pred, train_act)","metadata":{"execution":{"iopub.status.busy":"2021-08-26T10:10:50.213730Z","iopub.execute_input":"2021-08-26T10:10:50.214094Z","iopub.status.idle":"2021-08-26T10:10:52.908825Z","shell.execute_reply.started":"2021-08-26T10:10:50.214044Z","shell.execute_reply":"2021-08-26T10:10:52.907864Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Submission","metadata":{}},{"cell_type":"code","source":"class TestDataset(torch.utils.data.Dataset):\n    def __init__(self, image_paths):\n        self.image_paths = image_paths\n        self.transform = transforms.Compose([\n              transforms.Resize(size=(250, 500)),\n              transforms.ToTensor()\n        ])\n\n    def __len__(self):\n        return len(self.image_paths)\n\n    def __getitem__(self, idx):\n        img_loc = self.image_paths[idx]\n        image = Image.open(img_loc)\n        image = image.convert(\"RGB\")\n        image = self.transform(image)\n        return image","metadata":{"execution":{"iopub.status.busy":"2021-08-26T10:10:52.910817Z","iopub.execute_input":"2021-08-26T10:10:52.911167Z","iopub.status.idle":"2021-08-26T10:10:52.917990Z","shell.execute_reply.started":"2021-08-26T10:10:52.911130Z","shell.execute_reply":"2021-08-26T10:10:52.917030Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.read_csv(\"../input/count-the-blue-boxes/sample_submission.csv\")\nsubmission[\"image_path\"] = submission[\"image_id\"].apply(lambda x: f\"../input/count-the-blue-boxes/test/test/{x}.png\")","metadata":{"execution":{"iopub.status.busy":"2021-08-26T10:10:52.919644Z","iopub.execute_input":"2021-08-26T10:10:52.920276Z","iopub.status.idle":"2021-08-26T10:10:53.211620Z","shell.execute_reply.started":"2021-08-26T10:10:52.920238Z","shell.execute_reply":"2021-08-26T10:10:53.210762Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dataset = TestDataset(submission[\"image_path\"].tolist())\ntest_dataloader = torch.utils.data.DataLoader(test_dataset, batch_size=BATCH_SIZE, num_workers=2)\nprint(f\"Test Dataset: {len(test_dataset)}\\tTest DataLoader: {len(test_dataloader)}\")","metadata":{"execution":{"iopub.status.busy":"2021-08-26T10:10:53.212860Z","iopub.execute_input":"2021-08-26T10:10:53.213208Z","iopub.status.idle":"2021-08-26T10:10:53.221145Z","shell.execute_reply.started":"2021-08-26T10:10:53.213174Z","shell.execute_reply":"2021-08-26T10:10:53.220133Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_preds = []\nfor imgs in tqdm(test_dataloader):\n    logits = inference_model(imgs.to(\"cuda\"))\n    preds = torch.argmax(logits, dim=1)\n    y_preds.extend(preds.cpu().detach().numpy().tolist())","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-08-26T10:10:53.222894Z","iopub.execute_input":"2021-08-26T10:10:53.223331Z","iopub.status.idle":"2021-08-26T10:30:43.969411Z","shell.execute_reply.started":"2021-08-26T10:10:53.223296Z","shell.execute_reply":"2021-08-26T10:30:43.967862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission[\"count\"] = y_preds\nsubmission = submission[[\"image_id\", \"count\"]]\nprint(submission.shape)\nsubmission.head()","metadata":{"execution":{"iopub.status.busy":"2021-08-26T10:30:43.971226Z","iopub.execute_input":"2021-08-26T10:30:43.971627Z","iopub.status.idle":"2021-08-26T10:30:44.066568Z","shell.execute_reply.started":"2021-08-26T10:30:43.971581Z","shell.execute_reply":"2021-08-26T10:30:44.065550Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission[\"count\"].describe()","metadata":{"execution":{"iopub.status.busy":"2021-08-26T10:30:44.069614Z","iopub.execute_input":"2021-08-26T10:30:44.070000Z","iopub.status.idle":"2021-08-26T10:30:44.087495Z","shell.execute_reply.started":"2021-08-26T10:30:44.069958Z","shell.execute_reply":"2021-08-26T10:30:44.086447Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2021-08-26T10:30:44.089280Z","iopub.execute_input":"2021-08-26T10:30:44.089673Z","iopub.status.idle":"2021-08-26T10:30:44.411693Z","shell.execute_reply.started":"2021-08-26T10:30:44.089635Z","shell.execute_reply":"2021-08-26T10:30:44.410799Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Random Test Plots","metadata":{}},{"cell_type":"code","source":"import cv2","metadata":{"execution":{"iopub.status.busy":"2021-08-26T10:34:58.653183Z","iopub.execute_input":"2021-08-26T10:34:58.653529Z","iopub.status.idle":"2021-08-26T10:34:58.808611Z","shell.execute_reply.started":"2021-08-26T10:34:58.653491Z","shell.execute_reply":"2021-08-26T10:34:58.807769Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_random(paths, labels, h=4, w=4, title=\"\"):\n    f, ax = plt.subplots(h, w, figsize=(30, 30))\n    for i in range(h*w):\n        img = cv2.imread(paths[i])\n        ax[i // h, i % w].imshow(img)\n        ax[i // h, i % w].axis(\"off\")\n        ax[i // h, i % w].set_title(labels[i], fontdict={\"fontsize\": 20})\n    plt.tight_layout()\n    f.suptitle(title, fontsize=\"large\", fontweight=\"extra bold\")\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2021-08-26T10:35:10.378978Z","iopub.execute_input":"2021-08-26T10:35:10.379320Z","iopub.status.idle":"2021-08-26T10:35:10.387925Z","shell.execute_reply.started":"2021-08-26T10:35:10.379289Z","shell.execute_reply":"2021-08-26T10:35:10.387021Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission[\"image_path\"] = submission[\"image_id\"].apply(lambda x: f\"../input/count-the-blue-boxes/test/test/{x}.png\")","metadata":{"execution":{"iopub.status.busy":"2021-08-26T10:35:11.252041Z","iopub.execute_input":"2021-08-26T10:35:11.252364Z","iopub.status.idle":"2021-08-26T10:35:11.315811Z","shell.execute_reply.started":"2021-08-26T10:35:11.252335Z","shell.execute_reply":"2021-08-26T10:35:11.310884Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample = submission.sample(30)\nplot_random(sample[\"image_path\"].tolist(), sample[\"count\"].tolist())","metadata":{"execution":{"iopub.status.busy":"2021-08-26T10:35:12.519596Z","iopub.execute_input":"2021-08-26T10:35:12.519916Z","iopub.status.idle":"2021-08-26T10:35:14.551882Z","shell.execute_reply.started":"2021-08-26T10:35:12.519889Z","shell.execute_reply":"2021-08-26T10:35:14.551051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample = submission.sample(30)\nplot_random(sample[\"image_path\"].tolist(), sample[\"count\"].tolist())","metadata":{"execution":{"iopub.status.busy":"2021-08-26T10:35:14.553412Z","iopub.execute_input":"2021-08-26T10:35:14.553798Z","iopub.status.idle":"2021-08-26T10:35:16.280566Z","shell.execute_reply.started":"2021-08-26T10:35:14.553761Z","shell.execute_reply":"2021-08-26T10:35:16.279725Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample = submission.sample(30)\nplot_random(sample[\"image_path\"].tolist(), sample[\"count\"].tolist())","metadata":{"execution":{"iopub.status.busy":"2021-08-26T10:35:16.282290Z","iopub.execute_input":"2021-08-26T10:35:16.282675Z","iopub.status.idle":"2021-08-26T10:35:18.413267Z","shell.execute_reply.started":"2021-08-26T10:35:16.282636Z","shell.execute_reply":"2021-08-26T10:35:18.412490Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample = submission.sample(30)\nplot_random(sample[\"image_path\"].tolist(), sample[\"count\"].tolist())","metadata":{"execution":{"iopub.status.busy":"2021-08-26T10:35:18.414703Z","iopub.execute_input":"2021-08-26T10:35:18.415063Z","iopub.status.idle":"2021-08-26T10:35:20.447870Z","shell.execute_reply.started":"2021-08-26T10:35:18.415024Z","shell.execute_reply":"2021-08-26T10:35:20.447049Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample = submission.sample(30)\nplot_random(sample[\"image_path\"].tolist(), sample[\"count\"].tolist())","metadata":{"execution":{"iopub.status.busy":"2021-08-26T10:35:20.449071Z","iopub.execute_input":"2021-08-26T10:35:20.449396Z","iopub.status.idle":"2021-08-26T10:35:22.159901Z","shell.execute_reply.started":"2021-08-26T10:35:20.449369Z","shell.execute_reply":"2021-08-26T10:35:22.159068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}