{"cells":[{"metadata":{"papermill":{"duration":0.054636,"end_time":"2020-12-10T08:16:47.936364","exception":false,"start_time":"2020-12-10T08:16:47.881728","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## 2. Préparation de la base de données\n\n### 2.1 importer les bibliothèques nécessaires"},{"metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","execution":{"iopub.execute_input":"2020-12-10T08:16:48.064369Z","iopub.status.busy":"2020-12-10T08:16:48.0601Z","iopub.status.idle":"2020-12-10T08:17:07.447617Z","shell.execute_reply":"2020-12-10T08:17:07.446838Z"},"papermill":{"duration":19.457218,"end_time":"2020-12-10T08:17:07.447753","exception":false,"start_time":"2020-12-10T08:16:47.990535","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport random, re, math\nimport tensorflow as tf, tensorflow.keras.backend as K\nimport tensorflow_addons as tfa\nfrom tensorflow.keras.layers import Dense\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras import optimizers\nfrom kaggle_datasets import KaggleDatasets\nfrom tensorflow.keras.models import Sequential\nimport tensorflow.keras.layers as L\nfrom tensorflow.keras.applications import ResNet152V2, InceptionResNetV2, InceptionV3, Xception, VGG19\nfrom tensorflow.keras.layers import Dense, GlobalAveragePooling2D,GlobalMaxPooling2D\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras.callbacks import ReduceLROnPlateau , EarlyStopping , ModelCheckpoint , LearningRateScheduler\nfrom keras import regularizers\n\nimport matplotlib.pyplot as plt\n\n!pip install efficientnet\nimport efficientnet.tfkeras as efn","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":0.059283,"end_time":"2020-12-10T08:17:07.565877","exception":false,"start_time":"2020-12-10T08:17:07.506594","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## 2.2 Configuration de tpu"},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","execution":{"iopub.execute_input":"2020-12-10T08:17:07.698614Z","iopub.status.busy":"2020-12-10T08:17:07.697419Z","iopub.status.idle":"2020-12-10T08:17:11.953981Z","shell.execute_reply":"2020-12-10T08:17:11.953273Z"},"papermill":{"duration":4.327355,"end_time":"2020-12-10T08:17:11.954121","exception":false,"start_time":"2020-12-10T08:17:07.626766","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"AUTO = tf.data.experimental.AUTOTUNE\ntry:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver()\n    print('Running on TPU ', tpu.master())\nexcept ValueError:\n    tpu = None\n\nif tpu:\n    tf.config.experimental_connect_to_cluster(tpu)\n    tf.tpu.experimental.initialize_tpu_system(tpu)\n    strategy = tf.distribute.experimental.TPUStrategy(tpu)\nelse:\n    strategy = tf.distribute.get_strategy()\n\nprint(\"REPLICAS: \", strategy.num_replicas_in_sync)\n","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T08:17:12.09274Z","iopub.status.busy":"2020-12-10T08:17:12.0919Z","iopub.status.idle":"2020-12-10T08:17:12.403139Z","shell.execute_reply":"2020-12-10T08:17:12.402351Z"},"papermill":{"duration":0.380382,"end_time":"2020-12-10T08:17:12.403336","exception":false,"start_time":"2020-12-10T08:17:12.022954","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"GCS_DS_PATH = KaggleDatasets().get_gcs_path('ocular-disease-recognition-odir5k')","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T08:17:12.539251Z","iopub.status.busy":"2020-12-10T08:17:12.538403Z","iopub.status.idle":"2020-12-10T08:17:12.574836Z","shell.execute_reply":"2020-12-10T08:17:12.574156Z"},"papermill":{"duration":0.110512,"end_time":"2020-12-10T08:17:12.57498","exception":false,"start_time":"2020-12-10T08:17:12.464468","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"train = pd.read_csv('../input/new-df-csv-oc/new_df_oc.csv')\ntrain_paths = train.filename.apply(lambda x: GCS_DS_PATH+ '/ODIR-5K/ODIR-5K/Training Images/' + x).values\ntrain_labels = train.target.values","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T08:17:12.712702Z","iopub.status.busy":"2020-12-10T08:17:12.711823Z","iopub.status.idle":"2020-12-10T08:17:12.726719Z","shell.execute_reply":"2020-12-10T08:17:12.727349Z"},"papermill":{"duration":0.092452,"end_time":"2020-12-10T08:17:12.727532","exception":false,"start_time":"2020-12-10T08:17:12.63508","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"train.head(10)","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T08:17:12.861479Z","iopub.status.busy":"2020-12-10T08:17:12.860694Z","iopub.status.idle":"2020-12-10T08:17:12.864229Z","shell.execute_reply":"2020-12-10T08:17:12.863595Z"},"papermill":{"duration":0.076273,"end_time":"2020-12-10T08:17:12.864367","exception":false,"start_time":"2020-12-10T08:17:12.788094","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"train=train.drop(columns=['D','O'],axis=1)","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":0.061888,"end_time":"2020-12-10T08:17:12.986534","exception":false,"start_time":"2020-12-10T08:17:12.924646","status":"completed"},"tags":[]},"cell_type":"markdown","source":"### 2.3 Normal VS Cataract VS Glaucoma VS Myopia hypertension"},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T08:17:13.126622Z","iopub.status.busy":"2020-12-10T08:17:13.123615Z","iopub.status.idle":"2020-12-10T08:17:13.13036Z","shell.execute_reply":"2020-12-10T08:17:13.129561Z"},"papermill":{"duration":0.079147,"end_time":"2020-12-10T08:17:13.13049","exception":false,"start_time":"2020-12-10T08:17:13.051343","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"train=train[((train['N']== 1) | (train['C'] == 1)| (train['G'] == 1)| (train['M'] == 1)| (train['H'] == 1)| (train['A'] == 1))]","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T08:17:13.274024Z","iopub.status.busy":"2020-12-10T08:17:13.272933Z","iopub.status.idle":"2020-12-10T08:17:13.278333Z","shell.execute_reply":"2020-12-10T08:17:13.277724Z"},"papermill":{"duration":0.084815,"end_time":"2020-12-10T08:17:13.278473","exception":false,"start_time":"2020-12-10T08:17:13.193658","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"train","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":0.061903,"end_time":"2020-12-10T08:17:13.403271","exception":false,"start_time":"2020-12-10T08:17:13.341368","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## 2.4 Diviser notre dataset en 80% l'entraînement et 20% pour le test"},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T08:17:13.537022Z","iopub.status.busy":"2020-12-10T08:17:13.536086Z","iopub.status.idle":"2020-12-10T08:17:13.54176Z","shell.execute_reply":"2020-12-10T08:17:13.540969Z"},"papermill":{"duration":0.074711,"end_time":"2020-12-10T08:17:13.541889","exception":false,"start_time":"2020-12-10T08:17:13.467178","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"train,valid = train_test_split(train,test_size = 0.2,random_state = 42)","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":0.067013,"end_time":"2020-12-10T08:17:13.673109","exception":false,"start_time":"2020-12-10T08:17:13.606096","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## 3 Hyperparamètre"},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T08:17:13.804875Z","iopub.status.busy":"2020-12-10T08:17:13.804047Z","iopub.status.idle":"2020-12-10T08:17:13.806736Z","shell.execute_reply":"2020-12-10T08:17:13.8073Z"},"papermill":{"duration":0.070554,"end_time":"2020-12-10T08:17:13.807478","exception":false,"start_time":"2020-12-10T08:17:13.736924","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"BATCH_SIZE = 8*strategy.num_replicas_in_sync\nimg_size = 512\nEPOCHS = 35\nSEED = 42","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":0.062811,"end_time":"2020-12-10T08:17:13.932726","exception":false,"start_time":"2020-12-10T08:17:13.869915","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## 4. Prétraitement des données"},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T08:17:14.075814Z","iopub.status.busy":"2020-12-10T08:17:14.074897Z","iopub.status.idle":"2020-12-10T08:17:14.078395Z","shell.execute_reply":"2020-12-10T08:17:14.077618Z"},"papermill":{"duration":0.083778,"end_time":"2020-12-10T08:17:14.078528","exception":false,"start_time":"2020-12-10T08:17:13.99475","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"def decode_image(filename, label=None, image_size=(img_size,img_size)):\n    bits = tf.io.read_file(filename)\n    image = tf.image.decode_jpeg(bits, channels=3) \n    image = tf.image.resize(image, image_size)\n    image = tf.cast(image, tf.float32)\n    image = tf.image.per_image_standardization(image)\n    if label is None:\n        return image\n    else:\n        return image, label\n    \ndef preprocess(df,test=False):\n    paths = df.filename.apply(lambda x: GCS_DS_PATH + '/ODIR-5K/ODIR-5K/Training Images/' + x).values\n    labels = df.loc[:, ['N', 'C']].values\n    if test==False:\n        return paths,labels\n    else:\n        return paths\n    \ndef data_augment(image, label=None, seed=SEED):\n    image = tf.image.random_flip_left_right(image, seed=seed)\n    image = tf.image.random_flip_up_down(image, seed=seed)\n           \n    if label is None:\n        return image\n    else:\n        return image, label","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":0.065913,"end_time":"2020-12-10T08:17:14.211469","exception":false,"start_time":"2020-12-10T08:17:14.145556","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## 5. Augmentation"},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T08:17:14.3527Z","iopub.status.busy":"2020-12-10T08:17:14.351799Z","iopub.status.idle":"2020-12-10T08:17:14.363354Z","shell.execute_reply":"2020-12-10T08:17:14.362711Z"},"papermill":{"duration":0.084707,"end_time":"2020-12-10T08:17:14.363494","exception":false,"start_time":"2020-12-10T08:17:14.278787","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"def get_mat(rotation, shear, height_zoom, width_zoom, height_shift, width_shift):\n    rotation = math.pi * rotation / 180.\n    shear = math.pi * shear / 180.\n\n    c1 = tf.math.cos(rotation)\n    s1 = tf.math.sin(rotation)\n    one = tf.constant([1],dtype='float32')\n    zero = tf.constant([0],dtype='float32')\n    rotation_matrix = tf.reshape( tf.concat([c1,s1,zero, -s1,c1,zero, zero,zero,one],axis=0),[3,3] )\n\n    c2 = tf.math.cos(shear)\n    s2 = tf.math.sin(shear)\n    \n    shear_matrix = tf.reshape( tf.concat([one,s2,zero, zero,c2,zero, zero,zero,one],axis=0),[3,3] )    \n    zoom_matrix = tf.reshape( tf.concat([one/height_zoom,zero,zero, zero,one/width_zoom,zero, zero,zero,one],axis=0),[3,3] )\n    shift_matrix = tf.reshape( tf.concat([one,zero,height_shift, zero,one,width_shift, zero,zero,one],axis=0),[3,3] )\n    \n    return K.dot(K.dot(rotation_matrix, shear_matrix), K.dot(zoom_matrix, shift_matrix))","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T08:17:14.512097Z","iopub.status.busy":"2020-12-10T08:17:14.511251Z","iopub.status.idle":"2020-12-10T08:17:14.514864Z","shell.execute_reply":"2020-12-10T08:17:14.514203Z"},"papermill":{"duration":0.087419,"end_time":"2020-12-10T08:17:14.515","exception":false,"start_time":"2020-12-10T08:17:14.427581","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"def transform(image,label=None):\n    DIM = img_size\n    XDIM = DIM%2 \n    \n    rot = 15. * tf.random.normal([1],dtype='float32')\n    shr = 5. * tf.random.normal([1],dtype='float32') \n    h_zoom = 1.0 + tf.random.normal([1],dtype='float32')/10.\n    w_zoom = 1.0 + tf.random.normal([1],dtype='float32')/10.\n    h_shift = 8. * tf.random.normal([1],dtype='float32') \n    w_shift = 8. * tf.random.normal([1],dtype='float32') \n  \n    m = get_mat(rot,shr,h_zoom,w_zoom,h_shift,w_shift) \n\n    x = tf.repeat( tf.range(DIM//2,-DIM//2,-1), DIM )\n    y = tf.tile( tf.range(-DIM//2,DIM//2),[DIM] )\n    z = tf.ones([DIM*DIM],dtype='int32')\n    idx = tf.stack( [x,y,z] )\n    \n    idx2 = K.dot(m,tf.cast(idx,dtype='float32'))\n    idx2 = K.cast(idx2,dtype='int32')\n    idx2 = K.clip(idx2,-DIM//2+XDIM+1,DIM//2)\n              \n    idx3 = tf.stack( [DIM//2-idx2[0,], DIM//2-1+idx2[1,]] )\n    d = tf.gather_nd(image,tf.transpose(idx3))\n    \n    if label is None:\n        return tf.reshape(d,[DIM,DIM,3])\n    else:\n        return tf.reshape(d,[DIM,DIM,3]),label","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":0.061974,"end_time":"2020-12-10T08:17:14.639278","exception":false,"start_time":"2020-12-10T08:17:14.577304","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## 6.Création d'un générateur pour l'ensemble de données d'entraînement "},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T08:17:14.781113Z","iopub.status.busy":"2020-12-10T08:17:14.778974Z","iopub.status.idle":"2020-12-10T08:17:16.364549Z","shell.execute_reply":"2020-12-10T08:17:16.363754Z"},"papermill":{"duration":1.662969,"end_time":"2020-12-10T08:17:16.364707","exception":false,"start_time":"2020-12-10T08:17:14.701738","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"train_dataset = (tf.data.Dataset\n    .from_tensor_slices(preprocess(train))\n    .map(decode_image, num_parallel_calls=AUTO)\n    .map(data_augment, num_parallel_calls=AUTO)\n    #.map(transform,num_parallel_calls=AUTO)\n    .shuffle(SEED)\n    .batch(BATCH_SIZE)\n    .repeat()\n    .prefetch(AUTO))","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":0.061716,"end_time":"2020-12-10T08:17:16.489419","exception":false,"start_time":"2020-12-10T08:17:16.427703","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## 7. Création d'un générateur pour l'ensemble de données de test"},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T08:17:16.628068Z","iopub.status.busy":"2020-12-10T08:17:16.626552Z","iopub.status.idle":"2020-12-10T08:17:16.659202Z","shell.execute_reply":"2020-12-10T08:17:16.658424Z"},"papermill":{"duration":0.106774,"end_time":"2020-12-10T08:17:16.659357","exception":false,"start_time":"2020-12-10T08:17:16.552583","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"test_dataset= (tf.data.Dataset\n    .from_tensor_slices(preprocess(valid))\n    .map(decode_image, num_parallel_calls=AUTO)\n    .batch(BATCH_SIZE)\n    .cache()\n    .prefetch(AUTO))","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":0.063868,"end_time":"2020-12-10T08:17:16.786281","exception":false,"start_time":"2020-12-10T08:17:16.722413","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## 8. Fonction du taux d'apprentissage"},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T08:17:16.92695Z","iopub.status.busy":"2020-12-10T08:17:16.922149Z","iopub.status.idle":"2020-12-10T08:17:17.146253Z","shell.execute_reply":"2020-12-10T08:17:17.145285Z"},"papermill":{"duration":0.297829,"end_time":"2020-12-10T08:17:17.14645","exception":false,"start_time":"2020-12-10T08:17:16.848621","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"LR_START = 0.00001\nLR_MAX = 0.00005 * strategy.num_replicas_in_sync\nLR_MIN = 0.00001\nLR_RAMPUP_EPOCHS = 5\nLR_SUSTAIN_EPOCHS = 0\nLR_EXP_DECAY = .8\n\ndef lrfn(epoch):\n    if epoch < LR_RAMPUP_EPOCHS:\n        lr = (LR_MAX - LR_START) / LR_RAMPUP_EPOCHS * epoch + LR_START\n    elif epoch < LR_RAMPUP_EPOCHS + LR_SUSTAIN_EPOCHS:\n        lr = LR_MAX\n    else:\n        lr = (LR_MAX - LR_MIN) * LR_EXP_DECAY**(epoch - LR_RAMPUP_EPOCHS - LR_SUSTAIN_EPOCHS) + LR_MIN\n    return lr\n    \nlr_callback = tf.keras.callbacks.LearningRateScheduler(lrfn, verbose=True)\n\nrng = [i for i in range(EPOCHS)]\ny = [lrfn(x) for x in rng]\nplt.plot(rng, y)\nprint(\"Learning rate schedule: {:.3g} to {:.3g} to {:.3g}\".format(y[0], max(y), y[-1]))","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":0.069399,"end_time":"2020-12-10T08:17:17.284248","exception":false,"start_time":"2020-12-10T08:17:17.214849","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## 9. Fonction de perte"},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T08:17:17.428181Z","iopub.status.busy":"2020-12-10T08:17:17.427136Z","iopub.status.idle":"2020-12-10T08:17:17.430028Z","shell.execute_reply":"2020-12-10T08:17:17.430586Z"},"papermill":{"duration":0.078949,"end_time":"2020-12-10T08:17:17.430769","exception":false,"start_time":"2020-12-10T08:17:17.35182","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"def categorical_focal_loss(gamma=2., alpha=.25):\n    def categorical_focal_loss_fixed(y_true, y_pred):\n        y_pred /= K.sum(y_pred, axis=-1, keepdims=True)\n        epsilon = K.epsilon()\n        y_pred = K.clip(y_pred, epsilon, 1. - epsilon)\n        cross_entropy = -y_true * K.log(y_pred)\n        loss = alpha * K.pow(1 - y_pred, gamma) * cross_entropy\n        return K.sum(loss, axis=1)\n    return categorical_focal_loss_fixed","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":0.064055,"end_time":"2020-12-10T08:17:17.560341","exception":false,"start_time":"2020-12-10T08:17:17.496286","status":"completed"},"tags":[]},"cell_type":"markdown","source":"<p>\n<h1><center> EfficientNetB7 </center></h1>\n<center><img src='https://1.bp.blogspot.com/-DjZT_TLYZok/XO3BYqpxCJI/AAAAAAAAEKM/BvV53klXaTUuQHCkOXZZGywRMdU9v9T_wCLcBGAs/s1600/image2.png' height=350></center>\n<p>"},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T08:17:17.700582Z","iopub.status.busy":"2020-12-10T08:17:17.699646Z","iopub.status.idle":"2020-12-10T08:18:52.806373Z","shell.execute_reply":"2020-12-10T08:18:52.805443Z"},"papermill":{"duration":95.179081,"end_time":"2020-12-10T08:18:52.806527","exception":false,"start_time":"2020-12-10T08:17:17.627446","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"with strategy.scope():\n    enet = efn.EfficientNetB7(input_shape=(img_size, img_size, 3),weights='noisy-student',include_top=False)","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T08:18:53.501257Z","iopub.status.busy":"2020-12-10T08:18:53.495894Z","iopub.status.idle":"2020-12-10T08:18:53.543313Z","shell.execute_reply":"2020-12-10T08:18:53.542641Z"},"papermill":{"duration":0.426312,"end_time":"2020-12-10T08:18:53.543457","exception":false,"start_time":"2020-12-10T08:18:53.117145","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"with strategy.scope():\n    for layer in  enet.layers:\n        layer.trainable = False","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T08:18:54.176077Z","iopub.status.busy":"2020-12-10T08:18:54.139599Z","iopub.status.idle":"2020-12-10T08:19:15.039656Z","shell.execute_reply":"2020-12-10T08:19:15.038929Z"},"papermill":{"duration":21.20554,"end_time":"2020-12-10T08:19:15.039807","exception":false,"start_time":"2020-12-10T08:18:53.834267","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"with strategy.scope():\n    ef7 =tf.keras.Sequential()\n    ef7.add(enet)\n    ef7.add(tf.keras.layers.GlobalAveragePooling2D())\n    ef7.add(tf.keras.layers.Flatten())\n\n    ef7.add(tf.keras.layers.Dense(4096,activation='relu'))\n    ef7.add(tf.keras.layers.BatchNormalization())\n    ef7.add(tf.keras.layers.LeakyReLU())\n    ef7.add(tf.keras.layers.Dropout(0.55))\n    \n    ef7.add(tf.keras.layers.Dense(2048,activation='relu'))\n    ef7.add(tf.keras.layers.BatchNormalization())\n    ef7.add(tf.keras.layers.LeakyReLU())\n    ef7.add(tf.keras.layers.Dropout(0.55))\n\n    ef7.add(tf.keras.layers.Dense(1024,activation='relu'))\n    ef7.add(tf.keras.layers.BatchNormalization())\n    ef7.add(tf.keras.layers.LeakyReLU())\n    ef7.add(tf.keras.layers.Dropout(0.55))\n    \n    \n    ef7.add(tf.keras.layers.Dense(2,activation='softmax'))\n    ef7.compile(\n                optimizer=tf.optimizers.Adam(lr=0.0001),\n                loss=categorical_focal_loss(gamma=2., alpha=.25),\n                metrics=['categorical_accuracy',\n                        tf.keras.metrics.Recall(),\n                        tf.keras.metrics.Precision(),   \n                        tf.keras.metrics.AUC(),\n                        tfa.metrics.F1Score(num_classes=2, average=\"macro\")\n                       ])\n","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":0.297817,"end_time":"2020-12-10T08:19:15.634772","exception":false,"start_time":"2020-12-10T08:19:15.336955","status":"completed"},"tags":[]},"cell_type":"markdown","source":"# 10 Entraînement"},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T08:19:16.254242Z","iopub.status.busy":"2020-12-10T08:19:16.252739Z","iopub.status.idle":"2020-12-10T09:15:59.444441Z","shell.execute_reply":"2020-12-10T09:15:59.443728Z"},"papermill":{"duration":3403.513822,"end_time":"2020-12-10T09:15:59.444628","exception":false,"start_time":"2020-12-10T08:19:15.930806","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"h7=ef7.fit(\n    train_dataset,\n    steps_per_epoch=train_labels.shape[0] // BATCH_SIZE,\n    callbacks=[lr_callback],\n    epochs=EPOCHS)","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":1.306124,"end_time":"2020-12-10T09:16:02.118605","exception":false,"start_time":"2020-12-10T09:16:00.812481","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## 11. Affichage des courbes (acc,loss)"},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T09:16:04.737278Z","iopub.status.busy":"2020-12-10T09:16:04.736497Z","iopub.status.idle":"2020-12-10T09:16:05.805493Z","shell.execute_reply":"2020-12-10T09:16:05.804735Z"},"papermill":{"duration":2.391721,"end_time":"2020-12-10T09:16:05.805619","exception":false,"start_time":"2020-12-10T09:16:03.413898","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"import seaborn as sns\nsns.set()\nfig = plt.figure(0, (12, 4))\n\nax = plt.subplot(1, 2, 1)\nsns.lineplot(h7.epoch,h7.history['categorical_accuracy'], label = 'train')\nplt.title('Accuracy')\nplt.tight_layout()\n\nax = plt.subplot(1, 2, 2)\nsns.lineplot(h7.epoch,h7.history['loss'], label = 'train')\nplt.title('Loss')\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":1.323851,"end_time":"2020-12-10T09:16:08.455089","exception":false,"start_time":"2020-12-10T09:16:07.131238","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## 11. Test et évaluation"},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T09:16:11.200066Z","iopub.status.busy":"2020-12-10T09:16:11.198769Z","iopub.status.idle":"2020-12-10T09:16:58.048443Z","shell.execute_reply":"2020-12-10T09:16:58.04764Z"},"papermill":{"duration":48.269725,"end_time":"2020-12-10T09:16:58.048581","exception":false,"start_time":"2020-12-10T09:16:09.778856","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"ef7.evaluate(test_dataset)","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T09:17:00.720525Z","iopub.status.busy":"2020-12-10T09:17:00.719667Z","iopub.status.idle":"2020-12-10T09:17:35.448295Z","shell.execute_reply":"2020-12-10T09:17:35.4476Z"},"papermill":{"duration":36.062986,"end_time":"2020-12-10T09:17:35.448432","exception":false,"start_time":"2020-12-10T09:16:59.385446","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"from sklearn.metrics import confusion_matrix\nclasses=['N', 'C', 'G','M','H','A']\nY_pred = ef7.predict(test_dataset)\ntrue_classes = valid.loc[:, ['N', 'C', 'G','M','H','A']].values\nprint('Confusion Matrix')\ncm=confusion_matrix(true_classes.argmax(axis=1),Y_pred.argmax(axis=1))\ncm","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":1.430434,"end_time":"2020-12-10T09:17:38.194369","exception":false,"start_time":"2020-12-10T09:17:36.763935","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## 12. Matrice de confusion"},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T09:17:41.01112Z","iopub.status.busy":"2020-12-10T09:17:41.010246Z","iopub.status.idle":"2020-12-10T09:17:41.027182Z","shell.execute_reply":"2020-12-10T09:17:41.025059Z"},"papermill":{"duration":1.405458,"end_time":"2020-12-10T09:17:41.027444","exception":false,"start_time":"2020-12-10T09:17:39.621986","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"import seaborn as sns\nsns.set_style(\"darkgrid\")\nimport itertools\ndef plot_confusion_matrix(cm, classes, normalize=False, title='Confusion matrix', cmap=plt.cm.Oranges):\n    plt.figure(figsize=(6,6))\n    plt.imshow(cm, interpolation='nearest', cmap=cmap)\n    plt.title(title)\n    plt.colorbar()\n    tick_marks = np.arange(len(classes))\n    plt.xticks(tick_marks, classes, rotation=45)\n    plt.yticks(tick_marks, classes)\n    if normalize:\n        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]\n        cm = np.around(cm, decimals=2)\n        cm[np.isnan(cm)] = 0.0\n        print(\"Normalized confusion matrix\")\n    else:\n        print('Confusion matrix, without normalization')\n    thresh = cm.max() / 2.\n    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):\n        plt.text(j, i, cm[i, j],\n                 horizontalalignment=\"center\",\n                 color=\"white\" if cm[i, j] > thresh else \"black\")\n    plt.tight_layout()\n    plt.ylabel('True label')\n    plt.xlabel('Predicted label')","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T09:17:43.754431Z","iopub.status.busy":"2020-12-10T09:17:43.752825Z","iopub.status.idle":"2020-12-10T09:17:44.116279Z","shell.execute_reply":"2020-12-10T09:17:44.115504Z"},"papermill":{"duration":1.713627,"end_time":"2020-12-10T09:17:44.11641","exception":false,"start_time":"2020-12-10T09:17:42.402783","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"plot_confusion_matrix(cm,classes)","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":1.32175,"end_time":"2020-12-10T09:17:46.817581","exception":false,"start_time":"2020-12-10T09:17:45.495831","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## 13. specificity et sensitivity"},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T09:17:49.490497Z","iopub.status.busy":"2020-12-10T09:17:49.489388Z","iopub.status.idle":"2020-12-10T09:17:49.493406Z","shell.execute_reply":"2020-12-10T09:17:49.492776Z"},"papermill":{"duration":1.360595,"end_time":"2020-12-10T09:17:49.49355","exception":false,"start_time":"2020-12-10T09:17:48.132955","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"def calculate_sensitivity_specificity(y_test, y_pred_test):\n    actual_pos = y_test == 1\n    actual_neg = y_test == 0\n    \n    true_pos = (y_pred_test == 1) & (actual_pos)\n    false_pos = (y_pred_test == 1) & (actual_neg)\n    true_neg = (y_pred_test == 0) & (actual_neg)\n    false_neg = (y_pred_test == 0) & (actual_pos)\n    \n    # Calculate sensitivity and specificity\n    sensitivity = np.sum(true_pos) / np.sum(actual_pos)\n    specificity = np.sum(true_neg) / np.sum(actual_neg)\n    \n    return sensitivity, specificity","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T09:17:52.123734Z","iopub.status.busy":"2020-12-10T09:17:52.122579Z","iopub.status.idle":"2020-12-10T09:17:52.128837Z","shell.execute_reply":"2020-12-10T09:17:52.128177Z"},"papermill":{"duration":1.321808,"end_time":"2020-12-10T09:17:52.128975","exception":false,"start_time":"2020-12-10T09:17:50.807167","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"sensitivity, specificity= calculate_sensitivity_specificity(true_classes.argmax(axis=1),Y_pred.argmax(axis=1))\nprint ('Sensitivity:', sensitivity)\nprint ('Specificity:', specificity)","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":1.318563,"end_time":"2020-12-10T09:17:54.772906","exception":false,"start_time":"2020-12-10T09:17:53.454343","status":"completed"},"tags":[]},"cell_type":"markdown","source":"<p>\n<h1><center> DenseNet201 </center></h1>\n<center><img src='https://oi.readthedocs.io/en/latest/_images/cnn_vs_resnet_vs_densenet.png' height=500></center>\n<p>\n"},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T09:17:57.521291Z","iopub.status.busy":"2020-12-10T09:17:57.520507Z","iopub.status.idle":"2020-12-10T09:18:57.905729Z","shell.execute_reply":"2020-12-10T09:18:57.904812Z"},"papermill":{"duration":61.704413,"end_time":"2020-12-10T09:18:57.905881","exception":false,"start_time":"2020-12-10T09:17:56.201468","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"with strategy.scope():\n    DenseNet201 = tf.keras.applications.DenseNet201(input_shape=(512, 512, 3), weights='imagenet', include_top=False)","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T09:19:00.833939Z","iopub.status.busy":"2020-12-10T09:19:00.828531Z","iopub.status.idle":"2020-12-10T09:19:00.88137Z","shell.execute_reply":"2020-12-10T09:19:00.880517Z"},"papermill":{"duration":1.472209,"end_time":"2020-12-10T09:19:00.881559","exception":false,"start_time":"2020-12-10T09:18:59.40935","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"with strategy.scope():\n    for layer in  DenseNet201.layers:\n        layer.trainable = False\n\n    for i in range(-6,0):\n         DenseNet201.layers[i].trainable = True","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T09:19:03.736714Z","iopub.status.busy":"2020-12-10T09:19:03.715145Z","iopub.status.idle":"2020-12-10T09:19:25.464552Z","shell.execute_reply":"2020-12-10T09:19:25.465229Z"},"papermill":{"duration":23.177124,"end_time":"2020-12-10T09:19:25.465418","exception":false,"start_time":"2020-12-10T09:19:02.288294","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"with strategy.scope():\n    model_D201=tf.keras.Sequential()\n    model_D201.add(DenseNet201)\n    model_D201.add(tf.keras.layers.GlobalAveragePooling2D())\n    model_D201.add(tf.keras.layers.Flatten())\n\n    model_D201.add(tf.keras.layers.Dense(4096,activation='relu'))\n    model_D201.add(tf.keras.layers.BatchNormalization())\n    model_D201.add(tf.keras.layers.LeakyReLU())\n    model_D201.add(tf.keras.layers.Dropout(0.55))\n    \n    model_D201.add(tf.keras.layers.Dense(2048,activation='relu'))\n    model_D201.add(tf.keras.layers.BatchNormalization())\n    model_D201.add(tf.keras.layers.LeakyReLU())\n    model_D201.add(tf.keras.layers.Dropout(0.55))\n    \n    model_D201.add(tf.keras.layers.Dense(1024,activation='relu'))\n    model_D201.add(tf.keras.layers.BatchNormalization())\n    model_D201.add(tf.keras.layers.LeakyReLU())\n    model_D201.add(tf.keras.layers.Dropout(0.55))\n    \n    \n    model_D201.add(tf.keras.layers.Dense(6,activation='softmax'))\n    model_D201.compile(\n                optimizer=tf.optimizers.Adam(lr=0.0001),\n                loss=categorical_focal_loss(gamma=2., alpha=.25),\n                metrics=['categorical_accuracy',\n                        tf.keras.metrics.Recall(),\n                        tf.keras.metrics.Precision(),   \n                        tf.keras.metrics.AUC(),\n                        tfa.metrics.F1Score(num_classes=6, average=\"macro\")\n                       ])\n","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":1.325117,"end_time":"2020-12-10T09:19:28.128995","exception":false,"start_time":"2020-12-10T09:19:26.803878","status":"completed"},"tags":[]},"cell_type":"markdown","source":"# 1. Entraînement"},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T09:19:30.879973Z","iopub.status.busy":"2020-12-10T09:19:30.874717Z","iopub.status.idle":"2020-12-10T10:16:37.668166Z","shell.execute_reply":"2020-12-10T10:16:37.667511Z"},"papermill":{"duration":3428.177438,"end_time":"2020-12-10T10:16:37.668389","exception":false,"start_time":"2020-12-10T09:19:29.490951","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"D_201=model_D201.fit(\n    train_dataset, \n    steps_per_epoch=train_labels.shape[0] // BATCH_SIZE,\n    callbacks=[lr_callback],\n    epochs=EPOCHS)\n    #validation_data=test_dataset)","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":2.412697,"end_time":"2020-12-10T10:16:42.554262","exception":false,"start_time":"2020-12-10T10:16:40.141565","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## 2.Affichage des courbes (acc,loss)"},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T10:16:47.291922Z","iopub.status.busy":"2020-12-10T10:16:47.290922Z","iopub.status.idle":"2020-12-10T10:16:48.162015Z","shell.execute_reply":"2020-12-10T10:16:48.16124Z"},"papermill":{"duration":3.239685,"end_time":"2020-12-10T10:16:48.162143","exception":false,"start_time":"2020-12-10T10:16:44.922458","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"import seaborn as sns\nsns.set()\nfig = plt.figure(0, (12, 4))\n\nax = plt.subplot(1, 2, 1)\nsns.lineplot(D_201.epoch,D_201.history['categorical_accuracy'], label = 'train')\nplt.title('Accuracy')\nplt.tight_layout()\n\nax = plt.subplot(1, 2, 2)\nsns.lineplot(D_201.epoch,D_201.history['loss'], label = 'train')\nplt.title('Loss')\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":2.357091,"end_time":"2020-12-10T10:16:52.876112","exception":false,"start_time":"2020-12-10T10:16:50.519021","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## 3. Test et évaluation"},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T10:16:57.638085Z","iopub.status.busy":"2020-12-10T10:16:57.636783Z","iopub.status.idle":"2020-12-10T10:17:31.464364Z","shell.execute_reply":"2020-12-10T10:17:31.450512Z"},"papermill":{"duration":36.165148,"end_time":"2020-12-10T10:17:31.464505","exception":false,"start_time":"2020-12-10T10:16:55.299357","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"model_D201.evaluate(test_dataset)","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T10:17:36.267437Z","iopub.status.busy":"2020-12-10T10:17:36.266186Z","iopub.status.idle":"2020-12-10T10:18:11.313593Z","shell.execute_reply":"2020-12-10T10:18:11.312935Z"},"papermill":{"duration":37.51775,"end_time":"2020-12-10T10:18:11.313718","exception":false,"start_time":"2020-12-10T10:17:33.795968","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"from sklearn.metrics import confusion_matrix,classification_report\nY_pred = model_D201.predict(test_dataset)\ntrue_classes = valid.loc[:, ['N', 'C', 'G','M','H','A']].values\nprint('Confusion Matrix')\ncm=confusion_matrix(true_classes.argmax(axis=1),Y_pred.argmax(axis=1))\ncm","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T10:18:16.029407Z","iopub.status.busy":"2020-12-10T10:18:16.023915Z","iopub.status.idle":"2020-12-10T10:18:16.365726Z","shell.execute_reply":"2020-12-10T10:18:16.365084Z"},"papermill":{"duration":2.689326,"end_time":"2020-12-10T10:18:16.365863","exception":false,"start_time":"2020-12-10T10:18:13.676537","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"plot_confusion_matrix(cm,classes)","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":2.451271,"end_time":"2020-12-10T10:18:21.175329","exception":false,"start_time":"2020-12-10T10:18:18.724058","status":"completed"},"tags":[]},"cell_type":"markdown","source":"## 4. Matrice de confusion"},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T10:18:26.030758Z","iopub.status.busy":"2020-12-10T10:18:26.029892Z","iopub.status.idle":"2020-12-10T10:18:26.034903Z","shell.execute_reply":"2020-12-10T10:18:26.035722Z"},"papermill":{"duration":2.404795,"end_time":"2020-12-10T10:18:26.035922","exception":false,"start_time":"2020-12-10T10:18:23.631127","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"sensitivity, specificity= calculate_sensitivity_specificity(true_classes.argmax(axis=1),Y_pred.argmax(axis=1))\nprint ('Sensitivity:', sensitivity)\nprint ('Specificity:', specificity)","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T10:18:30.781737Z","iopub.status.busy":"2020-12-10T10:18:30.780591Z","iopub.status.idle":"2020-12-10T10:18:30.78383Z","shell.execute_reply":"2020-12-10T10:18:30.784398Z"},"papermill":{"duration":2.389734,"end_time":"2020-12-10T10:18:30.784574","exception":false,"start_time":"2020-12-10T10:18:28.39484","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"from keras.models import Sequential, load_model\nfrom keras.layers import (Activation, Dropout, Flatten, Dense, GlobalMaxPooling2D,\n                          BatchNormalization, Input, Conv2D, GlobalAveragePooling2D,concatenate,Concatenate,multiply, LocallyConnected2D, Lambda)\nfrom keras.callbacks import ModelCheckpoint\nfrom keras import metrics\nfrom keras.optimizers import Adam \nimport keras\nfrom keras.models import Model\nfrom keras.activations import hard_sigmoid\nCFG = dict(\n    inp_size          = 512,\n    read_size         = 512, \n    crop_size         = 512,\n    net_size          = 512)\n","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T10:18:35.626868Z","iopub.status.busy":"2020-12-10T10:18:35.61315Z","iopub.status.idle":"2020-12-10T10:19:58.102195Z","shell.execute_reply":"2020-12-10T10:19:58.101359Z"},"papermill":{"duration":84.907083,"end_time":"2020-12-10T10:19:58.102434","exception":false,"start_time":"2020-12-10T10:18:33.195351","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"with strategy.scope():\n    in_lay = Input(shape=(CFG['inp_size'], CFG['inp_size'],3))\n    base_model = efn.EfficientNetB7(weights='noisy-student',\n        input_shape=(CFG['inp_size'], CFG['inp_size'],3),\n        include_top=False\n                       )\n    #base_model.load_weights(\"../input/efficientnet-keras-weights-b0b5/efficientnet-b5_imagenet_1000_notop.h5\")\n    pt_depth = base_model.get_output_shape_at(0)[-1]\n    pt_features = base_model(in_lay)\n    bn_features = BatchNormalization()(pt_features)\n    \n    # ici nous faisons un mécanisme d'attention pour activer et désactiver les pixels dans le GAP\n    # lidee est baser sur cette explication \n    #1-http://akosiorek.github.io/ml/2017/10/14/visual-attention.html\n    #2-https://machinelearningmastery.com/how-does-attention-work-in-encoder-decoder-recurrent-neural-networks/\n    \n    \n    attn_layer = Conv2D(64, kernel_size = (1,1), padding = 'same', activation = 'relu')(Dropout(0.55)(bn_features))\n    attn_layer = Conv2D(16, kernel_size = (1,1), padding = 'same', activation = 'relu')(attn_layer)\n    attn_layer = Conv2D(8, kernel_size = (1,1), padding = 'same', activation = 'relu')(attn_layer)\n    attn_layer = Conv2D(1, \n                        kernel_size = (1,1), \n                        padding = 'valid', \n                        activation = 'sigmoid')(attn_layer)\n    # diffusez sur toutes les chaînes\n    # kernel_size  détermine les dimensions du noyau. Les dimensions courantes comprennent 1×1, 3×3, 5×5 et 7×7, qui peuvent être passées en (1, 1), (3, 3), (5, 5) ou (7, 7) tuples.\n    # Il s'agit d'un nombre entier ou d'un tuple/liste de 2 nombres entiers, spécifiant la hauteur et la largeur de la fenêtre de convolution 2D.\n    #  Ce paramètre doit être un nombre entier impair\n    # pour plus de details sur cette partie (mask et use_bias ... ) il ya  une bonne explication sur geekforgeeks\n    #https://www.geeksforgeeks.org/keras-conv2d-class/\n    \n    up_c2_w = np.ones((1, 1, 1, pt_depth))\n    up_c2 = Conv2D(pt_depth, kernel_size = (1,1), padding = 'same', \n                   activation = 'linear', use_bias = False, weights = [up_c2_w])\n    up_c2.trainable = False\n    attn_layer = up_c2(attn_layer)\n\n    mask_features = multiply([attn_layer, bn_features])\n    gap_features = GlobalAveragePooling2D()(mask_features)\n    gap_mask = GlobalAveragePooling2D()(attn_layer)\n    \n    # pour tenir compte des valeurs manquantes du modèle d'attention\n    # pour bien comprendre resaclegap il ya un bon exemple ici qui explique tellemnt bien cette partie \n    # https://codefellows.github.io/sea-python-401d5/lectures/rescaling_data.html\n    \n    gap = Lambda(lambda x: x[0]/x[1], name = 'RescaleGAP')([gap_features, gap_mask])\n    gap_dr = Dropout(0.55)(gap)\n    dr_steps = Dropout(0.55)(Dense(128, activation = 'relu')(gap_dr))\n    out_layer = Dense(6, activation = 'softmax')(dr_steps)\n    model = Model(inputs = [in_lay], outputs = [out_layer])  \n    model.compile(\n                optimizer=tf.optimizers.Adam(lr=0.0001),\n                loss=categorical_focal_loss(gamma=2., alpha=.25),\n                metrics=['categorical_accuracy',\n                        tf.keras.metrics.Recall(),\n                        tf.keras.metrics.Precision(),   \n                        tf.keras.metrics.AUC(),\n                        tfa.metrics.F1Score(num_classes=6, average=\"macro\")\n                       ])","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T10:20:02.851682Z","iopub.status.busy":"2020-12-10T10:20:02.837716Z","iopub.status.idle":"2020-12-10T11:22:56.070977Z","shell.execute_reply":"2020-12-10T11:22:56.071744Z"},"papermill":{"duration":3775.584893,"end_time":"2020-12-10T11:22:56.071972","exception":false,"start_time":"2020-12-10T10:20:00.487079","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"ATT_EF7= model.fit(\n    train_dataset, \n    steps_per_epoch=train_labels.shape[0] // BATCH_SIZE,\n    callbacks=[lr_callback],\n    epochs=EPOCHS)","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T11:23:02.851259Z","iopub.status.busy":"2020-12-10T11:23:02.850411Z","iopub.status.idle":"2020-12-10T11:23:03.801691Z","shell.execute_reply":"2020-12-10T11:23:03.800871Z"},"papermill":{"duration":4.346346,"end_time":"2020-12-10T11:23:03.801827","exception":false,"start_time":"2020-12-10T11:22:59.455481","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"import seaborn as sns\nsns.set()\nfig = plt.figure(0, (12, 4))\n\nax = plt.subplot(1, 2, 1)\nsns.lineplot(ATT_EF7.epoch,ATT_EF7.history['categorical_accuracy'], label = 'train')\nplt.title('Accuracy')\nplt.tight_layout()\n\nax = plt.subplot(1, 2, 2)\nsns.lineplot(ATT_EF7.epoch,ATT_EF7.history['loss'], label = 'train')\nplt.title('Loss')\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T11:23:10.707742Z","iopub.status.busy":"2020-12-10T11:23:10.706707Z","iopub.status.idle":"2020-12-10T11:23:48.88642Z","shell.execute_reply":"2020-12-10T11:23:48.872138Z"},"papermill":{"duration":41.628991,"end_time":"2020-12-10T11:23:48.886563","exception":false,"start_time":"2020-12-10T11:23:07.257572","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"model.evaluate(test_dataset)","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T11:23:55.690801Z","iopub.status.busy":"2020-12-10T11:23:55.689726Z","iopub.status.idle":"2020-12-10T11:24:33.595902Z","shell.execute_reply":"2020-12-10T11:24:33.595248Z"},"papermill":{"duration":41.336631,"end_time":"2020-12-10T11:24:33.596028","exception":false,"start_time":"2020-12-10T11:23:52.259397","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"from sklearn.metrics import confusion_matrix,classification_report\nY_pred = model.predict(test_dataset)\ntrue_classes = valid.loc[:, ['N', 'C', 'G','M','H','A']].values\nprint('Confusion Matrix')\ncm=confusion_matrix(true_classes.argmax(axis=1),Y_pred.argmax(axis=1))\ncm","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T11:24:40.560187Z","iopub.status.busy":"2020-12-10T11:24:40.558131Z","iopub.status.idle":"2020-12-10T11:24:40.896439Z","shell.execute_reply":"2020-12-10T11:24:40.895651Z"},"papermill":{"duration":3.869427,"end_time":"2020-12-10T11:24:40.896569","exception":false,"start_time":"2020-12-10T11:24:37.027142","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"plot_confusion_matrix(cm,classes)","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T11:24:47.805357Z","iopub.status.busy":"2020-12-10T11:24:47.80441Z","iopub.status.idle":"2020-12-10T11:24:47.810172Z","shell.execute_reply":"2020-12-10T11:24:47.809206Z"},"papermill":{"duration":3.406536,"end_time":"2020-12-10T11:24:47.810361","exception":false,"start_time":"2020-12-10T11:24:44.403825","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"sensitivity, specificity= calculate_sensitivity_specificity(true_classes.argmax(axis=1),Y_pred.argmax(axis=1))\nprint ('Sensitivity:', sensitivity)\nprint ('Specificity:', specificity)","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T11:24:54.710296Z","iopub.status.busy":"2020-12-10T11:24:54.70905Z","iopub.status.idle":"2020-12-10T11:26:18.512684Z","shell.execute_reply":"2020-12-10T11:26:18.511253Z"},"papermill":{"duration":87.305263,"end_time":"2020-12-10T11:26:18.512918","exception":false,"start_time":"2020-12-10T11:24:51.207655","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"with strategy.scope():\n    in_lay = Input(shape=(CFG['inp_size'], CFG['inp_size'],3))\n    base_model = tf.keras.applications.DenseNet201(weights='imagenet',\n        input_shape=(CFG['inp_size'], CFG['inp_size'],3),\n        include_top=False\n                       )\n    #base_model.load_weights(\"../input/efficientnet-keras-weights-b0b5/efficientnet-b5_imagenet_1000_notop.h5\")\n    pt_depth = base_model.get_output_shape_at(0)[-1]\n    pt_features = base_model(in_lay)\n    bn_features = BatchNormalization()(pt_features)\n    \n    # ici nous faisons un mécanisme d'attention pour activer et désactiver les pixels dans le GAP\n    # lidee est baser sur cette explication \n    #1-http://akosiorek.github.io/ml/2017/10/14/visual-attention.html\n    #2-https://machinelearningmastery.com/how-does-attention-work-in-encoder-decoder-recurrent-neural-networks/\n    \n    \n    attn_layer = Conv2D(64, kernel_size = (1,1), padding = 'same', activation = 'relu')(Dropout(0.55)(bn_features))\n    attn_layer = Conv2D(16, kernel_size = (1,1), padding = 'same', activation = 'relu')(attn_layer)\n    attn_layer = Conv2D(8, kernel_size = (1,1), padding = 'same', activation = 'relu')(attn_layer)\n    attn_layer = Conv2D(1, \n                        kernel_size = (1,1), \n                        padding = 'valid', \n                        activation = 'sigmoid')(attn_layer)\n    # diffusez sur toutes les chaînes\n    # kernel_size  détermine les dimensions du noyau. Les dimensions courantes comprennent 1×1, 3×3, 5×5 et 7×7, qui peuvent être passées en (1, 1), (3, 3), (5, 5) ou (7, 7) tuples.\n    # Il s'agit d'un nombre entier ou d'un tuple/liste de 2 nombres entiers, spécifiant la hauteur et la largeur de la fenêtre de convolution 2D.\n    #  Ce paramètre doit être un nombre entier impair\n    # pour plus de details sur cette partie (mask et use_bias ... ) il ya  une bonne explication sur geekforgeeks\n    #https://www.geeksforgeeks.org/keras-conv2d-class/\n    \n    up_c2_w = np.ones((1, 1, 1, pt_depth))\n    up_c2 = Conv2D(pt_depth, kernel_size = (1,1), padding = 'same', \n                   activation = 'linear', use_bias = False, weights = [up_c2_w])\n    up_c2.trainable = False\n    attn_layer = up_c2(attn_layer)\n\n    mask_features = multiply([attn_layer, bn_features])\n    gap_features = GlobalAveragePooling2D()(mask_features)\n    gap_mask = GlobalAveragePooling2D()(attn_layer)\n    \n    # pour tenir compte des valeurs manquantes du modèle d'attention\n    # pour bien comprendre resaclegap il ya un bon exemple ici qui explique tellemnt bien cette partie \n    # https://codefellows.github.io/sea-python-401d5/lectures/rescaling_data.html\n    \n    gap = Lambda(lambda x: x[0]/x[1], name = 'RescaleGAP')([gap_features, gap_mask])\n    gap_dr = Dropout(0.55)(gap)\n    dr_steps = Dropout(0.55)(Dense(128, activation = 'relu')(gap_dr))\n    out_layer = Dense(6, activation = 'softmax')(dr_steps)\n    model_d201 = Model(inputs = [in_lay], outputs = [out_layer])  \n    model_d201.compile(\n                optimizer=tf.optimizers.Adam(lr=0.0001),\n                loss=categorical_focal_loss(gamma=2., alpha=.25),\n                metrics=['categorical_accuracy',\n                        tf.keras.metrics.Recall(),\n                        tf.keras.metrics.Precision(),   \n                        tf.keras.metrics.AUC(),\n                        tfa.metrics.F1Score(num_classes=6, average=\"macro\")\n                       ])","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T11:26:25.461718Z","iopub.status.busy":"2020-12-10T11:26:25.460154Z","iopub.status.idle":"2020-12-10T12:29:55.258726Z","shell.execute_reply":"2020-12-10T12:29:55.257825Z"},"papermill":{"duration":3813.317559,"end_time":"2020-12-10T12:29:55.25892","exception":false,"start_time":"2020-12-10T11:26:21.941361","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"d201= model_d201.fit(\n    train_dataset, \n    steps_per_epoch=train_labels.shape[0] // BATCH_SIZE,\n    callbacks=[lr_callback],\n    epochs=EPOCHS)","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T12:30:04.340173Z","iopub.status.busy":"2020-12-10T12:30:04.339121Z","iopub.status.idle":"2020-12-10T12:30:05.298822Z","shell.execute_reply":"2020-12-10T12:30:05.297991Z"},"papermill":{"duration":5.497677,"end_time":"2020-12-10T12:30:05.298974","exception":false,"start_time":"2020-12-10T12:29:59.801297","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"import seaborn as sns\nsns.set()\nfig = plt.figure(0, (12, 4))\n\nax = plt.subplot(1, 2, 1)\nsns.lineplot(d201.epoch,d201.history['categorical_accuracy'], label = 'train')\nplt.title('Accuracy')\nplt.tight_layout()\n\nax = plt.subplot(1, 2, 2)\nsns.lineplot(d201.epoch,d201.history['loss'], label = 'train')\nplt.title('Loss')\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T12:30:14.310076Z","iopub.status.busy":"2020-12-10T12:30:14.30885Z","iopub.status.idle":"2020-12-10T12:30:58.992259Z","shell.execute_reply":"2020-12-10T12:30:58.974755Z"},"papermill":{"duration":49.168869,"end_time":"2020-12-10T12:30:58.99243","exception":false,"start_time":"2020-12-10T12:30:09.823561","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"model_d201.evaluate(test_dataset)","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T12:31:08.093834Z","iopub.status.busy":"2020-12-10T12:31:08.092936Z","iopub.status.idle":"2020-12-10T12:31:45.840121Z","shell.execute_reply":"2020-12-10T12:31:45.839189Z"},"papermill":{"duration":42.308572,"end_time":"2020-12-10T12:31:45.840348","exception":false,"start_time":"2020-12-10T12:31:03.531776","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"from sklearn.metrics import confusion_matrix,classification_report\nY_pred = model_d201.predict(test_dataset)\ntrue_classes = valid.loc[:, ['N', 'C', 'G','M','H','A']].values\nprint('Confusion Matrix')\ncm=confusion_matrix(true_classes.argmax(axis=1),Y_pred.argmax(axis=1))\ncm","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T12:31:54.871937Z","iopub.status.busy":"2020-12-10T12:31:54.867406Z","iopub.status.idle":"2020-12-10T12:31:55.241389Z","shell.execute_reply":"2020-12-10T12:31:55.240613Z"},"papermill":{"duration":4.863504,"end_time":"2020-12-10T12:31:55.241533","exception":false,"start_time":"2020-12-10T12:31:50.378029","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"plot_confusion_matrix(cm,classes)","execution_count":null,"outputs":[]},{"metadata":{"execution":{"iopub.execute_input":"2020-12-10T12:32:04.284751Z","iopub.status.busy":"2020-12-10T12:32:04.283806Z","iopub.status.idle":"2020-12-10T12:32:04.288716Z","shell.execute_reply":"2020-12-10T12:32:04.287878Z"},"papermill":{"duration":4.453284,"end_time":"2020-12-10T12:32:04.288896","exception":false,"start_time":"2020-12-10T12:31:59.835612","status":"completed"},"tags":[],"trusted":true},"cell_type":"code","source":"sensitivity, specificity= calculate_sensitivity_specificity(true_classes.argmax(axis=1),Y_pred.argmax(axis=1))\nprint ('Sensitivity:', sensitivity)\nprint ('Specificity:', specificity)","execution_count":null,"outputs":[]},{"metadata":{"papermill":{"duration":4.479287,"end_time":"2020-12-10T12:32:31.666575","exception":false,"start_time":"2020-12-10T12:32:27.187288","status":"completed"},"tags":[]},"cell_type":"markdown","source":"| Methodes | Loss | Accuracy  | Precision | Recall  |F1_score  |specificity |sensitivity  |\n| --- | --- | --- | --- | --- | --- | --- | --- |\n| VGG16 |  0.9876 | 0.9884  | 0.9840|0.9874 |0.9991 |0.9991 |0.9991 |\n| VGG19 | 0.9662  | 0.9807| 0.9484 |0.9657 |1.0000 |0.9991 |0.9991 |\n|DenseNet201|0.9662  | 0.9807| 0.9484 |0.9657 |1.0000 |0.9991 |0.9991 |\n|EfficientNetB7 |0.9662  | 0.9807| 0.9484 |0.9657 |1.0000 |0.9991 |0.9991 |"}],"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":4,"nbformat_minor":4}