TP-reseaux-profond/TP6.ipynb

1702 lines
967 KiB
Plaintext
Raw Normal View History

2023-06-22 18:35:38 +00:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "Kd4SVfDxz5aw"
},
"source": [
"<h1>Localisation et détection d'objet</h1>\n",
"\n",
"Dans ce TP, nous allons mettre en pratique certaines des méthodes présentées en cours pour localiser des objets dans une image.\n",
"\n",
"En localisation et détection, on cherche à déterminer la position d'un objet, ainsi que sa classe, sous la forme d'une boîte englobante de largeur $b_w$ et hauteur $b_h$, et dont le centre a pour coordonnées le point $(b_x, b_y)$. \n",
"\n",
"<center> <img src=\"https://drive.google.com/uc?id=1_jHHv6ZDe-3Xz25jIZ6o177laBEfmMRR\" style=\"width:500;height:300px;\"></center>\n",
"<caption><center> Figure 1: Modèle de boîte englobante utilisé pour la localisation </center></caption>\n",
"\n",
"Le problème de localisation considère qu'un seul objet est présent sur l'image, alors que le problème de détection cherche à déterminer l'ensemble des objets présents sur l'image.\n",
"\n",
"\n",
"\n",
"Pour commencer, récupérez les images de la base de données :\n"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"id": "2ZjveWpbuNeV"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"fatal: le chemin de destination 'mangeoires_loc' existe déjà et n'est pas un répertoire vide.\n"
]
}
],
"source": [
"!git clone https://github.com/axelcarlier/mangeoires_loc.git"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "LF6aRZLE2-Yl"
},
"source": [
"La base de données consiste en des photographies prises par une caméra reliée à une Raspberry Pi, cachée dans une mangeoire. Plusieurs mangeoires sont disséminées dans la nature en Occitanie, et l'objectif de [ce projet](https://econect.cnrs.fr/) est la reconnaissance des espèces et le comptage des individus qui viennent se poser devant le caméra, afin de suivre l'évolution des populations d'oiseaux et ainsi monitorer la biodiversité.\n",
"\n",
"La base de données qui vous est fournie regroupe 11 espèces d'animaux, majoritairement des oiseaux, désignés par un code : \n",
"\n",
"1. Mésange charbonnière (**MESCHA**)\n",
"2. Verdier d'Europe (**VEREUR**)\n",
"3. Écureuil roux (**ECUROU**)\n",
"4. Pie bavarde (**PIEBAV**)\n",
"5. Sittelle torchepot (**SITTOR**)\n",
"6. Pinson des arbres (**PINARB**)\n",
"7. Mésange noire (**MESNOI**)\n",
"8. Mésange nonnette (**MESNON**)\n",
"9. Mésange bleue (**MESBLE**)\n",
"10. Rouge-gorge (**ROUGOR**)\n",
"11. Accenteur mouchet (**ACCMOU**)\n",
"\n",
"\n",
"\n",
"<center> <img src=\"https://drive.google.com/uc?id=1Eit86N4D0Ea7ai1rBa0o-GmTwckhP9i0\" width=200>\n",
"<img src=\"https://drive.google.com/uc?id=1lC7WL93UqDT_KV2m21yx99N5dkf98nCY\" width=200>\n",
"<img src=\"https://drive.google.com/uc?id=10tzJORcSrSckDWmBDBtc8FUirxdbRxri\" width=200>\n",
"<img src=\"https://drive.google.com/uc?id=1IHZp_B6bc8bADtAReRHhcyOjDQZAXDBQ\" width=200></center>\n",
"<caption><center> Figure 2: Exemples d'images de la base de données </center></caption>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "kxZ6cVouz9Lp"
},
"source": [
"# Localisation et classification d'objet\n",
"\n",
"Dans cette partie, nous allons nous concentrer sur le problème de la localisation d'un seul objet par classe. La base de données a été épurée pour se concentrer uniquement sur ce cas.\n"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"id": "SBA3fa8RSDpt"
},
"outputs": [],
"source": [
"import PIL\n",
"from PIL import Image\n",
"import csv\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"\n",
"import tensorflow as tf\n",
"\n",
"from tensorflow import keras\n",
"from tensorflow.keras import layers\n",
"from tensorflow.keras import models\n",
"from tensorflow.keras.layers import Dense, Conv2D, MaxPooling2D, Flatten, Dropout, Input\n",
"from tensorflow.keras.models import Model, Sequential\n",
"from tensorflow.keras.optimizers import Adam\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "HKRm5oT-_Qsw"
},
"source": [
"## Préparation des données\n",
"\n",
"Le code ci-dessous permet de charger les données et les formater pour la classification. Prenez le temps de regarder un peu le format des labels $y$.\n",
"Notez que les images sont rendues carrées lors du chargement."
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"id": "Q54zSuMvGM-5"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['MESCHA', 'VEREUR', 'ECUROU', 'PIEBAV', 'SITTOR', 'PINARB', 'MESNOI', 'MESNON', 'MESBLE', 'ROUGOR', 'ACCMOU']\n"
]
}
],
"source": [
"# Lecture du CSV contenant les informations relatives à la base de données\n",
"dataset = []\n",
"with open('mangeoires_loc/bd_mangeoires_equilibre.csv', newline='') as csvfile:\n",
"\tfilereader = csv.reader(csvfile, delimiter=' ', quotechar='|')\n",
"\tfor row in filereader:\n",
"\t\tdata = row[0].split(',')\n",
"\t\tif data[0] != 'Data':\n",
"\t\t\tbox = [float(data[5]), float(data[6]), float(data[7]), float(data[8])]\n",
"\t\t\tnew_entry = {'type': data[0], 'specie': data[1], 'path': data[2], 'shape': [float(data[3]), float(data[4])], 'box': box}\n",
"\t\t\tdataset.append(new_entry)\n",
"\n",
"# Nombre de classes de la base de données et intitulé des classes\n",
"class_labels = list(dict.fromkeys([item['specie'] for item in dataset]))\n",
"num_classes = len(class_labels)\n",
"\n",
"# Extraction des données d'apprentissage et de test \n",
"dataset_train = [item for item in dataset if item['type']=='TRAIN']\n",
"dataset_test = [item for item in dataset if item['type']=='TEST']\n",
"\n",
"print(class_labels)"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"id": "JPzqdJBVJLWJ"
},
"outputs": [],
"source": [
"def build_localization_tensors(image_size, dataset, num_classes):\n",
" # Préparation des structures de données pour x et y\n",
" x = np.zeros((len(dataset), image_size, image_size, 3))\n",
" y = np.empty((len(dataset), num_classes + 5)) # 1 + 4 + num_classes : présence / boîte englobante / classes\n",
"\n",
" # Compteur de parcours du dataset\n",
" i = 0\n",
"\n",
" for item in dataset:\n",
" # Lecture de l'image\n",
" img = Image.open('mangeoires_loc/' + item['path'])\n",
" # Mise à l'échelle de l'image\n",
" img = img.resize((image_size,image_size), Image.ANTIALIAS)\n",
" # Remplissage de la variable x\n",
" x[i] = np.asarray(img)\n",
"\n",
" y[i, 0] = 1 # Un objet est toujours présent !\n",
"\n",
" # Coordonnées de boîte englobante\n",
" img_shape = item['shape']\n",
" box = item['box']\n",
" bx = (box[0] + (box[2] - box[0])/2)/img_shape[0]\n",
" by = (box[1] + (box[3] - box[1])/2)/img_shape[1]\n",
" bw = (box[2] - box[0])/img_shape[0]\n",
" bh = (box[3] - box[1])/img_shape[1]\n",
" y[i, 1] = bx\n",
" y[i, 2] = by\n",
" y[i, 3] = bw\n",
" y[i, 4] = bh\n",
"\n",
" # Probabilités de classe, sous la forme d'une one-hot vector\n",
" label = class_labels.index(item['specie'])\n",
" classes_probabilities = keras.utils.to_categorical(label, num_classes=num_classes)\n",
" y[i, 5:] = classes_probabilities\n",
"\n",
" i = i+1\n",
"\n",
" return x, y\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "fnlljZWc_i1L"
},
"source": [
"Séparation des données d'entraînement pour extraire un ensemble de validation, et pré-traitement des données."
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"id": "FJLRiuFX_VPL"
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/tmp/ipykernel_3171614/3333676307.py:13: DeprecationWarning: ANTIALIAS is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.LANCZOS instead.\n",
" img = img.resize((image_size,image_size), Image.ANTIALIAS)\n"
]
}
],
"source": [
"from sklearn.model_selection import train_test_split\n",
"\n",
"\n",
"# Pour la suite du TP on considèrera des images de taille 64x64x3\n",
"# Augmenter cette valeur donnerait de meilleurs résultats mais nécessiterait des calculs plus long.\n",
"IMAGE_SIZE = 64\n",
"\n",
"# Lecture des données d'entraînement et de test\n",
"x, y = build_localization_tensors(IMAGE_SIZE, dataset_train, num_classes)\n",
"x_test, y_test = build_localization_tensors(IMAGE_SIZE, dataset_test, num_classes)\n",
"\n",
"#Extraction d'un ensemble de validation\n",
"x_train, x_val, y_train, y_val = train_test_split(x, y, test_size=0.10, random_state=42)\n",
"\n",
"# Pour améliorer l'entraînement, on peut centrer-réduire les coordonnées des bounding boxes...\n",
"y_std = np.std(y_train, axis=0)\n",
"y_mean = np.mean(y_train, axis=0)\n",
"y_train[...,1:5] = (y_train[...,1:5] - y_mean[1:5])/y_std[1:5]\n",
"y_val[...,1:5] = (y_val[...,1:5] - y_mean[1:5])/y_std[1:5]\n",
"y_test[...,1:5] = (y_test[...,1:5] - y_mean[1:5])/y_std[1:5]\n",
"\n",
"# ... et normaliser les valeurs de couleur\n",
"x_train = x_train/255\n",
"x_val = x_val/255\n",
"x_test = x_test/255"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "DE4wQYq3AKnA"
},
"source": [
"## Fonctions utiles"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "n6NBpMtaM-C0"
},
"source": [
"Une fonction de calcul de l'intersection sur union, qui nous sera utile pour les métriques d'évaluation de nos méthodes :\n",
"\n",
"$$ IoU (R_1, R_2) = \\frac{\\mathcal{A} (R_1 \\cap R_2)}{\\mathcal{A} (R_1 \\cup R_2)} = \\frac{\\mathcal{A} (R_1 \\cap R_2)}{\\mathcal{A} (R_1) + \\mathcal{A} (R_2) - \\mathcal{A} (R_1 \\cap R_2)} $$ \n",
"\n",
"<center>\n",
"<img src=\"https://drive.google.com/uc?id=1BQx2kDOCltZ_5gcnKVWTVUVNmGk-7qBC\" width=500>\n",
"</center>\n"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"id": "rr-O1XuwLoL3"
},
"outputs": [],
"source": [
"### A COMPLETER\n",
"def intersection_sur_union(box1, box2):\n",
" \"\"\"\n",
" Calcul de l'intersection sur union entre deux rectangles box1 et box2\n",
"\n",
" Arguments:\n",
" box1, box2 -- les coordonnées des deux rectangles, chacun sous la forme [cx, cy, w, h]\n",
" où (cx, cy) désigne les coordonnées du centre du rectangle, \n",
" w sa largeur et h sa hauteur\n",
"\n",
" Retourne :\n",
" iou -- la valeur d'intersection sur union entre les deux rectangles \n",
" \"\"\"\n",
"\n",
" # unpacking\n",
" cx1, cy1, w1, h1 = box1\n",
" cx2, cy2, w2, h2 = box2\n",
"\n",
" # haut gauche R1\n",
" x1 = cx1 - w1/2\n",
" y1 = cy1 - h1/2\n",
" \n",
" # bas droite R1\n",
" x2 = cx1 + w1/2\n",
" y2 = cy1 + h1/2\n",
"\n",
" # haut gauche R2\n",
" x3 = cx2 - w2/2\n",
" y3 = cy2 - h2/2\n",
" \n",
" # bas droite R2\n",
" x4 = cx2 + w2/2\n",
" y4 = cy2 + 2/2\n",
"\n",
" # haut gauche intersection\n",
" xi1 = max(x1, x3)\n",
" yi1 = max(y1, y3)\n",
"\n",
" # bas droite intersection\n",
" xi2 = min(x2, x4)\n",
" yi2 = min(y2, y4)\n",
"\n",
" # dimension de l'intersection\n",
" wi = abs(xi2 - xi1)\n",
" hi = abs(yi2 - yi1)\n",
"\n",
" # calcul des aires\n",
" aR1iR2 = wi * hi\n",
" aR1 = w1 * h1\n",
" aR2 = w2 * h2\n",
"\n",
" return aR1iR2 / (aR1 + aR2 - aR1iR2)"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"id": "SdqAFWFxRx8l"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.2\n",
"0.0\n"
]
}
],
"source": [
"print(intersection_sur_union([2.5, 2, 1, 4], [2, 3, 4, 2])) # Résultat attendu : 0.2\n",
"print(intersection_sur_union([2.5, 2, 1, 4], [5, 3, 4, 2])) # Résultat attendu : 0.0"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "RLpMJGi3QC9i"
},
"source": [
"Calcul des différentes métriques : \n",
"\n",
"$$ P = \\frac{TP}{TP + FP} $$\n",
"\n",
"$$ R = \\frac{TP}{TP + FN} $$\n",
"\n",
"$$ F1 = \\frac{2}{\\frac{1}{P} + \\frac{1}{R}} $$\n",
"\n",
"où $TP$ désigne le nombre de vrais positifs, $FP$ le nombre de faux positifs, $FN$ le nombre de faux négatifs, $P$ la précision, $R$ le rappel et $F1$ le F1-score.\n",
"\n",
"On considère souvent qu'une détection est correcte si la classification est valide et que l'intersection sur union entre vérité terrain et prédiction est supérieure à 0.5 (on utilisera un seuil modifiable *iou_thres*)."
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {
"id": "5e_aIvjXLq32"
},
"outputs": [],
"source": [
"# A COMPLETER\n",
"def global_accuracy(y_true, y_pred, iou_thres=0.5):\n",
" \"\"\"\n",
" Calcul, pour chaque classe de la précision, du rappel et du F1-score ainsi \n",
" que du pourcentage global de bonnes détections.\n",
"\n",
" Arguments:\n",
" y_true -- les labels de la vérité terrain, de dimension (M, 1+4+N) où M désigne\n",
" le nombre d'éléments du dataset et N le nombre de classes (11 dans notre cas)\n",
" y_pred -- les labels prédits par un modèle, de dimension (M, 1+4+N) \n",
" iou_thres -- seuil d'intersection sur union entre une boîte \"vérité-terrain\" et \n",
" une boite prédite au-dessus duquel on considère que la prédiction est correcte \n",
"\n",
" Retourne :\n",
" class_res -- liste de longueur N contenant des dictionnaires sous la forme \n",
" {\"Précision\": p, \"Rappel\": r, \"F-score\": f} résumant les métriques\n",
" précision, rappel et F1-score pour chacune des classes.\n",
" accuracy -- pourcentage global de bonnes détections\n",
" \"\"\"\n",
" # Initialisation des métriques : nombre de vrais positifs (TP), faux positifs (FP)\n",
" # et faux négatifs (FN) pour chaque classe\n",
" class_metrics = []\n",
" for i in range(num_classes):\n",
" class_metrics.append({'TP': 0, 'FP': 0, 'FN': 0})\n",
"\n",
" # Nombres de détections correctes et de détections incorrectes\n",
" total_correct_detections = 0\n",
" total_incorrect_detections = 0\n",
" for i in range(y_true.shape[0]):\n",
" # Labels vérité-terrain et prédits\n",
" groundtruth_label = np.argmax(y_true[i,5:])\n",
" predicted_label = np.argmax(y_pred[i,5:])\n",
"\n",
" # Coordonnées de boîtes englobantes réelles et prédites\n",
" bx_true = (y_true[i,1]*y_std[1] + y_mean[1])\n",
" by_true = (y_true[i,2]*y_std[2] + y_mean[2])\n",
" bw_true = (y_true[i,3]*y_std[3] + y_mean[3])\n",
" bh_true = (y_true[i,4]*y_std[4] + y_mean[4]) \n",
" bx_pred = (y_pred[i,1]*y_std[1] + y_mean[1])\n",
" by_pred = (y_pred[i,2]*y_std[2] + y_mean[2])\n",
" bw_pred = (y_pred[i,3]*y_std[3] + y_mean[3])\n",
" bh_pred = (y_pred[i,4]*y_std[4] + y_mean[4]) \n",
"\n",
" # Calcul de l'intersection sur union\n",
" iou = intersection_sur_union([bx_true, by_true, bw_true, bh_true], [bx_pred, by_pred, bw_pred, bh_pred])\n",
" \n",
" # Si la détection est correcte : \n",
" if groundtruth_label == predicted_label and iou > iou_thres:\n",
" total_correct_detections += 1\n",
" class_metrics[predicted_label][\"TP\"] += 1\n",
" else:\n",
" total_incorrect_detections += 1\n",
" class_metrics[predicted_label][\"FP\"] += 1\n",
" class_metrics[groundtruth_label][\"FN\"] += 1\n",
"\n",
"# for i in range(num_classes):\n",
"# print(class_metrics[i])\n",
"\n",
" class_res = []\n",
" for i in range(num_classes):\n",
" TP = class_metrics[i][\"TP\"]\n",
" FP = class_metrics[i][\"FP\"]\n",
" FN = class_metrics[i][\"FN\"]\n",
" if (TP or FP) and (TP or FN): \n",
" P = TP / (TP + FP)\n",
" R = TP / (TP + FN)\n",
" F_score = 2 / ( 1/P + 1/R )\n",
" else:\n",
" P = 0\n",
" R = 0\n",
" F_score = 0\n",
" class_res.append({'Precision': P, 'Rappel': R, 'F-score': F_score})\n",
"\n",
" accuracy = total_correct_detections / (total_correct_detections + total_incorrect_detections)\n",
" return class_res, accuracy"
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {
"id": "AOOWhuk4VBZE"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"La précision globale est de 66.7%\n",
"\n",
"--------------------------------------------\n",
"| Classe | Précision | Rappel | F1-score |\n",
"--------------------------------------------\n",
"| Classe 1 | 1.00 | 1.00 | 1.00 |\n",
"--------------------------------------------\n",
"| Classe 2 | 0.00 | 0.00 | 0.00 |\n",
"--------------------------------------------\n",
"| Classe 3 | 0.50 | 1.00 | 0.67 |\n",
"--------------------------------------------\n"
]
}
],
"source": [
"num_class_test = 3\n",
"class_labels_test = ['Classe 1', 'Classe 2', 'Classe 3']\n",
"y_true_test = np.ones((num_class_test,8))\n",
"y_true_test[0,:2] = [0.5, 0.5]\n",
"y_true_test[0, 5:] = [1, 0, 0]\n",
"y_true_test[1,:2] = [0.5, 0.5]\n",
"y_true_test[1, 5:] = [0, 1, 0]\n",
"y_true_test[2,:2] = [0.5, 0.5]\n",
"y_true_test[2, 5:] = [0, 0, 1]\n",
"y_pred_test = np.ones((num_class_test,8))\n",
"y_pred_test[0,:2] = [0.6, 0.6]\n",
"y_pred_test[0, 5:] = [1, 0, 0]\n",
"y_pred_test[1,:2] = [2.5, 2.5]\n",
"y_pred_test[1, 5:] = [0, 0, 1]\n",
"y_pred_test[2,:2] = [0.6, 0.6]\n",
"y_pred_test[2, 5:] = [0, 0, 1]\n",
"\n",
"class_res_test, acc_test = global_accuracy(y_true_test, y_pred_test)\n",
"\n",
"print(f\"La précision globale est de {100 * acc_test:.1f}%\")\n",
"\n",
"print()\n",
"print(\"--------------------------------------------\")\n",
"print(\"| Classe | Précision | Rappel | F1-score |\")\n",
"print(\"--------------------------------------------\")\n",
"for i in range(num_class_test):\n",
" print(f\"| {class_labels_test[i]:9s}| {class_res_test[i]['Precision']:.2f} | {class_res_test[i]['Rappel']:.2f} | {class_res_test[i]['F-score']:.2f} |\")\n",
" print(\"--------------------------------------------\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Q1Tg4VFVVB-w"
},
"source": [
"**Affichage attendu :**\n",
"```\n",
"La précision globale est de 66.7%\n",
"\n",
"--------------------------------------------\n",
"| Classe | Précision | Rappel | F1-score |\n",
"--------------------------------------------\n",
"| Classe 1 | 1.00 | 1.00 | 1.00 |\n",
"--------------------------------------------\n",
"| Classe 2 | 0.00 | 0.00 | 0.00 |\n",
"--------------------------------------------\n",
"| Classe 3 | 0.50 | 1.00 | 0.67 |\n",
"--------------------------------------------\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "cMntCEgkANMg"
},
"source": [
"La fonction ci-dessous permet de calculer l'intersection sur union sur des tenseurs (et non des tableaux numpy), elle sera donc utilisable comme métrique pendant l'entraînement."
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {
"id": "tVk9cB1WAMUK"
},
"outputs": [],
"source": [
"def compute_iou(y_true, y_pred):\n",
" ### \"Dénormalisation\" des coordonnées des boîtes englobantes\n",
" pred_box_xy = y_pred[..., 0:2]* y_std[0:2] + y_mean[0:2]\n",
" true_box_xy = y_true[..., 0:2]* y_std[0:2] + y_mean[0:2]\n",
"\n",
" ### \"Dénormalisation\" des largeur et hauteur des boîtes englobantes\n",
" pred_box_wh = y_pred[..., 2:4] * y_std[2:4] + y_mean[2:4]\n",
" true_box_wh = y_true[..., 2:4] * y_std[2:4] + y_mean[2:4]\n",
" \n",
" # Calcul des coordonnées minimales et maximales des boiptes englobantes réelles\n",
" true_wh_half = true_box_wh / 2.\n",
" true_mins = true_box_xy - true_wh_half\n",
" true_maxes = true_box_xy + true_wh_half\n",
" \n",
" # Calcul des coordonnées minimales et maximales des boiptes englobantes prédites\n",
" pred_wh_half = pred_box_wh / 2.\n",
" pred_mins = pred_box_xy - pred_wh_half\n",
" pred_maxes = pred_box_xy + pred_wh_half \n",
" \n",
" # Détermination de l'intersection des boîtes englobantes\n",
" intersect_mins = tf.maximum(pred_mins, true_mins)\n",
" intersect_maxes = tf.minimum(pred_maxes, true_maxes)\n",
" intersect_wh = tf.maximum(intersect_maxes - intersect_mins, 0.)\n",
" intersect_areas = intersect_wh[..., 0] * intersect_wh[..., 1]\n",
" \n",
" # Aire des boîtes englobantes prédites et réelles\n",
" true_areas = true_box_wh[..., 0] * true_box_wh[..., 1]\n",
" pred_areas = pred_box_wh[..., 0] * pred_box_wh[..., 1]\n",
"\n",
" # Aire de l'union des boîtes prédites et réelles\n",
" union_areas = pred_areas + true_areas - intersect_areas\n",
"\n",
" iou_scores = tf.truediv(intersect_areas, union_areas)\n",
" return iou_scores\n",
"\n",
"def iou():\n",
" def iou_metrics(y_true, y_pred):\n",
" return compute_iou(y_true, y_pred)\n",
" iou_metrics.__name__= \"IoU\"\n",
" return iou_metrics"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "vidE3XHlAkst"
},
"source": [
"Visualisation des données et labels"
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {
"id": "8yotZHKgAiV1"
},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAPsAAAEICAYAAACZA4KlAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAABTnUlEQVR4nO29Z5RlWXUm+O3nXfjIjPSZZSkHFFBQlCghBILGSIIZMcg3kuipXr0kDRppDUaa6W5ptWbQGEn0yKAaIVHqVgvRQgjTwqsAFb4KU967tBGZEfEi4nl35sd78fa3d2VkRpKVEUW9860VK85757xzzz33nnv3Pnvvb0sIAREREc9+JLZ7ABEREVuDuNgjIkYEcbFHRIwI4mKPiBgRxMUeETEiiIs9ImJE8H272EXkfxGR/yQiG56DiBwQkYqIJDfR36yIfEdErnt6R3r+EJFPishbt3scEd/nCCE8Y/4AfArA75zm+zcCOAEgNfj8OgAfBJA8x/6/AOBfneb7NID/BuAHzvDbewBUBn9dAA36/JvbPXfnMecBwKXbPY6zjPENAG4DUB7cB38OYOw8+vvA4Lzf6L7/g8H3vzD4/AuDa11xf3sG9TcC+AqAFQBLAL4M4MX02wDgHe4YRwC8gj5fBeBjgz7WANzK9yGAQ4N+Uuc7j8+0N/stAH5ORMR9//MA/jqE0AGAEMInQwg/FULobtSRiKQ2e9AQQjuE8IYQwlfO0ObqEEIphFAC8M8AfmX9cwjhf9/McU43pnMZ5whjAsB/ALAHwJUA9gL4v86zzwcB/Mv1D4Pr8BYAj7h2X6XrvP53TETGAXwCwP8LYHowpt8G0KTfLgF4h4iMnW4AInIJ+g+IuwBcNDi/jwD4jIjccJ7n91Rs91PbPfXy6D/hXk7fTaH/Fn0++mrHu9C/IIsAPgRg2j0B3wbgSQBfou9SAH4X9o38R4PfXQHgs+hfmAcAvGUT4/wCSEIA8EsA7gOwDODTAA5SXQDwywAeAvAYgFeg/3R/J/pvqf80OMdPADg56OMTAPad7njovzFuA/B/D9o+BuB15zHnwzc7gH8P4L8C+M/ov2XuAnA5gHcDWABwGMBr6Le/ODjvNQCPAvjXru93ADgO4BiAf+WOlR2cw5MA5gG8D0B+k2P+7wHcdR7n/IHBsecBTA2++1EAnxzMLb/Zb9ugj+sAlM9wjPXr9HEA/46+H77ZB9f+H0/z2z8F8CV3Xz+73uwhhDr6C/hf0tdvAXB/COG7AH4VwJsA/BD6T8FlAH/suvkh9J/+/8L1/Vuwb+RfEZEi+gv9vwDYCeCnAPyJiFy12TGLyBsB/Cb6N+COwTH+xjV7E4Dr0RfZAGAX+m+DgwBuQv8h9peDzwcA1AH80RkOez36D6ZZAP8ngPefRhpaH9+fiMifbPZ8APwY9AH0bfQfXgn031y/A+DPqO0C+otkHP2F/wci8sLBcV8L4NcB/AiAS9F/yDHeg/6D5NpB/V4A/3aTY3w5+mrV+aAB4KPoX3Ogf8/91Tn8/kEAXRG5RUReJyJTG7T73wD8mohMn6bu1eg/XD0+BOBlIpI/h/GcHRfiDX0+f+jrQWUAucHnLwP4nwfl+wC8itruBtBG/819CP0n4MVUv/7duq7/Bdg38k8C+Gd3/D8DPYk3GOOwH/TfBm+jugSAGgZv98HxX0n1rwDQWj+/Dfq/FsDyBsf7BQAPU11hcIxd3+N8+zf7Z6nux9CXgpKDz2OD9pMb9PUPAN4+KP8FgP+D6i5dPxYAAVAFcAnV3wDgsU2M99XoP+QvP4977APoqwU3AvgqgEn03/J5PPXN3hncj+t/j1A/Vw76OjJo9zEAc/Tb2wblDwH4vUGZ3+wdAK89zfiuGMzVXjxb3+wAEEK4DcApAG8a6DQvQf/NC/TffB8RkbKIlNFf/F0Ac9TF4XM43EEA16/3N+jzZ9F/855LH++l3y+hfzPvPcOYToYQGusfRKQgIn8mIk+IyCr6KsjkGawIJ9YLIYTaoFg6hzGfCfNUrgM4FXRvpM7HGrzRviYiS4Nzfz360gbQl7z4vLm8A/2H1B00b58afL8hROSl6N8Lbw4hPLhBm58dWGAqIvLJM/U3uNd2APgtAJ8IfcnS42shhEn6u4R+f18I4RdCCPsAXDM45z88TR//FsC/EZE59/0p9F9YHrsB9NB/qD1teMYt9gH+Cn2x6ucAfDqEsH4DHkZfP+XJz4UQjtJvzxTG5+sOA/ii668UQvg35zDWw+jrqtxHPtjNPn9c//k3ADwHwPUhhHH0xVSg/9B4RkJEsgA+jL7uOxdCmATwj9AxHwewj36yn8qn0H9wXE1zNhH6m58bHe8F6L85fymE8PmN2oUQ/jroRtrrNnEq/xn9+T8XEf50x70f/bf8NRvU/T36DxXG5wD8D6fp7i3obwzWTlP3PeOZvNh/BMD/iP4O/TreB+B3ReQgAIjIjoHOvFnMA7iYPn8CwOUi8vMikh78vVhErjyHPt8H4N0icvVgTBMicroLeCaMoX/zlwe63b87x99vBzLob7KdBNARkdcBeA3VfwjAL4rIlSJSQF93BQCEEHoA/j/0dfydACAie0XE7LOsQ0SuQf/N/6shhI8/zefxH9FXDb50Lj8SkStE5DdEZN/g834APw3gaxv85LfR39eYdN/9gIj8rohMi8iYiPwq+i+6d57baZwdz8jFHkJ4HH37ZRH9p/k63jv4/BkRWUN/Yq8/h67fC+DNIrIsIv8xhLCG/g36U+jvGJ8A8Hvo38SbHetHBr/54EAEvxt9P4BzwR+iry+eQv+cPnWOv98QIvI+EXnf09XfOgZz9z+hv6iXAfwM6FqFED6J/kK6FcDD0EWwbpp65/r3g3n7HPrSzenwG+iL2+8nEf18N+jWx7kUQvh8GCjLp8ENdMz1vxejb4G4HsDXRaQ6OL+7B2M93XEeQ3/js0jfPYT+vsHzATyOvjT0EwD+RQjhy0/H+TFk43OMiHj6MJCW7gaQDQN/iYitxTPyzR7x7ICI/Hcikh2YpX4PwMfjQt8+xMUecSHxr9G3xT+CvtXkXDY+I55mRDE+ImJEcF5vdhF5rYg8ICIPi8i7nq5BRUREPP34nt/sA4ePB9E3WxwB8E0APx1CuHej32Ry+VAo9WMC+tYXwhnGwY6gQqZnH90qSfVBCUnbf080ZqbX1WOJf97RuMSZuY1DaoI+dPy56OdE0sa5dDo6jm676+raw3I6kxmWM/mMbdfT8SfcGHlYPeo+nbfj4GNLwvZRW1mjPvRY2YL13kwmN/L5Abp0numsjr/VbJp2OybUtJ5K2mtRWavSOOhkErZdaUzjTHxsVKC52sCjuN8/+J6w4Pug1/P967VO0vj5ez/mp4yD2vZ6fP+5caR1HiVh5z70+lshCyeXsLpaPe2Jnk/E1UvQd9t8FABE5IPoh6JuuNgLpTHc+MafAAB0Wvaih3ZLB+WGmqZFnUhqZSpjg4kydOO0iy1TV8uWh+Xqitbl1RLSH0dL/RjSwU5Pku51ydODZcE6XoWenlth3LpELy+uaPnEqqk7Na/Oa3sPqj/K3qsO2j4aerxCIm3qMjR39TUd/76r7TjKC+qclclZS+Md/6gm58qansvlL3ieaTdRGtcP7k5aPVkelncc0nM59sRjpt1Nr//BYXlmzD5MvvLFrw7LtbI+gFC07V76Q68YljstO6fdpl7rZJrOM9ibrEnXLC32xZOiOa5XV0xdu6H9j40V6PuqadfLaF06ba8ZapVhsUH3X9KNMbf7kPZRsPdtp9a/nr/+jt/HRjgfMX4vrAvkEVgXUQCAiNwkIreLyO2txum8ESMiIrYCFzyWOoRwM4CbAWBidsfQd+EpYg7ByyA9sMipT8WEE+OT9EBudBqmriN6vJyQWFxrm3bNhj7hV3DK1I31JoflUn5iWF5urJl2jSqJZcefNHVze9X9+9DVF5u6Q5dfNCwfflTDqu/+4m2m3eRudafOT8yYuiqdTrqk411btp6XkzvU/T/tVJ4Mify9NT23RM9emUxOP1fr9o0qCb1my0eXhuXpKStFVJuLw/K+2ctN3
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAQgAAAEICAYAAACj9mr/AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAABYN0lEQVR4nO29eZic11kn+ntrr+qq7uq9W92tbi1eZMu2bMtbbCdO4qwkcYBMCMNwHcaMGQaYcGEmceAZBmaGO2Ee7kC4DAQPAQwEgoGEJIbEcRwndhYvsiRbkmXt3S31vlV37eu5f9TX9b7viUpuWa2WzJzf8+jR6TrnO9/5ljr1rr+XjDFwcHBwOBt8l3oBDg4Oly/cBuHg4NAUboNwcHBoCrdBODg4NIXbIBwcHJrCbRAODg5N8c9mgyCi/0hEf0FETa+JiDYTUYaI/GuYr4uI9hPR7vVd6YWDiL5KRPdf6nU4/PPHZb1BENHXiOi/nOXz+4homogC3t/vAXAzgI8aY2rN5jPGjBtj4saYqnfct4jop88yfxDAIwD+nTFmT5O1HfI2mwwRVYmoIP7+ldd3xWuDMeY9xphHLsbcRGSIaPvFmHs9QUTdRPRXRLRMREtE9LkLmOvPvOu+z/r8d7zPP+r9/VHvWWesf5u8/ruI6HvemhaJ6LtEdIs41hDRx61znCGie8Tf1xDRl7050kT0FBG9SfSPePP8kzXPXxLRr7/ee9AMl/UGgfqX9F8REVmf/ySAzxljKgBgjPmqMeYjq1/8s2F1M1kLjDFlY8wPGWO+d44x13qbTRzAMwB+fvVvY8z/s5bznG1N57PO/8PxBQDTADYD6AHw2xc431EA/9fqH95z+DCAE9a474vnvPpvkohaATwG4P8D0AFgAMBvACiKYxcBfJyIEmdbABFtA/BdAAcAbAGwCcAXAXydiO6wht8mN46Lhct9g/gHAJ0A7l79gIjaAbwPwJ8TkY+IHiKiE0S0QESPElGHN251p32AiMYBfFN8FiCi3/Tm/X3vV+D3veOuJqInvF+AI0T04fNdNBH9ayI67P2yPU5Ew6LPENHPEdExAMeI6B7vV+QTRDQN4E+JqJ2IHiOiOW+Ox4hoUMzRkHy8X6bvENFve2NPeRLVBYOIfp2I/tb7dUoT0QEiupKIPklEs0R0mojeKcb/lHfdaSI6SUQ/Y833cSKaIqJJIvppKa0QUdi7hnEimiGizxBRtMm63glgCMB/NMYsexv6vgu83K8AuMt7vwDg3QBeRn0TWguuBABjzF8bY6rGmLwx5uvGmJfFmMMAvg/gl5rM8euob0C/aoxZNMakjTG/B+AvAPyWNfZ/APjNNa7tdeOy3iCMMXkAj0Ls7Kjv6q8aY14C8AsAPgjgLajvtksA/pc1zVsA7ADwLmvuX4X+5f95ImoB8ASAv0L9V+kjAP6AiK5Z65o9MfVXAPwIgG7vHH9tDfsggNsArM7bh/qvzjCAB1F/Ln/q/b0ZQB7A75/jtLcBOAKgC/UX57NnkbpW1/cHRPQHa70eAO9H/QVtB7APwOPe+gYA/BcAfyTGzqK+ebcC+CkAv0NEN3nnfTfqX4x7AWwHcI91nk+h/iXb5fUPAPi1Jmu6HfXrfcT7YXiBiN5yHtd0NhQAfAn1Zw7U37k/P4/jjwKoEtEjRPQesdHY+E8AfnH1h8zCOwD87Vk+fxTAndaG+QcAriSie89jjecPY8xl/Q/AXQBSACLe398F8H977cMA3i7G9gMoAwgAGAFgAGwV/aufBby/vwXgp0X/jwF4xjr/HwH4z6+xxsY8AL4K4AHR5wOQAzDs/W0AvE303wOgtHp9TebfBWCpyfk+CuC46It55+h7nffbANjutX8dwBOi7/0AMgD83t8Jb3yyyVz/AOBjXvtPAPx30bd99VwACEAWwDbRfweAU03mfdg79gEAQdS/1CkAXa/zmv8MwH/z3rXvA0gCmAEQBfAd1G1bq/e64p1r9d8JMc8Ob64z3rgvA+gVx37Haz8K4Le89hkA93jtCoB3n2V9V3vXOwDxDgP4dwCe9cb8JYBfX+/v32UtQQCAMeY7AOYBfNDT0W5F/RceqP/CfpGIUkSUQn3DqALoFVOcPo/TDaOu26XEnD+B+i/8+czxaXH8IupfgIFzrGnOGFNY/YOIYkT0R0Q0RkQrAJ4GkKTm3peGGGyMyXnN+Hms+VyYEe08gHnDtp68PJf3y/msp56lALwXdakGqEt48rpluxv1je1Fcd++5n1+NuQBjBpjPmvq6sXnvfnutAcS0U8QGxO/eq4L9d61bgC/CuAxU5dgbTxrjEmKf9vE8YeNMR81xgwC2Old8++eZY5fA/CzRNRrfT6P+o+cjX4ANdQlZIk/BtBLRO8/13VdCC77DcLDn6Mu8v0rAI8bY1Zf2tMA3mM9sIgxZkIce650VbvvNIBvW/PFjTE/ex5rPQ3gZ6w5okYbPO3z2n//MoCrANxmjGkF8Gbv87OqDZcDiCgM4O9RNxb2GmOSAP4JvOYpAIPikCHRnkf9S3+tuGdtpm4APhtexmvfw/qHxnzOsDFxLbaZv0T9/p+PenG2876KujSxs0nfF1DfiCS+AeBfnGW6D6Num8jJD40xJdQNof8VF+ndeCNtEPcC+DeoezZW8RkAv7lqBKS66+u+sxzfDDMAtoq/H0Ndr/tJIgp6/24hoh3nMednAHySiK711tRGRGd76OdCAvUvTMrTVf/zeR5/KRACEAYwB6DiGUrfKfofBfBTRLSDiGKo6+IAAFN3Tf9v1G0WPQBARANEpOxGAl8E0E5E9xORn4g+hPrm8911uI7fQ90W8PT5HER14/YvrxqTiWgIwI8DeLbJIb+Bup0maX32JiL6TSLqIKIEEf0C6j+On2gyz18AiKBuVF13vCE2CGPMKIDvAWhBXa9bxae9v79ORGnUH8Zt5zH1pwF8yLP+/54xJo36S/0RAJOoi+6/hfqLv9a1ftE75vOeenAQwPl6FX4Xdf13HvVr+tp5Ht8UnnfgM+s13yq8e/fvUd8IlgD8S4hnZYz5KupfvqcAHAd/cVbdgJ9Y/dy7b99AXYo627kWAXwAwH8AsAzgIQD3GWPm1+E6Fo0xTxpPsT8L7qAfjIO4BUAa9XfvOSLKetd3EHVp5GznOYX6l7tFfHYMdTvIDQBGUZe6fhTAu4wxZ938PHXv11A3cq87qPl9cHC4ePCksoMAwsaLZ3G4/PCGkCAc/nmAiH7Yi3doR13K+orbHC5vuA3CYSPxM6jHSpxA3dt0PsZfh0sAp2I4ODg0xQVJEET0bqqHIx8noofWa1EODg6XB163BOEF7RxF3SV0BsALAH7cGPNKs2NaE62mu7Me+xII6L0pm8002j6f7vP5OD4om8s22rFIxFqUTzT1HKbGeVxGuIx9Vnb4cjrVaIcCQdXn93MeVTgsHBtWVHO5XOI1RltUX7FUEOPKqq9a5UTUQICv2b4f8mz2dVYqrNJHwnx/0pm0Guf383HBYEj1ocbryKT5uHhrqxqmjrPeo3KFr01GfWdzypUPn4/74nGdw1Sr8DMrV/iehkLaqVTM85yFYlH1tSbZuF8V8+XFewQAxRLHRNWq2iwir8z+uvjF/ff7RRyb9e4U8vzcY2Gdj9fdzXF4sRjfg5qVmGxqfPKstf7UEjtwtl55VudPU7z44ovzxpizBqVdSObgraiH+J4EACL6PID7ADTdILo7u/E//lM90bG9XcfA7NnDXpxIRH+pYq180/a8wG7l66+9Vp/Az6Hq4ajO8ynmVhrtKvhB2ud6/BtfabQ39eoAyrZWDq/ftu0KPm1ABzhOTE422rtuuEn1jY4db7RnZqZU3/Iyfxk7OvhcsYi+Fr9YfzSh++Zn5xrt7VuvbLS//d2n1LhWcU8H+4dVnynyvXr6W99qtN9yr/bW9m7a1GjXinqzm5vnAEwSX+jn9z2vxsXEJvbmu9+q+tJLi4329DTHvg1t3qrGnXjlxUb7+MlR1ffO93Ou3cIi398D+59T406d4tc2uzKn+ioiSbhU1l+Ztha+/8k23kD9HQNq3MFXeP7dW/V38d/87
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# Si seuls x et y sont indiqués, on tire au hasard un numéro d'image et on affiche le label y associé à l'image\n",
"# Si un 2e y, nommé y_pred, est indiqué, alors les deux labels sont affichés côte à côte, afin de pouvoir les comparer\n",
"# Enfin on peut également indiquer l'id de l'image que l'on souhaite visualiser.\n",
"def print_data_localisation(x, y, y_pred=[], id=None, image_size=64):\n",
" if id==None:\n",
" # Tirage aléatoire d'une image dans la base\n",
" num_img = np.random.randint(x.shape[0]-1)\n",
" else:\n",
" num_img = id\n",
"\n",
" img = x[num_img]\n",
" lab = y[num_img]\n",
"\n",
" colors = [\"blue\", \"yellow\", \"red\", \"orange\", \"coral\", \"gold\", \"ivory\", \"fuchsia\", \"purple\", \"cyan\", \"navy\"] # Différentes couleurs pour les différentes classes\n",
" classes = ['MESCHA', 'VEREUR', 'ECUROU', 'PIEBAV', 'SITTOR', 'PINARB', 'MESNOI', 'MESNON', 'MESBLE', 'ROUGOR', 'ACCMOU']\n",
"\n",
" if np.any(y_pred):\n",
" plt.subplot(1, 2, 1)\n",
"\n",
" # Affichage de l'image\n",
" plt.imshow(img)\n",
" # Détermination de la classe\n",
" class_id = np.argmax(lab[5:])\n",
"\n",
" # Détermination des coordonnées de la boîte englobante dans le repère image\n",
" ax = (lab[1]*y_std[1] + y_mean[1]) * image_size\n",
" ay = (lab[2]*y_std[2] + y_mean[2]) * image_size\n",
" width = (lab[3]*y_std[3] + y_mean[3]) * image_size\n",
" height = (lab[4]*y_std[4] + y_mean[4]) * image_size\n",
" #print(\"x: {}, y: {}, w: {}, h:{}\".format(ax,ay,width, height))\n",
" # Détermination des extrema de la boîte englobante\n",
" p_x = [ax-width/2, ax+width/2]\n",
" p_y = [ay-height/2, ay+height/2]\n",
" # Affichage de la boîte englobante, dans la bonne couleur\n",
" plt.plot([p_x[0], p_x[0]],p_y,color=colors[class_id])\n",
" plt.plot([p_x[1], p_x[1]],p_y,color=colors[class_id])\n",
" plt.plot(p_x,[p_y[0],p_y[0]],color=colors[class_id])\n",
" plt.plot(p_x,[p_y[1],p_y[1]],color=colors[class_id])\n",
" plt.title(\"Vérité Terrain : Image {} - {}\".format(num_img, classes[class_id]))\n",
"\n",
" if np.any(y_pred):\n",
" plt.subplot(1, 2, 2)\n",
" # Affichage de l'image\n",
" plt.imshow(img)\n",
" lab = y_pred[num_img]\n",
" # Détermination de la classe\n",
" class_id = np.argmax(lab[5:])\n",
"\n",
" # Détermination des coordonnées de la boîte englobante dans le repère image\n",
" ax = (lab[1]*y_std[1] + y_mean[1]) * image_size\n",
" ay = (lab[2]*y_std[2] + y_mean[2]) * image_size\n",
" width = (lab[3]*y_std[3] + y_mean[3]) * image_size\n",
" height = (lab[4]*y_std[4] + y_mean[4]) * image_size\n",
" #print(\"x: {}, y: {}, w: {}, h:{}\".format(ax,ay,width, height))\n",
" # Détermination des extrema de la boîte englobante\n",
" p_x = [ax-width/2, ax+width/2]\n",
" p_y = [ay-height/2, ay+height/2]\n",
" # Affichage de la boîte englobante, dans la bonne couleur\n",
" plt.plot([p_x[0], p_x[0]],p_y,color=colors[class_id])\n",
" plt.plot([p_x[1], p_x[1]],p_y,color=colors[class_id])\n",
" plt.plot(p_x,[p_y[0],p_y[0]],color=colors[class_id])\n",
" plt.plot(p_x,[p_y[1],p_y[1]],color=colors[class_id])\n",
" plt.title(\"Prédiction : Image {} - {}\".format(num_img, classes[class_id]))\n",
"\n",
" plt.show()\n",
"\n",
"for i in range(10):#x.shape[0]):\n",
" print_data_localisation(x_train, y_train, image_size=IMAGE_SIZE, id=i)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "mE9_B3yuR4OH"
},
"source": [
"Fonction d'affichage des courbes d'apprentissage et de validation"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {
"id": "-6O7R3qnCtlN"
},
"outputs": [],
"source": [
"def plot_training_analysis(history, metric='loss'): \n",
"\n",
" loss = history.history[metric]\n",
" val_loss = history.history['val_' + metric]\n",
"\n",
" epochs = range(len(loss))\n",
"\n",
" plt.plot(epochs, loss, 'b', linestyle=\"--\",label='Training ' + metric)\n",
" plt.plot(epochs, val_loss, 'g', label='Validation ' + metric)\n",
" plt.title('Training and validation ' + metric)\n",
" plt.legend()\n",
"\n",
" plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "8F_l_yNlDapa"
},
"source": [
"## Travail à faire\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "E6D31NGPNyJp"
},
"source": [
"<center> <img src=\"https://drive.google.com/uc?id=1YzCZe4pgnjJDVGklAaCHZ7HhlPJsadg9\" width=500></center>\n",
"<caption><center> Figure 3: Illustration de l'architecture du réseau à construire. </center></caption>\n",
"\n",
"Complétez les codes qui vous sont fournis pour obtenir un algorithme de localisation. \n",
"Vous pouvez utiliser n'importe quelle base convolutive de votre choix (**commencez par exemple par réutiliser celle que vous avez implémenté au TP3**), en revanche vous devrez porter une attention particulière à la couche de sortie.\n",
"\n",
"Vous allez en fait produire 3 sorties différentes : une caractérisant la présence d'un objet, une autre fournissant les coordonnées de la boîte englobante, et enfin une dernière effectuant la classification."
]
},
{
"cell_type": "code",
"execution_count": 82,
"metadata": {
"id": "vPOXiJ7hDcbr"
},
"outputs": [],
"source": [
"def create_model_localisation(input_shape=(64, 64, 3)):\n",
"\n",
" input_layer = Input(shape=input_shape)\n",
"\n",
" conv1 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(input_layer)\n",
" conv1 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv1)\n",
" pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)\n",
"\n",
" conv2 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool1)\n",
" conv2 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv2)\n",
" pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)\n",
"\n",
" flat = Flatten()(pool2)\n",
" dense = Dense(128, activation = 'relu')(flat)\n",
"\n",
" prev_layer = dense\n",
"\n",
" output_p = Dense(1, activation='sigmoid', name='p')(prev_layer) # Sortie caractérisant la présence d'un objet\n",
" output_coord = Dense(4, activation='linear', name='coord')(prev_layer) # Sortie caractérisant les coordonnées de boîte englobante\n",
" output_class = Dense(len(class_labels), activation='softmax', name='classes')(prev_layer) # Sortie caractérisant les probabilités de classe\n",
" \n",
" output= [output_p, output_coord, output_class]\n",
" model = Model(input_layer, output)\n",
"\n",
" return model"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "MYoVYfQpotjy"
},
"source": [
"<center> <img src=\"https://drive.google.com/uc?id=1bnh8zU7Os-w-5TT8hV4xDoThKQc-Ywc2\" width=500></center>\n",
"<caption><center> Figure 4: Illustration des fonctions de coût à utiliser pour l'entraînement. </center></caption>\n",
"\n",
"Pour entraîner votre réseau, vous allez donc devoir associer une fonction de coût à chacune des sorties du réseau. La fonction de coût totale sera la somme des trois fonctions de coût précédemment définies, pondérées par des poids définis dans la variable *loss_weights*.\n",
"\n",
"**Prenez le temps de tester différentes valeurs de *loss_weights* en fonction de l'évolution des métriques que vous observerez pendant l'entraînement.**\n",
"\n",
"Vous évaluerez vos résultats de manière qualitative (en affichant les boîtes englobantes prédites et réelles) mais aussi quantitatives grâce aux fonctions définies dans la section précédente. **N'hésitez pas à modifier un peu le paramètre iou_threshold positionné par défaut à 0.5** (une valeur de 0.4 vous permettra d'obtenir de meilleurs résultats !)"
]
},
{
"cell_type": "code",
"execution_count": 83,
"metadata": {
"id": "s_ewlCn5Rovm"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model: \"model_6\"\n",
"__________________________________________________________________________________________________\n",
" Layer (type) Output Shape Param # Connected to \n",
"==================================================================================================\n",
" input_7 (InputLayer) [(None, 64, 64, 3)] 0 [] \n",
" \n",
" conv2d_22 (Conv2D) (None, 64, 64, 64) 1792 ['input_7[0][0]'] \n",
" \n",
" conv2d_23 (Conv2D) (None, 64, 64, 64) 36928 ['conv2d_22[0][0]'] \n",
" \n",
" max_pooling2d_11 (MaxPooling2D (None, 32, 32, 64) 0 ['conv2d_23[0][0]'] \n",
" ) \n",
" \n",
" conv2d_24 (Conv2D) (None, 32, 32, 128) 73856 ['max_pooling2d_11[0][0]'] \n",
" \n",
" conv2d_25 (Conv2D) (None, 32, 32, 128) 147584 ['conv2d_24[0][0]'] \n",
" \n",
" max_pooling2d_12 (MaxPooling2D (None, 16, 16, 128) 0 ['conv2d_25[0][0]'] \n",
" ) \n",
" \n",
" flatten_3 (Flatten) (None, 32768) 0 ['max_pooling2d_12[0][0]'] \n",
" \n",
" dense_5 (Dense) (None, 128) 4194432 ['flatten_3[0][0]'] \n",
" \n",
" p (Dense) (None, 1) 129 ['dense_5[0][0]'] \n",
" \n",
" coord (Dense) (None, 4) 516 ['dense_5[0][0]'] \n",
" \n",
" classes (Dense) (None, 11) 1419 ['dense_5[0][0]'] \n",
" \n",
"==================================================================================================\n",
"Total params: 4,456,656\n",
"Trainable params: 4,456,656\n",
"Non-trainable params: 0\n",
"__________________________________________________________________________________________________\n",
"Epoch 1/50\n",
"118/118 [==============================] - 15s 104ms/step - loss: 1.5293 - p_loss: 0.0235 - coord_loss: 1.1148 - classes_loss: 0.3911 - p_accuracy: 1.0000 - coord_IoU: 0.4255 - classes_accuracy: 0.1787 - val_loss: 0.8456 - val_p_loss: 0.0010 - val_coord_loss: 0.5451 - val_classes_loss: 0.2995 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5131 - val_classes_accuracy: 0.2810\n",
"Epoch 2/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.7562 - p_loss: 0.0018 - coord_loss: 0.4862 - classes_loss: 0.2681 - p_accuracy: 1.0000 - coord_IoU: 0.5129 - classes_accuracy: 0.4040 - val_loss: 0.7039 - val_p_loss: 8.6872e-04 - val_coord_loss: 0.4485 - val_classes_loss: 0.2545 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5107 - val_classes_accuracy: 0.4048\n",
"Epoch 3/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.6387 - p_loss: 6.8169e-04 - coord_loss: 0.4034 - classes_loss: 0.2346 - p_accuracy: 1.0000 - coord_IoU: 0.5332 - classes_accuracy: 0.5032 - val_loss: 0.6252 - val_p_loss: 0.0010 - val_coord_loss: 0.3901 - val_classes_loss: 0.2341 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5327 - val_classes_accuracy: 0.4762\n",
"Epoch 4/50\n",
"118/118 [==============================] - 10s 87ms/step - loss: 0.5672 - p_loss: 5.0588e-04 - coord_loss: 0.3520 - classes_loss: 0.2147 - p_accuracy: 1.0000 - coord_IoU: 0.5354 - classes_accuracy: 0.5292 - val_loss: 0.5895 - val_p_loss: 2.2709e-04 - val_coord_loss: 0.3826 - val_classes_loss: 0.2066 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5358 - val_classes_accuracy: 0.5000\n",
"Epoch 5/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.4793 - p_loss: 2.0704e-04 - coord_loss: 0.2845 - classes_loss: 0.1946 - p_accuracy: 1.0000 - coord_IoU: 0.5772 - classes_accuracy: 0.5610 - val_loss: 0.5538 - val_p_loss: 2.4165e-04 - val_coord_loss: 0.3575 - val_classes_loss: 0.1961 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5256 - val_classes_accuracy: 0.5286\n",
"Epoch 6/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.4431 - p_loss: 1.6858e-04 - coord_loss: 0.2604 - classes_loss: 0.1825 - p_accuracy: 1.0000 - coord_IoU: 0.6001 - classes_accuracy: 0.5732 - val_loss: 0.5183 - val_p_loss: 1.1366e-04 - val_coord_loss: 0.3382 - val_classes_loss: 0.1800 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5732 - val_classes_accuracy: 0.5333\n",
"Epoch 7/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.3859 - p_loss: 1.0205e-04 - coord_loss: 0.2163 - classes_loss: 0.1695 - p_accuracy: 1.0000 - coord_IoU: 0.6207 - classes_accuracy: 0.5944 - val_loss: 0.5467 - val_p_loss: 1.3684e-04 - val_coord_loss: 0.3726 - val_classes_loss: 0.1740 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5229 - val_classes_accuracy: 0.5762\n",
"Epoch 8/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.3621 - p_loss: 9.5203e-05 - coord_loss: 0.1990 - classes_loss: 0.1630 - p_accuracy: 1.0000 - coord_IoU: 0.6330 - classes_accuracy: 0.6108 - val_loss: 0.4850 - val_p_loss: 6.6984e-05 - val_coord_loss: 0.3162 - val_classes_loss: 0.1688 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5435 - val_classes_accuracy: 0.5476\n",
"Epoch 9/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.3252 - p_loss: 8.0633e-05 - coord_loss: 0.1702 - classes_loss: 0.1549 - p_accuracy: 1.0000 - coord_IoU: 0.6402 - classes_accuracy: 0.6257 - val_loss: 0.4909 - val_p_loss: 5.5699e-05 - val_coord_loss: 0.3324 - val_classes_loss: 0.1584 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5603 - val_classes_accuracy: 0.5762\n",
"Epoch 10/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.2911 - p_loss: 5.4550e-05 - coord_loss: 0.1445 - classes_loss: 0.1466 - p_accuracy: 1.0000 - coord_IoU: 0.6725 - classes_accuracy: 0.6495 - val_loss: 0.4471 - val_p_loss: 4.2831e-05 - val_coord_loss: 0.2914 - val_classes_loss: 0.1556 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5763 - val_classes_accuracy: 0.5714\n",
"Epoch 11/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.2748 - p_loss: 4.0582e-05 - coord_loss: 0.1337 - classes_loss: 0.1411 - p_accuracy: 1.0000 - coord_IoU: 0.6778 - classes_accuracy: 0.6617 - val_loss: 0.5055 - val_p_loss: 2.8487e-05 - val_coord_loss: 0.3523 - val_classes_loss: 0.1532 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5665 - val_classes_accuracy: 0.5571\n",
"Epoch 12/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.2577 - p_loss: 3.7545e-05 - coord_loss: 0.1205 - classes_loss: 0.1371 - p_accuracy: 1.0000 - coord_IoU: 0.6899 - classes_accuracy: 0.6691 - val_loss: 0.4531 - val_p_loss: 1.9267e-05 - val_coord_loss: 0.3026 - val_classes_loss: 0.1505 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5872 - val_classes_accuracy: 0.6048\n",
"Epoch 13/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.2374 - p_loss: 3.0101e-05 - coord_loss: 0.1064 - classes_loss: 0.1309 - p_accuracy: 1.0000 - coord_IoU: 0.7021 - classes_accuracy: 0.6909 - val_loss: 0.4378 - val_p_loss: 2.6943e-05 - val_coord_loss: 0.2922 - val_classes_loss: 0.1455 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5917 - val_classes_accuracy: 0.6238\n",
"Epoch 14/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.2291 - p_loss: 3.2337e-05 - coord_loss: 0.1018 - classes_loss: 0.1273 - p_accuracy: 1.0000 - coord_IoU: 0.7118 - classes_accuracy: 0.7052 - val_loss: 0.4363 - val_p_loss: 2.6610e-05 - val_coord_loss: 0.2911 - val_classes_loss: 0.1452 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5864 - val_classes_accuracy: 0.6238\n",
"Epoch 15/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.2152 - p_loss: 2.7226e-05 - coord_loss: 0.0912 - classes_loss: 0.1239 - p_accuracy: 1.0000 - coord_IoU: 0.7252 - classes_accuracy: 0.7169 - val_loss: 0.4317 - val_p_loss: 3.0600e-05 - val_coord_loss: 0.2906 - val_classes_loss: 0.1411 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5881 - val_classes_accuracy: 0.6381\n",
"Epoch 16/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.2030 - p_loss: 2.6618e-05 - coord_loss: 0.0832 - classes_loss: 0.1198 - p_accuracy: 1.0000 - coord_IoU: 0.7442 - classes_accuracy: 0.7397 - val_loss: 0.4165 - val_p_loss: 1.5708e-05 - val_coord_loss: 0.2784 - val_classes_loss: 0.1381 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5916 - val_classes_accuracy: 0.6238\n",
"Epoch 17/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.2058 - p_loss: 3.1942e-05 - coord_loss: 0.0886 - classes_loss: 0.1172 - p_accuracy: 1.0000 - coord_IoU: 0.7303 - classes_accuracy: 0.7386 - val_loss: 0.4309 - val_p_loss: 6.8455e-05 - val_coord_loss: 0.2904 - val_classes_loss: 0.1405 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5980 - val_classes_accuracy: 0.6190\n",
"Epoch 18/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.1907 - p_loss: 2.9955e-05 - coord_loss: 0.0776 - classes_loss: 0.1130 - p_accuracy: 1.0000 - coord_IoU: 0.7450 - classes_accuracy: 0.7609 - val_loss: 0.4112 - val_p_loss: 1.6949e-05 - val_coord_loss: 0.2780 - val_classes_loss: 0.1332 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5937 - val_classes_accuracy: 0.6571\n",
"Epoch 19/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.1740 - p_loss: 2.3655e-05 - coord_loss: 0.0654 - classes_loss: 0.1086 - p_accuracy: 1.0000 - coord_IoU: 0.7620 - classes_accuracy: 0.7662 - val_loss: 0.4295 - val_p_loss: 7.7834e-06 - val_coord_loss: 0.2988 - val_classes_loss: 0.1308 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5796 - val_classes_accuracy: 0.6905\n",
"Epoch 20/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.1670 - p_loss: 2.2241e-05 - coord_loss: 0.0623 - classes_loss: 0.1047 - p_accuracy: 1.0000 - coord_IoU: 0.7619 - classes_accuracy: 0.7821 - val_loss: 0.4024 - val_p_loss: 2.5984e-05 - val_coord_loss: 0.2725 - val_classes_loss: 0.1298 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.6069 - val_classes_accuracy: 0.6810\n",
"Epoch 21/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.1687 - p_loss: 2.1902e-05 - coord_loss: 0.0664 - classes_loss: 0.1023 - p_accuracy: 1.0000 - coord_IoU: 0.7641 - classes_accuracy: 0.7884 - val_loss: 0.4067 - val_p_loss: 9.9703e-06 - val_coord_loss: 0.2822 - val_classes_loss: 0.1245 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5956 - val_classes_accuracy: 0.7000\n",
"Epoch 22/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.1523 - p_loss: 1.5818e-05 - coord_loss: 0.0550 - classes_loss: 0.0973 - p_accuracy: 1.0000 - coord_IoU: 0.7689 - classes_accuracy: 0.7990 - val_loss: 0.4198 - val_p_loss: 1.6219e-05 - val_coord_loss: 0.2917 - val_classes_loss: 0.1281 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5777 - val_classes_accuracy: 0.7095\n",
"Epoch 23/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.1517 - p_loss: 1.6976e-05 - coord_loss: 0.0574 - classes_loss: 0.0944 - p_accuracy: 1.0000 - coord_IoU: 0.7685 - classes_accuracy: 0.8070 - val_loss: 0.3936 - val_p_loss: 1.5322e-05 - val_coord_loss: 0.2671 - val_classes_loss: 0.1265 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5896 - val_classes_accuracy: 0.7048\n",
"Epoch 24/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.1395 - p_loss: 1.3186e-05 - coord_loss: 0.0486 - classes_loss: 0.0909 - p_accuracy: 1.0000 - coord_IoU: 0.7819 - classes_accuracy: 0.8261 - val_loss: 0.4031 - val_p_loss: 1.2730e-05 - val_coord_loss: 0.2800 - val_classes_loss: 0.1230 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.6027 - val_classes_accuracy: 0.7524\n",
"Epoch 25/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.1389 - p_loss: 1.2866e-05 - coord_loss: 0.0517 - classes_loss: 0.0872 - p_accuracy: 1.0000 - coord_IoU: 0.7672 - classes_accuracy: 0.8399 - val_loss: 0.4047 - val_p_loss: 2.1689e-05 - val_coord_loss: 0.2824 - val_classes_loss: 0.1223 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5614 - val_classes_accuracy: 0.7286\n",
"Epoch 26/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.1326 - p_loss: 1.3932e-05 - coord_loss: 0.0485 - classes_loss: 0.0841 - p_accuracy: 1.0000 - coord_IoU: 0.7796 - classes_accuracy: 0.8478 - val_loss: 0.4003 - val_p_loss: 9.8319e-06 - val_coord_loss: 0.2825 - val_classes_loss: 0.1178 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.6046 - val_classes_accuracy: 0.7524\n",
"Epoch 27/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.1250 - p_loss: 1.0477e-05 - coord_loss: 0.0449 - classes_loss: 0.0801 - p_accuracy: 1.0000 - coord_IoU: 0.7908 - classes_accuracy: 0.8579 - val_loss: 0.3921 - val_p_loss: 6.6715e-06 - val_coord_loss: 0.2763 - val_classes_loss: 0.1158 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5834 - val_classes_accuracy: 0.7476\n",
"Epoch 28/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.1239 - p_loss: 1.2673e-05 - coord_loss: 0.0470 - classes_loss: 0.0769 - p_accuracy: 1.0000 - coord_IoU: 0.7836 - classes_accuracy: 0.8680 - val_loss: 0.3843 - val_p_loss: 1.1446e-05 - val_coord_loss: 0.2687 - val_classes_loss: 0.1156 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5992 - val_classes_accuracy: 0.7524\n",
"Epoch 29/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.1191 - p_loss: 1.0588e-05 - coord_loss: 0.0452 - classes_loss: 0.0739 - p_accuracy: 1.0000 - coord_IoU: 0.7808 - classes_accuracy: 0.8818 - val_loss: 0.3907 - val_p_loss: 1.1466e-05 - val_coord_loss: 0.2760 - val_classes_loss: 0.1148 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.6082 - val_classes_accuracy: 0.7429\n",
"Epoch 30/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.1193 - p_loss: 1.0438e-05 - coord_loss: 0.0486 - classes_loss: 0.0707 - p_accuracy: 1.0000 - coord_IoU: 0.7825 - classes_accuracy: 0.8881 - val_loss: 0.3991 - val_p_loss: 1.1293e-05 - val_coord_loss: 0.2860 - val_classes_loss: 0.1131 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5731 - val_classes_accuracy: 0.7762\n",
"Epoch 31/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.1125 - p_loss: 8.7969e-06 - coord_loss: 0.0445 - classes_loss: 0.0680 - p_accuracy: 1.0000 - coord_IoU: 0.7844 - classes_accuracy: 0.8940 - val_loss: 0.3903 - val_p_loss: 5.9613e-06 - val_coord_loss: 0.2771 - val_classes_loss: 0.1132 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5902 - val_classes_accuracy: 0.7714\n",
"Epoch 32/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.1079 - p_loss: 8.5401e-06 - coord_loss: 0.0434 - classes_loss: 0.0644 - p_accuracy: 1.0000 - coord_IoU: 0.7930 - classes_accuracy: 0.9062 - val_loss: 0.3907 - val_p_loss: 3.9751e-06 - val_coord_loss: 0.2794 - val_classes_loss: 0.1113 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.6132 - val_classes_accuracy: 0.7810\n",
"Epoch 33/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.1041 - p_loss: 6.3921e-06 - coord_loss: 0.0421 - classes_loss: 0.0619 - p_accuracy: 1.0000 - coord_IoU: 0.7967 - classes_accuracy: 0.9168 - val_loss: 0.3941 - val_p_loss: 9.8752e-06 - val_coord_loss: 0.2780 - val_classes_loss: 0.1160 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5973 - val_classes_accuracy: 0.7333\n",
"Epoch 34/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.0981 - p_loss: 8.5369e-06 - coord_loss: 0.0395 - classes_loss: 0.0585 - p_accuracy: 1.0000 - coord_IoU: 0.8023 - classes_accuracy: 0.9226 - val_loss: 0.3971 - val_p_loss: 3.0896e-06 - val_coord_loss: 0.2855 - val_classes_loss: 0.1116 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5973 - val_classes_accuracy: 0.7524\n",
"Epoch 35/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.0926 - p_loss: 5.3509e-06 - coord_loss: 0.0377 - classes_loss: 0.0549 - p_accuracy: 1.0000 - coord_IoU: 0.8007 - classes_accuracy: 0.9348 - val_loss: 0.3745 - val_p_loss: 6.3115e-06 - val_coord_loss: 0.2608 - val_classes_loss: 0.1137 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.6280 - val_classes_accuracy: 0.7619\n",
"Epoch 36/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.0863 - p_loss: 4.5172e-06 - coord_loss: 0.0340 - classes_loss: 0.0523 - p_accuracy: 1.0000 - coord_IoU: 0.8094 - classes_accuracy: 0.9380 - val_loss: 0.3905 - val_p_loss: 1.8461e-06 - val_coord_loss: 0.2769 - val_classes_loss: 0.1136 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5988 - val_classes_accuracy: 0.7476\n",
"Epoch 37/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.0808 - p_loss: 3.7010e-06 - coord_loss: 0.0318 - classes_loss: 0.0489 - p_accuracy: 1.0000 - coord_IoU: 0.8073 - classes_accuracy: 0.9507 - val_loss: 0.3798 - val_p_loss: 4.9560e-06 - val_coord_loss: 0.2730 - val_classes_loss: 0.1068 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5770 - val_classes_accuracy: 0.8000\n",
"Epoch 38/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.0803 - p_loss: 3.8230e-06 - coord_loss: 0.0338 - classes_loss: 0.0465 - p_accuracy: 1.0000 - coord_IoU: 0.8084 - classes_accuracy: 0.9560 - val_loss: 0.3729 - val_p_loss: 2.7241e-06 - val_coord_loss: 0.2624 - val_classes_loss: 0.1105 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.6056 - val_classes_accuracy: 0.7857\n",
"Epoch 39/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.0754 - p_loss: 3.1915e-06 - coord_loss: 0.0323 - classes_loss: 0.0431 - p_accuracy: 1.0000 - coord_IoU: 0.8181 - classes_accuracy: 0.9581 - val_loss: 0.3831 - val_p_loss: 4.8808e-06 - val_coord_loss: 0.2767 - val_classes_loss: 0.1064 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.6058 - val_classes_accuracy: 0.7952\n",
"Epoch 40/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.0741 - p_loss: 3.3675e-06 - coord_loss: 0.0332 - classes_loss: 0.0409 - p_accuracy: 1.0000 - coord_IoU: 0.8164 - classes_accuracy: 0.9661 - val_loss: 0.3762 - val_p_loss: 2.6131e-06 - val_coord_loss: 0.2668 - val_classes_loss: 0.1094 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.6179 - val_classes_accuracy: 0.7952\n",
"Epoch 41/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.0717 - p_loss: 2.9842e-06 - coord_loss: 0.0330 - classes_loss: 0.0388 - p_accuracy: 1.0000 - coord_IoU: 0.8165 - classes_accuracy: 0.9708 - val_loss: 0.3781 - val_p_loss: 2.0115e-06 - val_coord_loss: 0.2716 - val_classes_loss: 0.1064 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.6109 - val_classes_accuracy: 0.8048\n",
"Epoch 42/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.0667 - p_loss: 2.6782e-06 - coord_loss: 0.0311 - classes_loss: 0.0356 - p_accuracy: 1.0000 - coord_IoU: 0.8156 - classes_accuracy: 0.9719 - val_loss: 0.3922 - val_p_loss: 2.0544e-06 - val_coord_loss: 0.2870 - val_classes_loss: 0.1051 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5667 - val_classes_accuracy: 0.8000\n",
"Epoch 43/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.0719 - p_loss: 2.8606e-06 - coord_loss: 0.0370 - classes_loss: 0.0349 - p_accuracy: 1.0000 - coord_IoU: 0.7998 - classes_accuracy: 0.9756 - val_loss: 0.3827 - val_p_loss: 3.2613e-06 - val_coord_loss: 0.2734 - val_classes_loss: 0.1093 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.6156 - val_classes_accuracy: 0.8048\n",
"Epoch 44/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.0692 - p_loss: 2.8178e-06 - coord_loss: 0.0368 - classes_loss: 0.0324 - p_accuracy: 1.0000 - coord_IoU: 0.8033 - classes_accuracy: 0.9814 - val_loss: 0.3922 - val_p_loss: 1.6154e-06 - val_coord_loss: 0.2802 - val_classes_loss: 0.1120 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5931 - val_classes_accuracy: 0.7952\n",
"Epoch 45/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.0639 - p_loss: 2.7500e-06 - coord_loss: 0.0331 - classes_loss: 0.0308 - p_accuracy: 1.0000 - coord_IoU: 0.8090 - classes_accuracy: 0.9783 - val_loss: 0.3965 - val_p_loss: 1.2561e-06 - val_coord_loss: 0.2813 - val_classes_loss: 0.1152 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5977 - val_classes_accuracy: 0.7810\n",
"Epoch 46/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.0593 - p_loss: 2.0790e-06 - coord_loss: 0.0309 - classes_loss: 0.0284 - p_accuracy: 1.0000 - coord_IoU: 0.8117 - classes_accuracy: 0.9852 - val_loss: 0.3921 - val_p_loss: 9.9823e-07 - val_coord_loss: 0.2795 - val_classes_loss: 0.1125 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5989 - val_classes_accuracy: 0.8048\n",
"Epoch 47/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.0582 - p_loss: 2.2083e-06 - coord_loss: 0.0316 - classes_loss: 0.0266 - p_accuracy: 1.0000 - coord_IoU: 0.8052 - classes_accuracy: 0.9857 - val_loss: 0.4020 - val_p_loss: 1.3179e-06 - val_coord_loss: 0.2929 - val_classes_loss: 0.1091 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.6036 - val_classes_accuracy: 0.8048\n",
"Epoch 48/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.0585 - p_loss: 2.2486e-06 - coord_loss: 0.0332 - classes_loss: 0.0253 - p_accuracy: 1.0000 - coord_IoU: 0.8175 - classes_accuracy: 0.9878 - val_loss: 0.3783 - val_p_loss: 8.4552e-07 - val_coord_loss: 0.2659 - val_classes_loss: 0.1125 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.6222 - val_classes_accuracy: 0.7905\n",
"Epoch 49/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.0535 - p_loss: 1.7950e-06 - coord_loss: 0.0302 - classes_loss: 0.0233 - p_accuracy: 1.0000 - coord_IoU: 0.8218 - classes_accuracy: 0.9894 - val_loss: 0.3774 - val_p_loss: 2.5507e-06 - val_coord_loss: 0.2659 - val_classes_loss: 0.1115 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.6127 - val_classes_accuracy: 0.7857\n",
"Epoch 50/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.0472 - p_loss: 1.3065e-06 - coord_loss: 0.0260 - classes_loss: 0.0212 - p_accuracy: 1.0000 - coord_IoU: 0.8263 - classes_accuracy: 0.9931 - val_loss: 0.3771 - val_p_loss: 1.0610e-06 - val_coord_loss: 0.2671 - val_classes_loss: 0.1100 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.6085 - val_classes_accuracy: 0.8095\n"
]
}
],
"source": [
"batch_size=16\n",
"model = create_model_localisation()\n",
"model.summary()\n",
"opt = Adam(learning_rate=3e-4) \n",
"\n",
"# Ici mettre, dans l'ordre, les fonctions de coût associées à chacune des sorties\n",
"loss=['binary_crossentropy', 'mean_squared_error', 'binary_crossentropy']\n",
"# On va associer une métrique à chaque sortie : l'accuracy pour les deux classifications, \n",
"# et l'IoU définie plus tôt pour la qualité des boîtes englobantes. \n",
"metrics=[ ['accuracy'], [iou()], ['accuracy']]\n",
"loss_weights = [1, 1, 1]\n",
"\n",
"model.compile(loss=loss,\n",
" optimizer=opt,\n",
" metrics=metrics,\n",
" loss_weights=loss_weights\n",
")\n",
"history = model.fit(\n",
" x_train,\n",
" [y_train[:,0], y_train[:,1:5], y_train[:,5:]],\n",
" epochs=50,\n",
" batch_size=batch_size, \n",
" validation_data=(x_val, [y_val[:,0], y_val[:,1:5], y_val[:,5:]])\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 84,
"metadata": {
"id": "Jc-sGe8LNzA-"
},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYYAAADHCAYAAAAd8/SYAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAC20UlEQVR4nOz9e9xtWVrXh36fMcacc631Xvalqrqq+kKDtAQjiWgU4iVKQOONi0YDSEBAtDWf4zFGTiKSY9QcL2DyCRJBsXNQ8BIbCCIcEzSiosFbvEAUJXLTprvp7qruqn1533etOecY4zl/PGPMOddbe1ftXVXd+93NGvuz9rsuc4455xi/Z4zn/oiqcmiHdmiHdmiHVpt71DdwaId2aId2aFerHTaGQzu0Qzu0Q9trh43h0A7t0A7t0PbaYWM4tEM7tEM7tL122BgO7dAO7dAOba8dNoZDO7RDO7RD22uv28YgIv+liPw5EblvnyLyMSJyJiL+Afp7UkR+QER+7ut1j69XE5HvFpEvftT3cWhXu4nILxSRfyQiN1/mmG8SkT9Y3v8HIvKvXuW1vkFEfu+rvddDO7S9pqr3fQF/Ffhv7/H95wDvB0L5/CuBdwL+5fq7Rz/fC/zme3zfAP8r8Ate5tx/AZyVVwJ2i89f+TD3cZVegAJve9T38RD3+6df6z0XHCjwsy59/x3l+08rn38/MC7m+Qy4tTj+c4AfAO4AHwT+JvBxi98/Afi28ttt4J8BvwvwwMeWa4VL9/BNwC1gW673AeDPl/ff/TLP9BbgbwNveIVn/ybgDz7keH0J8H2Peu5f7f0/4vv9JWWeX/U9l/FX4Gsuff855ftvKp8rps4uvT6v/P5m4NsXePxB4EsW/bUF8z8CnAP/ptDbx5bfX7J+Ap8GvOc+8xSBZx/kGV9JYvhm4AtFRC59/0XAX1DVCKCq362qn6+q6X4diUh4hWtNTVVHVf3Vqvr3XuaYn6mqx6p6DPwfwG+vn1X1Dz/Ide51Tw9znz/Vm4j8IuDjX6fufhj4jYu+nwB+PvD8peO+ZTHPx6p6vRz/NuDPAl8OXAM+Dvh6jGlARD4e+IfAu4F/R1WvAf8J8HOBkwe4v88qWPs5GPF54JeJyDOLe56wo6rvVtVfoqrPPfAIHNqHtYlIA3wthoPX2n4M+NxL68UXYzi+3K5fwuy3lO//HIbHtwJPYOvqBxbn/S/AZwNfgGH6ZwH/BPiMh7lRETkCfh22+Xzhg5zzShvDXy43/B8sLnID+Ezgz4qIE5GvEJEfE5EPici3VrFZRD5WRFREvkxEfgL4m4vvgoj8odLv1xX10teV8z5RRP66iLwgIv9KRD73YQah9PGbROSHRORFEflrIvLWxW8qIv8PEfkR4EdE5NNE5D0i8rtF5P3AnxGRGyLyV0Tk+dLHXxGRNy/6+F4R+c3l/ZeIyPeJyH9fjv3XIvIrH/ae7/Mcv19Evk1E/ryI3BWRfy4inyAiv0dEnhORd4vIf7Q4/kvLc98VkR8Xkd96qb//SkTeJyI/KSK/uYzF28pvXXmGnxCRDxTVxPpl7i0Afxz4f74ezwr8BeDzFmrG34BJDMMDnv/JwL9W1b+h1u6q6rer6k+U3/8A8PdU9Xep6vsAVPVfqeoXqOqtB71JVX0vttm8B5M43rfEE4CIfGZRg94Skb8nIv9uPV9EfraI/NMyR98CrBa/fZqIvGfx+S0i8pcKDj8kIl8nIj8D+Abg5xe6uVWOnVRS5fNvEZEfLXT0XSLyxsVvKiK/TUR+pNzj19+D+XvotqDvLy3YfLFc5+eJyD8r1/q6xfEfLyJ/szzbB0XkL4jI9cXvP0dEvr+M1beJyLdcesb7jvN92pcD/zvwf7/WZ8U0Jv8c+OXlXm4CvwD4rofo4+dh0sW5qkZV/X5V/e7S3y8FfhnwOar6j8rvt1X161X1Gx/yXn8dJvX+t9jm9YrtZTcGVd0C38qCkwM+F/i/VfX/whaFX4OJZ28EXsS4tGX7JcDPoAzgou//mn1O/7eL7Wx/HfifgTcAnw/8CRH5tx/kYQBE5HOArwT+Y+Cpco2/eOmwXwN8KlD7fQa4ie3cb8fG5c+Uzx+DqRG+jvu3TwX+FfAk8EeBb7wfoYnInxCRP/GgzwN8FsZZ3AC+H/hr5f7ehE30n1oc+xy2aZ8CXwp8jYj8nHLdX4GpTX4p8DaM6122r8JULZ9cfn8T8N+8zH39F8DfUdV/9hDP8nLtJ4F/CdSN7jdiEsCDtn8KfKKIfI2I/Icicnzp91+KcWCvqYnIv49h4nuwzQwWeBKRn42J+78VY6r+FPBdZeNtMWbrz2F4+zaMaO91HQ/8FeBdmEriTcA7VfWHgN8G/P2lxHTp3E8H/ghGq8+WPt556bDPxBamf7cc98u5RxORX1Q3n4donwr8dODzgD8G/NfY+P9MjMv+JbX7cp9vxNaIt2CqE8pYfQemArmJ0fCvXdzXfcf5Ps/xVuA3YTTzerU/y7w2fj7wnUD/EOf/A+DrReTzReRjLv32S4H/U1Xf/dpvky/Gxu+dGI38e694xgPo034Rttusyue/C/wX5f0PAZ+xOPZZTAccmPVrP23xe/2u2ia+l4WODAPS/3Hp+n8K+H2vcI9TP8B3A1+2+M0BF8Bby2cFPv2STm6oz3ef/j8ZePE+1/sS4EcXv23KNZ55EF3ePa416esxIvnri98+C9NR+vL5pBx//T59/WXgPy/v/zTwRxa/va1eCyPQc+DjF7//fIwDv1e/bwF+FLh2+Z5f5TN/L/CbMTH3LwKfCPxw+e097NsYhoLH+vpbi37+fYyReR6zOX0TcFx+G4Ff8TL3ULF569KrXu9s8d0HgTW2WCvw9kU/fxL4/1zq+19hDNIvxjZAWfz29yj6bhb6YWY1WrjHvX4Jl2wMLHT9wDcCf3Tx23F5/qqbVuAXLX7/VuArXuXcLa9bx/BNi98/RNGpl8/fDvzO+/T1a4DvL+9/MfDeS2P1fYtr3Xec79P3dzLr9qd7fpXP/CXlXtaY6ucatsj/QuAP8lIbw2VM/Yzy+w2MIfsXmBT6A8DPK7/9Txgj8Ep0c3Gp7zMWNgaMicnAJ5fPfw342ld6xlf0SlLV78MI4deI6Wk/BePowTjq7yii3C1so0jA04suHmbHeyvwqbW/0ud/inH0D9PH1y7OfwFb+N70Mvf0vKru6gcR2YjInxKRd4nIHeDvANfl/t5U769vVPWivL3Msb7attQ5boEP6mzL2S6vJSK/UkT+QVEf3AJ+FSbFgHFly+devn8K29D+yWLc/mr5/l7tj2FOCbdf6eZF5CuLyuNMRL7hFQ7/S8CnA78d46rv1b5VVa8vXv9h/UFV/4Gqfq6qPoWpKX8xxq2CLVDPvtL9Ak8u+2fG+q8pn58DvlpVt2pqJTAVQm1vBb78Eobfgo3/G4H3aqHQ0t51n/t4C/AuLXa8h2xvXParqmfY8y9p4P2L9xe8fniFl2L28ueK16dF5J0i8t5CZ3+efbxeHqslZl9unPeaiHwWcKKzbv++TWbPyTMROXu5Y9U0Kv8r8P8GnlDVv3ufQ5+8hNkfKue/qKpfoao/E1szfwD4y0Xb8KB4/R2X8PqZl37/IuCHVPUHyue/AHyBmL3lvu1B3VWryPSFwF9T1TrR7wZ+5aWHXi0IBmzHvF+7/Nu7gb99qb9jVf3PHvA+ax+/9VIfa903ZF++7uXPXw78W8CnquoptsCAbTBXshUR+tuB/x54uoDkf2O+5/dhXhC1vWXx/oMYwf7MxZhdUzO23qt9BvDficj7xewyAH9fRL7g8oGq+od1Nrr9tpd7hrKpfjfwn3H/jeGBmqr+I2yj+aTy1fdwH7XNgzYR+QWYiuT3XHr2z5LZCPlu4A9dwt9GVf8iNgdvuqRmvKxCqO3dwMfIvZ0hXo6mwKSSpV3tCFO3vPe+Zzya9oexZ/l3Cp19Ift4vTxWS8y+3Dhfbp8B/NzFnH0e8DtF5DsvH6iqP7HA64NsltXh4c8/wLH3bar6QYx234ipzr4H+BRZ2DZfZfuNwE9bPPv/gG2+v+rlTnqYjeGXAr8F8
"text/plain": [
"<Figure size 432x288 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYgAAADHCAYAAAADOsQrAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAADWKElEQVR4nOz9eZxu63bXhX7H08w536aqVrP7s08TCBDASwgCAUJ3CUp/afQGvIAEgwG9gatyEQQVVJqIfhQ0QgiCtJcQpBEVMARupEdFwABJSEJOm7O71VW9zZzzaYZ/jOetVWudtfdeK3ufVQtPjfVZn6p6m9n+nvmMZ4zf+A1RVa7syq7syq7syh42d9kHcGVXdmVXdmXPpl1NEFd2ZVd2ZVf2SLuaIK7syq7syq7skXY1QVzZlV3ZlV3ZI+1qgriyK7uyK7uyR9rVBHFlV3ZlV3Zlj7T3bYIQkV8jIn9YRN52myLyIRHZiIh/jO09JyJ/T0R++Pt1jO+XicifF5FfctnHcWXPtonIl4jI/yoiN97hM39ARH5z+/3Hici3fy/39bUi8u99b4/1yq7skaaqb/sf+AvAf/iI13828BoQ2t8/Dfh6wL/T9h6xnW8GftkjXo/A/wj8mHf47j8ENu1/AcYLf//6JzmOZ+k/oMDnX/ZxvMsx/kSgXrjeG+CXvIftffOF+/cW8KeAlx/6zA8C/ixwDzgD/v8X8dGO6ZPvhjHg+zWsvgmcAt8B/JfAqxc+cw343Q3jO2Bu/zfA68AfAD4G7Ntrr7XX1he28UHgfwZeeJdz/wPAb37C6/XlwF+7bBx8b4//ko7zoxfu1wb4xvewrS9vz5xNw9DfB37mQ5/pgd8GfLzt9zuAXwPIQ8f0k9/p3gId8O8D3w5sgU8Bfx745x/xvW9peH2t4ffahfd/E5DaMd8F/gbwo9/tXN9tBfEHgV8kIvLQ678Y+KOqmgFU9c+r6i9Q1fJ2GxKR8C77OjdVTar6M1T1b7zDZ36wqq5VdQ38VeCrDn+r6m99nP086pie5Dg/x+17Llzvtar+wfe4va9q9/LzgTXwnx7eEJHvC/x1bAB8HvAK8KeBbxSRH/24OxCRzwf+NvA9wBep6jHwJcB3AT+2faYDvgn4MPCjgRPgDjY4/33ghwE/HJtEflY75h8KfBHw6w/7UtVPqOpPUNU3nvA6XNlnz37WBbz+8+9xW3+z3ftrwO8Cvl5Erl14/08AXwr8dOAIe2Z+JfA7n3A//y3mkP/LwHUM/78T+BmHD4jIrwb+Y2wCOgF+FIbfv9jwfLA/3o75OczB+hPvuvd3mSkXmMf24y+8dh3z9r4QC1H9OmyA3QK+AbjRPvcRzBv+CmwW/SsXXgvAb+FBz/9r2ve+APiLwG1s1vyyx5jRv5kHvcR/BfhWbGD/T8CHL7ynwP8bm9G/m+Z5Ar8Wm3n/cDvH/wHzMu+031991P5oMz72QLvTtvnT3oN3cr6CwGb9PwH8Ecxr/hbg+wP/DvAG8AkueBLAL23nfQb8E+CXP7Ttfxv4NPaA/GUP7atv5/BxzEv+WmDxNsf4E3mEt/4ezvnh+/evA//wwt9/GPhzj/je7wb+yjsd00P36o8A//27HMtXtGu7uvDaR4H/qOH0GPhPME/tJ1/A021g1z7/M4G/x31P7Ydc2NYXAf97u0d/HFvN/OZHnQO2CvlTDYe3gK8BfiA2Zg4e7N322T/ABU8e+FeB72zH9WeBVx7C2K/AxsBd4L/igmf7hPfufL/cH9+/tGHzTtvPjwD+j7avr7nw3e8L/OV2bm8Bf5QHvd4fBvzddq3+RLteF8/xba/zI47zozzkrb8HvH45D3r5y3beP6L9/aXtHn3woe99cbtvn/92x3Rx2w1fey48ex5xLMcNB1/20Ovrhpt/5cKz5I9ceP8HtWN+/p3O9R1XEKq6xx76//KFl78M+DZV/fvArwR+DvATMK/uDga2i/YTMFD/lIe2/Rt40PP/KhFZYZPD/w94AfgFwO8SkR/0Tsd50UTkZ2Oe3M8Dnm/7+GMPfeznYDfrsN2XgBvYrPuV2MT337S/P4TdpK95h91+MTaZPQf8duD3PWLVdTi+3yUiv+txzwf4WdyftP4uNuE54APAfwj8nguffQMbNMfYIP3PReSHtf3+VODfwkD3+djD6KJ9NTb5/ND2/gcwj/nt7AUReV1EvltE/vN2796zichN7N5954WX/zke7e18A/AlIrJ4zM3/ZOBPvstn/jngz6vq9qHX/yowYPfjp2Mhp4P9fMy5+P0i8kXA7wd+OXATuz9/VkT65s39Gex+3mjn9C886iBanu5/wEJZH8Hux9er6rdiD92/2cbNtUd89ydh4Y0vA15u2/j6hz72M7EH9w9pn/spPMJE5MeKyN1HvfcO9sVYKO/nA78D+A3Ytf/BwJeJyE84bL4d5yvYM+KD2IPssJL709gEdAMbwz/3wnG97XV+h+P6oyLypoh8o4h84ROe0yOt3adfioVvPtZe/ueAv62qn7j4WVX925gz+qWPufmf3LbzyXf4zI/BcPmnHtrXBvhz7VgePuYOe6bfwp7Zb2+PMVv+WGyGHtrffx34N9vv3wp86YXPvoxdqMB9b+L7XHj/8Nohd/HNPOg5/nzgrz60/98D/MZ3Ocbz7WDxua+48J7DvL0PX/CeftKF938iNtiHd9j+DwXuvM3+vhz4zkd4Ey99L72Th1cQf/HCez8L8xZ8+/uoff7a22zrzwD/n/b77wd+24X3Pv+wL2ygboHve+H9Hw1899ts9yVscnXYkvevAL/ne3O+F67nDlutKuYVfujC+xn4qY/43he0z3+Ax1tBPLAd4KswbG+A39te+ybgqx/axkfbZyrm6f4u7GGwaftX4C9xP3fxHz30/W/HHKUfj63eLsah/waPWEG06/8mbaw8tL0v56EcBA968r8P+O0X3ltj4/IjFzD2Yy+8/w3Ar/te3ruL+/3I4X5ceP8W8PMv/P0ngX/jbbb1c4C/237/8Vi8/eK1+msX9vW21/lttv0lWERkia3AX+Ntxs1jnPOXNyzdbdd1zwUPHvivscn8Ud/9W8BvuICrd1pBPLAdbKK8i42Tsb32i4DX3mZfX017fmDPkrl9v7T78hPf7VzflcWkqn8NGxQ/p8WCfyTm4YN52H9aRO42L+Nb285fvLCJB2bRd7EPA1982F7b5i/EHkhPso3feeH7t7EH4Afe4ZjeVNXx8IeILEXk94jIx0TkFHsAXnsH9tVrh19Uddd+XT/BMb+TvX7h9z3wlt7P9ewv7ktEfpqI/C0Rud3O/adjqxowL+3ieV/8/Xls4PydC9ftL7TXP8NU9TVV/UeqWlX1u7HQ1dt5wr++Mdc2IvK173Cev0pVTzCP9jrw6oX33sKcj4ftZeyhfQcbsPERn4nYIAYbFOfbUdWvUfPAf8eF777dvn5e29cvVNV/HXsQ/pz23i/EJqvnMPz96ocw/EHs+r8CfErbiG32MR5tHwQ+pi3P94T2ysXtqnmTt3hwDLx24fcd7x9e4TMx+/DfB7y+KCJfLyKfauPsj/AgXh++Vhcx+07X+TNMVf+6qu5Vdaeqvw17UP64hz93gWm5EZHNO5zj32rYuY6F8C5u6+0wRHv9rfb7ozD7Tni93fb5z2Ih4cO+nnub3OnFfQF8Q/v+i8A/aNt5R3tcmusfwpYkvwj4n1T1cMM/gcXbr134P6jqpy58Vx/e2Du89wngf35oe2tV/dce8zgP2/jlD21joQ8mvB/e78N//2rgBwBfrJbI/PHt9UeGjZ4Fa0vrP4nlEV5sQPhz3D/mT/PgQ/eDF35/Cxu4P/jCNTtRS2g9jilvgyVV/a16PzH4K951Q6rfAvxm4L+6EKb7JuD/+YiPfxkWatlhuZPnROT8mNv3P8z9h+Vfwh7072TfBPy0R4TMfhwwYR7gw/a/YJ70f4rh77c8hL+lqv4x7B584KHw44fe5jg+AXzobQb+O40psFXKhw9/tHO5iXnkz5L9Vuxc/m9tnP0iHsTrw9fqImbf6To/jimPGM+q+vELeH1X/LfJ918DfnELe4Fh6
"text/plain": [
"<Figure size 432x288 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# Analyse des résultats : courbes d'évolution de la fonction de perte, et de l'IoU des boîtes englobantes ainsi que de la précision des classes prédites\n",
"plot_training_analysis(history, metric='loss')\n",
"plot_training_analysis(history, metric='coord_IoU')\n",
"plot_training_analysis(history, metric='classes_accuracy')\n",
"\n",
"# Prédiction des données de test\n",
"y_pred_presence, y_pred_coords, y_pred_classes = model.predict(x_test)\n",
"y_pred = np.zeros(y_test.shape)\n",
"for i in range(y_pred.shape[0]):\n",
" y_pred[i, 0] = y_pred_presence[i]\n",
" y_pred[i, 1:5] = y_pred_coords[i]\n",
" y_pred[i, 5:] = y_pred_classes[i]\n",
"\n",
"# Affichage des résultats sur plusieurs images\n",
"print_data_localisation(x_test, y_test, y_pred = y_pred, id=1, image_size=IMAGE_SIZE)\n",
"print_data_localisation(x_test, y_test, y_pred = y_pred, id=2, image_size=IMAGE_SIZE)\n",
"print_data_localisation(x_test, y_test, y_pred = y_pred, id=3, image_size=IMAGE_SIZE)\n",
"print_data_localisation(x_test, y_test, y_pred = y_pred, id=4, image_size=IMAGE_SIZE)\n",
"print_data_localisation(x_test, y_test, y_pred = y_pred, id=5, image_size=IMAGE_SIZE)\n",
"print_data_localisation(x_test, y_test, y_pred = y_pred, id=6, image_size=IMAGE_SIZE)\n",
"print_data_localisation(x_test, y_test, y_pred = y_pred, id=7, image_size=IMAGE_SIZE)\n",
"print_data_localisation(x_test, y_test, y_pred = y_pred, id=8, image_size=IMAGE_SIZE)"
]
},
{
"cell_type": "code",
"execution_count": 85,
"metadata": {
"id": "UVU1bR_YEIMs"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"La précision globale est de 56.2%\n",
"\n",
"------------------------------------------\n",
"| Classe | Précision | Rappel | F1-score |\n",
"------------------------------------------\n",
"| MESCHA | 0.14 | 0.09 | 0.11 |\n",
"------------------------------------------\n",
"| VEREUR | 0.52 | 0.59 | 0.55 |\n",
"------------------------------------------\n",
"| ECUROU | 0.86 | 0.86 | 0.86 |\n",
"------------------------------------------\n",
"| PIEBAV | 0.91 | 0.91 | 0.91 |\n",
"------------------------------------------\n",
"| SITTOR | 0.55 | 0.27 | 0.36 |\n",
"------------------------------------------\n",
"| PINARB | 0.71 | 0.77 | 0.74 |\n",
"------------------------------------------\n",
"| MESNOI | 0.36 | 0.57 | 0.44 |\n",
"------------------------------------------\n",
"| MESNON | 0.29 | 0.36 | 0.32 |\n",
"------------------------------------------\n",
"| MESBLE | 0.30 | 0.27 | 0.29 |\n",
"------------------------------------------\n",
"| ROUGOR | 0.71 | 0.71 | 0.71 |\n",
"------------------------------------------\n",
"| ACCMOU | 0.71 | 0.77 | 0.74 |\n",
"------------------------------------------\n"
]
}
],
"source": [
"class_res, accuracy = global_accuracy(y_test, y_pred)\n",
"\n",
"print(f\"La précision globale est de {100 * accuracy:.1f}%\")\n",
"\n",
"print()\n",
"print(\"------------------------------------------\")\n",
"print(\"| Classe | Précision | Rappel | F1-score |\")\n",
"print(\"------------------------------------------\")\n",
"for i in range(num_classes):\n",
" print(f\"| {class_labels[i]:7s}| {class_res[i]['Precision']:.2f} | {class_res[i]['Rappel']:.2f} | {class_res[i]['F-score']:.2f} |\")\n",
" print(\"------------------------------------------\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "eiFO6fBns-OI"
},
"source": [
"En pratique, il est délicat de trouver une bonne combinaison des fonctions de perte tel que vous l'avez fait sur les cellules précédentes. L'entropie croisée et l'erreur quadratique moyenne donnent des valeurs trop différentes pour être combinables efficacement.\n",
"\n",
"Une variante, peut-être plus simple à faire fonctionner, est d'utiliser uniquement l'erreur quadratique moyenne comme perte pour toutes les sorties. C'est cette variante qui est implémentée dans l'algorithme YOLO, dont nous implémenterons une version simplifiée dans le prochain TP.\n",
"Testez cette solution ci-dessous. Comme sur l'exercice précédent, n'hésitez pas à faire varier le poids des différents éléments de la fonction de coût."
]
},
{
"cell_type": "code",
"execution_count": 86,
"metadata": {
"id": "ttGCeqz0Dc3y"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1/50\n",
"118/118 [==============================] - 11s 88ms/step - loss: 1.4310 - p_loss: 0.0151 - coord_loss: 1.3283 - classes_loss: 0.0876 - p_accuracy: 0.9989 - coord_IoU: 0.4143 - classes_accuracy: 0.0859 - val_loss: 0.6519 - val_p_loss: 5.9735e-04 - val_coord_loss: 0.5653 - val_classes_loss: 0.0860 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.4729 - val_classes_accuracy: 0.1286\n",
"Epoch 2/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.5781 - p_loss: 0.0011 - coord_loss: 0.4942 - classes_loss: 0.0828 - p_accuracy: 1.0000 - coord_IoU: 0.5069 - classes_accuracy: 0.1729 - val_loss: 0.5192 - val_p_loss: 5.8288e-04 - val_coord_loss: 0.4374 - val_classes_loss: 0.0812 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5086 - val_classes_accuracy: 0.2143\n",
"Epoch 3/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.4808 - p_loss: 7.0716e-04 - coord_loss: 0.4026 - classes_loss: 0.0774 - p_accuracy: 1.0000 - coord_IoU: 0.5380 - classes_accuracy: 0.2964 - val_loss: 0.4908 - val_p_loss: 9.9283e-04 - val_coord_loss: 0.4128 - val_classes_loss: 0.0770 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5183 - val_classes_accuracy: 0.3143\n",
"Epoch 4/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.4210 - p_loss: 4.7277e-04 - coord_loss: 0.3479 - classes_loss: 0.0726 - p_accuracy: 1.0000 - coord_IoU: 0.5572 - classes_accuracy: 0.3881 - val_loss: 0.4603 - val_p_loss: 2.6880e-04 - val_coord_loss: 0.3883 - val_classes_loss: 0.0718 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.4756 - val_classes_accuracy: 0.3476\n",
"Epoch 5/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.3553 - p_loss: 2.5311e-04 - coord_loss: 0.2874 - classes_loss: 0.0676 - p_accuracy: 1.0000 - coord_IoU: 0.5813 - classes_accuracy: 0.4316 - val_loss: 0.3913 - val_p_loss: 1.5167e-04 - val_coord_loss: 0.3239 - val_classes_loss: 0.0672 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5942 - val_classes_accuracy: 0.3952\n",
"Epoch 6/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.3121 - p_loss: 2.1208e-04 - coord_loss: 0.2483 - classes_loss: 0.0636 - p_accuracy: 1.0000 - coord_IoU: 0.6031 - classes_accuracy: 0.4708 - val_loss: 0.3978 - val_p_loss: 1.8132e-04 - val_coord_loss: 0.3330 - val_classes_loss: 0.0647 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5796 - val_classes_accuracy: 0.4429\n",
"Epoch 7/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.2712 - p_loss: 1.4645e-04 - coord_loss: 0.2110 - classes_loss: 0.0600 - p_accuracy: 1.0000 - coord_IoU: 0.6217 - classes_accuracy: 0.5048 - val_loss: 0.3656 - val_p_loss: 9.9904e-05 - val_coord_loss: 0.3042 - val_classes_loss: 0.0613 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.6001 - val_classes_accuracy: 0.4762\n",
"Epoch 8/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.2488 - p_loss: 1.8330e-04 - coord_loss: 0.1911 - classes_loss: 0.0576 - p_accuracy: 1.0000 - coord_IoU: 0.6303 - classes_accuracy: 0.5223 - val_loss: 0.3516 - val_p_loss: 2.8725e-04 - val_coord_loss: 0.2916 - val_classes_loss: 0.0597 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.6061 - val_classes_accuracy: 0.4952\n",
"Epoch 9/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.2226 - p_loss: 1.1546e-04 - coord_loss: 0.1673 - classes_loss: 0.0552 - p_accuracy: 1.0000 - coord_IoU: 0.6481 - classes_accuracy: 0.5451 - val_loss: 0.3517 - val_p_loss: 9.4986e-05 - val_coord_loss: 0.2937 - val_classes_loss: 0.0579 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5699 - val_classes_accuracy: 0.5048\n",
"Epoch 10/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.2028 - p_loss: 1.1011e-04 - coord_loss: 0.1493 - classes_loss: 0.0533 - p_accuracy: 1.0000 - coord_IoU: 0.6572 - classes_accuracy: 0.5551 - val_loss: 0.3346 - val_p_loss: 6.5773e-05 - val_coord_loss: 0.2787 - val_classes_loss: 0.0558 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.6171 - val_classes_accuracy: 0.5571\n",
"Epoch 11/50\n",
"118/118 [==============================] - 10s 85ms/step - loss: 0.1809 - p_loss: 7.7123e-05 - coord_loss: 0.1293 - classes_loss: 0.0515 - p_accuracy: 1.0000 - coord_IoU: 0.6801 - classes_accuracy: 0.5870 - val_loss: 0.3483 - val_p_loss: 3.8490e-05 - val_coord_loss: 0.2935 - val_classes_loss: 0.0547 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.5973 - val_classes_accuracy: 0.5333\n",
"Epoch 12/50\n",
"118/118 [==============================] - 10s 86ms/step - loss: 0.1652 - p_loss: 7.5254e-05 - coord_loss: 0.1155 - classes_loss: 0.0496 - p_accuracy: 1.0000 - coord_IoU: 0.6897 - classes_accuracy: 0.5960 - val_loss: 0.3261 - val_p_loss: 7.5853e-05 - val_coord_loss: 0.2731 - val_classes_loss: 0.0529 - val_p_accuracy: 1.0000 - val_coord_IoU: 0.6050 - val_classes_accuracy: 0.5619\n",
"Epoch 13/50\n",
" 86/118 [====================>.........] - ETA: 2s - loss: 0.1487 - p_loss: 5.7952e-05 - coord_loss: 0.0999 - classes_loss: 0.0488 - p_accuracy: 1.0000 - coord_IoU: 0.6981 - classes_accuracy: 0.6054"
]
},
{
"ename": "KeyboardInterrupt",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m/home/laurent/Documents/Cours/ENSEEIHT/S8 - Réseau Profond/TP6.ipynb Cell 33'\u001b[0m in \u001b[0;36m<cell line: 14>\u001b[0;34m()\u001b[0m\n\u001b[1;32m <a href='vscode-notebook-cell:/home/laurent/Documents/Cours/ENSEEIHT/S8%20-%20R%C3%A9seau%20Profond/TP6.ipynb#ch0000032?line=6'>7</a>\u001b[0m loss_weights \u001b[39m=\u001b[39m [\u001b[39m1\u001b[39m, \u001b[39m1\u001b[39m, \u001b[39m1\u001b[39m]\n\u001b[1;32m <a href='vscode-notebook-cell:/home/laurent/Documents/Cours/ENSEEIHT/S8%20-%20R%C3%A9seau%20Profond/TP6.ipynb#ch0000032?line=8'>9</a>\u001b[0m model\u001b[39m.\u001b[39mcompile(loss\u001b[39m=\u001b[39mloss,\n\u001b[1;32m <a href='vscode-notebook-cell:/home/laurent/Documents/Cours/ENSEEIHT/S8%20-%20R%C3%A9seau%20Profond/TP6.ipynb#ch0000032?line=9'>10</a>\u001b[0m optimizer\u001b[39m=\u001b[39mopt,\n\u001b[1;32m <a href='vscode-notebook-cell:/home/laurent/Documents/Cours/ENSEEIHT/S8%20-%20R%C3%A9seau%20Profond/TP6.ipynb#ch0000032?line=10'>11</a>\u001b[0m metrics\u001b[39m=\u001b[39mmetrics,\n\u001b[1;32m <a href='vscode-notebook-cell:/home/laurent/Documents/Cours/ENSEEIHT/S8%20-%20R%C3%A9seau%20Profond/TP6.ipynb#ch0000032?line=11'>12</a>\u001b[0m loss_weights\u001b[39m=\u001b[39mloss_weights\n\u001b[1;32m <a href='vscode-notebook-cell:/home/laurent/Documents/Cours/ENSEEIHT/S8%20-%20R%C3%A9seau%20Profond/TP6.ipynb#ch0000032?line=12'>13</a>\u001b[0m )\n\u001b[0;32m---> <a href='vscode-notebook-cell:/home/laurent/Documents/Cours/ENSEEIHT/S8%20-%20R%C3%A9seau%20Profond/TP6.ipynb#ch0000032?line=13'>14</a>\u001b[0m history \u001b[39m=\u001b[39m model\u001b[39m.\u001b[39;49mfit(x_train, [y_train[:,\u001b[39m0\u001b[39;49m], y_train[:,\u001b[39m1\u001b[39;49m:\u001b[39m5\u001b[39;49m], y_train[:,\u001b[39m5\u001b[39;49m:]],\n\u001b[1;32m <a href='vscode-notebook-cell:/home/laurent/Documents/Cours/ENSEEIHT/S8%20-%20R%C3%A9seau%20Profond/TP6.ipynb#ch0000032?line=14'>15</a>\u001b[0m epochs\u001b[39m=\u001b[39;49m\u001b[39m50\u001b[39;49m,\n\u001b[1;32m <a href='vscode-notebook-cell:/home/laurent/Documents/Cours/ENSEEIHT/S8%20-%20R%C3%A9seau%20Profond/TP6.ipynb#ch0000032?line=15'>16</a>\u001b[0m batch_size\u001b[39m=\u001b[39;49mbatch_size, \n\u001b[1;32m <a href='vscode-notebook-cell:/home/laurent/Documents/Cours/ENSEEIHT/S8%20-%20R%C3%A9seau%20Profond/TP6.ipynb#ch0000032?line=16'>17</a>\u001b[0m validation_data\u001b[39m=\u001b[39;49m(x_val, [y_val[:,\u001b[39m0\u001b[39;49m], y_val[:,\u001b[39m1\u001b[39;49m:\u001b[39m5\u001b[39;49m], y_val[:,\u001b[39m5\u001b[39;49m:]]))\n",
"File \u001b[0;32m/tmp/deepl/.env/lib/python3.8/site-packages/keras/utils/traceback_utils.py:64\u001b[0m, in \u001b[0;36mfilter_traceback.<locals>.error_handler\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/utils/traceback_utils.py?line=61'>62</a>\u001b[0m filtered_tb \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/utils/traceback_utils.py?line=62'>63</a>\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m---> <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/utils/traceback_utils.py?line=63'>64</a>\u001b[0m \u001b[39mreturn\u001b[39;00m fn(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/utils/traceback_utils.py?line=64'>65</a>\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mException\u001b[39;00m \u001b[39mas\u001b[39;00m e: \u001b[39m# pylint: disable=broad-except\u001b[39;00m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/utils/traceback_utils.py?line=65'>66</a>\u001b[0m filtered_tb \u001b[39m=\u001b[39m _process_traceback_frames(e\u001b[39m.\u001b[39m__traceback__)\n",
"File \u001b[0;32m/tmp/deepl/.env/lib/python3.8/site-packages/keras/engine/training.py:1389\u001b[0m, in \u001b[0;36mModel.fit\u001b[0;34m(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_batch_size, validation_freq, max_queue_size, workers, use_multiprocessing)\u001b[0m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/engine/training.py?line=1386'>1387</a>\u001b[0m logs \u001b[39m=\u001b[39m tmp_logs \u001b[39m# No error, now safe to assign to logs.\u001b[39;00m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/engine/training.py?line=1387'>1388</a>\u001b[0m end_step \u001b[39m=\u001b[39m step \u001b[39m+\u001b[39m data_handler\u001b[39m.\u001b[39mstep_increment\n\u001b[0;32m-> <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/engine/training.py?line=1388'>1389</a>\u001b[0m callbacks\u001b[39m.\u001b[39;49mon_train_batch_end(end_step, logs)\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/engine/training.py?line=1389'>1390</a>\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mstop_training:\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/engine/training.py?line=1390'>1391</a>\u001b[0m \u001b[39mbreak\u001b[39;00m\n",
"File \u001b[0;32m/tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py:438\u001b[0m, in \u001b[0;36mCallbackList.on_train_batch_end\u001b[0;34m(self, batch, logs)\u001b[0m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=430'>431</a>\u001b[0m \u001b[39m\"\"\"Calls the `on_train_batch_end` methods of its callbacks.\u001b[39;00m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=431'>432</a>\u001b[0m \n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=432'>433</a>\u001b[0m \u001b[39mArgs:\u001b[39;00m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=433'>434</a>\u001b[0m \u001b[39m batch: Integer, index of batch within the current epoch.\u001b[39;00m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=434'>435</a>\u001b[0m \u001b[39m logs: Dict. Aggregated metric results up until this batch.\u001b[39;00m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=435'>436</a>\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=436'>437</a>\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_should_call_train_batch_hooks:\n\u001b[0;32m--> <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=437'>438</a>\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_call_batch_hook(ModeKeys\u001b[39m.\u001b[39;49mTRAIN, \u001b[39m'\u001b[39;49m\u001b[39mend\u001b[39;49m\u001b[39m'\u001b[39;49m, batch, logs\u001b[39m=\u001b[39;49mlogs)\n",
"File \u001b[0;32m/tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py:297\u001b[0m, in \u001b[0;36mCallbackList._call_batch_hook\u001b[0;34m(self, mode, hook, batch, logs)\u001b[0m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=294'>295</a>\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_call_batch_begin_hook(mode, batch, logs)\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=295'>296</a>\u001b[0m \u001b[39melif\u001b[39;00m hook \u001b[39m==\u001b[39m \u001b[39m'\u001b[39m\u001b[39mend\u001b[39m\u001b[39m'\u001b[39m:\n\u001b[0;32m--> <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=296'>297</a>\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_call_batch_end_hook(mode, batch, logs)\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=297'>298</a>\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=298'>299</a>\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mValueError\u001b[39;00m(\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=299'>300</a>\u001b[0m \u001b[39mf\u001b[39m\u001b[39m'\u001b[39m\u001b[39mUnrecognized hook: \u001b[39m\u001b[39m{\u001b[39;00mhook\u001b[39m}\u001b[39;00m\u001b[39m. Expected values are [\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mbegin\u001b[39m\u001b[39m\"\u001b[39m\u001b[39m, \u001b[39m\u001b[39m\"\u001b[39m\u001b[39mend\u001b[39m\u001b[39m\"\u001b[39m\u001b[39m]\u001b[39m\u001b[39m'\u001b[39m)\n",
"File \u001b[0;32m/tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py:318\u001b[0m, in \u001b[0;36mCallbackList._call_batch_end_hook\u001b[0;34m(self, mode, batch, logs)\u001b[0m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=314'>315</a>\u001b[0m batch_time \u001b[39m=\u001b[39m time\u001b[39m.\u001b[39mtime() \u001b[39m-\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_batch_start_time\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=315'>316</a>\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_batch_times\u001b[39m.\u001b[39mappend(batch_time)\n\u001b[0;32m--> <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=317'>318</a>\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_call_batch_hook_helper(hook_name, batch, logs)\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=319'>320</a>\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mlen\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_batch_times) \u001b[39m>\u001b[39m\u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_num_batches_for_timing_check:\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=320'>321</a>\u001b[0m end_hook_name \u001b[39m=\u001b[39m hook_name\n",
"File \u001b[0;32m/tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py:356\u001b[0m, in \u001b[0;36mCallbackList._call_batch_hook_helper\u001b[0;34m(self, hook_name, batch, logs)\u001b[0m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=353'>354</a>\u001b[0m \u001b[39mfor\u001b[39;00m callback \u001b[39min\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mcallbacks:\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=354'>355</a>\u001b[0m hook \u001b[39m=\u001b[39m \u001b[39mgetattr\u001b[39m(callback, hook_name)\n\u001b[0;32m--> <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=355'>356</a>\u001b[0m hook(batch, logs)\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=357'>358</a>\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_check_timing:\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=358'>359</a>\u001b[0m \u001b[39mif\u001b[39;00m hook_name \u001b[39mnot\u001b[39;00m \u001b[39min\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_hook_times:\n",
"File \u001b[0;32m/tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py:1034\u001b[0m, in \u001b[0;36mProgbarLogger.on_train_batch_end\u001b[0;34m(self, batch, logs)\u001b[0m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=1032'>1033</a>\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mon_train_batch_end\u001b[39m(\u001b[39mself\u001b[39m, batch, logs\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m):\n\u001b[0;32m-> <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=1033'>1034</a>\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_batch_update_progbar(batch, logs)\n",
"File \u001b[0;32m/tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py:1106\u001b[0m, in \u001b[0;36mProgbarLogger._batch_update_progbar\u001b[0;34m(self, batch, logs)\u001b[0m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=1101'>1102</a>\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mseen \u001b[39m+\u001b[39m\u001b[39m=\u001b[39m add_seen\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=1103'>1104</a>\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mverbose \u001b[39m==\u001b[39m \u001b[39m1\u001b[39m:\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=1104'>1105</a>\u001b[0m \u001b[39m# Only block async when verbose = 1.\u001b[39;00m\n\u001b[0;32m-> <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=1105'>1106</a>\u001b[0m logs \u001b[39m=\u001b[39m tf_utils\u001b[39m.\u001b[39;49msync_to_numpy_or_python_type(logs)\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/callbacks.py?line=1106'>1107</a>\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mprogbar\u001b[39m.\u001b[39mupdate(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mseen, \u001b[39mlist\u001b[39m(logs\u001b[39m.\u001b[39mitems()), finalize\u001b[39m=\u001b[39m\u001b[39mFalse\u001b[39;00m)\n",
"File \u001b[0;32m/tmp/deepl/.env/lib/python3.8/site-packages/keras/utils/tf_utils.py:563\u001b[0m, in \u001b[0;36msync_to_numpy_or_python_type\u001b[0;34m(tensors)\u001b[0m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/utils/tf_utils.py?line=559'>560</a>\u001b[0m \u001b[39mreturn\u001b[39;00m t\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/utils/tf_utils.py?line=560'>561</a>\u001b[0m \u001b[39mreturn\u001b[39;00m t\u001b[39m.\u001b[39mitem() \u001b[39mif\u001b[39;00m np\u001b[39m.\u001b[39mndim(t) \u001b[39m==\u001b[39m \u001b[39m0\u001b[39m \u001b[39melse\u001b[39;00m t\n\u001b[0;32m--> <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/utils/tf_utils.py?line=562'>563</a>\u001b[0m \u001b[39mreturn\u001b[39;00m tf\u001b[39m.\u001b[39;49mnest\u001b[39m.\u001b[39;49mmap_structure(_to_single_numpy_or_python_type, tensors)\n",
"File \u001b[0;32m/tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/util/nest.py:914\u001b[0m, in \u001b[0;36mmap_structure\u001b[0;34m(func, *structure, **kwargs)\u001b[0m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/util/nest.py?line=909'>910</a>\u001b[0m flat_structure \u001b[39m=\u001b[39m (flatten(s, expand_composites) \u001b[39mfor\u001b[39;00m s \u001b[39min\u001b[39;00m structure)\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/util/nest.py?line=910'>911</a>\u001b[0m entries \u001b[39m=\u001b[39m \u001b[39mzip\u001b[39m(\u001b[39m*\u001b[39mflat_structure)\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/util/nest.py?line=912'>913</a>\u001b[0m \u001b[39mreturn\u001b[39;00m pack_sequence_as(\n\u001b[0;32m--> <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/util/nest.py?line=913'>914</a>\u001b[0m structure[\u001b[39m0\u001b[39m], [func(\u001b[39m*\u001b[39mx) \u001b[39mfor\u001b[39;00m x \u001b[39min\u001b[39;00m entries],\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/util/nest.py?line=914'>915</a>\u001b[0m expand_composites\u001b[39m=\u001b[39mexpand_composites)\n",
"File \u001b[0;32m/tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/util/nest.py:914\u001b[0m, in \u001b[0;36m<listcomp>\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/util/nest.py?line=909'>910</a>\u001b[0m flat_structure \u001b[39m=\u001b[39m (flatten(s, expand_composites) \u001b[39mfor\u001b[39;00m s \u001b[39min\u001b[39;00m structure)\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/util/nest.py?line=910'>911</a>\u001b[0m entries \u001b[39m=\u001b[39m \u001b[39mzip\u001b[39m(\u001b[39m*\u001b[39mflat_structure)\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/util/nest.py?line=912'>913</a>\u001b[0m \u001b[39mreturn\u001b[39;00m pack_sequence_as(\n\u001b[0;32m--> <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/util/nest.py?line=913'>914</a>\u001b[0m structure[\u001b[39m0\u001b[39m], [func(\u001b[39m*\u001b[39;49mx) \u001b[39mfor\u001b[39;00m x \u001b[39min\u001b[39;00m entries],\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/util/nest.py?line=914'>915</a>\u001b[0m expand_composites\u001b[39m=\u001b[39mexpand_composites)\n",
"File \u001b[0;32m/tmp/deepl/.env/lib/python3.8/site-packages/keras/utils/tf_utils.py:557\u001b[0m, in \u001b[0;36msync_to_numpy_or_python_type.<locals>._to_single_numpy_or_python_type\u001b[0;34m(t)\u001b[0m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/utils/tf_utils.py?line=553'>554</a>\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39m_to_single_numpy_or_python_type\u001b[39m(t):\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/utils/tf_utils.py?line=554'>555</a>\u001b[0m \u001b[39m# Don't turn ragged or sparse tensors to NumPy.\u001b[39;00m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/utils/tf_utils.py?line=555'>556</a>\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39misinstance\u001b[39m(t, tf\u001b[39m.\u001b[39mTensor):\n\u001b[0;32m--> <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/utils/tf_utils.py?line=556'>557</a>\u001b[0m t \u001b[39m=\u001b[39m t\u001b[39m.\u001b[39;49mnumpy()\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/utils/tf_utils.py?line=557'>558</a>\u001b[0m \u001b[39m# Strings, ragged and sparse tensors don't have .item(). Return them as-is.\u001b[39;00m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/keras/utils/tf_utils.py?line=558'>559</a>\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39misinstance\u001b[39m(t, (np\u001b[39m.\u001b[39mndarray, np\u001b[39m.\u001b[39mgeneric)):\n",
"File \u001b[0;32m/tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/framework/ops.py:1223\u001b[0m, in \u001b[0;36m_EagerTensorBase.numpy\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/framework/ops.py?line=1199'>1200</a>\u001b[0m \u001b[39m\"\"\"Copy of the contents of this Tensor into a NumPy array or scalar.\u001b[39;00m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/framework/ops.py?line=1200'>1201</a>\u001b[0m \n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/framework/ops.py?line=1201'>1202</a>\u001b[0m \u001b[39mUnlike NumPy arrays, Tensors are immutable, so this method has to copy\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/framework/ops.py?line=1219'>1220</a>\u001b[0m \u001b[39m NumPy dtype.\u001b[39;00m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/framework/ops.py?line=1220'>1221</a>\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/framework/ops.py?line=1221'>1222</a>\u001b[0m \u001b[39m# TODO(slebedev): Consider avoiding a copy for non-CPU or remote tensors.\u001b[39;00m\n\u001b[0;32m-> <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/framework/ops.py?line=1222'>1223</a>\u001b[0m maybe_arr \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_numpy() \u001b[39m# pylint: disable=protected-access\u001b[39;00m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/framework/ops.py?line=1223'>1224</a>\u001b[0m \u001b[39mreturn\u001b[39;00m maybe_arr\u001b[39m.\u001b[39mcopy() \u001b[39mif\u001b[39;00m \u001b[39misinstance\u001b[39m(maybe_arr, np\u001b[39m.\u001b[39mndarray) \u001b[39melse\u001b[39;00m maybe_arr\n",
"File \u001b[0;32m/tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/framework/ops.py:1189\u001b[0m, in \u001b[0;36m_EagerTensorBase._numpy\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/framework/ops.py?line=1186'>1187</a>\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39m_numpy\u001b[39m(\u001b[39mself\u001b[39m):\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/framework/ops.py?line=1187'>1188</a>\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m-> <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/framework/ops.py?line=1188'>1189</a>\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_numpy_internal()\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/framework/ops.py?line=1189'>1190</a>\u001b[0m \u001b[39mexcept\u001b[39;00m core\u001b[39m.\u001b[39m_NotOkStatusException \u001b[39mas\u001b[39;00m e: \u001b[39m# pylint: disable=protected-access\u001b[39;00m\n\u001b[1;32m <a href='file:///tmp/deepl/.env/lib/python3.8/site-packages/tensorflow/python/framework/ops.py?line=1190'>1191</a>\u001b[0m \u001b[39mraise\u001b[39;00m core\u001b[39m.\u001b[39m_status_to_exception(e) \u001b[39mfrom\u001b[39;00m \u001b[39mNone\u001b[39m\n",
"\u001b[0;31mKeyboardInterrupt\u001b[0m: "
]
}
],
"source": [
"batch_size=16\n",
"model = create_model_localisation()\n",
"opt = Adam(learning_rate=3e-4) \n",
"\n",
"loss = ['mean_squared_error', \"mean_squared_error\", 'mean_squared_error']\n",
"metrics =[ ['accuracy'], [iou()], ['accuracy']]\n",
"loss_weights = [1, 1, 1]\n",
"\n",
"model.compile(loss=loss,\n",
" optimizer=opt,\n",
" metrics=metrics,\n",
" loss_weights=loss_weights\n",
" )\n",
"history = model.fit(x_train, [y_train[:,0], y_train[:,1:5], y_train[:,5:]],\n",
" epochs=50,\n",
" batch_size=batch_size, \n",
" validation_data=(x_val, [y_val[:,0], y_val[:,1:5], y_val[:,5:]]))\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "gKlN9-clJMrI"
},
"outputs": [],
"source": [
"# Analyse des résultats : courbes d'évolution de la fonction de perte, et de l'IoU des boîtes englobantes ainsi que de la précision des classes prédites\n",
"plot_training_analysis(history, metric='loss')\n",
"plot_training_analysis(history, metric='coord_IoU')\n",
"plot_training_analysis(history, metric='classes_accuracy')\n",
"\n",
"# Prédiction des données de test\n",
"y_pred_presence, y_pred_coords, y_pred_classes = model.predict(x_test)\n",
"y_pred = np.zeros(y_test.shape)\n",
"for i in range(y_pred.shape[0]):\n",
" y_pred[i, 0] = y_pred_presence[i]\n",
" y_pred[i, 1:5] = y_pred_coords[i]\n",
" y_pred[i, 5:] = y_pred_classes[i]\n",
"\n",
"# Affichage des résultats sur plusieurs images\n",
"print_data_localisation(x_test, y_test, y_pred = y_pred, id=1, image_size=IMAGE_SIZE)\n",
"print_data_localisation(x_test, y_test, y_pred = y_pred, id=2, image_size=IMAGE_SIZE)\n",
"print_data_localisation(x_test, y_test, y_pred = y_pred, id=3, image_size=IMAGE_SIZE)\n",
"print_data_localisation(x_test, y_test, y_pred = y_pred, id=4, image_size=IMAGE_SIZE)\n",
"print_data_localisation(x_test, y_test, y_pred = y_pred, id=5, image_size=IMAGE_SIZE)\n",
"print_data_localisation(x_test, y_test, y_pred = y_pred, id=6, image_size=IMAGE_SIZE)\n",
"print_data_localisation(x_test, y_test, y_pred = y_pred, id=7, image_size=IMAGE_SIZE)\n",
"print_data_localisation(x_test, y_test, y_pred = y_pred, id=8, image_size=IMAGE_SIZE)\n",
"\n",
"\n",
"class_res, accuracy = global_accuracy(y_test, y_pred, iou_thres=0.4)\n",
"\n",
"print(f\"La précision globale est de {100 * accuracy:.1f}%\")\n",
"\n",
"print()\n",
"print(\"------------------------------------------\")\n",
"print(\"| Classe | Précision | Rappel | F1-score |\")\n",
"print(\"------------------------------------------\")\n",
"for i in range(num_classes):\n",
" print(f\"| {class_labels[i]:7s}| {class_res[i]['Precision']:.2f} | {class_res[i]['Rappel']:.2f} | {class_res[i]['F-score']:.2f} |\")\n",
" print(\"------------------------------------------\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "stQpmnmAt_bf"
},
"source": [
"Compte-tenu de la taille réduite de la base de données, les résultats ne sont pas mal du tout ! On observe quelques confusions entre certaines classes mais les prédictions sont souvent intéressantes.\n",
"\n",
"Il devrait cependant subsister un fort surapprentissage à ce stade. Comme nous l'avons vu dans de précédents TPs, vous avez plusieurs possibilités qui s'offrent à vous pour le corriger : \n",
"\n",
"* Augmentation de la base de données. Vous pouvez pour cela vous appuyer sur l'exemple fourni en TP précédent, avec une classe *Sequence* et l'utilisation de la librairie *Albumentation*. Je vous fournis une Sequence qui fonctionne ci-dessous.\n",
"* Utilisation de *transfer learning* : partant d'un réseau entraîné sur ImageNet (qui contient de nombreuses classes d'animaux), vous bénéficieriez de filtres très généraux qui aiderait à limiter le surapprentissage. \n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "3Jp6jwZidJgx"
},
"source": [
"# Code fourni pour vous aider à mettre en place l'augmentation de données"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "jKbK2AEkUF3M"
},
"source": [
"Il y a des problèmes avec les versions d'openCV et d'Albumentation, voici comment les résoudre :"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "eTq-d6uadJgx"
},
"outputs": [],
"source": [
"!pip uninstall opencv-python-headless==4.5.5.62\n",
"!pip install opencv-python-headless==4.1.2.30\n",
"!pip install -q -U albumentations\n",
"!echo \"$(pip freeze | grep albumentations) is successfully installed\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "B5WuA43ZULxP"
},
"source": [
"Définition des augmentations (uniquement colorimétriques ici)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "WS5wxAXvdJgx"
},
"outputs": [],
"source": [
"from albumentations import (Compose, RandomBrightness, RandomContrast, RandomGamma, ShiftScaleRotate, RandomSizedBBoxSafeCrop)\n",
"import albumentations as A\n",
"\n",
"AUGMENTATIONS_TRAIN = Compose([\n",
" RandomContrast(limit=0.2, p=0.5),\n",
" RandomGamma(gamma_limit=(80, 120), p=0.5),\n",
" RandomBrightness(limit=0.2, p=0.5)\n",
"], bbox_params=A.BboxParams(format='yolo', label_fields=['class_labels']))"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "sND_uaWPURfE"
},
"source": [
"Une sequence qui permet d'implanter l'augmentation de données :"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "x9GXnEyYdJgy"
},
"outputs": [],
"source": [
"from tensorflow.keras.utils import Sequence\n",
"\n",
"class MangeoireSequence(Sequence):\n",
" # Initialisation de la séquence avec différents paramètres\n",
" def __init__(self, x_set, y_set, batch_size,augmentations):\n",
" self.x, self.y = x_set, y_set\n",
" self.classes = ['MESCHA', 'VEREUR', 'ECUROU', 'PIEBAV', 'SITTOR', 'PINARB', 'MESNOI', 'MESNON', 'MESBLE', 'ROUGOR', 'ACCMOU']\n",
" self.batch_size = batch_size\n",
" self.augment = augmentations\n",
" self.indices1 = np.arange(x_set.shape[0]) \n",
" np.random.shuffle(self.indices1) # Les indices permettent d'accéder\n",
" # aux données et sont randomisés à chaque epoch pour varier la composition\n",
" # des batches au cours de l'entraînement\n",
"\n",
" # Fonction calculant le nombre de pas de descente du gradient par epoch\n",
" def __len__(self):\n",
" return int(np.ceil(len(self.x) / float(self.batch_size)))\n",
"\n",
" # Il y a des problèmes d'arrondi dans les conversions de boîtes englobantes \n",
" # internes à la librairie Albumentations\n",
" # Pour les contourner, si les boîtes sont trop proches des bords, on les érode un peu\n",
" def erode_bounding_box(self, box):\n",
" epsilon = 0.01\n",
" \n",
" xmin = max(box[0] - box[2]/2, epsilon)\n",
" ymin = max(box[1] - box[3]/2, epsilon)\n",
" xmax = min(box[0] + box[2]/2, 1-epsilon)\n",
" ymax = min(box[1] + box[3]/2, 1-epsilon)\n",
" \n",
" cx = xmin + (xmax - xmin)/2\n",
" cy = ymin + (ymax - ymin)/2\n",
" width = xmax - xmin\n",
" height = ymax - ymin\n",
" \n",
" return np.array([cx, cy, width, height])\n",
" \n",
" # Application de l'augmentation de données à chaque image du batch et aux\n",
" # boîtes englobantes associées\n",
" def apply_augmentation(self, bx, by):\n",
"\n",
" batch_x = np.zeros((bx.shape[0], IMAGE_SIZE, IMAGE_SIZE, 3))\n",
" batch_y = by\n",
" \n",
" # Pour chaque image du batch\n",
" for i in range(len(bx)):\n",
" bboxes = []\n",
" box = by[i,1:5]\n",
" # Dénormalisation des coordonnées de boites englobantes\n",
" box[0] = (box[0]*y_std[1] + y_mean[1])\n",
" box[1] = (box[1]*y_std[2] + y_mean[2])\n",
" box[2] = (box[2]*y_std[3] + y_mean[3])\n",
" box[3] = (box[3]*y_std[4] + y_mean[4])\n",
" box = self.erode_bounding_box(box)\n",
" bboxes.append(box)\n",
" \n",
" class_labels = []\n",
" class_id = np.argmax(by[i, 5:])\n",
" class_labels.append(self.classes[class_id])\n",
"\n",
" img = bx[i]\n",
"\n",
" # Application de l'augmentation à l'image et aux masques\n",
" transformed = self.augment(image=img.astype('float32'), bboxes=bboxes, class_labels=class_labels)\n",
" batch_x[i] = transformed['image']\n",
" batch_y_transformed = transformed['bboxes']\n",
" \n",
" # Renormalisation des coordonnées de boîte englobante transformée\n",
" batch_y[i, 1] = (batch_y_transformed[0][0] - y_mean[1])/y_std[1]\n",
" batch_y[i, 2] = (batch_y_transformed[0][1] - y_mean[2])/y_std[2]\n",
" batch_y[i, 3] = (batch_y_transformed[0][2] - y_mean[3])/y_std[3]\n",
" batch_y[i, 4] = (batch_y_transformed[0][3] - y_mean[4])/y_std[4]\n",
"\n",
" return batch_x, batch_y\n",
"\n",
" # Fonction appelée à chaque nouveau batch : sélection et augmentation des données\n",
" def __getitem__(self, idx):\n",
" batch_x = self.x[self.indices1[idx * self.batch_size:(idx + 1) * self.batch_size]]\n",
" batch_y = self.y[self.indices1[idx * self.batch_size:(idx + 1) * self.batch_size]]\n",
" batch_x, batch_y = self.apply_augmentation(batch_x, batch_y)\n",
" \n",
" batch_y = np.array(batch_y)\n",
" return np.array(batch_x), [batch_y[:,0], batch_y[:,1:5], batch_y[:,5:]]\n",
"\n",
" # Fonction appelée à la fin d'un epoch ; on randomise les indices d'accès aux données\n",
" def on_epoch_end(self):\n",
" np.random.shuffle(self.indices1)\n",
" \n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "BUbm6gTMdJgy"
},
"outputs": [],
"source": [
"# Instanciation d'une Sequence\n",
"train_gen = MangeoireSequence(x_train, y_train, 16, augmentations=AUGMENTATIONS_TRAIN)\n",
"\n",
"# Pour tester la séquence, nous sélectionnons les éléments du premier batch et les affichons\n",
"batch_x, batch_y = train_gen.__getitem__(0)\n",
"\n",
"y_batch = np.zeros((batch_y[0].shape[0],1+4+num_classes))\n",
"\n",
"for i in range(batch_y[0].shape[0]):\n",
" y_batch[i, 0] = batch_y[0][i]\n",
" y_batch[i, 1:5] = batch_y[1][i]\n",
" y_batch[i, 5:] = batch_y[2][i]\n",
"\n",
"print_data_localisation(batch_x, y_batch, image_size=IMAGE_SIZE)"
]
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"collapsed_sections": [],
"name": "TP6 - Localisation d'objet - Sujet.ipynb",
"provenance": [],
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3.10.6 64-bit",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.6"
},
"vscode": {
"interpreter": {
"hash": "767d51c1340bd893661ea55ea3124f6de3c7a262a8b4abca0554b478b1e2ff90"
}
}
},
"nbformat": 4,
"nbformat_minor": 0
}