{"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":"## secondary model which is trained on masks of first model","metadata":{}},{"cell_type":"markdown","source":"For this Notebook it is necessary to add the output data from fynn's Notebook.These are mask outputs of every timestep.\n\nYou can access the data of fynns Notebook here: https://www.kaggle.com/fynnjunge/contrails-apply-model-on-all-timesteps\n\nThe filepath should look like this.\n/kaggle/input/contrails-apply-model-on-all-timesteps\n\nIn addition it is necessary to add the data from the competetion to gain access to the correct/official labels/masks.","metadata":{}},{"cell_type":"code","source":"import sys\nsys.path.append(\"/kaggle/input/smp-github/segmentation_models.pytorch-master\")\nsys.path.append(\"/kaggle/input/pretrained-models-pytorch\")\nsys.path.append(\"/kaggle/input/efficientnet-pytorch\")","metadata":{"execution":{"iopub.status.busy":"2023-07-30T09:27:00.105438Z","iopub.execute_input":"2023-07-30T09:27:00.105802Z","iopub.status.idle":"2023-07-30T09:27:00.110988Z","shell.execute_reply.started":"2023-07-30T09:27:00.105769Z","shell.execute_reply":"2023-07-30T09:27:00.110004Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport pytorch_lightning as pl\nimport segmentation_models_pytorch as smp\nfrom torch.optim.lr_scheduler import CosineAnnealingLR, ReduceLROnPlateau\nfrom torch.optim import AdamW\nimport torch.nn as nn\nfrom torchmetrics.functional import dice\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2023-07-30T09:25:34.970465Z","iopub.execute_input":"2023-07-30T09:25:34.971271Z","iopub.status.idle":"2023-07-30T09:25:52.190254Z","shell.execute_reply.started":"2023-07-30T09:25:34.971228Z","shell.execute_reply":"2023-07-30T09:25:52.189301Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport numpy as np\nimport torch\nimport torchvision.transforms as T\n\nfrom torch.utils.data import Dataset, DataLoader\n\nTRAIN_PATH = \"/kaggle/input/contrails-apply-model-on-all-timesteps/train/\"\nVALIDATION_PATH = \"/kaggle/input/contrails-apply-model-on-all-timesteps/validation/\"\nPATH = \"/kaggle/input/google-research-identify-contrails-reduce-global-warming/\" #For Labels\n\nclass MasksDataset(Dataset):\n    def __init__(self, split=\"train\", mode=\"single\"):\n        self.split = split\n        self.mode = mode\n        self.path = TRAIN_PATH if split == \"train\" else VALIDATION_PATH\n        self.maskpath = f'{PATH}{split}/'\n        self.examples = os.listdir(self.path)\n        self.normalize_image = T.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225))\n    \n    def read_record(self, filename):\n        record_data = np.load(filename)[\"arr_0\"]\n        return record_data\n\n    \n    def __getitem__(self, index):\n        filename = os.path.join(self.path, self.examples[index])\n        data = self.read_record(filename)\n        \n        img = data\n        \n        if self.mode == \"single\":\n            img = torch.tensor(np.expand_dims(img, axis=0)).to(torch.float32)\n        else:\n            img = torch.tensor(img).to(torch.float32)\n        \n        #img = self.normalize_image(img)\n        \n        if self.split in [\"train\", \"validation\"]:\n            label = np.load(os.path.join(self.maskpath, f\"{self.examples[index][:-4]}/human_pixel_masks.npy\")).squeeze()\n            label = torch.Tensor(label).to(torch.int64)\n            return img.float(), label\n        \n        return img.float()\n    \n    def __len__(self):\n        return len(self.examples)","metadata":{"execution":{"iopub.status.busy":"2023-07-26T15:00:02.816239Z","iopub.execute_input":"2023-07-26T15:00:02.816788Z","iopub.status.idle":"2023-07-26T15:00:05.802985Z","shell.execute_reply.started":"2023-07-26T15:00:02.816755Z","shell.execute_reply":"2023-07-26T15:00:05.802066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# config\nconfig = {\n    \"data_path\": \"/kaggle/input/contrails-images-ash-color\", # only used for the labels\n    \"model\": {\n        \"encoder_name\": \"None\", # not used!\n        \"loss_smooth\": 1.0,\n        \"optimizer_params\": {\"lr\": 0.003, \"weight_decay\": 0.01},\n        \"scheduler\": {\n            \"name\": \"CosineAnnealingLR\",\n            \"params\": {\n                \"CosineAnnealingLR\": {\"T_max\": 500, \"eta_min\": 1e-06, \"last_epoch\": -1},\n                \"ReduceLROnPlateau\": {\n                    \"factor\": 0.31622776601,\n                    \"mode\": \"min\",\n                    \"patience\": 4,\n                    \"verbose\": True,\n                },\n            },\n        },\n        \"seg_model\": \"Linknet\",\n    },\n    \"output_dir\": \"models\",\n    \"progress_bar_refresh_rate\": 50,\n    \"seed\": 42,\n    \"train_bs\": 32,\n    \"trainer\": {\n        \"enable_progress_bar\": True,\n        \"max_epochs\": 30,\n        \"min_epochs\": 30,\n    },\n    \"valid_bs\": 64,\n    \"workers\": 2,\n}","metadata":{"execution":{"iopub.status.busy":"2023-07-26T15:00:16.061802Z","iopub.execute_input":"2023-07-26T15:00:16.062422Z","iopub.status.idle":"2023-07-26T15:00:16.070777Z","shell.execute_reply.started":"2023-07-26T15:00:16.062389Z","shell.execute_reply":"2023-07-26T15:00:16.069057Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mask_train_dataset = MasksDataset(split=\"train\", mode=\"multi\")\nmask_validation_dataset = MasksDataset(split=\"validation\", mode=\"multi\")","metadata":{"execution":{"iopub.status.busy":"2023-07-26T15:00:22.144737Z","iopub.execute_input":"2023-07-26T15:00:22.146722Z","iopub.status.idle":"2023-07-26T15:00:22.534133Z","shell.execute_reply.started":"2023-07-26T15:00:22.146681Z","shell.execute_reply":"2023-07-26T15:00:22.533104Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_loader_train = DataLoader(\n    mask_train_dataset, batch_size=config[\"train_bs\"], shuffle=True, num_workers=config[\"workers\"]\n)\ndata_loader_validation = DataLoader(\n    mask_validation_dataset, batch_size=config[\"valid_bs\"], shuffle=False, num_workers=config[\"workers\"]\n)\n\npl.seed_everything(config[\"seed\"])","metadata":{"execution":{"iopub.status.busy":"2023-07-26T15:01:00.081327Z","iopub.execute_input":"2023-07-26T15:01:00.082159Z","iopub.status.idle":"2023-07-26T15:01:00.102844Z","shell.execute_reply.started":"2023-07-26T15:01:00.082123Z","shell.execute_reply":"2023-07-26T15:01:00.101905Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mask_train_dataset[0][0].shape","metadata":{"execution":{"iopub.status.busy":"2023-07-26T15:01:18.94384Z","iopub.execute_input":"2023-07-26T15:01:18.944208Z","iopub.status.idle":"2023-07-26T15:01:19.000006Z","shell.execute_reply.started":"2023-07-26T15:01:18.944179Z","shell.execute_reply":"2023-07-26T15:01:18.999043Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mask_train_dataset[0][1].shape","metadata":{"execution":{"iopub.status.busy":"2023-07-26T15:01:21.820009Z","iopub.execute_input":"2023-07-26T15:01:21.820659Z","iopub.status.idle":"2023-07-26T15:01:21.841349Z","shell.execute_reply.started":"2023-07-26T15:01:21.820623Z","shell.execute_reply":"2023-07-26T15:01:21.839979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from pprint import pprint\nfrom pytorch_lightning.callbacks import ModelCheckpoint, EarlyStopping, TQDMProgressBar","metadata":{"execution":{"iopub.status.busy":"2023-07-26T15:01:24.954615Z","iopub.execute_input":"2023-07-26T15:01:24.954979Z","iopub.status.idle":"2023-07-26T15:01:24.961322Z","shell.execute_reply.started":"2023-07-26T15:01:24.95495Z","shell.execute_reply":"2023-07-26T15:01:24.960115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Lightning module\n\nseg_models = {\n    \"Unet\": smp.Unet,\n    \"Unet++\": smp.UnetPlusPlus,\n    \"MAnet\": smp.MAnet,\n    \"Linknet\": smp.Linknet,\n    \"FPN\": smp.FPN,\n    \"PSPNet\": smp.PSPNet,\n    \"PAN\": smp.PAN,\n    \"DeepLabV3\": smp.DeepLabV3,\n    \"DeepLabV3+\": smp.DeepLabV3Plus,\n}\n\n\nclass LightningModule(pl.LightningModule):\n    def __init__(self, config):\n        super().__init__()\n        self.config = config\n        self.model = model = seg_models[config[\"seg_model\"]](\n            #encoder_name=config[\"encoder_name\"], # no encoder name\n            encoder_weights=None,  # random wncoder weights\n            in_channels=8,\n            classes=1,\n            activation=None,\n        )\n        self.loss_module = smp.losses.DiceLoss(mode=\"binary\", smooth=config[\"loss_smooth\"])\n        self.val_step_outputs = []\n        self.val_step_labels = []\n\n    def forward(self, batch):\n        imgs = batch\n        preds = self.model(imgs)\n        return preds\n\n    def configure_optimizers(self):\n        optimizer = AdamW(self.parameters(), **self.config[\"optimizer_params\"])\n\n        if self.config[\"scheduler\"][\"name\"] == \"CosineAnnealingLR\":\n            scheduler = CosineAnnealingLR(\n                optimizer,\n                **self.config[\"scheduler\"][\"params\"][self.config[\"scheduler\"][\"name\"]],\n            )\n            lr_scheduler_dict = {\"scheduler\": scheduler, \"interval\": \"step\"}\n            return {\"optimizer\": optimizer, \"lr_scheduler\": lr_scheduler_dict}\n        elif self.config[\"scheduler\"][\"name\"] == \"ReduceLROnPlateau\":\n            scheduler = ReduceLROnPlateau(\n                optimizer,\n                **self.config[\"scheduler\"][\"params\"][self.config[\"scheduler\"][\"name\"]],\n            )\n            lr_scheduler = {\"scheduler\": scheduler, \"monitor\": \"val_loss\"}\n            return {\"optimizer\": optimizer, \"lr_scheduler\": lr_scheduler}\n\n    def training_step(self, batch, batch_idx):\n        imgs, labels = batch\n        preds = self.model(imgs)\n        loss = self.loss_module(preds, labels)\n        self.log(\"train_loss\", loss, on_step=True, on_epoch=True, prog_bar=True, batch_size=16)\n\n        for param_group in self.trainer.optimizers[0].param_groups:\n            lr = param_group[\"lr\"]\n        self.log(\"lr\", lr, on_step=True, on_epoch=False, prog_bar=True)\n\n        return loss\n\n    def validation_step(self, batch, batch_idx):\n        imgs, labels = batch\n        preds = self.model(imgs)\n        loss = self.loss_module(preds, labels)\n        self.log(\"val_loss\", loss, on_step=False, on_epoch=True, prog_bar=True)\n        self.val_step_outputs.append(preds)\n        self.val_step_labels.append(labels)\n\n    def on_validation_epoch_end(self):\n        all_preds = torch.cat(self.val_step_outputs)\n        all_labels = torch.cat(self.val_step_labels)\n        self.val_step_outputs.clear()\n        self.val_step_labels.clear()\n        val_dice = dice(all_preds, all_labels.long())\n        self.log(\"val_dice\", val_dice, on_step=False, on_epoch=True, prog_bar=True)","metadata":{"execution":{"iopub.status.busy":"2023-07-26T15:01:26.7674Z","iopub.execute_input":"2023-07-26T15:01:26.76776Z","iopub.status.idle":"2023-07-26T15:01:27.114577Z","shell.execute_reply.started":"2023-07-26T15:01:26.767729Z","shell.execute_reply":"2023-07-26T15:01:27.113392Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"logger = pl.loggers.CSVLogger(\"csv_log\")","metadata":{"execution":{"iopub.status.busy":"2023-07-26T15:01:29.875942Z","iopub.execute_input":"2023-07-26T15:01:29.876631Z","iopub.status.idle":"2023-07-26T15:01:29.881435Z","shell.execute_reply.started":"2023-07-26T15:01:29.876596Z","shell.execute_reply":"2023-07-26T15:01:29.880306Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"filename = f\"model\"\n\ncheckpoint_callback = ModelCheckpoint(\n    monitor=\"val_dice\",\n    dirpath=config[\"output_dir\"],\n    mode=\"max\",\n    filename=filename,\n    save_top_k=1,\n    verbose=1,\n)","metadata":{"execution":{"iopub.status.busy":"2023-07-26T15:01:31.649548Z","iopub.execute_input":"2023-07-26T15:01:31.64992Z","iopub.status.idle":"2023-07-26T15:01:31.659608Z","shell.execute_reply.started":"2023-07-26T15:01:31.649889Z","shell.execute_reply":"2023-07-26T15:01:31.658541Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training","metadata":{}},{"cell_type":"code","source":"progress_bar_callback = TQDMProgressBar(refresh_rate=config[\"progress_bar_refresh_rate\"])\n\nearly_stop_callback = EarlyStopping(monitor=\"val_loss\", mode=\"min\", patience=5, verbose=1)\n\ntrainer = pl.Trainer(\n    callbacks=[checkpoint_callback, early_stop_callback, progress_bar_callback], logger=logger, **config[\"trainer\"]\n)","metadata":{"execution":{"iopub.status.busy":"2023-07-26T15:01:33.770563Z","iopub.execute_input":"2023-07-26T15:01:33.77092Z","iopub.status.idle":"2023-07-26T15:01:34.344926Z","shell.execute_reply.started":"2023-07-26T15:01:33.770892Z","shell.execute_reply":"2023-07-26T15:01:34.343947Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = LightningModule(config[\"model\"])","metadata":{"execution":{"iopub.status.busy":"2023-07-26T15:01:36.194676Z","iopub.execute_input":"2023-07-26T15:01:36.195083Z","iopub.status.idle":"2023-07-26T15:01:36.54761Z","shell.execute_reply.started":"2023-07-26T15:01:36.195027Z","shell.execute_reply":"2023-07-26T15:01:36.546584Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainer.fit(model, data_loader_train, data_loader_validation)","metadata":{"execution":{"iopub.status.busy":"2023-07-26T15:01:38.864792Z","iopub.execute_input":"2023-07-26T15:01:38.865186Z","iopub.status.idle":"2023-07-26T15:30:36.327609Z","shell.execute_reply.started":"2023-07-26T15:01:38.865153Z","shell.execute_reply":"2023-07-26T15:30:36.319128Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Predictions","metadata":{}},{"cell_type":"code","source":"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nmodel.to(device)\nmodel.eval()\nmodel.zero_grad()","metadata":{"execution":{"iopub.status.busy":"2023-07-26T12:59:04.817032Z","iopub.execute_input":"2023-07-26T12:59:04.817503Z","iopub.status.idle":"2023-07-26T12:59:04.837003Z","shell.execute_reply.started":"2023-07-26T12:59:04.817467Z","shell.execute_reply":"2023-07-26T12:59:04.836014Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"examples_to_check = [100, 80, 64, 42, 3]\n\nnrows, ncols = (5,2)\n\nfig, axs = plt.subplots(nrows, ncols, figsize = (16,16))\n\nfor i, img in enumerate(examples_to_check):\n    label = mask_train_dataset[img][1]\n    preds = model(torch.unsqueeze(mask_train_dataset[img][0].to(device), 0))\n    \n    \n    axs[i, 0].imshow(label,cmap='gray')\n    axs[i, 1].imshow(preds.to(\"cpu\").detach().squeeze(),cmap='gray')\n        \nplt.show()\n\ndel preds","metadata":{"execution":{"iopub.status.busy":"2023-07-26T14:23:19.001625Z","iopub.execute_input":"2023-07-26T14:23:19.00224Z","iopub.status.idle":"2023-07-26T14:23:21.283916Z","shell.execute_reply.started":"2023-07-26T14:23:19.002195Z","shell.execute_reply":"2023-07-26T14:23:21.282782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# more examples\nexamples_to_check = [100, 81, 65, 43, 4]\n\nnrows, ncols = (5,2)\n\nfig, axs = plt.subplots(nrows, ncols, figsize = (16,16))\n\nfor i, img in enumerate(examples_to_check):\n    label = mask_train_dataset[img][1]\n    preds = model(torch.unsqueeze(mask_train_dataset[img][0].to(device), 0))    \n    \n    axs[i, 0].imshow(label)\n    axs[i, 1].imshow(preds.to(\"cpu\").detach().squeeze())\n        \nplt.show()\n\ndel preds","metadata":{"execution":{"iopub.status.busy":"2023-07-26T13:21:36.895653Z","iopub.execute_input":"2023-07-26T13:21:36.896123Z","iopub.status.idle":"2023-07-26T13:21:37.727833Z","shell.execute_reply.started":"2023-07-26T13:21:36.896077Z","shell.execute_reply":"2023-07-26T13:21:37.726622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Further explorations of output","metadata":{}},{"cell_type":"code","source":"mask_train_dataset[100][1].sum()","metadata":{"execution":{"iopub.status.busy":"2023-07-26T13:43:19.593151Z","iopub.execute_input":"2023-07-26T13:43:19.593571Z","iopub.status.idle":"2023-07-26T13:43:19.61641Z","shell.execute_reply.started":"2023-07-26T13:43:19.593536Z","shell.execute_reply":"2023-07-26T13:43:19.61547Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mask_train_dataset[100][1]","metadata":{"execution":{"iopub.status.busy":"2023-07-26T13:43:39.62263Z","iopub.execute_input":"2023-07-26T13:43:39.623036Z","iopub.status.idle":"2023-07-26T13:43:39.644375Z","shell.execute_reply.started":"2023-07-26T13:43:39.622997Z","shell.execute_reply":"2023-07-26T13:43:39.643437Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.unique(mask_train_dataset[100][1])","metadata":{"execution":{"iopub.status.busy":"2023-07-26T14:20:46.082978Z","iopub.execute_input":"2023-07-26T14:20:46.083435Z","iopub.status.idle":"2023-07-26T14:20:46.10638Z","shell.execute_reply.started":"2023-07-26T14:20:46.083384Z","shell.execute_reply":"2023-07-26T14:20:46.105286Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.unique(mask_train_dataset[100][0])","metadata":{"execution":{"iopub.status.busy":"2023-07-26T13:47:49.078888Z","iopub.execute_input":"2023-07-26T13:47:49.079319Z","iopub.status.idle":"2023-07-26T13:47:49.121824Z","shell.execute_reply.started":"2023-07-26T13:47:49.079287Z","shell.execute_reply":"2023-07-26T13:47:49.120727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"my_tensor80 = mask_train_dataset[80][0]\nmy_tensor100 = mask_train_dataset[100][0]","metadata":{"execution":{"iopub.status.busy":"2023-07-26T14:16:53.761811Z","iopub.execute_input":"2023-07-26T14:16:53.762274Z","iopub.status.idle":"2023-07-26T14:16:53.807762Z","shell.execute_reply.started":"2023-07-26T14:16:53.762235Z","shell.execute_reply":"2023-07-26T14:16:53.806746Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Convert the tensor to a NumPy array\nmy_np_array = my_tensor80.numpy()\n\n# Compute the histogram using numpy.histogram()\n# You can specify the number of bins using the `bins` parameter.\nhist_values, hist_bins = np.histogram(my_np_array, bins=np.arange(my_np_array.min(), my_np_array.max() + 2))\n\n# Plot the histogram\nplt.bar(hist_bins[:-1], hist_values, align='center', width=0.8)\nplt.xlabel('Value')\nplt.ylabel('Frequency')\nplt.title('Histogram of Values within the Tensor')\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2023-07-26T14:17:03.595533Z","iopub.execute_input":"2023-07-26T14:17:03.595929Z","iopub.status.idle":"2023-07-26T14:17:04.023208Z","shell.execute_reply.started":"2023-07-26T14:17:03.595899Z","shell.execute_reply":"2023-07-26T14:17:04.022146Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# Convert the tensor to a NumPy array\nmy_np_array = my_tensor100.numpy()\n\n# Compute the histogram using numpy.histogram()\n# You can specify the number of bins using the `bins` parameter.\nhist_values, hist_bins = np.histogram(my_np_array, bins=np.arange(my_np_array.min(), my_np_array.max() + 2))\n\n# Plot the histogram\nplt.bar(hist_bins[:-1], hist_values, align='center', width=0.8)\nplt.xlabel('Value')\nplt.ylabel('Frequency')\nplt.title('Histogram of Values within the Tensor')\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2023-07-26T14:17:13.772039Z","iopub.execute_input":"2023-07-26T14:17:13.772553Z","iopub.status.idle":"2023-07-26T14:17:14.641318Z","shell.execute_reply.started":"2023-07-26T14:17:13.772504Z","shell.execute_reply":"2023-07-26T14:17:14.64032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# Convert the tensor to a NumPy array\nmy_np_array = mask_train_dataset[64][0].numpy()\n\n# Compute the histogram using numpy.histogram()\n# You can specify the number of bins using the `bins` parameter.\nhist_values, hist_bins = np.histogram(my_np_array, bins=np.arange(my_np_array.min(), my_np_array.max() + 2))\n\n# Plot the histogram\nplt.bar(hist_bins[:-1], hist_values, align='center', width=0.8)\nplt.xlabel('Value')\nplt.ylabel('Frequency')\nplt.title('Histogram of Values within the Tensor')\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2023-07-26T14:19:02.160978Z","iopub.execute_input":"2023-07-26T14:19:02.161451Z","iopub.status.idle":"2023-07-26T14:19:02.594585Z","shell.execute_reply.started":"2023-07-26T14:19:02.161394Z","shell.execute_reply":"2023-07-26T14:19:02.593372Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## How do we convert the data into binary data?","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}