{"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":"none","dataSources":[{"sourceId":14774,"databundleVersionId":875431,"sourceType":"competition"}],"dockerImageVersionId":30635,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-03-12T11:34:43.112319Z","iopub.execute_input":"2024-03-12T11:34:43.112833Z","iopub.status.idle":"2024-03-12T11:34:43.978160Z","shell.execute_reply.started":"2024-03-12T11:34:43.112794Z","shell.execute_reply":"2024-03-12T11:34:43.977383Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Importing essential headers","metadata":{}},{"cell_type":"code","source":"# Imports here\nfrom __future__ import print_function, division\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom torch.utils import data\nimport torch\nfrom torch import nn\nfrom torch import optim\nimport torchvision\nimport torch.nn.functional as F\nfrom torchvision import datasets, transforms, models\nimport torchvision.models as models\nfrom torch.utils.data.sampler import SubsetRandomSampler\nfrom torch.utils.data import Dataset, DataLoader\nfrom skimage import io, transform\nimport torch.utils.data as data_utils\nfrom PIL import Image, ImageFile\nimport json\nfrom torch.optim import lr_scheduler\nimport time\nimport os\nimport argparse\nimport copy\nimport pandas as pd\nImageFile.LOAD_TRUNCATED_IMAGES = True\nimport cv2\n# Import useful sklearn functions\nimport sklearn\nfrom sklearn.metrics import cohen_kappa_score, accuracy_score\n\nimport time\nfrom tqdm import tqdm_notebook\n\nimport os\nprint(os.listdir(\"../input\"))\nbase_dir = \"../input/aptos2019-blindness-detection/\"","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:34:43.979877Z","iopub.execute_input":"2024-03-12T11:34:43.980490Z","iopub.status.idle":"2024-03-12T11:34:43.990479Z","shell.execute_reply.started":"2024-03-12T11:34:43.980449Z","shell.execute_reply":"2024-03-12T11:34:43.989314Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(os.listdir(\"../input/aptos2019-blindness-detection\"))","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:34:43.991747Z","iopub.execute_input":"2024-03-12T11:34:43.992325Z","iopub.status.idle":"2024-03-12T11:34:43.999867Z","shell.execute_reply.started":"2024-03-12T11:34:43.992289Z","shell.execute_reply":"2024-03-12T11:34:43.999156Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import seaborn as sns","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:34:44.002112Z","iopub.execute_input":"2024-03-12T11:34:44.002617Z","iopub.status.idle":"2024-03-12T11:34:44.007727Z","shell.execute_reply.started":"2024-03-12T11:34:44.002588Z","shell.execute_reply":"2024-03-12T11:34:44.007103Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Loading data + EDA","metadata":{}},{"cell_type":"code","source":"train_csv = pd.read_csv('../input/aptos2019-blindness-detection/train.csv')\ntest_csv = pd.read_csv('../input/aptos2019-blindness-detection/test.csv')","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:34:44.008708Z","iopub.execute_input":"2024-03-12T11:34:44.009154Z","iopub.status.idle":"2024-03-12T11:34:44.027523Z","shell.execute_reply.started":"2024-03-12T11:34:44.009125Z","shell.execute_reply":"2024-03-12T11:34:44.026766Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('Train Size = {}'.format(len(train_csv)))\nprint('Public Test Size = {}'.format(len(test_csv)))","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:34:44.028803Z","iopub.execute_input":"2024-03-12T11:34:44.029308Z","iopub.status.idle":"2024-03-12T11:34:44.033809Z","shell.execute_reply.started":"2024-03-12T11:34:44.029273Z","shell.execute_reply":"2024-03-12T11:34:44.033137Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_csv.head()","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:34:44.035155Z","iopub.execute_input":"2024-03-12T11:34:44.035620Z","iopub.status.idle":"2024-03-12T11:34:44.046781Z","shell.execute_reply.started":"2024-03-12T11:34:44.035593Z","shell.execute_reply":"2024-03-12T11:34:44.045959Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"counts = train_csv['diagnosis'].value_counts()\nclass_list = ['No DR', 'Mild', 'Moderate', 'Severe', 'Proliferate']\nfor i,x in enumerate(class_list):\n    counts[x] = counts.pop(i)\n\nplt.figure(figsize=(10,5))\nsns.barplot(x=counts.index, y=counts.values, alpha=0.8, palette='bright')\nplt.title('Distribution of Output Classes')\nplt.ylabel('Number of Occurrences', fontsize=12)\nplt.xlabel('Target Classes', fontsize=12)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:34:44.048038Z","iopub.execute_input":"2024-03-12T11:34:44.048570Z","iopub.status.idle":"2024-03-12T11:34:44.374127Z","shell.execute_reply.started":"2024-03-12T11:34:44.048540Z","shell.execute_reply":"2024-03-12T11:34:44.373426Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Visualising the training data","metadata":{}},{"cell_type":"code","source":"fig = plt.figure(figsize=(30, 6))\n# display 20 images\ntrain_imgs = os.listdir(base_dir+\"/train_images\")\nfor idx, img in enumerate(np.random.choice(train_imgs, 16)):\n    ax = fig.add_subplot(2, 16//2, idx+1, xticks=[], yticks=[])\n    im = Image.open(base_dir+\"/train_images/\" + img)\n    plt.imshow(im)\n    lab = train_csv.loc[train_csv['id_code'] == img.split('.')[0], 'diagnosis'].values[0]\n    ax.set_title('Severity: %s'%lab)","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:34:44.375430Z","iopub.execute_input":"2024-03-12T11:34:44.375754Z","iopub.status.idle":"2024-03-12T11:34:59.212527Z","shell.execute_reply.started":"2024-03-12T11:34:44.375723Z","shell.execute_reply":"2024-03-12T11:34:59.211709Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Visualising Test data","metadata":{}},{"cell_type":"code","source":"fig = plt.figure(figsize=(30, 6))\n# display 20 images\ntest_imgs = os.listdir(base_dir+\"/test_images\")\nfor idx, img in enumerate(np.random.choice(test_imgs, 16)):\n    ax = fig.add_subplot(2, 16//2, idx+1, xticks=[], yticks=[])\n    im = Image.open(base_dir+\"/test_images/\" + img)\n    plt.imshow(im)","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:34:59.216318Z","iopub.execute_input":"2024-03-12T11:34:59.216844Z","iopub.status.idle":"2024-03-12T11:35:06.601387Z","shell.execute_reply.started":"2024-03-12T11:34:59.216811Z","shell.execute_reply":"2024-03-12T11:35:06.600210Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Data Processing","metadata":{}},{"cell_type":"code","source":"class CreateDataset(Dataset):\n    def __init__(self, df_data, data_dir = '../input/', transform=None):\n        super().__init__()\n        self.df = df_data.values\n        self.data_dir = data_dir\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, index):\n        img_name,label = self.df[index]\n        img_path = os.path.join(self.data_dir, img_name+'.png')\n        image = cv2.imread(img_path)\n        if self.transform is not None:\n            image = self.transform(image)\n        return image, label","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:35:06.602788Z","iopub.execute_input":"2024-03-12T11:35:06.603117Z","iopub.status.idle":"2024-03-12T11:35:06.611095Z","shell.execute_reply.started":"2024-03-12T11:35:06.603086Z","shell.execute_reply":"2024-03-12T11:35:06.610282Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_transforms = transforms.Compose([\n    transforms.ToPILImage(),\n    transforms.Resize((224, 224)),\n    transforms.RandomHorizontalFlip(p=0.4),\n    #transforms.ColorJitter(brightness=2, contrast=2),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225))\n])","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:35:06.612362Z","iopub.execute_input":"2024-03-12T11:35:06.612820Z","iopub.status.idle":"2024-03-12T11:35:06.622735Z","shell.execute_reply.started":"2024-03-12T11:35:06.612790Z","shell.execute_reply":"2024-03-12T11:35:06.621670Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_transforms = transforms.Compose([transforms.Resize(256),\n                                      transforms.CenterCrop(224),\n                                      transforms.ToTensor(),\n                                      transforms.Normalize([0.485, 0.456, 0.406],[0.229, 0.224, 0.225])])","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:35:06.624678Z","iopub.execute_input":"2024-03-12T11:35:06.624995Z","iopub.status.idle":"2024-03-12T11:35:06.640347Z","shell.execute_reply.started":"2024-03-12T11:35:06.624969Z","shell.execute_reply":"2024-03-12T11:35:06.639176Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_path = \"../input/aptos2019-blindness-detection/train_images/\"\ntest_path = \"../input/aptos2019-blindness-detection/test_images/\"","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:35:06.641603Z","iopub.execute_input":"2024-03-12T11:35:06.642674Z","iopub.status.idle":"2024-03-12T11:35:06.652632Z","shell.execute_reply.started":"2024-03-12T11:35:06.642641Z","shell.execute_reply":"2024-03-12T11:35:06.651104Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data = CreateDataset(df_data=train_csv, data_dir=train_path, transform=train_transforms)\ntest_data = CreateDataset(df_data=test_csv, data_dir=test_path, transform=test_transforms)","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:35:06.653899Z","iopub.execute_input":"2024-03-12T11:35:06.654797Z","iopub.status.idle":"2024-03-12T11:35:06.662812Z","shell.execute_reply.started":"2024-03-12T11:35:06.654765Z","shell.execute_reply":"2024-03-12T11:35:06.661910Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_size = 0.2\nnum_train = len(train_data)\nindices = list(range(num_train))\nnp.random.shuffle(indices)\nsplit = int(np.floor(valid_size * num_train))\ntrain_idx, valid_idx = indices[split:], indices[:split]","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:35:06.664092Z","iopub.execute_input":"2024-03-12T11:35:06.664754Z","iopub.status.idle":"2024-03-12T11:35:06.672323Z","shell.execute_reply.started":"2024-03-12T11:35:06.664711Z","shell.execute_reply":"2024-03-12T11:35:06.671485Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_sampler = SubsetRandomSampler(train_idx)\nvalid_sampler = SubsetRandomSampler(valid_idx)","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:35:06.673610Z","iopub.execute_input":"2024-03-12T11:35:06.674080Z","iopub.status.idle":"2024-03-12T11:35:06.681793Z","shell.execute_reply.started":"2024-03-12T11:35:06.674038Z","shell.execute_reply":"2024-03-12T11:35:06.681017Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainloader = torch.utils.data.DataLoader(train_data, batch_size=64,sampler=train_sampler)\nvalidloader = torch.utils.data.DataLoader(train_data, batch_size=64, sampler=valid_sampler)\ntestloader = torch.utils.data.DataLoader(test_data, batch_size=64)","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:35:06.683096Z","iopub.execute_input":"2024-03-12T11:35:06.683470Z","iopub.status.idle":"2024-03-12T11:35:06.691648Z","shell.execute_reply.started":"2024-03-12T11:35:06.683425Z","shell.execute_reply":"2024-03-12T11:35:06.690758Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"training examples contain : {len(train_data)}\")\nprint(f\"testing examples contain : {len(test_data)}\")\n\nprint(len(trainloader))\nprint(len(validloader))\nprint(len(testloader))","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:35:06.692816Z","iopub.execute_input":"2024-03-12T11:35:06.693800Z","iopub.status.idle":"2024-03-12T11:35:06.702835Z","shell.execute_reply.started":"2024-03-12T11:35:06.693767Z","shell.execute_reply":"2024-03-12T11:35:06.701738Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# LOADING ONE BATCH OF TESTING SET TO CHECK THE IMAGES AND THEIR LABELS\nimages, labels = next(iter(trainloader))\n\n# Checking shape of image\nprint(f\"Image shape : {images.shape}\")\nprint(f\"Label shape : {labels.shape}\")\n\n# denormalizing images\ndef imshow(inp, title=None):\n    \"\"\"Imshow for Tensor.\"\"\"\n    inp = inp.numpy().transpose((1, 2, 0))\n    mean = np.array([0.485, 0.456, 0.406])\n    std = np.array([0.229, 0.224, 0.225])\n    inp = std * inp + mean\n    inp = np.clip(inp, 0, 1)\n    plt.imshow(inp)\n    if title is not None:\n        plt.title(title)\n    plt.pause(0.001)","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:35:06.704419Z","iopub.execute_input":"2024-03-12T11:35:06.704760Z","iopub.status.idle":"2024-03-12T11:35:15.467278Z","shell.execute_reply.started":"2024-03-12T11:35:06.704730Z","shell.execute_reply":"2024-03-12T11:35:15.466265Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# plotting the images of loaded batch with given fig size and frame data    \nimport torchvision\nimport matplotlib.pyplot as plt\nimport numpy as np\ngrid = torchvision.utils.make_grid(images, nrow = 20, padding = 2)\nplt.figure(figsize = (20, 20))  \nplt.imshow(np.transpose(grid, (1, 2, 0)))   \nprint('labels:', labels)    ","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:35:15.468518Z","iopub.execute_input":"2024-03-12T11:35:15.469360Z","iopub.status.idle":"2024-03-12T11:35:17.045955Z","shell.execute_reply.started":"2024-03-12T11:35:15.469328Z","shell.execute_reply":"2024-03-12T11:35:17.045153Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_names = ['No DR', 'Mild', 'Moderate', 'Severe', 'Proliferative DR']\n\nimages, labels = next(iter(trainloader))\nout = torchvision.utils.make_grid(images)\nimshow(out, title=[class_names[x] for x in labels])","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:35:17.047244Z","iopub.execute_input":"2024-03-12T11:35:17.047767Z","iopub.status.idle":"2024-03-12T11:35:27.912168Z","shell.execute_reply.started":"2024-03-12T11:35:17.047734Z","shell.execute_reply":"2024-03-12T11:35:27.911251Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pip install torch","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:35:27.913494Z","iopub.execute_input":"2024-03-12T11:35:27.913908Z","iopub.status.idle":"2024-03-12T11:35:41.151936Z","shell.execute_reply.started":"2024-03-12T11:35:27.913864Z","shell.execute_reply":"2024-03-12T11:35:41.150381Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nimport torch\nimport tensorflow as tf\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, BatchNormalization, GlobalMaxPooling2D, Dense, Dropout\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.utils import to_categorical\nfrom torchvision.transforms import ToPILImage, Resize, ToTensor\nfrom torch.utils.data import DataLoader\nfrom torchvision.datasets import CIFAR10\nfrom PIL import Image\n\n# Assuming  defined  trainloader, valloader, and testloader\n\n#  resizing the input images and reorder dimensions\nresize_transform = transforms.Compose([\n    ToPILImage(),\n    Resize((180, 180)),\n    ToTensor(),\n])\n\n# Defining the model\nmodel = Sequential()\nmodel.add(Conv2D(16, kernel_size=(3, 3), padding='same', input_shape=(180, 180, 3)))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(BatchNormalization())\n\nmodel.add(Conv2D(32, kernel_size=(3, 3), padding='same'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(BatchNormalization())\n\nmodel.add(Conv2D(64, kernel_size=(3, 3), padding='same'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(BatchNormalization())\n\nmodel.add(GlobalMaxPooling2D())\n\nmodel.add(Dense(256, activation='relu'))\nmodel.add(Dropout(0.5))\n\nmodel.add(Dense(5, activation='softmax'))\n\n# Compile the model\noptimizer = Adam()\nmodel.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])\n\n# Training the model\nnum_epochs = 50\n\nfor epoch in range(50):\n    for images, labels in trainloader:\n        # Resize and reorder dimensions of the input images\n        images_resized = torch.stack([resize_transform(img) for img in images])\n        images_resized = images_resized.permute(0, 2, 3, 1)  # Change dimensions from (batch_size, channels, height, width) to (batch_size, height, width, channels)\n        \n        # Assuming  labels are in tensor format,  converting them to numpy and then to categorical\n        labels = to_categorical(labels.numpy(), num_classes=5)\n        \n        # Training the model on the batch\n        model.fit(images_resized.numpy(), labels, batch_size=7)  # Adjust batch size as needed\n    \n    # After each epoch, evaluating on the validation set\n    #val_loss, val_acc = model.evaluate(validloader)\n    # After each epoch, evaluating on the validation set\nval_loss, val_acc = 0.0, 0.0\nnum_batches = len(validloader)\n\nfor images, labels in validloader:\n    # Resize and reorder dimensions of the input images\n    images_resized = torch.stack([resize_transform(img) for img in images])\n    images_resized = images_resized.permute(0, 2, 3, 1)  # Change dimensions from (batch_size, channels, height, width) to (batch_size, height, width, channels)\n    \n    # Assuming labels are in tensor format, converting them to numpy and then to categorical\n    labels = to_categorical(labels.numpy(), num_classes=5)\n    \n    # Calculate loss and accuracy for the batch\n    batch_loss, batch_acc = model.evaluate(images_resized.numpy(), labels, verbose=0)\n    val_loss += batch_loss\n    val_acc += batch_acc\n\n# Average loss and accuracy over all batches\nval_loss /= num_batches\nval_acc /= num_batches\n\nprint(f'Epoch {epoch+1}/{num_epochs}, Validation Loss: {val_loss}, Validation Accuracy: {val_acc}')\n    #print(f'Epoch {epoch+1}/{num_epochs}, Validation Loss: {val_loss}, Validation Accuracy: {val_acc}')\n\n# Save the model as a .h5 file\nmodel.save('your_model.h5')\n","metadata":{"execution":{"iopub.status.busy":"2024-03-12T11:35:41.153958Z","iopub.execute_input":"2024-03-12T11:35:41.154356Z","iopub.status.idle":"2024-03-12T17:58:25.502964Z","shell.execute_reply.started":"2024-03-12T11:35:41.154321Z","shell.execute_reply":"2024-03-12T17:58:25.499232Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_history(history, x):\n    \"\"\"Plots accuracy/loss for training/validation set as a function of the epochs\n\n        :param history: Training history of model\n        :return:\n    \"\"\"\n\n    fig, axs = plt.subplots(2)\n\n    # create accuracy sublpot\n    axs[0].plot(history.history[\"accuracy\"], label=\"train accuracy\")\n    axs[0].plot(history.history[\"val_acc\"], label=\"test accuracy\")\n    axs[0].set_ylabel(\"Accuracy\")\n    axs[0].legend(loc=\"lower right\")\n    axs[0].set_title(\"Accuracy eval\")\n\n    # create error sublpot\n    axs[1].plot(history.history[\"loss\"], label=\"train error\")\n    axs[1].plot(history.history[\"val_loss\"], label=\"test error\")\n    axs[1].set_ylabel(\"Error\")\n    axs[1].set_xlabel(\"Epoch\")\n    axs[1].legend(loc=\"upper right\")\n    axs[1].set_title(\"Error eval\")\n\n    plt.show()\n    #plt.savefig(str(x/100) + \".png\")","metadata":{"execution":{"iopub.status.busy":"2024-03-12T17:58:59.088525Z","iopub.execute_input":"2024-03-12T17:58:59.088990Z","iopub.status.idle":"2024-03-12T17:58:59.099153Z","shell.execute_reply.started":"2024-03-12T17:58:59.088952Z","shell.execute_reply":"2024-03-12T17:58:59.097874Z"},"trusted":true},"execution_count":null,"outputs":[]}]}