{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":8089,"databundleVersionId":44321,"sourceType":"competition"}],"dockerImageVersionId":30887,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"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","trusted":true,"execution":{"iopub.status.busy":"2025-02-10T22:34:58.055863Z","iopub.execute_input":"2025-02-10T22:34:58.056081Z","iopub.status.idle":"2025-02-10T22:34:59.556335Z","shell.execute_reply.started":"2025-02-10T22:34:58.056060Z","shell.execute_reply":"2025-02-10T22:34:59.555465Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nprint(\"GPUs available:\", tf.config.list_physical_devices('GPU'))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T22:35:46.866435Z","iopub.execute_input":"2025-02-10T22:35:46.866754Z","iopub.status.idle":"2025-02-10T22:36:08.239592Z","shell.execute_reply.started":"2025-02-10T22:35:46.866731Z","shell.execute_reply":"2025-02-10T22:36:08.238598Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport sys\nimport random\n\nimport warnings\nimport numpy as np\nimport pandas as pd\n\nimport matplotlib.pyplot as plt\n\nfrom tqdm import tqdm\nfrom itertools import chain\nfrom skimage.io import imread, imshow, imread_collection, concatenate_images\nfrom skimage.transform import resize\nfrom skimage.morphology import label\n\nfrom keras.models import Model, load_model\nfrom keras.layers import Input,Dropout, Lambda, Conv2D, Conv2DTranspose, MaxPooling2D,concatenate\n\nfrom keras.callbacks import EarlyStopping, ModelCheckpoint\nfrom keras import backend as K\n\nimport tensorflow as tf\n\n# Set some parameters\nIMG_WIDTH = 128\nIMG_HEIGHT = 128\nIMG_CHANNELS = 3\n\n\nwarnings.filterwarnings('ignore', category=UserWarning, module='skimage')\nseed = 42\nrandom.seed = seed\nnp.random.seed = seed","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T22:46:22.323030Z","iopub.execute_input":"2025-02-10T22:46:22.323349Z","iopub.status.idle":"2025-02-10T22:46:22.330208Z","shell.execute_reply.started":"2025-02-10T22:46:22.323325Z","shell.execute_reply":"2025-02-10T22:46:22.329368Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\n# List all datasets in the Kaggle input directory\nprint(\"Available datasets in /kaggle/input/:\")\nprint(os.listdir(\"/kaggle/input/data-science-bowl-2018\"))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T22:47:19.097137Z","iopub.execute_input":"2025-02-10T22:47:19.097454Z","iopub.status.idle":"2025-02-10T22:47:19.104745Z","shell.execute_reply.started":"2025-02-10T22:47:19.097431Z","shell.execute_reply":"2025-02-10T22:47:19.103987Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from zipfile import ZipFile\nimport os\n\n# Paths\nzip_path = \"/kaggle/input/data-science-bowl-2018/stage1_train.zip\"  # Path to the zip file\nextract_path = \"./stage1_train\"  # Path where files will be extracted\n\n# Extract the zip file\nwith ZipFile(zip_path, \"r\") as zip_ref:\n    zip_ref.extractall(extract_path)\n\nprint(\"Extraction completed!\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T22:48:28.781913Z","iopub.execute_input":"2025-02-10T22:48:28.782215Z","iopub.status.idle":"2025-02-10T22:48:33.375585Z","shell.execute_reply.started":"2025-02-10T22:48:28.782194Z","shell.execute_reply":"2025-02-10T22:48:33.374774Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from zipfile import ZipFile\nimport os\n\n# Paths\nzip_path = \"/kaggle/input/data-science-bowl-2018/stage1_test.zip\"  # Path to the zip file\nextract_path = \"./stage1_test\"  # Path where files will be extracted\n\n# Extract the zip file\nwith ZipFile(zip_path, \"r\") as zip_ref:\n    zip_ref.extractall(extract_path)\n\nprint(\"Extraction completed!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T22:49:11.539108Z","iopub.execute_input":"2025-02-10T22:49:11.539418Z","iopub.status.idle":"2025-02-10T22:49:11.850937Z","shell.execute_reply.started":"2025-02-10T22:49:11.539394Z","shell.execute_reply":"2025-02-10T22:49:11.850051Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"TRAIN_PATH = \"./stage1_train/\"\nTEST_PATH=\"./stage1_test/\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T22:49:55.544002Z","iopub.execute_input":"2025-02-10T22:49:55.544323Z","iopub.status.idle":"2025-02-10T22:49:55.547986Z","shell.execute_reply.started":"2025-02-10T22:49:55.544296Z","shell.execute_reply":"2025-02-10T22:49:55.547049Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nfrom skimage.io import imread\nfrom skimage.transform import resize\nfrom tqdm import tqdm\nimport numpy as np\n\n# Constants\nIMG_HEIGHT = 128\nIMG_WIDTH = 128\nIMG_CHANNELS = 3\n\n# Updated TRAIN_PATH\nTRAIN_PATH = \"./stage1_train/\"\ntrain_ids = next(os.walk(TRAIN_PATH))[1]\n\n# Initialize arrays\nX_train = np.zeros((len(train_ids), IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS), dtype=np.uint8)\nY_train = np.zeros((len(train_ids), IMG_HEIGHT, IMG_WIDTH, 1), dtype=bool)\n\nprint('Getting and resizing train images and masks ... ')\nfor n, id_ in tqdm(enumerate(train_ids), total=len(train_ids)):\n    # Construct paths\n    path = os.path.join(TRAIN_PATH, id_)\n    image_path = os.path.join(path, 'images', f\"{id_}.png\")\n    \n    try:\n        # Load and resize the image\n        img = imread(image_path)[:, :, :IMG_CHANNELS]\n        img = resize(img, (IMG_HEIGHT, IMG_WIDTH), mode='constant', preserve_range=True)\n        X_train[n] = img\n\n        # Process masks\n        mask = np.zeros((IMG_HEIGHT, IMG_WIDTH, 1), dtype=bool)\n        mask_dir = os.path.join(path, 'masks')\n        for mask_file in next(os.walk(mask_dir))[2]:\n            mask_ = imread(os.path.join(mask_dir, mask_file))\n            mask_ = np.expand_dims(resize(mask_, (IMG_HEIGHT, IMG_WIDTH), mode='constant',\n                                          preserve_range=True), axis=-1)\n            mask = np.maximum(mask, mask_)\n        Y_train[n] = mask\n\n    except FileNotFoundError:\n        print(f\"File not found: {image_path}\")\n    except NotADirectoryError:\n        print(f\"Error: {path} is not a directory. Did you extract the zip file?\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T22:50:18.792692Z","iopub.execute_input":"2025-02-10T22:50:18.793011Z","iopub.status.idle":"2025-02-10T22:54:12.338832Z","shell.execute_reply.started":"2025-02-10T22:50:18.792976Z","shell.execute_reply":"2025-02-10T22:54:12.338096Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train.shape,Y_train.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T22:54:34.276906Z","iopub.execute_input":"2025-02-10T22:54:34.277258Z","iopub.status.idle":"2025-02-10T22:54:34.283664Z","shell.execute_reply.started":"2025-02-10T22:54:34.277221Z","shell.execute_reply":"2025-02-10T22:54:34.282737Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print('Getting and resizing test images ... ')\ntest_ids = next(os.walk(TEST_PATH))[1]\nsizes_test = []\nX_test = np.zeros((len(test_ids), IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS), dtype=np.uint8)\nfor n, id_ in tqdm(enumerate(test_ids), total=len(test_ids)):\n    # Construct paths\n    path = os.path.join(TEST_PATH, id_)\n    image_path = os.path.join(path, 'images', f\"{id_}.png\")\n    \n    try:\n        # Load the original image and store its size\n        img = imread(image_path)[:, :, :IMG_CHANNELS]\n        sizes_test.append([img.shape[0], img.shape[1]])\n\n        # Resize the image\n        img = resize(img, (IMG_HEIGHT, IMG_WIDTH), mode='constant', preserve_range=True)\n        X_test[n] = img\n    except FileNotFoundError:\n        print(f\"Test image not found: {image_path}\")\n    except NotADirectoryError:\n        print(f\"Error: {path} is not a directory. Did you extract the zip file?\")\n\nprint('Done!')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T22:55:42.462590Z","iopub.execute_input":"2025-02-10T22:55:42.462900Z","iopub.status.idle":"2025-02-10T22:55:43.760803Z","shell.execute_reply.started":"2025-02-10T22:55:42.462876Z","shell.execute_reply":"2025-02-10T22:55:43.760024Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_test.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T22:55:46.874824Z","iopub.execute_input":"2025-02-10T22:55:46.875111Z","iopub.status.idle":"2025-02-10T22:55:46.880881Z","shell.execute_reply.started":"2025-02-10T22:55:46.875089Z","shell.execute_reply":"2025-02-10T22:55:46.879930Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ix = random.randint(0, len(train_ids))\nimshow(X_train[ix])\nplt.show()\nimshow(np.squeeze(Y_train[ix]))\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T22:55:49.771471Z","iopub.execute_input":"2025-02-10T22:55:49.771785Z","iopub.status.idle":"2025-02-10T22:55:50.340882Z","shell.execute_reply.started":"2025-02-10T22:55:49.771759Z","shell.execute_reply":"2025-02-10T22:55:50.340204Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nfrom keras import layers, Model\nfrom keras.layers import Lambda\n\ndef residual_block(x, filters):\n    # Save the input as a shortcut\n    shortcut = layers.Conv2D(filters, (1, 1), padding=\"same\")(x)  # Match the number of filters\n\n    # Apply convolutions\n    x = layers.Conv2D(filters, (3, 3), padding=\"same\")(x)\n    x = layers.BatchNormalization()(x)\n    x = layers.ReLU()(x)\n\n    x = layers.Conv2D(filters, (3, 3), padding=\"same\")(x)\n    x = layers.BatchNormalization()(x)\n\n    # Add shortcut to the output\n    x = layers.Add()([shortcut, x])  # Now shapes match\n    x = layers.ReLU()(x)\n    return x\n\n\ndef attention_block(input_x, gating_x, inter_filters):\n    theta_x = layers.Conv2D(inter_filters, (1, 1), strides=(1, 1), padding='same')(input_x)\n    phi_g = layers.Conv2D(inter_filters, (1, 1), strides=(1, 1), padding='same')(gating_x)\n\n    add_xg = layers.Add()([theta_x, phi_g])\n    relu_xg = layers.Activation('relu')(add_xg)\n\n    psi = layers.Conv2D(1, (1, 1), strides=(1, 1), padding='same')(relu_xg)\n    sigmoid_xg = layers.Activation('sigmoid')(psi)\n\n    upsample_psi = layers.UpSampling2D(size=(input_x.shape[1] // sigmoid_xg.shape[1],\n                                             input_x.shape[2] // sigmoid_xg.shape[2]))(sigmoid_xg)\n\n    upsample_psi = layers.Reshape(input_x.shape[1:])(upsample_psi)\n    multiply_xg = layers.Multiply()([input_x, upsample_psi])\n\n    return multiply_xg\n\ndef encoder_block(x, filters):\n    x = residual_block(x, filters)\n    skip = x\n    x = layers.MaxPooling2D((2, 2))(x)\n    return x, skip\n\ndef decoder_block(x, skip, filters):\n    x = layers.Conv2DTranspose(filters, (2, 2), strides=(2, 2), padding=\"same\")(x)\n    x = layers.Concatenate()([x, skip])\n    x = residual_block(x, filters)\n    return x\n\ndef CellSegUNet(input_shape):\n    inputs = layers.Input(input_shape)\n\n    # Scale inputs\n    s = Lambda(lambda x: x / 255) (inputs)\n\n    # Encoder\n    x1, skip1 = encoder_block(s, 32)\n    x2, skip2 = encoder_block(x1, 64)\n    x3, skip3 = encoder_block(x2, 128)\n    x4, skip4 = encoder_block(x3, 256)\n\n    # Bottleneck\n    bottleneck = residual_block(x4, 512)\n\n    # Decoder\n    x = decoder_block(bottleneck, skip4, 256)\n    x = decoder_block(x, skip3, 128)\n    x = decoder_block(x, skip2, 64)\n    x = decoder_block(x, skip1, 32)\n\n    # Output Layer\n    outputs = layers.Conv2D(1, (1, 1), activation=\"sigmoid\")(x)\n\n    return Model(inputs, outputs)\n\n# Define the model\ninput_shape = (IMG_HEIGHT, IMG_WIDTH, IMG_CHANNELS)\nmodel = CellSegUNet(input_shape)\nmodel.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T22:59:35.610873Z","iopub.execute_input":"2025-02-10T22:59:35.611226Z","iopub.status.idle":"2025-02-10T22:59:36.073758Z","shell.execute_reply.started":"2025-02-10T22:59:35.611199Z","shell.execute_reply":"2025-02-10T22:59:36.072893Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\ndef dice_coefficient(y_true, y_pred):\n    numerator = 2 * tf.reduce_sum(y_true * y_pred)\n    denominator = tf.reduce_sum(y_true + y_pred)\n    return numerator / (denominator + tf.keras.backend.epsilon())\n    \ndef dice_loss(y_true, y_pred):\n    return 1 - dice_coefficient(y_true, y_pred)\n    \ndef iou(y_true, y_pred):\n    intersection = tf.reduce_sum(y_true * y_pred)\n    union = tf.reduce_sum(y_true + y_pred - y_true * y_pred)\n    return intersection / (union + tf.keras.backend.epsilon())\nY_train = Y_train.astype('float32')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T23:13:25.996124Z","iopub.execute_input":"2025-02-10T23:13:25.996443Z","iopub.status.idle":"2025-02-10T23:13:26.013880Z","shell.execute_reply.started":"2025-02-10T23:13:25.996417Z","shell.execute_reply":"2025-02-10T23:13:26.013048Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.compile(\n    optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4),\n    loss=dice_loss,  #  Dice Loss\n    metrics=[dice_coefficient, iou]  # Dice Coefficient and IoU\n)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T23:13:28.929371Z","iopub.execute_input":"2025-02-10T23:13:28.929688Z","iopub.status.idle":"2025-02-10T23:13:28.938191Z","shell.execute_reply.started":"2025-02-10T23:13:28.929663Z","shell.execute_reply":"2025-02-10T23:13:28.937448Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"earlystopper = EarlyStopping(patience=10, verbose=1)\ncheckpointer = ModelCheckpoint('model-dsbowl2018-1.keras', verbose=1, save_best_only=True)\nresults = model.fit(X_train, Y_train, validation_split=0.1, batch_size=16, epochs=80, \n                    callbacks=[earlystopper, checkpointer])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T23:16:29.403029Z","iopub.execute_input":"2025-02-10T23:16:29.403343Z","iopub.status.idle":"2025-02-10T23:21:18.572557Z","shell.execute_reply.started":"2025-02-10T23:16:29.403319Z","shell.execute_reply":"2025-02-10T23:21:18.571674Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nfrom skimage.transform import resize\nimport matplotlib.pyplot as plt\n\n# Predict on test data\nprint(\"Predicting on test data...\")\npredictions = model.predict(X_test, verbose=1)\n\n# Apply a threshold to convert probabilities to binary masks\nthreshold = 0.5\npredictions_binary = (predictions > threshold).astype(np.uint8)\n\n# Reshape predictions back to their original sizes\nresized_predictions = []\nfor i, prediction in enumerate(predictions_binary):\n    original_size = sizes_test[i]\n    resized_pred = resize(prediction.squeeze(), \n                          (original_size[0], original_size[1]), \n                          mode='constant', preserve_range=True)\n    resized_predictions.append((resized_pred > threshold).astype(np.uint8))\n\n# Convert the list to a NumPy array\n\n\nprint(\"Predictions complete!\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T23:28:24.343605Z","iopub.execute_input":"2025-02-10T23:28:24.343953Z","iopub.status.idle":"2025-02-10T23:28:24.981802Z","shell.execute_reply.started":"2025-02-10T23:28:24.343924Z","shell.execute_reply":"2025-02-10T23:28:24.980991Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Visualize test image, ground truth, and prediction\nfor i in range(3):  # Display first 3 test samples\n    plt.figure(figsize=(10, 10))\n    \n    plt.subplot(1, 3, 1)\n    plt.title(\"Test Image\")\n    plt.imshow(X_test[i])\n    \n    plt.subplot(1, 3, 2)\n    plt.title(\"Prediction (Resized)\")\n    plt.imshow(resized_predictions[i], cmap='gray')\n    \n    plt.subplot(1, 3, 3)\n    plt.title(\"Binary Mask Prediction\")\n    plt.imshow(predictions_binary[i].squeeze(), cmap='gray')\n    \n    plt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T23:29:31.230116Z","iopub.execute_input":"2025-02-10T23:29:31.230446Z","iopub.status.idle":"2025-02-10T23:29:32.402856Z","shell.execute_reply.started":"2025-02-10T23:29:31.230415Z","shell.execute_reply":"2025-02-10T23:29:32.402063Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# Access the loss values from the history object\ntraining_loss = results.history['loss']\nvalidation_loss = results.history['val_loss']\n\n# Plot the training and validation loss\nplt.figure(figsize=(8, 6))\nplt.plot(training_loss, label='Training Loss')\nplt.plot(validation_loss, label='Validation Loss')\nplt.title('Loss Over Epochs')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\nplt.grid()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T23:34:57.516683Z","iopub.execute_input":"2025-02-10T23:34:57.516974Z","iopub.status.idle":"2025-02-10T23:34:57.705100Z","shell.execute_reply.started":"2025-02-10T23:34:57.516950Z","shell.execute_reply":"2025-02-10T23:34:57.704294Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n\n\n# Check if the metrics (e.g., Dice coefficient) are available\nif 'dice_coefficient' in results.history:\n    training_metric = results.history['dice_coefficient']\n    validation_metric = results.history['val_dice_coefficient']\n    metric_name = \"Dice Coefficient\"\n\nelse:\n    raise ValueError(\"Metric not found in history. Ensure it was defined during model.compile().\")\n\n\n# Plot training and validation metrics\nplt.subplot(1, 2, 2)\nplt.plot(training_metric, label=f'Training {metric_name}')\nplt.plot(validation_metric, label=f'Validation {metric_name}')\nplt.title(f'{metric_name} Over Epochs')\nplt.xlabel('Epochs')\nplt.ylabel(metric_name)\nplt.legend()\nplt.grid()\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T23:40:07.727692Z","iopub.execute_input":"2025-02-10T23:40:07.728282Z","iopub.status.idle":"2025-02-10T23:40:08.005758Z","shell.execute_reply.started":"2025-02-10T23:40:07.728234Z","shell.execute_reply":"2025-02-10T23:40:08.004917Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if 'iou' in results.history:\n    training_metric = results.history['iou']\n    validation_metric = results.history['val_iou']\n    metric_name = \"IoU\"\nelse:\n    raise ValueError(\"Metric not found in history. Ensure it was defined during model.compile().\")\nplt.subplot(1, 2, 2)\nplt.plot(training_metric, label=f'Training {metric_name}')\nplt.plot(validation_metric, label=f'Validation {metric_name}')\nplt.title(f'{metric_name} Over Epochs')\nplt.xlabel('Epochs')\nplt.ylabel(metric_name)\nplt.legend()\nplt.grid()\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-10T23:40:47.476131Z","iopub.execute_input":"2025-02-10T23:40:47.476485Z","iopub.status.idle":"2025-02-10T23:40:47.723486Z","shell.execute_reply.started":"2025-02-10T23:40:47.476453Z","shell.execute_reply":"2025-02-10T23:40:47.722545Z"}},"outputs":[],"execution_count":null}]}