{"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":"raw","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":"2023-04-14T11:53:02.808800Z","iopub.execute_input":"2023-04-14T11:53:02.809176Z","iopub.status.idle":"2023-04-14T11:54:39.810014Z","shell.execute_reply.started":"2023-04-14T11:53:02.809142Z","shell.execute_reply":"2023-04-14T11:54:39.808248Z"},"jupyter":{"outputs_hidden":true,"source_hidden":true}}},{"cell_type":"code","source":"#imports\n\nimport os\nimport json\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\nimport tensorflow as tf\n\nfrom PIL import Image","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:07:47.398524Z","iopub.execute_input":"2023-05-01T17:07:47.398932Z","iopub.status.idle":"2023-05-01T17:08:03.401565Z","shell.execute_reply.started":"2023-05-01T17:07:47.398868Z","shell.execute_reply":"2023-05-01T17:08:03.400259Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:08:03.404012Z","iopub.execute_input":"2023-05-01T17:08:03.404964Z","iopub.status.idle":"2023-05-01T17:09:29.800740Z","shell.execute_reply.started":"2023-05-01T17:08:03.404891Z","shell.execute_reply":"2023-05-01T17:09:29.799727Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# upload data/directories\n\n# modified smaller datasets for testing loop\n# train  = \"/kaggle/input/testing-train\"\n# labels = \"/kaggle/input/testing-labels\"\n\ntrain  = \"/kaggle/input/benetech-making-graphs-accessible/train/images\"\nlabel = \"/kaggle/input/benetech-making-graphs-accessible/train/annotations\"\ntest   = \"/kaggle/input/benetech-making-graphs-accessible/test/images\"\n\ntrain_dir = os.listdir(train)\nlabel_dir = os.listdir(label)\n\ntrain_dir = sorted(train_dir)\nlabel_dir = sorted(label_dir)\nprint(train_dir[:5], '\\n', label_dir[:5])","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:09:29.802334Z","iopub.execute_input":"2023-05-01T17:09:29.803388Z","iopub.status.idle":"2023-05-01T17:09:29.904216Z","shell.execute_reply.started":"2023-05-01T17:09:29.803343Z","shell.execute_reply":"2023-05-01T17:09:29.903169Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# INPUTS / preprocess images (greyscale, resize)\nx_train_full = []\n\nfor image in train_dir:\n    open_img = Image.open(train + '/' + image, 'r')\n    greyscale_img = open_img.convert('L') # convert to greyscale\n    resize_img = greyscale_img.resize((28,28))\n    x_train_full.append(np.asarray(resize_img))","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:09:29.907209Z","iopub.execute_input":"2023-05-01T17:09:29.907704Z","iopub.status.idle":"2023-05-01T17:17:56.881970Z","shell.execute_reply.started":"2023-05-01T17:09:29.907662Z","shell.execute_reply":"2023-05-01T17:17:56.880796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# LABELS / extract labels from json file\ny_train_full = []\n\nfor label in label_dir:\n    json_open = open(\"/kaggle/input/benetech-making-graphs-accessible/train/annotations/\" + label, 'r')\n    json_load = json.load(json_open)\n    chart_type = (json_load['chart-type'])\n    y_train_full.append(chart_type)\n    json_open.close()","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:17:56.883528Z","iopub.execute_input":"2023-05-01T17:17:56.883933Z","iopub.status.idle":"2023-05-01T17:23:12.439571Z","shell.execute_reply.started":"2023-05-01T17:17:56.883868Z","shell.execute_reply":"2023-05-01T17:23:12.438437Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# convert labels into data\n# Plot Types: line, dot, scatter, vertical_bar, horizontal_bar\n# https://www.geeksforgeeks.org/ml-label-encoding-of-datasets-in-python/\n\nfrom sklearn.preprocessing import LabelEncoder\nx_train_full = np.array(x_train_full)\ny_train_full = np.array(y_train_full)\nlabel_encoder = LabelEncoder()\ny_train_full = label_encoder.fit_transform(y_train_full)","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:23:12.442336Z","iopub.execute_input":"2023-05-01T17:23:12.442636Z","iopub.status.idle":"2023-05-01T17:23:12.885695Z","shell.execute_reply.started":"2023-05-01T17:23:12.442607Z","shell.execute_reply":"2023-05-01T17:23:12.884598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#scale pixel intensities to between 0 and 1\nx_train_full = x_train_full / 255\n\n# Creating validation set\n\n#use first 80% as training set, last 20% as validation set\ntrain_valid_split_percent = int( len(train_dir) * 0.2 )\n\nx_train, y_train = x_train_full[train_valid_split_percent:], y_train_full[train_valid_split_percent:]\nx_valid, y_valid = x_train_full[:train_valid_split_percent], y_train_full[:train_valid_split_percent]\n\nprint(len(x_train), len(y_train), len(x_valid), len(y_valid))","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:23:12.887356Z","iopub.execute_input":"2023-05-01T17:23:12.887854Z","iopub.status.idle":"2023-05-01T17:23:13.022274Z","shell.execute_reply.started":"2023-05-01T17:23:12.887810Z","shell.execute_reply":"2023-05-01T17:23:13.020994Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Experiment 1**: SGD vs RMSPROP vs ADAM using a Convolutional Neural Network (CNN)","metadata":{}},{"cell_type":"code","source":"# SGD\nfrom functools import partial\n\nDefaultConv2D = partial(tf.keras.layers.Conv2D,\n                       kernel_size = 3,\n                       padding = 'same',\n                       activation = 'relu',\n                       kernel_initializer = 'he_normal')\n\ncnn_sgd = tf.keras.Sequential([\n    DefaultConv2D(filters = 64, kernel_size = 3, input_shape = [28, 28, 1]),\n    tf.keras.layers.MaxPool2D(),\n    DefaultConv2D(filters = 128),\n    tf.keras.layers.MaxPool2D(),\n    DefaultConv2D(filters = 256),\n    tf.keras.layers.MaxPool2D(),\n    tf.keras.layers.Flatten(),\n    tf.keras.layers.Dense(units = 128, activation = 'relu', kernel_initializer = 'he_normal'),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(units = 64,  activation = 'relu', kernel_initializer = 'he_normal'),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(5, activation = 'softmax')\n])\n\ncnn_sgd.compile(loss = 'sparse_categorical_crossentropy',\n             optimizer=tf.keras.optimizers.SGD(learning_rate=0.001),\n             metrics = ['accuracy'])\n\ncnn_sgd_history = cnn_sgd.fit(x_train, y_train, epochs=30, validation_data=(x_valid, y_valid))","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:23:13.024017Z","iopub.execute_input":"2023-05-01T17:23:13.024784Z","iopub.status.idle":"2023-05-01T17:28:02.041441Z","shell.execute_reply.started":"2023-05-01T17:23:13.024736Z","shell.execute_reply":"2023-05-01T17:28:02.040376Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# SGD plot\npd.DataFrame(cnn_sgd_history.history).plot(ylim = [0,1])","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:28:02.043267Z","iopub.execute_input":"2023-05-01T17:28:02.043570Z","iopub.status.idle":"2023-05-01T17:28:02.411873Z","shell.execute_reply.started":"2023-05-01T17:28:02.043541Z","shell.execute_reply":"2023-05-01T17:28:02.410862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# RMSprop\nfrom functools import partial\n\nDefaultConv2D = partial(tf.keras.layers.Conv2D,\n                       kernel_size = 3,\n                       padding = 'same',\n                       activation = 'relu',\n                       kernel_initializer = 'he_normal')\n\ncnn_rmsprop = tf.keras.Sequential([\n    DefaultConv2D(filters = 64, kernel_size = 3, input_shape = [28, 28, 1]),\n    tf.keras.layers.MaxPool2D(),\n    DefaultConv2D(filters = 128),\n    tf.keras.layers.MaxPool2D(),\n    DefaultConv2D(filters = 256),\n    tf.keras.layers.MaxPool2D(),\n    tf.keras.layers.Flatten(),\n    tf.keras.layers.Dense(units = 128, activation = 'relu', kernel_initializer = 'he_normal'),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(units = 64,  activation = 'relu', kernel_initializer = 'he_normal'),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(5, activation = 'softmax')\n])\n\ncnn_rmsprop.compile(loss = 'sparse_categorical_crossentropy',\n             optimizer=tf.keras.optimizers.RMSprop(learning_rate=0.001),\n             metrics = ['accuracy'])\n\ncnn_rmsprop_history = cnn_rmsprop.fit(x_train, y_train, epochs=30, validation_data=(x_valid, y_valid))","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:28:02.416067Z","iopub.execute_input":"2023-05-01T17:28:02.416380Z","iopub.status.idle":"2023-05-01T17:32:34.211196Z","shell.execute_reply.started":"2023-05-01T17:28:02.416349Z","shell.execute_reply":"2023-05-01T17:32:34.210091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# RMSprop plot\npd.DataFrame(cnn_rmsprop_history.history).plot(ylim = [0,1])","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:32:34.213278Z","iopub.execute_input":"2023-05-01T17:32:34.213888Z","iopub.status.idle":"2023-05-01T17:32:34.478558Z","shell.execute_reply.started":"2023-05-01T17:32:34.213844Z","shell.execute_reply":"2023-05-01T17:32:34.477595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Adam\nfrom functools import partial\nfrom keras import optimizers\n\nDefaultConv2D = partial(tf.keras.layers.Conv2D,\n                       kernel_size = 3,\n                       padding = 'same',\n                       activation = 'relu',\n                       kernel_initializer = 'he_normal')\n\ncnn_adam = tf.keras.Sequential([\n    DefaultConv2D(filters = 64, kernel_size = 3, input_shape = [28, 28, 1]),\n    tf.keras.layers.MaxPool2D(),\n    DefaultConv2D(filters = 128),\n    tf.keras.layers.MaxPool2D(),\n    DefaultConv2D(filters = 256),\n    tf.keras.layers.MaxPool2D(),\n    tf.keras.layers.Flatten(),\n    tf.keras.layers.Dense(units = 128, activation = 'relu', kernel_initializer = 'he_normal'),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(units = 64,  activation = 'relu', kernel_initializer = 'he_normal'),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(5, activation = 'softmax')\n])\n\ncnn_adam.compile(loss = 'sparse_categorical_crossentropy',\n             optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),\n             metrics = ['accuracy'])\n\ncnn_adam_history = cnn_adam.fit(x_train, y_train, epochs=30, validation_data=(x_valid, y_valid))","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:32:34.480238Z","iopub.execute_input":"2023-05-01T17:32:34.480876Z","iopub.status.idle":"2023-05-01T17:37:58.015575Z","shell.execute_reply.started":"2023-05-01T17:32:34.480834Z","shell.execute_reply":"2023-05-01T17:37:58.014486Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Adam plot\npd.DataFrame(cnn_adam_history.history).plot(ylim = [0,1])","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:37:58.017781Z","iopub.execute_input":"2023-05-01T17:37:58.018697Z","iopub.status.idle":"2023-05-01T17:37:58.277517Z","shell.execute_reply.started":"2023-05-01T17:37:58.018655Z","shell.execute_reply":"2023-05-01T17:37:58.276536Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Experiment 2**: CNN Less Layers vs CNN More Layers vs Standard Dense\n","metadata":{}},{"cell_type":"code","source":"from functools import partial\n\nDefaultConv2D = partial(tf.keras.layers.Conv2D,\n                       kernel_size = 3,\n                       padding = 'same',\n                       activation = 'relu',\n                       kernel_initializer = 'he_normal')\n\ncnn_less = tf.keras.Sequential([\n    DefaultConv2D(filters = 64, kernel_size = 3, input_shape = [28, 28, 1]),\n    tf.keras.layers.MaxPool2D(),\n    DefaultConv2D(filters = 128),\n    tf.keras.layers.MaxPool2D(),\n    tf.keras.layers.Flatten(),\n    tf.keras.layers.Dense(units = 128, activation = 'relu', kernel_initializer = 'he_normal'),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(units = 64,  activation = 'relu', kernel_initializer = 'he_normal'),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(5, activation = 'softmax')\n])\n\ncnn_more = tf.keras.Sequential([\n    DefaultConv2D(filters = 64, kernel_size = 3, input_shape = [28, 28, 1]),\n    tf.keras.layers.MaxPool2D(),\n    DefaultConv2D(filters = 128),\n    tf.keras.layers.MaxPool2D(),\n    DefaultConv2D(filters = 256),\n    tf.keras.layers.MaxPool2D(),\n    DefaultConv2D(filters = 512),\n    tf.keras.layers.MaxPool2D(),\n    tf.keras.layers.Flatten(),\n    tf.keras.layers.Dense(units = 512, activation = 'relu', kernel_initializer = 'he_normal'),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(units = 256, activation = 'relu', kernel_initializer = 'he_normal'),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(units = 128, activation = 'relu', kernel_initializer = 'he_normal'),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(units = 64,  activation = 'relu', kernel_initializer = 'he_normal'),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(units = 32,  activation = 'relu', kernel_initializer = 'he_normal'),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(units = 16,  activation = 'relu', kernel_initializer = 'he_normal'),\n    tf.keras.layers.Dense(5, activation = 'softmax')\n])\n\ndense = tf.keras.Sequential([\n        tf.keras.layers.Flatten(input_shape = [28, 28]),\n        tf.keras.layers.Dense(512, activation = 'relu'),\n        tf.keras.layers.Dense(256, activation = 'relu'),\n        tf.keras.layers.Dense(64, activation = 'relu'),\n        tf.keras.layers.Dense(16, activation = 'relu'),\n        tf.keras.layers.Dense(5, activation = 'softmax')\n    ])\n\ncnn_less.summary()\ncnn_more.summary()\ndense.summary()","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:49:24.914417Z","iopub.execute_input":"2023-05-01T17:49:24.915143Z","iopub.status.idle":"2023-05-01T17:49:25.270106Z","shell.execute_reply.started":"2023-05-01T17:49:24.915102Z","shell.execute_reply":"2023-05-01T17:49:25.269223Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# CNN Less\ncnn_less.compile(loss = 'sparse_categorical_crossentropy',\n             optimizer = 'sgd',\n             metrics = ['accuracy'])\n\ncnn_less_history = cnn_less.fit(x_train, y_train, epochs=15, validation_data=(x_valid, y_valid))","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:37:58.689303Z","iopub.execute_input":"2023-05-01T17:37:58.689706Z","iopub.status.idle":"2023-05-01T17:40:01.785030Z","shell.execute_reply.started":"2023-05-01T17:37:58.689663Z","shell.execute_reply":"2023-05-01T17:40:01.783877Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# CNN Less plot\npd.DataFrame(cnn_less_history.history).plot(ylim = [0,1])","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:40:01.787285Z","iopub.execute_input":"2023-05-01T17:40:01.787770Z","iopub.status.idle":"2023-05-01T17:40:02.065025Z","shell.execute_reply.started":"2023-05-01T17:40:01.787729Z","shell.execute_reply":"2023-05-01T17:40:02.063918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# CNN More\ncnn_more.compile(loss = 'sparse_categorical_crossentropy',\n             optimizer = 'sgd',\n             metrics = ['accuracy'])\n\ncnn_more_history = cnn_more.fit(x_train, y_train, epochs=15, validation_data=(x_valid, y_valid))","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:49:31.415127Z","iopub.execute_input":"2023-05-01T17:49:31.416350Z","iopub.status.idle":"2023-05-01T17:52:39.229855Z","shell.execute_reply.started":"2023-05-01T17:49:31.416301Z","shell.execute_reply":"2023-05-01T17:52:39.228669Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# CNN More plot\npd.DataFrame(cnn_more_history.history).plot(ylim = [0,1])","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:53:49.926440Z","iopub.execute_input":"2023-05-01T17:53:49.927297Z","iopub.status.idle":"2023-05-01T17:53:50.208044Z","shell.execute_reply.started":"2023-05-01T17:53:49.927251Z","shell.execute_reply":"2023-05-01T17:53:50.206891Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Dense\ndense.compile(loss = 'sparse_categorical_crossentropy',\n             optimizer = 'sgd',\n             metrics = ['accuracy'])\n\ndense_history = dense.fit(x_train, y_train, epochs=15, validation_data=(x_valid, y_valid))","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:43:08.198818Z","iopub.execute_input":"2023-05-01T17:43:08.201297Z","iopub.status.idle":"2023-05-01T17:45:31.150628Z","shell.execute_reply.started":"2023-05-01T17:43:08.201252Z","shell.execute_reply":"2023-05-01T17:45:31.149470Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Dense plot\npd.DataFrame(dense_history.history).plot(ylim = [0,1])","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:45:31.153224Z","iopub.execute_input":"2023-05-01T17:45:31.153658Z","iopub.status.idle":"2023-05-01T17:45:31.434015Z","shell.execute_reply.started":"2023-05-01T17:45:31.153616Z","shell.execute_reply":"2023-05-01T17:45:31.432875Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Final Model**: CNN Less Layers with Adam optimizer\n","metadata":{}},{"cell_type":"code","source":"# Final Model\n\nfrom functools import partial\n\nDefaultConv2D = partial(tf.keras.layers.Conv2D,\n                       kernel_size = 3,\n                       padding = 'same',\n                       activation = 'relu',\n                       kernel_initializer = 'he_normal')\n\nfinal_model = tf.keras.Sequential([\n    DefaultConv2D(filters = 64, kernel_size = 3, input_shape = [28, 28, 1]),\n    tf.keras.layers.MaxPool2D(),\n    DefaultConv2D(filters = 128),\n    tf.keras.layers.MaxPool2D(),\n    tf.keras.layers.Flatten(),\n    tf.keras.layers.Dense(units = 128, activation = 'relu', kernel_initializer = 'he_normal'),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(units = 64,  activation = 'relu', kernel_initializer = 'he_normal'),\n    tf.keras.layers.Dropout(0.2),\n    tf.keras.layers.Dense(5, activation = 'softmax')\n])\n\nfinal_model.compile(loss = 'sparse_categorical_crossentropy',\n             optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),\n             metrics = ['accuracy'])\n\nfinal_model_history = final_model.fit(x_train, y_train, epochs=15, validation_data=(x_valid, y_valid))","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:59:08.929338Z","iopub.execute_input":"2023-05-01T17:59:08.930415Z","iopub.status.idle":"2023-05-01T18:01:14.946971Z","shell.execute_reply.started":"2023-05-01T17:59:08.930376Z","shell.execute_reply":"2023-05-01T18:01:14.945774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Final Model plot\npd.DataFrame(final_model_history.history).plot(ylim = [0,1])","metadata":{"execution":{"iopub.status.busy":"2023-05-01T18:01:14.949228Z","iopub.execute_input":"2023-05-01T18:01:14.949588Z","iopub.status.idle":"2023-05-01T18:01:15.216843Z","shell.execute_reply.started":"2023-05-01T18:01:14.949535Z","shell.execute_reply":"2023-05-01T18:01:15.215835Z"},"trusted":true},"execution_count":null,"outputs":[]}]}