{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"<div align=\"center\"><h1><blod>Detección de fracturas de la columna cervical mediante técnicas de aprendizaje automático</blod></h1></div>\n\n<br>\n\n<div align=\"center\"><h2>TRABAJO FIN DE GRADO</h2></div>\n<div align=\"center\"><h3>2022-2023</h3></div>\n\n<br>\n\n<div align=\"center\"><h2>Domingo José Caballero Navarro</h2></div>\n\n<br>\n\n<div align=\"center\"><h2>Tutorizado por:</h2></div>\n\n<div align=\"center\"><h3>José Antonio Gámez Martín</h3></div>\n<div align=\"center\"><h3>Juan Carlos Alfaro Jiménez</h3></div>","metadata":{}},{"cell_type":"markdown","source":"---","metadata":{}},{"cell_type":"markdown","source":"## Índice\n1. **[Datos necesarios](#datos)**\n    \n2. **[Diseño del modelo](#modelo)**\n\n3. **[Resultados y discusión](#resultados)**\n\n---","metadata":{}},{"cell_type":"markdown","source":"# 1. Datos necesarios <a name=\"datos\"></a>\n<div align=\"justify\">Hola</div>\n","metadata":{}},{"cell_type":"code","source":"! pip install python-gdcm\n! pip install pylibjpeg pylibjpeg-libjpeg pydicom\n! pip install vit-keras","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:11:43.690427Z","iopub.execute_input":"2023-05-16T21:11:43.690757Z","iopub.status.idle":"2023-05-16T21:12:23.465477Z","shell.execute_reply.started":"2023-05-16T21:11:43.690685Z","shell.execute_reply":"2023-05-16T21:12:23.464316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"seed = 270221","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:29.882423Z","iopub.execute_input":"2023-05-16T21:12:29.882858Z","iopub.status.idle":"2023-05-16T21:12:29.889084Z","shell.execute_reply.started":"2023-05-16T21:12:29.882817Z","shell.execute_reply":"2023-05-16T21:12:29.887975Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:30.454167Z","iopub.execute_input":"2023-05-16T21:12:30.455098Z","iopub.status.idle":"2023-05-16T21:12:34.928326Z","shell.execute_reply.started":"2023-05-16T21:12:30.45505Z","shell.execute_reply":"2023-05-16T21:12:34.927321Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device_type = \"GPU\"  # The device type\ndevices = tf.config.list_physical_devices(device_type)\n\nif not devices:\n    # Raise an informative message when there are no devices in the host runtime\n    raise RuntimeError(f\"No {device_type} devices are used in the host.\")","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:34.930974Z","iopub.execute_input":"2023-05-16T21:12:34.931906Z","iopub.status.idle":"2023-05-16T21:12:35.098421Z","shell.execute_reply.started":"2023-05-16T21:12:34.931863Z","shell.execute_reply":"2023-05-16T21:12:35.097336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\n\ndata_df = pd.read_csv(\"../input/rsna-2022-cervical-spine-fracture-detection/train.csv\")","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:35.100429Z","iopub.execute_input":"2023-05-16T21:12:35.100763Z","iopub.status.idle":"2023-05-16T21:12:35.121818Z","shell.execute_reply.started":"2023-05-16T21:12:35.100733Z","shell.execute_reply":"2023-05-16T21:12:35.120932Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\ntrain_df, test_df = train_test_split(data_df, test_size=0.1, stratify=data_df.patient_overall, random_state=seed)","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:35.1244Z","iopub.execute_input":"2023-05-16T21:12:35.124853Z","iopub.status.idle":"2023-05-16T21:12:35.433963Z","shell.execute_reply.started":"2023-05-16T21:12:35.124817Z","shell.execute_reply":"2023-05-16T21:12:35.432995Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Train: \", train_df.shape)\nprint(\"Test: \", test_df.shape)","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:35.435349Z","iopub.execute_input":"2023-05-16T21:12:35.435822Z","iopub.status.idle":"2023-05-16T21:12:35.443478Z","shell.execute_reply.started":"2023-05-16T21:12:35.435779Z","shell.execute_reply":"2023-05-16T21:12:35.442283Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df_t1 = train_df[:360]","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:35.445495Z","iopub.execute_input":"2023-05-16T21:12:35.44639Z","iopub.status.idle":"2023-05-16T21:12:35.451741Z","shell.execute_reply.started":"2023-05-16T21:12:35.446302Z","shell.execute_reply":"2023-05-16T21:12:35.450422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df_t1, val_df_t1 = train_test_split(train_df_t1, test_size=0.1, stratify=train_df_t1.patient_overall, random_state=seed)","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:35.453198Z","iopub.execute_input":"2023-05-16T21:12:35.454294Z","iopub.status.idle":"2023-05-16T21:12:35.463845Z","shell.execute_reply.started":"2023-05-16T21:12:35.454254Z","shell.execute_reply":"2023-05-16T21:12:35.462657Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df_t1.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:35.465204Z","iopub.execute_input":"2023-05-16T21:12:35.46564Z","iopub.status.idle":"2023-05-16T21:12:35.485581Z","shell.execute_reply.started":"2023-05-16T21:12:35.465585Z","shell.execute_reply":"2023-05-16T21:12:35.484558Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os \nfrom os import listdir\n\npath = \"../input/rsna-2022-cervical-spine-fracture-detection\"\npath_train_images = os.path.join(path, \"train_images\")\npath_segmentations = os.path.join(path, \"segmentations\")","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:35.486923Z","iopub.execute_input":"2023-05-16T21:12:35.487448Z","iopub.status.idle":"2023-05-16T21:12:35.492898Z","shell.execute_reply.started":"2023-05-16T21:12:35.487411Z","shell.execute_reply":"2023-05-16T21:12:35.491894Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"metadata_df = pd.read_csv(\"../input/explicacionrsna/metadata_df.csv\")","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:35.497032Z","iopub.execute_input":"2023-05-16T21:12:35.497712Z","iopub.status.idle":"2023-05-16T21:12:37.513123Z","shell.execute_reply.started":"2023-05-16T21:12:35.497674Z","shell.execute_reply":"2023-05-16T21:12:37.512084Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"metadata_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:37.51466Z","iopub.execute_input":"2023-05-16T21:12:37.515028Z","iopub.status.idle":"2023-05-16T21:12:37.53283Z","shell.execute_reply.started":"2023-05-16T21:12:37.51499Z","shell.execute_reply":"2023-05-16T21:12:37.531698Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<div align=\"justify\">En este caso podemos apreciar la forma de la vértebra, en este caso podemos apreciar cómo esta mínimamente desplaza hacía arriba. Teniendo esto en cuenta, deberemos comprobar con otros ejemplos si esto sucede también en los demás pacientes dado que de ser negativo tendríamos que centrar todas las imágenes. Por lo tanto, comprobaremos el segundo paciente del conjunto de entrenamiento.</div>","metadata":{}},{"cell_type":"code","source":"train_df_t1.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:37.534116Z","iopub.execute_input":"2023-05-16T21:12:37.535062Z","iopub.status.idle":"2023-05-16T21:12:37.549429Z","shell.execute_reply.started":"2023-05-16T21:12:37.535015Z","shell.execute_reply":"2023-05-16T21:12:37.548571Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Preprocesamiento","metadata":{}},{"cell_type":"code","source":"train_segmented = pd.read_csv(\"../input/segmentation/train_segmented.csv\")","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:37.550754Z","iopub.execute_input":"2023-05-16T21:12:37.55119Z","iopub.status.idle":"2023-05-16T21:12:40.875205Z","shell.execute_reply.started":"2023-05-16T21:12:37.551152Z","shell.execute_reply":"2023-05-16T21:12:40.874153Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_segmented = train_segmented[['SOPInstanceUID','C1','C2','C3','C4','C5','C6','C7']]\ntrain_segmented.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:40.876628Z","iopub.execute_input":"2023-05-16T21:12:40.877097Z","iopub.status.idle":"2023-05-16T21:12:40.947042Z","shell.execute_reply.started":"2023-05-16T21:12:40.877059Z","shell.execute_reply":"2023-05-16T21:12:40.945978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_segmented[train_segmented['SOPInstanceUID']=='1.2.826.0.1.3680043.14723.1.100'][['C1','C2','C3','C4','C5','C6','C7']]","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:40.950803Z","iopub.execute_input":"2023-05-16T21:12:40.951134Z","iopub.status.idle":"2023-05-16T21:12:41.058125Z","shell.execute_reply.started":"2023-05-16T21:12:40.951105Z","shell.execute_reply":"2023-05-16T21:12:41.057249Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2. Diseño del modelo <a name=\"modelo\"></a>\n<div align=\"justify\">Modelo</div>","metadata":{}},{"cell_type":"markdown","source":"# RSNA Efficient-net Baseline","metadata":{}},{"cell_type":"code","source":"import os\nimport cv2\nimport glob\nimport traceback\nimport numpy as np\nimport pandas as pd\nfrom path import Path\nfrom tqdm import tqdm\nimport nibabel as nib\nimport pydicom\nimport tensorflow as tf\nfrom keras import layers\nfrom pydicom import dcmread\nfrom tensorflow import keras\nimport tensorflow_hub as hub\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras import backend as K\nfrom pydicom.data import get_testdata_files\nfrom tensorflow.keras.utils import to_categorical\nfrom sklearn.model_selection import StratifiedKFold\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nfrom tensorflow.keras.layers import Input, Dense, Flatten, Conv2D\nfrom tensorflow.keras.preprocessing.image import load_img, img_to_array","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:41.060405Z","iopub.execute_input":"2023-05-16T21:12:41.061057Z","iopub.status.idle":"2023-05-16T21:12:42.72535Z","shell.execute_reply.started":"2023-05-16T21:12:41.061016Z","shell.execute_reply":"2023-05-16T21:12:42.724329Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path_train_png = '../input/images-preprocessed/images_preprocessed/train_images_preprocessed'","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:42.72673Z","iopub.execute_input":"2023-05-16T21:12:42.727103Z","iopub.status.idle":"2023-05-16T21:12:42.737263Z","shell.execute_reply.started":"2023-05-16T21:12:42.727068Z","shell.execute_reply":"2023-05-16T21:12:42.733954Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport cv2\nfrom PIL import Image","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:42.738739Z","iopub.execute_input":"2023-05-16T21:12:42.739498Z","iopub.status.idle":"2023-05-16T21:12:42.748875Z","shell.execute_reply.started":"2023-05-16T21:12:42.739069Z","shell.execute_reply":"2023-05-16T21:12:42.747919Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_dicom(path, size = 64):\n    try:\n        img=pydicom.dcmread(path)\n        img.PhotometricInterpretation = 'YBR_FULL'\n        data=img.pixel_array\n        data=data-np.min(data)\n        if np.max(data) != 0:\n            data=data/np.max(data)\n        data=(data*255).astype(np.uint8)        \n        return cv2.cvtColor(data.reshape(512, 512), cv2.COLOR_GRAY2RGB)\n    except:        \n        return np.zeros((512, 512, 3))\n    \ndef load_png(path, size = 66):\n    img = Image.open(path).convert(\"RGB\")\n    img = img.resize((size, size))\n    img_array = np.array(img) / 255.0\n    return img_array","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:42.750001Z","iopub.execute_input":"2023-05-16T21:12:42.750297Z","iopub.status.idle":"2023-05-16T21:12:42.761299Z","shell.execute_reply.started":"2023-05-16T21:12:42.750271Z","shell.execute_reply":"2023-05-16T21:12:42.760251Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pydicom\nfrom pydicom import dcmread\nfrom pydicom.data import get_testdata_files\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\n\nimport tensorflow as tf\nfrom keras import layers\nfrom tensorflow import keras\nimport tensorflow_hub as hub\nfrom tensorflow.keras import backend as K\nfrom tensorflow.keras.utils import to_categorical\nfrom tensorflow.keras.layers import Input, Dense, Flatten, Conv2D\nfrom tensorflow.keras.preprocessing.image import load_img, img_to_array","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:42.763189Z","iopub.execute_input":"2023-05-16T21:12:42.76359Z","iopub.status.idle":"2023-05-16T21:12:42.772936Z","shell.execute_reply.started":"2023-05-16T21:12:42.763552Z","shell.execute_reply":"2023-05-16T21:12:42.771988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_indices = train_df_t1.index.tolist()","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:42.774198Z","iopub.execute_input":"2023-05-16T21:12:42.774653Z","iopub.status.idle":"2023-05-16T21:12:42.780428Z","shell.execute_reply.started":"2023-05-16T21:12:42.774618Z","shell.execute_reply":"2023-05-16T21:12:42.779356Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"@tf.autograph.experimental.do_not_convert\ndef data_generator():\n    \n    for i in train_indices: \n        \n        idt = train_df_t1.loc[i, 'StudyInstanceUID']\n        path_png = os.path.join(path_train_png, idt)\n            \n        for im in os.listdir(path_png):\n            train_label = []\n            img = load_png(os.path.join(path_png , im))\n                \n            sop_uid = idt+'.1.'+im\n            sop_uid = sop_uid.split(\".png\")[0]\n                \n            if sop_uid in np.array(train_segmented['SOPInstanceUID']):\n                vert_prob = np.array(train_segmented[train_segmented['SOPInstanceUID']==sop_uid][['C1','C2','C3','C4','C5','C6','C7']])\n                vert_prob = vert_prob[0]\n                vert_prob = np.array(vert_prob)\n                \n                train_label.extend([\n                    train_df_t1.loc[i, \"C1\"],\n                    train_df_t1.loc[i, \"C2\"],\n                    train_df_t1.loc[i, \"C3\"],\n                    train_df_t1.loc[i, \"C4\"],\n                    train_df_t1.loc[i, \"C5\"],\n                    train_df_t1.loc[i, \"C6\"],\n                    train_df_t1.loc[i, \"C7\"]\n                ])\n\n                train_label = np.array(train_label)\n\n                fracture_label = vert_prob * train_label\n                \n                    \n                #yield (img, vert_prob), fracture_label\n                \n                yield img, fracture_label\n                ","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:42.782105Z","iopub.execute_input":"2023-05-16T21:12:42.782514Z","iopub.status.idle":"2023-05-16T21:12:42.79656Z","shell.execute_reply.started":"2023-05-16T21:12:42.782479Z","shell.execute_reply":"2023-05-16T21:12:42.795634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def data_generator_without_vert():\n    \n    for i in train_indices: \n        \n        idt = train_df_t1.loc[i, 'StudyInstanceUID']\n        path_png = os.path.join(path_train_png, idt)\n            \n        for im in os.listdir(path_png):\n            train_label = []\n\n            img = load_png(os.path.join(path_png,im))\n                \n            img = cv2.resize(img, (64 , 64))\n            image = img_to_array(img)\n            image = image / 255.0\n            \n            train_label.extend([\n                train_df_t1.loc[i, \"patient_overall\"],\n                train_df_t1.loc[i, \"C1\"],\n                train_df_t1.loc[i, \"C2\"],\n                train_df_t1.loc[i, \"C3\"],\n                train_df_t1.loc[i, \"C4\"],\n                train_df_t1.loc[i, \"C5\"],\n                train_df_t1.loc[i, \"C6\"],\n                train_df_t1.loc[i, \"C7\"]\n            ])\n                    \n            yield image, train_label\n                ","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:42.798206Z","iopub.execute_input":"2023-05-16T21:12:42.798636Z","iopub.status.idle":"2023-05-16T21:12:42.808384Z","shell.execute_reply.started":"2023-05-16T21:12:42.798579Z","shell.execute_reply":"2023-05-16T21:12:42.807438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_indices = val_df_t1.index.tolist()","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:42.80982Z","iopub.execute_input":"2023-05-16T21:12:42.810414Z","iopub.status.idle":"2023-05-16T21:12:42.820688Z","shell.execute_reply.started":"2023-05-16T21:12:42.810379Z","shell.execute_reply":"2023-05-16T21:12:42.81977Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"@tf.autograph.experimental.do_not_convert\ndef val_generator():\n    \n    for i in val_indices: \n        \n        idt = val_df_t1.loc[i, 'StudyInstanceUID']\n        path_png = os.path.join(path_train_png, idt)\n            \n        for im in os.listdir(path_png):\n            train_label = []\n            img = load_png(os.path.join(path_png , im))\n                \n            sop_uid = idt+'.1.'+im\n            sop_uid = sop_uid.split(\".png\")[0]\n                \n            if sop_uid in np.array(train_segmented['SOPInstanceUID']):\n                vert_prob = np.array(train_segmented[train_segmented['SOPInstanceUID']==sop_uid][['C1','C2','C3','C4','C5','C6','C7']])\n                vert_prob = vert_prob[0]\n                vert_prob = np.array(vert_prob)\n                \n                train_label.extend([\n                    val_df_t1.loc[i, \"C1\"],\n                    val_df_t1.loc[i, \"C2\"],\n                    val_df_t1.loc[i, \"C3\"],\n                    val_df_t1.loc[i, \"C4\"],\n                    val_df_t1.loc[i, \"C5\"],\n                    val_df_t1.loc[i, \"C6\"],\n                    val_df_t1.loc[i, \"C7\"]\n                ])\n\n                train_label = np.array(train_label)\n\n                fracture_label = vert_prob * train_label\n                \n                    \n                #yield (img, vert_prob), fracture_label\n                \n                yield img, fracture_label","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:42.825301Z","iopub.execute_input":"2023-05-16T21:12:42.825671Z","iopub.status.idle":"2023-05-16T21:12:42.837141Z","shell.execute_reply.started":"2023-05-16T21:12:42.825636Z","shell.execute_reply":"2023-05-16T21:12:42.836218Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def val_generator_without_vert():\n    \n    for i in val_indices: \n        \n        idt = val_df_t1.loc[i, 'StudyInstanceUID']\n        path_dcm = os.path.join(path_train_images, idt)\n        path_png = os.path.join(path_train_png, idt)\n            \n        for im in os.listdir(path_png):\n            train_label = []\n\n            img = load_png(os.path.join(path_png,im))\n                \n            img = cv2.resize(img, (64 , 64))\n            image = img_to_array(img)\n            image = image / 255.0\n            \n            train_label.extend([\n                val_df_t1.loc[i, \"patient_overall\"],\n                val_df_t1.loc[i, \"C1\"],\n                val_df_t1.loc[i, \"C2\"],\n                val_df_t1.loc[i, \"C3\"],\n                val_df_t1.loc[i, \"C4\"],\n                val_df_t1.loc[i, \"C5\"],\n                val_df_t1.loc[i, \"C6\"],\n                val_df_t1.loc[i, \"C7\"]\n            ])\n                    \n            yield image, train_label\n                ","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:42.838891Z","iopub.execute_input":"2023-05-16T21:12:42.839177Z","iopub.status.idle":"2023-05-16T21:12:42.850821Z","shell.execute_reply.started":"2023-05-16T21:12:42.839152Z","shell.execute_reply":"2023-05-16T21:12:42.849841Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_model():\n    inp1 = keras.layers.Input(shape=(None, None, 1), name='image')\n    inp2 = keras.layers.Input(shape=(7,), name='vert_prob')\n    \n    x = Conv2D(3, 3, padding='SAME')(inp1)\n    \n    x = keras.applications.efficientnet.EfficientNetB5(include_top=False)(x)\n    x = keras.layers.GlobalAveragePooling2D()(x)\n    x = keras.layers.BatchNormalization()(x)\n    \n    x2 = keras.layers.Dense(32, activation='relu')(inp2)\n    \n    x = keras.layers.concatenate([x, x2])\n    \n    x = keras.layers.Dropout(0.2)(x)\n    \n    out = keras.layers.Dense(7, 'sigmoid')(x)\n    \n    model = keras.models.Model(inputs=[inp1, inp2], outputs=out)\n    \n    return model","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:42.852478Z","iopub.execute_input":"2023-05-16T21:12:42.852897Z","iopub.status.idle":"2023-05-16T21:12:42.863535Z","shell.execute_reply.started":"2023-05-16T21:12:42.852863Z","shell.execute_reply":"2023-05-16T21:12:42.861989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_model_unet():\n    inp1 = keras.layers.Input(shape=(None, None, 1), name='image')\n    inp2 = keras.layers.Input(shape=(7,), name='vert_prob')\n\n    # Encoder\n    conv1 = keras.layers.Conv2D(64, 3, activation='relu', padding='same')(inp1)\n    pool1 = keras.layers.MaxPooling2D(pool_size=(2, 2))(conv1)\n    conv2 = keras.layers.Conv2D(128, 3, activation='relu', padding='same')(pool1)\n    pool2 = keras.layers.MaxPooling2D(pool_size=(2, 2))(conv2)\n    conv3 = keras.layers.Conv2D(256, 3, activation='relu', padding='same')(pool2)\n    pool3 = keras.layers.MaxPooling2D(pool_size=(2, 2))(conv3)\n    conv4 = keras.layers.Conv2D(512, 3, activation='relu', padding='same')(pool3)\n    drop4 = keras.layers.Dropout(0.5)(conv4)\n\n    # Decoder\n    up6 = keras.layers.Conv2D(256, 2, activation='relu', padding='same')(keras.layers.UpSampling2D(size=(2, 2))(drop4))\n    merge6 = keras.layers.concatenate([conv3, up6], axis=3)\n    conv6 = keras.layers.Conv2D(256, 3, activation='relu', padding='same')(merge6)\n    up7 = keras.layers.Conv2D(128, 2, activation='relu', padding='same')(keras.layers.UpSampling2D(size=(2, 2))(conv6))\n    merge7 = keras.layers.concatenate([conv2, up7], axis=3)\n    conv7 = keras.layers.Conv2D(128, 3, activation='relu', padding='same')(merge7)\n    up8 = keras.layers.Conv2D(64, 2, activation='relu', padding='same')(keras.layers.UpSampling2D(size=(2, 2))(conv7))\n    merge8 = keras.layers.concatenate([conv1, up8], axis=3)\n    conv8 = keras.layers.Conv2D(64, 3, activation='relu', padding='same')(merge8)\n\n    # Final conv layer\n    out_unet = keras.layers.Conv2D(7, 1, activation='sigmoid')(conv8)\n    # Reshape out_unet to match inp2 shape\n    out_unet_reshaped = keras.layers.Reshape((7,), name='out_unet_reshaped')(out_unet)\n    \n    # Concatenate with inp2\n    x = keras.layers.concatenate([out_unet_reshaped, inp2])\n    \n    dense1 = keras.layers.Dense(128, activation='relu')(x)\n    out = keras.layers.Dense(7, activation='sigmoid')(x)\n\n    model = keras.models.Model(inputs=[inp1, inp2], outputs=out)\n    return model","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:12:42.866031Z","iopub.execute_input":"2023-05-16T21:12:42.866299Z","iopub.status.idle":"2023-05-16T21:12:42.885386Z","shell.execute_reply.started":"2023-05-16T21:12:42.866275Z","shell.execute_reply":"2023-05-16T21:12:42.884453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from vit_keras import vit, utils","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:13:06.503289Z","iopub.execute_input":"2023-05-16T21:13:06.503701Z","iopub.status.idle":"2023-05-16T21:13:06.748912Z","shell.execute_reply.started":"2023-05-16T21:13:06.503667Z","shell.execute_reply":"2023-05-16T21:13:06.747955Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow_addons as tfa","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:14:00.124385Z","iopub.execute_input":"2023-05-16T21:14:00.124954Z","iopub.status.idle":"2023-05-16T21:14:00.130761Z","shell.execute_reply.started":"2023-05-16T21:14:00.124911Z","shell.execute_reply":"2023-05-16T21:14:00.12957Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def ViT_Model():\n    Vit = vit.vit_b32(\n        image_size = (64, 64),\n        activation = 'softmax',\n        pretrained = True,\n        include_top = False,\n        pretrained_top = False,\n        weights='imagenet21k+imagenet2012',\n        classes = 1000)\n\n    model = tf.keras.Sequential([\n#             tf.keras.layers.experimental.preprocessing.RandomFlip('horizontal', seed=0),\n#             tf.keras.layers.experimental.preprocessing.RandomFlip('vertical', seed=15),\n#             tf.keras.layers.experimental.preprocessing.RandomContrast(0.1, seed=30),\n#             tf.keras.layers.experimental.preprocessing.RandomTranslation(0.1, 0.1, seed=45),\n#             tf.keras.layers.experimental.preprocessing.RandomRotation(factor=0.25, seed=60),\n#             tf.keras.layers.experimental.preprocessing.RandomZoom(height_factor=0.2, width_factor=0.1, seed=75),\n            tf.keras.layers.Conv2D(3, 3, padding='valid', input_shape=(66, 66, 1)),\n            Vit,\n            tf.keras.layers.Flatten(),\n            tf.keras.layers.BatchNormalization(),\n            tf.keras.layers.Dense(64, activation = tfa.activations.gelu),\n            tf.keras.layers.BatchNormalization(),\n            tf.keras.layers.Dense(7, 'sigmoid')\n        ], name = 'vision_transformer'\n    )\n    model.build(input_shape=(None, 66, 66, 1))\n    return model\n    \n\ndef competiton_loss(y_true, y_pred):\n\n    competition_weights = {\n        '-' : tf.constant([1, 1, 1, 1, 1, 1, 1], dtype=tf.float32),\n        '+' : tf.constant([2, 2, 2, 2, 2, 2, 2], dtype=tf.float32)\n    }\n    \n    loss = tf.keras.losses.BinaryCrossentropy(reduction=tf.keras.losses.Reduction.NONE)(tf.expand_dims(y_true, -1),tf.expand_dims(y_pred,-1))\n    weights  = y_true*competition_weights['+'] + (1-y_true)*competition_weights['-'] \n    \n    loss = tf.reduce_mean(tf.reduce_sum(loss * weights, axis=1)) / tf.reduce_sum(weights)\n    return loss\n\n#model = tf.keras.models.load_model(cfg['model_path'], custom_objects={'competiton_loss': competiton_loss}, compile=False)","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:16:16.932465Z","iopub.execute_input":"2023-05-16T21:16:16.932965Z","iopub.status.idle":"2023-05-16T21:16:16.95039Z","shell.execute_reply.started":"2023-05-16T21:16:16.932925Z","shell.execute_reply":"2023-05-16T21:16:16.949161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_model_unet_without_vert():\n    inp1 = keras.layers.Input(shape=(None, None, 1), name='image')\n\n    # Encoder\n    conv1 = keras.layers.Conv2D(64, 3, activation='relu', padding='same')(inp1)\n    pool1 = keras.layers.MaxPooling2D(pool_size=(2, 2))(conv1)\n    conv2 = keras.layers.Conv2D(128, 3, activation='relu', padding='same')(pool1)\n    pool2 = keras.layers.MaxPooling2D(pool_size=(2, 2))(conv2)\n    conv3 = keras.layers.Conv2D(256, 3, activation='relu', padding='same')(pool2)\n    pool3 = keras.layers.MaxPooling2D(pool_size=(2, 2))(conv3)\n    conv4 = keras.layers.Conv2D(512, 3, activation='relu', padding='same')(pool3)\n    drop4 = keras.layers.Dropout(0.5)(conv4)\n\n    # Decoder\n    up6 = keras.layers.Conv2D(256, 2, activation='relu', padding='same')(keras.layers.UpSampling2D(size=(2, 2))(drop4))\n    merge6 = keras.layers.concatenate([conv3, up6], axis=3)\n    conv6 = keras.layers.Conv2D(256, 3, activation='relu', padding='same')(merge6)\n    up7 = keras.layers.Conv2D(128, 2, activation='relu', padding='same')(keras.layers.UpSampling2D(size=(2, 2))(conv6))\n    merge7 = keras.layers.concatenate([conv2, up7], axis=3)\n    conv7 = keras.layers.Conv2D(128, 3, activation='relu', padding='same')(merge7)\n    up8 = keras.layers.Conv2D(64, 2, activation='relu', padding='same')(keras.layers.UpSampling2D(size=(2, 2))(conv7))\n    merge8 = keras.layers.concatenate([conv1, up8], axis=3)\n    conv8 = keras.layers.Conv2D(64, 3, activation='relu', padding='same')(merge8)\n    \n    \n    # Final conv layer\n    out = layers.Conv2D(1, 1, activation='sigmoid', padding='same')(conv8)\n    out = layers.Reshape((7,))(out)\n    out = layers.Activation('softmax')(out)\n\n    model = keras.models.Model(inputs=inp1, outputs=out)\n    \n    return model","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:54.035121Z","iopub.execute_input":"2023-05-16T16:21:54.036163Z","iopub.status.idle":"2023-05-16T16:21:54.054093Z","shell.execute_reply.started":"2023-05-16T16:21:54.036114Z","shell.execute_reply":"2023-05-16T16:21:54.053036Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_model_without_vert():\n    inp = keras.layers.Input(shape=(None, None, 1), name='image')\n    \n    x = Conv2D(3, 3, padding='SAME')(inp)\n    \n    x = keras.applications.EfficientNetV2.pretrained()(x)\n    \n    x = keras.layers.GlobalAveragePooling2D()(x)\n    \n    x = keras.layers.Dense(16, activation='relu')(x)\n    x = keras.layers.Dropout(0.2)(x)\n    out = keras.layers.Dense(8, 'softmax')(x)\n    \n    model = keras.models.Model(inputs=inp, outputs=out)\n    \n    return model","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:54.172495Z","iopub.execute_input":"2023-05-16T16:21:54.172968Z","iopub.status.idle":"2023-05-16T16:21:54.180776Z","shell.execute_reply.started":"2023-05-16T16:21:54.17293Z","shell.execute_reply":"2023-05-16T16:21:54.179605Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import traceback\nfrom sklearn.model_selection import StratifiedKFold","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:54.336095Z","iopub.execute_input":"2023-05-16T16:21:54.336421Z","iopub.status.idle":"2023-05-16T16:21:54.343234Z","shell.execute_reply.started":"2023-05-16T16:21:54.336391Z","shell.execute_reply":"2023-05-16T16:21:54.342327Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def configure_for_performance(data):\n    data = data.cache()\n    data = data.batch(8)\n    data = data.prefetch(buffer_size=tf.data.AUTOTUNE)\n    return data","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:54.44697Z","iopub.execute_input":"2023-05-16T16:21:54.44727Z","iopub.status.idle":"2023-05-16T16:21:54.452725Z","shell.execute_reply.started":"2023-05-16T16:21:54.447226Z","shell.execute_reply":"2023-05-16T16:21:54.451557Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data = tf.data.Dataset.from_generator(data_generator, (tf.float32, tf.float32))","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:54.594467Z","iopub.execute_input":"2023-05-16T16:21:54.594747Z","iopub.status.idle":"2023-05-16T16:21:54.619809Z","shell.execute_reply.started":"2023-05-16T16:21:54.594715Z","shell.execute_reply":"2023-05-16T16:21:54.618951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data = configure_for_performance(train_data)","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:54.717052Z","iopub.execute_input":"2023-05-16T16:21:54.71741Z","iopub.status.idle":"2023-05-16T16:21:54.724961Z","shell.execute_reply.started":"2023-05-16T16:21:54.717377Z","shell.execute_reply":"2023-05-16T16:21:54.723797Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_data = tf.data.Dataset.from_generator(val_generator, (tf.float32, tf.float32))","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:54.868115Z","iopub.execute_input":"2023-05-16T16:21:54.868743Z","iopub.status.idle":"2023-05-16T16:21:54.892819Z","shell.execute_reply.started":"2023-05-16T16:21:54.868709Z","shell.execute_reply":"2023-05-16T16:21:54.891833Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_data = configure_for_performance(val_data)","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:55.214727Z","iopub.execute_input":"2023-05-16T16:21:55.215114Z","iopub.status.idle":"2023-05-16T16:21:55.222632Z","shell.execute_reply.started":"2023-05-16T16:21:55.215081Z","shell.execute_reply":"2023-05-16T16:21:55.221564Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#train_data_wv = tf.data.Dataset.from_generator(data_generator_without_vert, (tf.float32, tf.int8))","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:55.358671Z","iopub.execute_input":"2023-05-16T16:21:55.359266Z","iopub.status.idle":"2023-05-16T16:21:55.364443Z","shell.execute_reply.started":"2023-05-16T16:21:55.359209Z","shell.execute_reply":"2023-05-16T16:21:55.363303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#train_data_wv = configure_for_performance(train_data_wv)","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:55.643214Z","iopub.execute_input":"2023-05-16T16:21:55.643554Z","iopub.status.idle":"2023-05-16T16:21:55.647757Z","shell.execute_reply.started":"2023-05-16T16:21:55.643526Z","shell.execute_reply":"2023-05-16T16:21:55.646796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#val_data_wv = tf.data.Dataset.from_generator(val_generator_without_vert, (tf.float32, tf.int8))","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:55.808445Z","iopub.execute_input":"2023-05-16T16:21:55.80906Z","iopub.status.idle":"2023-05-16T16:21:55.814137Z","shell.execute_reply.started":"2023-05-16T16:21:55.809019Z","shell.execute_reply":"2023-05-16T16:21:55.813071Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#val_data_wv = configure_for_performance(val_data_wv)","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:55.970172Z","iopub.execute_input":"2023-05-16T16:21:55.970496Z","iopub.status.idle":"2023-05-16T16:21:55.975231Z","shell.execute_reply.started":"2023-05-16T16:21:55.970467Z","shell.execute_reply":"2023-05-16T16:21:55.973891Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#model_wv = get_model_without_vert()\n#model_wv.summary()","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:56.079214Z","iopub.execute_input":"2023-05-16T16:21:56.079774Z","iopub.status.idle":"2023-05-16T16:21:56.084341Z","shell.execute_reply.started":"2023-05-16T16:21:56.079744Z","shell.execute_reply":"2023-05-16T16:21:56.083263Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.callbacks import ModelCheckpoint\nfrom tensorflow.keras.callbacks import EarlyStopping\n\n\"\"\"checkpoint_filepath = 'p1_best_model_efficientnetb5.h5'\n\nmodel_checkpoint_callback = ModelCheckpoint(\n    checkpoint_filepath,\n    save_best_only=True,\n    monitor='val_accuracy',\n    mode='max',\n    verbose=1)\n\nearly_stopping = EarlyStopping(monitor='val_loss', \n                               min_delta=0, \n                               patience=5, \n                               verbose=1)\n\ncallbacks = [early_stopping, model_checkpoint_callback]\"\"\"","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:56.227342Z","iopub.execute_input":"2023-05-16T16:21:56.227954Z","iopub.status.idle":"2023-05-16T16:21:56.235023Z","shell.execute_reply.started":"2023-05-16T16:21:56.227915Z","shell.execute_reply":"2023-05-16T16:21:56.234045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"model_wv.compile(optimizer=tf.keras.optimizers.Adam(), \n              loss=tf.keras.losses.CategoricalCrossentropy(),\n              metrics=[tf.keras.metrics.CategoricalAccuracy()]\n             )\"\"\"","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:56.361517Z","iopub.execute_input":"2023-05-16T16:21:56.362452Z","iopub.status.idle":"2023-05-16T16:21:56.372783Z","shell.execute_reply.started":"2023-05-16T16:21:56.362416Z","shell.execute_reply":"2023-05-16T16:21:56.371347Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#hist = model_wv.fit(train_data_wv, validation_data=val_data_wv, epochs = 25, callbacks=callbacks)","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:56.508117Z","iopub.execute_input":"2023-05-16T16:21:56.508607Z","iopub.status.idle":"2023-05-16T16:21:56.513801Z","shell.execute_reply.started":"2023-05-16T16:21:56.508556Z","shell.execute_reply":"2023-05-16T16:21:56.512659Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#model_wv.fit(val_data_wv, epochs=2)","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:56.845102Z","iopub.execute_input":"2023-05-16T16:21:56.845849Z","iopub.status.idle":"2023-05-16T16:21:56.850563Z","shell.execute_reply.started":"2023-05-16T16:21:56.84581Z","shell.execute_reply":"2023-05-16T16:21:56.849403Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#model_wv.save('t3_model_without_vert_efficientnetb5.h5')","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:57.042699Z","iopub.execute_input":"2023-05-16T16:21:57.043043Z","iopub.status.idle":"2023-05-16T16:21:57.04733Z","shell.execute_reply.started":"2023-05-16T16:21:57.043012Z","shell.execute_reply":"2023-05-16T16:21:57.046289Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#model = get_model()\n    \n#hist = model.fit(train_data, steps_per_epoch=len(train_indices) // batch_size, epochs = 2)","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:57.237615Z","iopub.execute_input":"2023-05-16T16:21:57.238223Z","iopub.status.idle":"2023-05-16T16:21:57.243035Z","shell.execute_reply.started":"2023-05-16T16:21:57.238182Z","shell.execute_reply":"2023-05-16T16:21:57.241757Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#model = get_model_unet_without_vert()","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:57.404268Z","iopub.execute_input":"2023-05-16T16:21:57.404631Z","iopub.status.idle":"2023-05-16T16:21:57.534378Z","shell.execute_reply.started":"2023-05-16T16:21:57.4046Z","shell.execute_reply":"2023-05-16T16:21:57.533439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"model.compile(optimizer=tf.keras.optimizers.Adam(), \n                loss=tf.keras.losses.BinaryCrossentropy(),\n                metrics=[tf.keras.metrics.Precision(), tf.keras.metrics.AUC(multi_label=True)]\n                )\"\"\"","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:57.571008Z","iopub.execute_input":"2023-05-16T16:21:57.571322Z","iopub.status.idle":"2023-05-16T16:21:57.586277Z","shell.execute_reply.started":"2023-05-16T16:21:57.571294Z","shell.execute_reply":"2023-05-16T16:21:57.585427Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = ViT_Model()\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-05-16T21:16:18.194261Z","iopub.execute_input":"2023-05-16T21:16:18.194806Z","iopub.status.idle":"2023-05-16T21:16:18.256091Z","shell.execute_reply.started":"2023-05-16T21:16:18.194759Z","shell.execute_reply":"2023-05-16T21:16:18.253472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(\n    optimizer=tfa.optimizers.RectifiedAdam(learning_rate=1e-04),\n    loss= competiton_loss,\n    #metrics = ['accuracy']\n)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"checkpoint = keras.callbacks.ModelCheckpoint(\n    filepath='/kaggle/working/best_model.h5',\n    monitor='val_loss',\n    verbose=0,\n    save_best_only=True,\n    mode='min'\n)\n\nreduce_lr = keras.callbacks.ReduceLROnPlateau(\n    monitor='val_loss',\n    factor=0.9,\n    min_lr=1e-07,\n    patience=3,\n    verbose=0,\n    mode='min'\n)\n\nes = keras.callbacks.EarlyStopping(\n    patience=5,\n    min_delta=0,\n    monitor='val_loss',\n    restore_best_weights=True,\n    verbose=0,\n    mode='min',\n    baseline=None\n)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.fit(train_data, validation_data=val_data, epochs = 25, callbacks=[es,reduce_lr,checkpoint])","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:21:57.79345Z","iopub.execute_input":"2023-05-16T16:21:57.793772Z","iopub.status.idle":"2023-05-16T16:22:01.830778Z","shell.execute_reply.started":"2023-05-16T16:21:57.793744Z","shell.execute_reply":"2023-05-16T16:22:01.827474Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"try:\n    model.load_weights('/kaggle/working/best_model.h5')\nexcept:\n    print(\"No se han cargado los pesos\")","metadata":{"execution":{"iopub.status.busy":"2023-05-16T16:22:01.831773Z","iopub.status.idle":"2023-05-16T16:22:01.832271Z","shell.execute_reply.started":"2023-05-16T16:22:01.832026Z","shell.execute_reply":"2023-05-16T16:22:01.832048Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.fit(val_data, epochs=2)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save('p1_model_vit_b32.h5')","metadata":{},"execution_count":null,"outputs":[]}]}