{"metadata":{"colab":{"provenance":[]},"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.7.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"accelerator":"TPU","gpuClass":"standard"},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# import thư viện\n\n# Để 1 seed để có kết quả luôn giống nhau\nnr_seed = 2019\nimport numpy as np \nnp.random.seed(nr_seed)\nimport tensorflow as tf\ntf.random.set_seed(nr_seed)\nimport pandas as pd\n\nimport os, shutil\n\nimport cv2\n# from PIL import Image\n\n# import scipy\nimport matplotlib.pyplot as plt\n\nfrom keras import backend as K\n# from keras import layers\nfrom keras.applications.densenet import DenseNet121\nfrom keras.callbacks import Callback, ModelCheckpoint\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Sequential\nfrom keras.optimizers import Adam\n\n# from sklearn.model_selection import train_test_split\nfrom sklearn.metrics import cohen_kappa_score, accuracy_score\n\n\n%matplotlib inline","metadata":{"id":"zVDhJKYWFYWW","execution":{"iopub.status.busy":"2023-04-09T08:33:16.664384Z","iopub.execute_input":"2023-04-09T08:33:16.664905Z","iopub.status.idle":"2023-04-09T08:33:26.61051Z","shell.execute_reply.started":"2023-04-09T08:33:16.664862Z","shell.execute_reply":"2023-04-09T08:33:26.608966Z"},"trusted":true},"execution_count":1,"outputs":[]},{"cell_type":"code","source":"original_dataset_img_dir = '/kaggle/input/diabetic-retinopathy-resized/'\noriginal_dataset_label_dir =\"/kaggle/input/diabetic-retinopathy-resized/trainLabels.csv\"","metadata":{"id":"cIv4nT6pFoas","execution":{"iopub.status.busy":"2023-04-09T08:33:26.616929Z","iopub.execute_input":"2023-04-09T08:33:26.617868Z","iopub.status.idle":"2023-04-09T08:33:26.629723Z","shell.execute_reply.started":"2023-04-09T08:33:26.617802Z","shell.execute_reply":"2023-04-09T08:33:26.628565Z"},"trusted":true},"execution_count":2,"outputs":[]},{"cell_type":"code","source":"!pip install keras==2.9","metadata":{"id":"E5NWedb2GmJE","colab":{"base_uri":"https://localhost:8080/"},"outputId":"e6af765a-85fb-4704-a3b3-6fd8eda1a24f","execution":{"iopub.status.busy":"2023-04-09T08:33:26.631311Z","iopub.execute_input":"2023-04-09T08:33:26.632403Z","iopub.status.idle":"2023-04-09T08:33:39.575581Z","shell.execute_reply.started":"2023-04-09T08:33:26.632366Z","shell.execute_reply":"2023-04-09T08:33:39.57424Z"},"trusted":true},"execution_count":3,"outputs":[{"name":"stdout","text":"Collecting keras==2.9\n  Downloading keras-2.9.0-py2.py3-none-any.whl (1.6 MB)\n\u001b[2K     \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m1.6/1.6 MB\u001b[0m \u001b[31m33.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m\n\u001b[?25hInstalling collected packages: keras\n  Attempting uninstall: keras\n    Found existing installation: keras 2.11.0\n    Uninstalling keras-2.11.0:\n      Successfully uninstalled keras-2.11.0\n\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\ntensorflow 2.11.0 requires keras<2.12,>=2.11.0, but you have keras 2.9.0 which is incompatible.\ntensorflow 2.11.0 requires protobuf<3.20,>=3.9.2, but you have protobuf 3.20.3 which is incompatible.\ntensorflow-transform 1.12.0 requires pyarrow<7,>=6, but you have pyarrow 5.0.0 which is incompatible.\ntensorflow-serving-api 2.11.0 requires protobuf<3.20,>=3.9.2, but you have protobuf 3.20.3 which is incompatible.\u001b[0m\u001b[31m\n\u001b[0mSuccessfully installed keras-2.9.0\n\u001b[33mWARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv\u001b[0m\u001b[33m\n\u001b[0m","output_type":"stream"}]},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers","metadata":{"id":"0k1Peg_uFxgh","execution":{"iopub.status.busy":"2023-04-09T08:33:39.580105Z","iopub.execute_input":"2023-04-09T08:33:39.580475Z","iopub.status.idle":"2023-04-09T08:33:39.589761Z","shell.execute_reply.started":"2023-04-09T08:33:39.580412Z","shell.execute_reply":"2023-04-09T08:33:39.587488Z"},"trusted":true},"execution_count":4,"outputs":[]},{"cell_type":"code","source":"# import shutil\n\n# dir_path = '/kaggle/working/Small_data'\n\n# try:\n#     shutil.rmtree(dir_path)\n# except OSError as e:\n#     print(\"Error: %s : %s\" % (dir_path, e.strerror))","metadata":{"id":"HGtxzOx5jCYL","execution":{"iopub.status.busy":"2023-04-09T08:33:39.591507Z","iopub.execute_input":"2023-04-09T08:33:39.592304Z","iopub.status.idle":"2023-04-09T08:33:39.603139Z","shell.execute_reply.started":"2023-04-09T08:33:39.592265Z","shell.execute_reply":"2023-04-09T08:33:39.601922Z"},"trusted":true},"execution_count":5,"outputs":[]},{"cell_type":"code","source":"# import os, shutil\n# # dataset was uncompressed\n# original_dataset_dir = '/kaggle/input/diabetic-retinopathy-resized/resized_train/resized_train'\n# # The directory where we will\n# # store our smaller dataset\n# base_dir = '/kaggle/working/Small_data'\n# os.mkdir(base_dir)\n# # Directories for our training,\n# # validation and test splits\n# train_dir = os.path.join(base_dir, 'train')\n# os.mkdir(train_dir)\n# validation_dir = os.path.join(base_dir, 'validation')\n# os.mkdir(validation_dir)\n# test_dir = os.path.join(base_dir, 'test')\n# os.mkdir(test_dir)\n\n# # --------------------------------TẠO THƯ MỤC TRAIN-------------------------------------\n# # Directory with our training cat pictures\n# train_0_dir = os.path.join(train_dir, '0')\n# os.mkdir(train_0_dir)\n# # Directory with our training dog pictures\n# train_1_dir = os.path.join(train_dir, '1')\n# os.mkdir(train_1_dir)\n# # Directory with our training dog pictures\n# train_2_dir = os.path.join(train_dir, '2')\n# os.mkdir(train_2_dir)\n# # Directory with our training dog pictures\n# train_3_dir = os.path.join(train_dir, '3')\n# os.mkdir(train_3_dir)\n# # Directory with our training dog pictures\n# train_4_dir = os.path.join(train_dir, '4')\n# os.mkdir(train_4_dir)\n\n# # --------------------------------TẠO THƯ MỤC VALIDATION-------------------------------------\n# # Directory with our validationing cat pictures\n# validation_0_dir = os.path.join(validation_dir, '0')\n# os.mkdir(validation_0_dir)\n# # Directory with our validationing dog pictures\n# validation_1_dir = os.path.join(validation_dir, '1')\n# os.mkdir(validation_1_dir)\n# # Directory with our validationing dog pictures\n# validation_2_dir = os.path.join(validation_dir, '2')\n# os.mkdir(validation_2_dir)\n# # Directory with our validationing dog pictures\n# validation_3_dir = os.path.join(validation_dir, '3')\n# os.mkdir(validation_3_dir)\n# # Directory with our validationing dog pictures\n# validation_4_dir = os.path.join(validation_dir, '4')\n# os.mkdir(validation_4_dir)\n\n# # --------------------------------TẠO THƯ MỤC TEST-------------------------------------\n# # Directory with our validationing cat pictures\n# test_0_dir = os.path.join(test_dir, '0')\n# os.mkdir(test_0_dir)\n# # Directory with our testing dog pictures\n# test_1_dir = os.path.join(test_dir, '1')\n# os.mkdir(test_1_dir)\n# # Directory with our testing dog pictures\n# test_2_dir = os.path.join(test_dir, '2')\n# os.mkdir(test_2_dir)\n# # Directory with our testing dog pictures\n# test_3_dir = os.path.join(test_dir, '3')\n# os.mkdir(test_3_dir)\n# # Directory with our testing dog pictures\n# test_4_dir = os.path.join(test_dir, '4')\n# os.mkdir(test_4_dir)\n","metadata":{"id":"6rWbm1zoOc9t","execution":{"iopub.status.busy":"2023-04-09T08:33:39.605049Z","iopub.execute_input":"2023-04-09T08:33:39.605591Z","iopub.status.idle":"2023-04-09T08:33:39.614886Z","shell.execute_reply.started":"2023-04-09T08:33:39.605548Z","shell.execute_reply":"2023-04-09T08:33:39.613851Z"},"trusted":true},"execution_count":6,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv(original_dataset_label_dir)","metadata":{"id":"WTJ5eJoKhsb7","execution":{"iopub.status.busy":"2023-04-09T08:33:39.61682Z","iopub.execute_input":"2023-04-09T08:33:39.617182Z","iopub.status.idle":"2023-04-09T08:33:39.666159Z","shell.execute_reply.started":"2023-04-09T08:33:39.617147Z","shell.execute_reply":"2023-04-09T08:33:39.665003Z"},"trusted":true},"execution_count":7,"outputs":[]},{"cell_type":"code","source":"#Lưu đường dẫn thư mục ảnh vào label vào df\noriginal_dataset_img_dir = '/kaggle/input/diabetic-retinopathy-resized/resized_train/resized_train'\nAddress = []\n# df = pd.read_csv(original_dataset_label_dir)\nfor i in range(len(df)):\n  Add = (original_dataset_img_dir + '/' + str(df.loc[i,'image']) + '.jpeg')\n  Address.append(Add)\ndf['Address'] = Address\ndf = df.sample(frac = 1).reset_index(drop=True)","metadata":{"id":"rxwEXo5sQKl7","colab":{"base_uri":"https://localhost:8080/","height":423},"outputId":"1b964205-ee3f-43fe-b136-5bfb8e743b81","execution":{"iopub.status.busy":"2023-04-09T08:33:39.668124Z","iopub.execute_input":"2023-04-09T08:33:39.668962Z","iopub.status.idle":"2023-04-09T08:33:40.041709Z","shell.execute_reply.started":"2023-04-09T08:33:39.668909Z","shell.execute_reply":"2023-04-09T08:33:40.040652Z"},"trusted":true},"execution_count":8,"outputs":[]},{"cell_type":"code","source":"# im_size= 128\n# def display_samples(df, columns=5, rows=3):\n#     fig=plt.figure(figsize=(5*columns, 4*rows))\n\n    \n#     for i in range(0,15):\n#         image_path = df.loc[i,'Address']\n#         image_id = df.loc[i,'level']\n#         img = cv2.imread(f'{image_path}')\n#         img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n#         # img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n#         #img = crop_image_from_gray(img)\n#         img = cv2.resize(img, (im_size,im_size))\n#         img = cv2.addWeighted(img,4,cv2.GaussianBlur(img, (0,0), im_size/40) ,-4 ,128)\n        \n#         fig.add_subplot(rows, columns, i+1)\n#         plt.title(image_id)\n#         plt.imshow(img)\n    \n#     plt.tight_layout()\n\n# display_samples(df)","metadata":{"colab":{"base_uri":"https://localhost:8080/","height":570},"id":"4gZpX-JP_B9A","outputId":"d2d66ab8-ee4a-43c3-d66d-b47bf4cae38a","execution":{"iopub.status.busy":"2023-04-09T08:33:40.043359Z","iopub.execute_input":"2023-04-09T08:33:40.04381Z","iopub.status.idle":"2023-04-09T08:33:40.049849Z","shell.execute_reply.started":"2023-04-09T08:33:40.043766Z","shell.execute_reply":"2023-04-09T08:33:40.04855Z"},"trusted":true},"execution_count":9,"outputs":[]},{"cell_type":"code","source":"# #Lưu dữ liệu train vào từng mục\n# for class_id in sorted(df['level'].unique()):\n#   for i in range(28000):\n#     if df.loc[i,'level'] == class_id:\n#       src = os.path.join(df.loc[i,'Address'])\n#       fnames = str(df.loc[i,'image']) +\".jpeg\"\n#       if df.loc[i,'level'] == 0:\n#         dst = os.path.join(train_0_dir, fnames)\n#       if df.loc[i,'level'] == 1:\n#         dst = os.path.join(train_1_dir, fnames)\n#       if df.loc[i,'level'] == 2:\n#         dst = os.path.join(train_2_dir, fnames)\n#       if df.loc[i,'level'] == 3:\n#         dst = os.path.join(train_3_dir, fnames)\n#       if df.loc[i,'level'] == 4:\n#         dst = os.path.join(train_4_dir, fnames)\n#       shutil.copyfile(src, dst)","metadata":{"id":"AiH9kIp1SAUa","execution":{"iopub.status.busy":"2023-04-09T08:33:40.055348Z","iopub.execute_input":"2023-04-09T08:33:40.05683Z","iopub.status.idle":"2023-04-09T08:33:40.061865Z","shell.execute_reply.started":"2023-04-09T08:33:40.056792Z","shell.execute_reply":"2023-04-09T08:33:40.060654Z"},"trusted":true},"execution_count":10,"outputs":[]},{"cell_type":"code","source":"# #Lưu dữ liệu validation vào từng mục\n# for class_id in sorted(df['level'].unique()):\n#   for i in range(28001,34000):\n#     if df.loc[i,'level'] == class_id:\n#       src = os.path.join(df.loc[i,'Address'])\n#       fnames = str(df.loc[i,'image']) +\".jpeg\"\n#       if df.loc[i,'level'] == 0:\n#         dst = os.path.join(validation_0_dir, fnames)\n#       if df.loc[i,'level'] == 1:\n#         dst = os.path.join(validation_1_dir, fnames)\n#       if df.loc[i,'level'] == 2:\n#         dst = os.path.join(validation_2_dir, fnames)\n#       if df.loc[i,'level'] == 3:\n#         dst = os.path.join(validation_3_dir, fnames)\n#       if df.loc[i,'level'] == 4:\n#         dst = os.path.join(validation_4_dir, fnames)\n#       shutil.copyfile(src, dst)","metadata":{"id":"F6rfKXW1cC2T","execution":{"iopub.status.busy":"2023-04-09T08:33:40.063274Z","iopub.execute_input":"2023-04-09T08:33:40.06381Z","iopub.status.idle":"2023-04-09T08:33:40.072435Z","shell.execute_reply.started":"2023-04-09T08:33:40.063773Z","shell.execute_reply":"2023-04-09T08:33:40.071482Z"},"trusted":true},"execution_count":11,"outputs":[]},{"cell_type":"code","source":"# #Lưu dữ liệu validation vào từng mục\n# for class_id in sorted(df['level'].unique()):\n#   for i in range(34001,35000):\n#     if df.loc[i,'level'] == class_id:\n#       src = os.path.join(df.loc[i,'Address'])\n#       fnames = str(df.loc[i,'image']) +\".jpeg\"\n#       if df.loc[i,'level'] == 0:\n#         dst = os.path.join(test_0_dir, fnames)\n#       if df.loc[i,'level'] == 1:\n#         dst = os.path.join(test_1_dir, fnames)\n#       if df.loc[i,'level'] == 2:\n#         dst = os.path.join(test_2_dir, fnames)\n#       if df.loc[i,'level'] == 3:\n#         dst = os.path.join(test_3_dir, fnames)\n#       if df.loc[i,'level'] == 4:\n#         dst = os.path.join(test_4_dir, fnames)\n#       shutil.copyfile(src, dst)","metadata":{"id":"-LRNR5b5msXs","execution":{"iopub.status.busy":"2023-04-09T08:33:40.073919Z","iopub.execute_input":"2023-04-09T08:33:40.074381Z","iopub.status.idle":"2023-04-09T08:33:40.085569Z","shell.execute_reply.started":"2023-04-09T08:33:40.074319Z","shell.execute_reply":"2023-04-09T08:33:40.084387Z"},"trusted":true},"execution_count":12,"outputs":[]},{"cell_type":"code","source":"def crop_image1(img,tol=7):\n    # img is image data\n    # tol  is tolerance\n        \n    mask = img>tol\n    return img[np.ix_(mask.any(1),mask.any(0))]\n\ndef crop_image_from_gray(img,tol=7):\n    if img.ndim ==2:\n        mask = img>tol\n        return img[np.ix_(mask.any(1),mask.any(0))]\n    elif img.ndim==3:\n        gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)\n        mask = gray_img>tol\n        \n        check_shape = img[:,:,0][np.ix_(mask.any(1),mask.any(0))].shape[0]\n        if (check_shape == 0): # image is too dark so that we crop out everything,\n            return img # return original image\n        else:\n            img1=img[:,:,0][np.ix_(mask.any(1),mask.any(0))]\n            img2=img[:,:,1][np.ix_(mask.any(1),mask.any(0))]\n            img3=img[:,:,2][np.ix_(mask.any(1),mask.any(0))]\n            img = np.stack([img1,img2,img3],axis=-1)\n        return img\n\ndef preprocess_image(image_path, desired_size=224):\n    img = cv2.imread(image_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    img = crop_image_from_gray(img)\n    img = cv2.resize(img, (desired_size,desired_size))\n    img = cv2.addWeighted(img,4,cv2.GaussianBlur(img, (0,0), desired_size/30) ,-4 ,128)\n    \n    return img\n","metadata":{"id":"DTOzFvSx-5iW","execution":{"iopub.status.busy":"2023-04-09T08:33:40.087392Z","iopub.execute_input":"2023-04-09T08:33:40.087812Z","iopub.status.idle":"2023-04-09T08:33:40.10063Z","shell.execute_reply.started":"2023-04-09T08:33:40.087728Z","shell.execute_reply":"2023-04-09T08:33:40.099775Z"},"trusted":true},"execution_count":13,"outputs":[]},{"cell_type":"code","source":"# validation set\nim_size= 64\nN = df.loc[28001:34000].shape[0]\nx_val = np.empty((N, im_size, im_size, 3), dtype=np.uint8)\n\nfor i, image_id in enumerate(df['Address'].loc[28001:34000]):\n    x_val[i, :, :, :] = preprocess_image(\n        f'{image_id}',\n        desired_size = im_size\n    )","metadata":{"id":"7BSidvtODwD6","execution":{"iopub.status.busy":"2023-04-09T08:33:40.10212Z","iopub.execute_input":"2023-04-09T08:33:40.102769Z","iopub.status.idle":"2023-04-09T08:36:37.155022Z","shell.execute_reply.started":"2023-04-09T08:33:40.102735Z","shell.execute_reply":"2023-04-09T08:36:37.153875Z"},"trusted":true},"execution_count":14,"outputs":[]},{"cell_type":"code","source":"# train set\nim_size= 64\nN = df.loc[0:28000].shape[0]\nx_train_df = np.empty((N, im_size, im_size, 3), dtype=np.uint8)\n\nfor i, image_id in enumerate(df['Address'].loc[0:28000]):\n    x_train_df[i, :, :, :] = preprocess_image(\n        f'{image_id}',\n        desired_size = im_size\n    )","metadata":{"execution":{"iopub.status.busy":"2023-04-09T09:07:16.378037Z","iopub.execute_input":"2023-04-09T09:07:16.378815Z","iopub.status.idle":"2023-04-09T09:17:53.292042Z","shell.execute_reply.started":"2023-04-09T09:07:16.378765Z","shell.execute_reply":"2023-04-09T09:17:53.290918Z"},"trusted":true},"execution_count":36,"outputs":[]},{"cell_type":"code","source":"x_val.shape","metadata":{"execution":{"iopub.status.busy":"2023-04-09T08:36:37.157635Z","iopub.execute_input":"2023-04-09T08:36:37.157927Z","iopub.status.idle":"2023-04-09T08:36:37.168692Z","shell.execute_reply.started":"2023-04-09T08:36:37.1579Z","shell.execute_reply":"2023-04-09T08:36:37.167488Z"},"trusted":true},"execution_count":15,"outputs":[{"execution_count":15,"output_type":"execute_result","data":{"text/plain":"(6000, 64, 64, 3)"},"metadata":{}}]},{"cell_type":"code","source":"y_train = pd.get_dummies(df['level'].loc[0:28000]).values\ny_val = pd.get_dummies(df['level'].loc[28001:34000]).values","metadata":{"id":"C1wNOsAbMXiK","execution":{"iopub.status.busy":"2023-04-09T08:36:37.170649Z","iopub.execute_input":"2023-04-09T08:36:37.171576Z","iopub.status.idle":"2023-04-09T08:36:37.181616Z","shell.execute_reply.started":"2023-04-09T08:36:37.171536Z","shell.execute_reply":"2023-04-09T08:36:37.180644Z"},"trusted":true},"execution_count":16,"outputs":[]},{"cell_type":"code","source":"# print(y_train.shape)\n# print(x_val.shape)\n# print(y_val.shape)","metadata":{"execution":{"iopub.status.busy":"2023-04-09T08:36:37.182876Z","iopub.execute_input":"2023-04-09T08:36:37.183917Z","iopub.status.idle":"2023-04-09T08:36:37.187941Z","shell.execute_reply.started":"2023-04-09T08:36:37.183878Z","shell.execute_reply":"2023-04-09T08:36:37.186924Z"},"trusted":true},"execution_count":17,"outputs":[]},{"cell_type":"code","source":"y_train_multi = np.empty(y_train.shape, dtype=y_train.dtype)\ny_train_multi[:, 4] = y_train[:, 4]\n\nfor i in range(3, -1, -1):\n    y_train_multi[:, i] = np.logical_or(y_train[:, i], y_train_multi[:, i+1])\n\ny_val_multi = np.empty(y_val.shape, dtype=y_val.dtype)\ny_val_multi[:, 4] = y_val[:, 4]\n\nfor i in range(3, -1, -1):\n    y_val_multi[:, i] = np.logical_or(y_val[:, i], y_val_multi[:, i+1])\n\n# print(\"Y_train multi: {}\".format(y_train_multi.shape))\n# print(\"Y_val multi: {}\".format(y_val_multi.shape))","metadata":{"id":"LI6cy0cVNWSF","execution":{"iopub.status.busy":"2023-04-09T08:36:37.189613Z","iopub.execute_input":"2023-04-09T08:36:37.190347Z","iopub.status.idle":"2023-04-09T08:36:37.199526Z","shell.execute_reply.started":"2023-04-09T08:36:37.190308Z","shell.execute_reply":"2023-04-09T08:36:37.198243Z"},"trusted":true},"execution_count":18,"outputs":[]},{"cell_type":"code","source":"y_train = y_train_multi\ny_val = y_val_multi","metadata":{"id":"NI5CbOVTNcmW","execution":{"iopub.status.busy":"2023-04-09T08:36:37.201285Z","iopub.execute_input":"2023-04-09T08:36:37.20168Z","iopub.status.idle":"2023-04-09T08:36:37.211349Z","shell.execute_reply.started":"2023-04-09T08:36:37.201644Z","shell.execute_reply":"2023-04-09T08:36:37.210342Z"},"trusted":true},"execution_count":19,"outputs":[]},{"cell_type":"code","source":"class Metrics(Callback):\n\n    def on_epoch_end(self, epoch, logs={}):\n        X_val, y_val = self.validation_data[:2]\n        y_val = y_val.sum(axis=1) - 1\n        \n        y_pred = self.model.predict(X_val) > 0.5\n        y_pred = y_pred.astype(int).sum(axis=1) - 1\n\n        _val_kappa = cohen_kappa_score(\n            y_val,\n            y_pred, \n            weights='quadratic'\n        )\n\n        self.val_kappas.append(_val_kappa)\n\n        print(f\"val_kappa: {_val_kappa:.4f}\")\n        \n        if _val_kappa == max(self.val_kappas):\n            print(\"Validation Kappa has improved. Saving model.\")\n            self.model.save('model.h5')\n\n        return","metadata":{"execution":{"iopub.status.busy":"2023-04-09T08:36:37.213395Z","iopub.execute_input":"2023-04-09T08:36:37.213774Z","iopub.status.idle":"2023-04-09T08:36:37.222832Z","shell.execute_reply.started":"2023-04-09T08:36:37.213738Z","shell.execute_reply":"2023-04-09T08:36:37.221701Z"},"trusted":true},"execution_count":20,"outputs":[]},{"cell_type":"code","source":"def create_datagen():\n    return ImageDataGenerator(\n        featurewise_std_normalization = True,\n        horizontal_flip = True,\n        vertical_flip = True,\n        rotation_range = 360\n    )","metadata":{"execution":{"iopub.status.busy":"2023-04-09T08:36:37.224699Z","iopub.execute_input":"2023-04-09T08:36:37.225113Z","iopub.status.idle":"2023-04-09T08:36:37.23379Z","shell.execute_reply.started":"2023-04-09T08:36:37.225053Z","shell.execute_reply":"2023-04-09T08:36:37.232839Z"},"trusted":true},"execution_count":21,"outputs":[]},{"cell_type":"code","source":"bucket_num = 8\ndiv = round(df.loc[0:28000].shape[0]/bucket_num)","metadata":{"execution":{"iopub.status.busy":"2023-04-09T08:36:37.235616Z","iopub.execute_input":"2023-04-09T08:36:37.235998Z","iopub.status.idle":"2023-04-09T08:36:37.24429Z","shell.execute_reply.started":"2023-04-09T08:36:37.235963Z","shell.execute_reply":"2023-04-09T08:36:37.243298Z"},"trusted":true},"execution_count":22,"outputs":[]},{"cell_type":"code","source":"df_init = {\n    'val_loss': [0.0],\n    'val_acc': [0.0],\n    'loss': [0.0], \n    'acc': [0.0],\n    'bucket': [0.0]\n}\nresults = pd.DataFrame(df_init)","metadata":{"execution":{"iopub.status.busy":"2023-04-09T08:36:37.246112Z","iopub.execute_input":"2023-04-09T08:36:37.246487Z","iopub.status.idle":"2023-04-09T08:36:37.255329Z","shell.execute_reply.started":"2023-04-09T08:36:37.246452Z","shell.execute_reply":"2023-04-09T08:36:37.254318Z"},"trusted":true},"execution_count":23,"outputs":[]},{"cell_type":"code","source":"# I found that changing the nr. of epochs for each bucket helped in terms of performances\nepochs = [5,5,10,15,15,20,20,30]\nkappa_metrics = Metrics()\nkappa_metrics.val_kappas = []","metadata":{"execution":{"iopub.status.busy":"2023-04-09T08:36:37.257192Z","iopub.execute_input":"2023-04-09T08:36:37.257657Z","iopub.status.idle":"2023-04-09T08:36:37.265922Z","shell.execute_reply.started":"2023-04-09T08:36:37.257616Z","shell.execute_reply":"2023-04-09T08:36:37.264851Z"},"trusted":true},"execution_count":24,"outputs":[]},{"cell_type":"code","source":"# shutil.rmtree(densenet_keras_dir)\n# densenet_keras_dir = os.path.join(base_dir, 'densenet')\n# os.mkdir(densenet_keras_dir)\n","metadata":{"execution":{"iopub.status.busy":"2023-04-09T08:36:37.267269Z","iopub.execute_input":"2023-04-09T08:36:37.267578Z","iopub.status.idle":"2023-04-09T08:36:37.275571Z","shell.execute_reply.started":"2023-04-09T08:36:37.267549Z","shell.execute_reply":"2023-04-09T08:36:37.27455Z"},"trusted":true},"execution_count":25,"outputs":[]},{"cell_type":"code","source":"im_size = 64\ndensenet = DenseNet121(\n    weights= \"/kaggle/input/densenet-keras/DenseNet-BC-121-32-no-top.h5\",\n    include_top=False,\n    input_shape=(im_size,im_size,3)\n)","metadata":{"execution":{"iopub.status.busy":"2023-04-09T08:36:37.276892Z","iopub.execute_input":"2023-04-09T08:36:37.277171Z","iopub.status.idle":"2023-04-09T08:36:45.606237Z","shell.execute_reply.started":"2023-04-09T08:36:37.277144Z","shell.execute_reply":"2023-04-09T08:36:45.604974Z"},"trusted":true},"execution_count":26,"outputs":[]},{"cell_type":"code","source":"from tqdm import *\nfrom tqdm.notebook import tqdm","metadata":{"execution":{"iopub.status.busy":"2023-04-09T08:36:45.608105Z","iopub.execute_input":"2023-04-09T08:36:45.60852Z","iopub.status.idle":"2023-04-09T08:36:45.729359Z","shell.execute_reply.started":"2023-04-09T08:36:45.608478Z","shell.execute_reply":"2023-04-09T08:36:45.728372Z"},"trusted":true},"execution_count":27,"outputs":[]},{"cell_type":"code","source":"from keras import layers\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Dropout, Flatten\nfrom keras.layers.convolutional import Conv2D, MaxPooling2D\nfrom tensorflow.keras.optimizers import Adam\ndef build_model():\n    model = Sequential()\n    model.add(densenet)\n    model.add(layers.GlobalAveragePooling2D())\n    model.add(layers.Dropout(0.5))\n    model.add(layers.Dense(5, activation='sigmoid'))\n    \n    model.compile(\n        loss='binary_crossentropy',\n        optimizer = Adam(learning_rate=0.0001),\n        metrics=['accuracy']\n    )\n    \n    return model","metadata":{"execution":{"iopub.status.busy":"2023-04-09T08:36:45.739027Z","iopub.execute_input":"2023-04-09T08:36:45.74189Z","iopub.status.idle":"2023-04-09T08:36:45.752237Z","shell.execute_reply.started":"2023-04-09T08:36:45.74185Z","shell.execute_reply":"2023-04-09T08:36:45.751346Z"},"trusted":true},"execution_count":28,"outputs":[]},{"cell_type":"code","source":"model = build_model()\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-04-09T08:36:45.756886Z","iopub.execute_input":"2023-04-09T08:36:45.759457Z","iopub.status.idle":"2023-04-09T08:36:46.863616Z","shell.execute_reply.started":"2023-04-09T08:36:45.759382Z","shell.execute_reply":"2023-04-09T08:36:46.862495Z"},"trusted":true},"execution_count":29,"outputs":[{"name":"stdout","text":"Model: \"sequential\"\n_________________________________________________________________\n Layer (type)                Output Shape              Param #   \n=================================================================\n densenet121 (Functional)    (None, 2, 2, 1024)        7037504   \n                                                                 \n global_average_pooling2d (G  (None, 1024)             0         \n lobalAveragePooling2D)                                          \n                                                                 \n dropout (Dropout)           (None, 1024)              0         \n                                                                 \n dense (Dense)               (None, 5)                 5125      \n                                                                 \n=================================================================\nTotal params: 7,042,629\nTrainable params: 6,958,981\nNon-trainable params: 83,648\n_________________________________________________________________\n","output_type":"stream"}]},{"cell_type":"code","source":"y_train.shape","metadata":{"execution":{"iopub.status.busy":"2023-04-09T08:36:46.864931Z","iopub.execute_input":"2023-04-09T08:36:46.865937Z","iopub.status.idle":"2023-04-09T08:36:46.873478Z","shell.execute_reply.started":"2023-04-09T08:36:46.865895Z","shell.execute_reply":"2023-04-09T08:36:46.87217Z"},"trusted":true},"execution_count":30,"outputs":[{"execution_count":30,"output_type":"execute_result","data":{"text/plain":"(28001, 5)"},"metadata":{}}]},{"cell_type":"code","source":"df.shape","metadata":{"execution":{"iopub.status.busy":"2023-04-09T08:39:57.037297Z","iopub.execute_input":"2023-04-09T08:39:57.038064Z","iopub.status.idle":"2023-04-09T08:39:57.048598Z","shell.execute_reply.started":"2023-04-09T08:39:57.038025Z","shell.execute_reply":"2023-04-09T08:39:57.047353Z"},"trusted":true},"execution_count":32,"outputs":[{"execution_count":32,"output_type":"execute_result","data":{"text/plain":"(35126, 3)"},"metadata":{}}]},{"cell_type":"code","source":"x_train.shape","metadata":{"execution":{"iopub.status.busy":"2023-04-09T09:23:38.23546Z","iopub.execute_input":"2023-04-09T09:23:38.235819Z","iopub.status.idle":"2023-04-09T09:23:38.243702Z","shell.execute_reply.started":"2023-04-09T09:23:38.235787Z","shell.execute_reply":"2023-04-09T09:23:38.242256Z"},"trusted":true},"execution_count":38,"outputs":[{"execution_count":38,"output_type":"execute_result","data":{"text/plain":"(28001, 64, 64, 3)"},"metadata":{}}]},{"cell_type":"code","source":"BATCH_SIZE = 32\nfor i in range(0,bucket_num):\n    if i != (bucket_num-1):\n        print(\"Bucket Nr: {}\".format(i))\n        N = ((df.shape[0] // bucket_num) // BATCH_SIZE) * BATCH_SIZE  # Số mẫu huấn luyện là bội số của BATCH_SIZE\n\n        x_train = np.empty((N, im_size, im_size, 3), dtype=np.uint8)\n        for j, image_id in enumerate(tqdm(df['Address'].loc[i*div:i*div+N-1])):\n            x_train[j, :, :, :] = preprocess_image(f'{image_id}', desired_size=im_size)\n\n        data_generator = create_datagen().flow(x_train, y_train[i*div:i*div+N,:], batch_size=BATCH_SIZE)\n        history = model.fit_generator(\n                        data_generator,\n                        steps_per_epoch=N // BATCH_SIZE,  # Số bước trên một epoch\n                        epochs=epochs[i],\n                        validation_data=(x_val, y_val),\n                        callbacks=[]\n                        )\n\n        dic = history.history\n        df_model = pd.DataFrame(dic)\n        df_model['bucket'] = i\n    else:\n        print(\"Bucket Nr: {}\".format(i))\n        N = df[i*div:].shape[0]\n        \n        # Tương tự, sửa lại N thành một số chia hết cho BATCH_SIZE\n        N = ((N // BATCH_SIZE) // BATCH_SIZE) * BATCH_SIZE\n        x_train = np.empty((N, im_size, im_size, 3), dtype=np.uint8)\n        for j, image_id in enumerate(tqdm(df['Address'].loc[i*div:i*div+N-1])):\n            x_train[j, :, :, :] = preprocess_image(f'{image_id}', desired_size = im_size)\n        data_generator = create_datagen().flow(x_train, y_train[i*div:i*div+N,:], batch_size=BATCH_SIZE)\n\n        history = model.fit_generator(\n                        data_generator,\n                        steps_per_epoch=N // BATCH_SIZE,\n                        epochs=epochs[i],\n                        validation_data=(x_val, y_val),\n                        callbacks=[]\n                        )\n\n        dic = history.history\n        df_model = pd.DataFrame(dic)\n        df_model['bucket'] = i\n\n    results = results.append(df_model)\n\n    del data_generator\n    del x_train\n\n    print('-'*40)\n","metadata":{"execution":{"iopub.status.busy":"2023-04-09T09:23:50.018114Z","iopub.execute_input":"2023-04-09T09:23:50.018496Z"},"trusted":true},"execution_count":null,"outputs":[{"name":"stdout","text":"Bucket Nr: 0\n","output_type":"stream"},{"output_type":"display_data","data":{"text/plain":"  0%|          | 0/4384 [00:00<?, ?it/s]","application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"bcd010cfb836485cb163bfc97f48bd7d"}},"metadata":{}},{"name":"stderr","text":"/opt/conda/lib/python3.7/site-packages/ipykernel_launcher.py:17: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.\n  app.launch_new_instance()\n/opt/conda/lib/python3.7/site-packages/keras/preprocessing/image.py:1862: UserWarning: This ImageDataGenerator specifies `featurewise_center`, but it hasn't been fit on any training data. Fit it first by calling `.fit(numpy_data)`.\n  augment: Boolean (default: False).\n/opt/conda/lib/python3.7/site-packages/keras/preprocessing/image.py:1872: UserWarning: This ImageDataGenerator specifies `featurewise_std_normalization`, but it hasn't been fit on any training data. Fit it first by calling `.fit(numpy_data)`.\n  'Got array with shape: ' + str(x.shape))\n","output_type":"stream"},{"name":"stdout","text":"Epoch 1/5\nWARNING: AutoGraph could not transform <function Model.make_train_function.<locals>.train_function at 0x73c28cb3e680> and will run it as-is.\nPlease report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.\nCause: closure mismatch, requested ('self', 'step_function'), but source function had ()\nTo silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert\n137/137 [==============================] - ETA: 0s - loss: 0.6247 - accuracy: 0.6937WARNING: AutoGraph could not transform <function Model.make_test_function.<locals>.test_function at 0x73befd0e1c20> and will run it as-is.\nPlease report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.\nCause: closure mismatch, requested ('self', 'step_function'), but source function had ()\nTo silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert\n137/137 [==============================] - 43s 150ms/step - loss: 0.6247 - accuracy: 0.6937 - val_loss: 0.3468 - val_accuracy: 1.0000\nEpoch 2/5\n137/137 [==============================] - 15s 113ms/step - loss: 0.3521 - accuracy: 0.9877 - val_loss: 0.2987 - val_accuracy: 1.0000\nEpoch 3/5\n137/137 [==============================] - 16s 116ms/step - loss: 0.3241 - accuracy: 0.9966 - val_loss: 0.2803 - val_accuracy: 1.0000\nEpoch 4/5\n137/137 [==============================] - 15s 113ms/step - loss: 0.3118 - accuracy: 0.9989 - val_loss: 0.2861 - val_accuracy: 1.0000\nEpoch 5/5\n137/137 [==============================] - 16s 118ms/step - loss: 0.3020 - accuracy: 0.9991 - val_loss: 0.2691 - val_accuracy: 1.0000\n----------------------------------------\nBucket Nr: 1\n","output_type":"stream"},{"output_type":"display_data","data":{"text/plain":"  0%|          | 0/4384 [00:00<?, ?it/s]","application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"cb7e362d1f2c481abe61110316aa1573"}},"metadata":{}},{"name":"stdout","text":"Epoch 1/5\n137/137 [==============================] - 18s 129ms/step - loss: 0.2892 - accuracy: 0.9993 - val_loss: 0.2793 - val_accuracy: 1.0000\nEpoch 2/5\n137/137 [==============================] - 17s 126ms/step - loss: 0.2850 - accuracy: 0.9998 - val_loss: 0.2852 - val_accuracy: 1.0000\nEpoch 3/5\n137/137 [==============================] - 18s 132ms/step - loss: 0.2803 - accuracy: 0.9998 - val_loss: 0.2681 - val_accuracy: 1.0000\nEpoch 4/5\n137/137 [==============================] - 16s 113ms/step - loss: 0.2692 - accuracy: 1.0000 - val_loss: 0.2800 - val_accuracy: 1.0000\nEpoch 5/5\n137/137 [==============================] - 18s 132ms/step - loss: 0.2682 - accuracy: 0.9998 - val_loss: 0.2988 - val_accuracy: 1.0000\n----------------------------------------\nBucket Nr: 2\n","output_type":"stream"},{"output_type":"display_data","data":{"text/plain":"  0%|          | 0/4384 [00:00<?, ?it/s]","application/vnd.jupyter.widget-view+json":{"version_major":2,"version_minor":0,"model_id":"67737ac4f28744628d1bcf6789dd08a1"}},"metadata":{}},{"name":"stdout","text":"Epoch 1/10\n137/137 [==============================] - 18s 129ms/step - loss: 0.2569 - accuracy: 1.0000 - val_loss: 0.4687 - val_accuracy: 1.0000\nEpoch 2/10\n137/137 [==============================] - 15s 111ms/step - loss: 0.2566 - accuracy: 1.0000 - val_loss: 0.2684 - val_accuracy: 1.0000\nEpoch 3/10\n137/137 [==============================] - 17s 126ms/step - loss: 0.2572 - accuracy: 1.0000 - val_loss: 0.2524 - val_accuracy: 1.0000\nEpoch 4/10\n137/137 [==============================] - 15s 113ms/step - loss: 0.2515 - accuracy: 1.0000 - val_loss: 0.3648 - val_accuracy: 1.0000\nEpoch 5/10\n137/137 [==============================] - 17s 127ms/step - loss: 0.2544 - accuracy: 1.0000 - val_loss: 0.2810 - val_accuracy: 1.0000\nEpoch 6/10\n 61/137 [============>.................] - ETA: 6s - loss: 0.2555 - accuracy: 1.0000","output_type":"stream"}]},{"cell_type":"code","source":"results = results.iloc[1:]\nresults['kappa'] = kappa_metrics.val_kappas\nresults = results.reset_index()\nresults = results.rename(index=str, columns={\"index\": \"epoch\"})\nresults","metadata":{"execution":{"iopub.status.busy":"2023-04-09T08:36:54.078415Z","iopub.status.idle":"2023-04-09T08:36:54.078943Z","shell.execute_reply.started":"2023-04-09T08:36:54.078682Z","shell.execute_reply":"2023-04-09T08:36:54.078709Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Add our data-augmentation parameters to ImageDataGenerator\n\n# train_datagen = ImageDataGenerator(rescale = 1./255., rotation_range = 40, width_shift_range = 0.2, height_shift_range = 0.2, shear_range = 0.2, zoom_range = 0.2, horizontal_flip = True)\n\n# test_datagen = ImageDataGenerator(rescale = 1.0/255.)\n\n# train_generator = train_datagen.flow_from_directory(train_dir, batch_size = 20, class_mode = 'binary', target_size = (224, 224))\n\n# validation_generator = test_datagen.flow_from_directory( validation_dir, batch_size = 20, class_mode = 'binary', target_size = (224, 224))","metadata":{"id":"pDqGnoSpF3Gq","colab":{"base_uri":"https://localhost:8080/"},"outputId":"b5b98c90-9910-40e2-8ceb-298937f93e8d","execution":{"iopub.status.busy":"2023-04-09T08:36:54.08102Z","iopub.status.idle":"2023-04-09T08:36:54.081588Z","shell.execute_reply.started":"2023-04-09T08:36:54.081319Z","shell.execute_reply":"2023-04-09T08:36:54.081345Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !pip install efficientnet","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"TjlUehRKnwDq","outputId":"be5910eb-bab1-4589-d1ec-bd62d43789b0","execution":{"iopub.status.busy":"2023-04-09T08:36:54.083417Z","iopub.status.idle":"2023-04-09T08:36:54.08394Z","shell.execute_reply.started":"2023-04-09T08:36:54.083679Z","shell.execute_reply":"2023-04-09T08:36:54.083704Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import efficientnet.keras as efn","metadata":{"id":"GpNn-rfqnt1Y","execution":{"iopub.status.busy":"2023-04-09T08:36:54.085735Z","iopub.status.idle":"2023-04-09T08:36:54.086269Z","shell.execute_reply.started":"2023-04-09T08:36:54.085996Z","shell.execute_reply":"2023-04-09T08:36:54.086023Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# base_model = efn.EfficientNetB0(input_shape = (224, 224, 3), include_top = False, weights = 'imagenet')","metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"JUmlg8MFnjst","outputId":"1eb77cb0-16dc-4377-bcc3-d6dfbb2d31f4","execution":{"iopub.status.busy":"2023-04-09T08:36:54.08811Z","iopub.status.idle":"2023-04-09T08:36:54.088631Z","shell.execute_reply.started":"2023-04-09T08:36:54.088353Z","shell.execute_reply":"2023-04-09T08:36:54.088379Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# for layer in base_model.layers:\n#     layer.trainable = False","metadata":{"id":"e9kfj7fUn-ae","execution":{"iopub.status.busy":"2023-04-09T08:36:54.097061Z","iopub.status.idle":"2023-04-09T08:36:54.097656Z","shell.execute_reply.started":"2023-04-09T08:36:54.097381Z","shell.execute_reply":"2023-04-09T08:36:54.097407Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from keras.layers.convolutional import Conv2D, MaxPooling2D\n# from keras.models import Sequential\n# from keras.layers import Dense, Activation, Flatten, Dropout\n# from tensorflow.keras import Model\n# from keras import optimizers","metadata":{"id":"CVMgEfBco1rV","execution":{"iopub.status.busy":"2023-04-09T08:36:54.099544Z","iopub.status.idle":"2023-04-09T08:36:54.100614Z","shell.execute_reply.started":"2023-04-09T08:36:54.10028Z","shell.execute_reply":"2023-04-09T08:36:54.100314Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# x = base_model.output\n# x = Flatten()(x)\n# x = Dense(1024, activation=\"relu\")(x)\n# x = Dropout(0.5)(x)\n\n# # Add a final sigmoid layer with 1 node for classification output\n# predictions = Dense(1, activation=\"sigmoid\")(x)\n# model_final = tf.keras.models.Model(base_model.input, predictions)\n# # model_final = Model(inputs = base_model.input, output = predictions)","metadata":{"id":"xtXOaC5XoBR1","execution":{"iopub.status.busy":"2023-04-09T08:36:54.10222Z","iopub.status.idle":"2023-04-09T08:36:54.103198Z","shell.execute_reply.started":"2023-04-09T08:36:54.10292Z","shell.execute_reply":"2023-04-09T08:36:54.102951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model_final.compile(optimizers.RMSprop(lr=0.0001, decay=1e-6),loss='binary_crossentropy',metrics=['accuracy'])","metadata":{"id":"6RbbJLjqqpxF","colab":{"base_uri":"https://localhost:8080/"},"outputId":"ad4cac40-7494-4f25-ed51-4b41f75987ae","execution":{"iopub.status.busy":"2023-04-09T08:36:54.104855Z","iopub.status.idle":"2023-04-09T08:36:54.105386Z","shell.execute_reply.started":"2023-04-09T08:36:54.105115Z","shell.execute_reply":"2023-04-09T08:36:54.105142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# eff_history = model_final.fit_generator(train_generator, validation_data = validation_generator, steps_per_epoch = 100, epochs = 10)\n","metadata":{"id":"HSV8xI2JqsEI","colab":{"base_uri":"https://localhost:8080/","height":567},"outputId":"d567b25a-1017-47e0-d6eb-9b0c0b3f72d5","execution":{"iopub.status.busy":"2023-04-09T08:36:54.107335Z","iopub.status.idle":"2023-04-09T08:36:54.107885Z","shell.execute_reply.started":"2023-04-09T08:36:54.107607Z","shell.execute_reply":"2023-04-09T08:36:54.107634Z"},"trusted":true},"execution_count":null,"outputs":[]}]}