TP-reseaux-profond/TP5.ipynb

1693 lines
1.1 MiB
Plaintext
Raw Permalink Normal View History

2023-06-22 18:35:38 +00:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "XMMppWbnG3dN"
},
"source": [
"\n",
"# Estimation de posture dans une image\n",
"\n",
"Pour ce TP ainsi que le suivant, nous allons traiter le problème de la détection du \"squelette\" d'un humain dans une image, tel qu'illustré dans la figure ci-dessous.\n",
"\n",
"![Texte alternatif…](https://drive.google.com/uc?id=1HpyLwzwkFdyQ6APoGZQJL7f837JCHNkh)\n",
"\n",
"Nous allons pour ce faire utiliser le [Leeds Sport Pose Dataset](https://sam.johnson.io/research/lspet.html) qui introduit 10000 images présentant des sportifs dans diverses situations, augmentées d'une annotation manuelle du squelette.\n",
"\n",
"À chaque image est associée une matrice de taille 3x14, correspondant aux coordonnées dans l'image des 14 joints du squelette de la personne décrite dans l'image. La 3e dimension désigne la visibilité du joint (1 s'il est visible, 0 s'il est occulté)\n",
"\n",
"Ces joints sont, dans l'ordre :\n",
"* Cheville droite\n",
"* Genou droit\n",
"* Hanche droite\n",
"* Hanche gauche\n",
"* Genou gauche\n",
"* Cheville gauche\n",
"* Poignet droit\n",
"* Coude droit\n",
"* Épaule droite\n",
"* Épaule gauche\n",
"* Coude gauche\n",
"* Poignet gauche\n",
"* Cou\n",
"* Sommet du crâne\n",
"\n",
"Pour un rappel des notions vues en cours sur ce sujet, vous pouvez regarder la vidéo ci-dessous :\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"id": "COfRON-Mp1Iu"
},
"outputs": [
{
"data": {
"text/html": [
"\n",
" <iframe\n",
" width=\"640\"\n",
" height=\"360\"\n",
" src=\"https://video.polymny.studio/?v=84ace9c1-f460-4375-9b33-917c3ff82c83/\"\n",
" frameborder=\"0\"\n",
" allowfullscreen\n",
" \n",
" ></iframe>\n",
" "
],
"text/plain": [
"<IPython.lib.display.IFrame at 0x7f4a74088460>"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from IPython.display import IFrame\n",
"IFrame(\"https://video.polymny.studio/?v=84ace9c1-f460-4375-9b33-917c3ff82c83/\", width=640, height=360)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "z3mdNJJXc6Wy"
},
"source": [
"Commencez par télécharger la base de données sur Github\n",
"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"id": "3IVjmLKWRDag"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"fatal: le chemin de destination 'lsp' existe déjà et n'est pas un répertoire vide.\n"
]
}
],
"source": [
"!git clone https://github.com/axelcarlier/lsp.git"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"id": "quOHEF__pf36"
},
"outputs": [
{
"data": {
"text/plain": [
"((10, 64, 64, 3), (10, 3, 14))"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import numpy as np\n",
"import PIL\n",
"from PIL import Image\n",
"import os, sys\n",
"from scipy.io import loadmat\n",
"\n",
"# Cette fonction permettra plus tard de charger plus ou moins d'images (en modifiant le paramètre num_images)\n",
"# et de modifier la dimension d'entrée\n",
"def load_data(image_size=128, num_images=1000):\n",
"\n",
" path = \"./lsp/images/\"\n",
" dirs = sorted(os.listdir(path))\n",
"\n",
" x = np.zeros((min(num_images,len(dirs)),image_size,image_size,3))\n",
" y = np.zeros((min(num_images,len(dirs)), 3, 14))\n",
" \n",
" #Chargement des joints \n",
" mat_contents = loadmat('./lsp/joints.mat')\n",
" joints = mat_contents['joints']\n",
"\n",
" # Chargement des images, qui sont rangées dans lsp/images\n",
" for i in range(min(num_images,len(dirs))):\n",
" item = dirs[i]\n",
" if os.path.isfile(path+item):\n",
" img = Image.open(path+item)\n",
" # Redimensionnement et sauvegarde des joints\n",
" y[i, 0] = joints[:,0,i]*image_size/img.size[0]\n",
" y[i, 1] = joints[:,1,i]*image_size/img.size[1]\n",
" y[i, 2] = joints[:,2,i]\n",
" # Redimensionnement et sauvegarde des images \n",
" img = img.resize((image_size,image_size))\n",
" x[i] = np.asarray(img)\n",
"\n",
"\n",
" return x, y\n",
"\n",
"# Chargement de seulement 10 images, de taille 64x64\n",
"x, y = load_data(image_size=64, num_images=10) \n",
"x.shape, y.shape"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"id": "zRc0B4oxe6h_"
},
"outputs": [],
"source": [
"labels= {0: 'Cheville droite',\n",
" 1: 'Genou droit',\n",
" 2: 'Hanche droite',\n",
" 3: 'Hanche gauche',\n",
" 4: 'Genou gauche',\n",
" 5: 'Cheville gauche',\n",
" 6: 'Poignet droit',\n",
" 7: 'Coude droit',\n",
" 8: 'Épaule droite',\n",
" 9: 'Épaule gauche',\n",
" 10: 'Coude gauche',\n",
" 11: 'Poignet gauche',\n",
" 12: 'Cou',\n",
" 13: 'Sommet du crâne'}"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "meezS1y4G8QO"
},
"source": [
"La fonction suivante vous permet de visualiser les données. Vous vous rendrez compte que certaines données sont manquantes ! En effet quand des joints sont occultés dans les images, des valeurs de position aberrantes (négatives) sont indiquées. Dans ce cas, nous n'afficherons pas les articulations."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"id": "JvcqdQIZdCYk"
},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 360x360 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"# Fonction d'affichage d'une image et de son label associé\n",
"def print_data(x,y,i):\n",
" \n",
" if y.shape[1] < 3:\n",
" y_new = np.ones((y.shape[0], 3, y.shape[2]))\n",
" y_new[:,0:2,:] = y\n",
" y = y_new\n",
" \n",
" plt.figure(figsize=(5, 5))\n",
" plt.imshow(x[i]/255)\n",
" for j in range(0,14):\n",
" if y[i, 2, j] == 1:\n",
" plt.scatter(y[i,0,j],y[i,1,j],label=labels.get(j))\n",
"\n",
" # Jambe droite \n",
" if (y[i, 2, 0] + y[i, 2, 1] == 2):\n",
" plt.plot(y[i,0,0:2],y[i,1,0:2],'b')\n",
" # Cuisse droite \n",
" if (y[i, 2, 1] + y[i, 2, 2] == 2):\n",
" plt.plot(y[i,0,1:3],y[i,1,1:3],'b')\n",
" # Bassin \n",
" if (y[i, 2, 2] + y[i, 2, 3] == 2):\n",
" plt.plot(y[i,0,2:4],y[i,1,2:4],'b')\n",
" # Cuisse gauche \n",
" if (y[i, 2, 3] + y[i, 2, 4] == 2):\n",
" plt.plot(y[i,0,3:5],y[i,1,3:5],'b')\n",
" # Jambe gauche \n",
" if (y[i, 2, 4] + y[i, 2, 5] == 2):\n",
" plt.plot(y[i,0,4:6],y[i,1,4:6],'b')\n",
" # Avant-bras droit \n",
" if (y[i, 2, 6] + y[i, 2, 7] == 2):\n",
" plt.plot(y[i,0,6:8],y[i,1,6:8],'b')\n",
" # Bras droit \n",
" if (y[i, 2, 7] + y[i, 2, 8] == 2):\n",
" plt.plot(y[i,0,7:9],y[i,1,7:9],'b')\n",
" # Bras gauche \n",
" if (y[i, 2, 9] + y[i, 2, 10] == 2):\n",
" plt.plot(y[i,0,9:11],y[i,1,9:11],'b')\n",
" # Avant-bras gauche \n",
" if (y[i, 2, 10] + y[i, 2, 11] == 2):\n",
" plt.plot(y[i,0,10:12],y[i,1,10:12],'b') \n",
" # Buste droit\n",
" x1=[y[i,0,2],y[i,0,12]]\n",
" y1=[y[i,1,2],y[i,1,12]]\n",
" if (y[i, 2, 2] + y[i, 2, 12] == 2):\n",
" plt.plot(x1, y1,'b')\n",
" # Buste gauche\n",
" x1=[y[i,0,3],y[i,0,12]]\n",
" y1=[y[i,1,3],y[i,1,12]]\n",
" if (y[i, 2, 3] + y[i, 2, 12] == 2):\n",
" plt.plot(x1, y1,'b')\n",
" # Omoplate droite\n",
" x1=[y[i,0,8],y[i,0,12]]\n",
" y1=[y[i,1,8],y[i,1,12]]\n",
" if (y[i, 2, 8] + y[i, 2, 12] == 2):\n",
" plt.plot(x1, y1,'b')\n",
" # Omoplate gauche\n",
" x1=[y[i,0,9],y[i,0,12]]\n",
" y1=[y[i,1,9],y[i,1,12]]\n",
" if (y[i, 2, 9] + y[i, 2, 12] == 2):\n",
" plt.plot(x1, y1,'b')\n",
" # Tete \n",
" if (y[i, 2, 12] + y[i, 2, 13] == 2):\n",
" plt.plot(y[i,0,12:14],y[i,1,12:14],'b')\n",
"\n",
" plt.axis([0, x.shape[1], x.shape[2], 0])\n",
" plt.show()\n",
" #plt.legend()\n",
"\n",
"# Affichage aléatoire d'une image\n",
"print_data(x,y,np.random.randint(x.shape[0]-1))\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "WueEErACp1Iy"
},
"source": [
"Pour comparer nos résultats avec ceux du TP 5, nous redéfinissons le **PCK0.5** (*Percentage of Correct Keypoints*). Pour rappel, *0.5* correspond à un seuil en-deça duquel on considère qu'un joint est correctement estimé. Cette question du seuil est particulièrement sensible car il faut utiliser une valeur qui soit valable pour n'importe quelle image. La personne considérée peut apparaître plus ou moins largement sur l'image, de face ou de profil, ce qui fait qu'une erreur de prédiction sur un joint peut avoir une importance très grande ou très faible selon les cas.\n",
"\n",
"Pour résoudre cette ambiguïté, on considère dans la métrique du **PCK0.5** que la référence est la taille de la tête, définie par la distance entre le joint du cou et le joint de la tête sur la vérité terrain. Un joint prédit par le réseau sera considéré correct s'il est situé à une distance inférieure à la moitié (*0.5*) de la taille de la tête par rapport au joint réel. ([Andriluka et al.] 2D Human Pose Estimation: New Benchmark and State of the Art Analysis)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"id": "NZjjvx9cp1Iz"
},
"outputs": [],
"source": [
"import numpy.matlib \n",
"\n",
"# Calcul du \"Percentage of Correct Keypoint\" avec seuil alpha :\n",
"# On compte corrects les joints pour lesquels la distance entre valeurs réelle et prédite \n",
"# est inférieure à alpha fois la dimension de la tête (c'est un peu arbitraire...)\n",
"# On ne comptera pas les joints invisibles.\n",
"# y_true est de dimension Nx3x14 et y_pred Nx2x14 (le réseau ne prédit pas la visibilité)\n",
"def compute_PCK_alpha(y_true, y_pred, alpha=0.5):\n",
" # Calcul des seuils ; la taille de la tête est la distance entre joints 12 et 13\n",
" head_sizes = np.sqrt(np.square(y_true[:,0,13]-y_true[:,0,12])+np.square(y_true[:,1,13]-y_true[:,1,12]))\n",
" thresholds = alpha*head_sizes\n",
" thresholds = np.matlib.repmat(np.expand_dims(thresholds, 1), 1, 14)\n",
"\n",
" # Calcul des distances inter-joints\n",
" joints_distances = np.sqrt(np.square(y_true[:,0,:]-y_pred[:,0,:]) + np.square(y_true[:,1,:]-y_pred[:,1,:]))\n",
"\n",
" # Visibilité des joints de la vérité terrain\n",
" visibility = y_true[:,2,:]\n",
" \n",
" total_joints = np.count_nonzero(visibility==1)\n",
" correctly_predicted_joints = np.count_nonzero(np.logical_and(joints_distances<thresholds, visibility == 1))\n",
" \n",
" return correctly_predicted_joints/total_joints"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "JVmEnDdyB-_E"
},
"source": [
"## Petit retour sur le TP précédent : \n",
"\n",
"Si vous n'êtes pas allés jusqu'au bout du TP précédent, sachez que même avec un réseau bien construit, de capacité suffisante, en utilisant les 10000 images de la base d'apprentissage, de la régularisation et de l'augmentation de données (non demandé dans le TP), vous ne seriez pas arrivé à limiter le sur-apprentissage suffisamment pour obtenir des résultats satisfaisants sur l'ensemble de test. On plafonne à un pourcentage de joints correctement prédits (PCK@0.5) aux alentours de 20\\%.\n",
"\n",
"Cela est principalement dû à la formulation du problème, plus difficile à résoudre, et aux architectures mises en place. En effet, les couches de sous-échantillonnage (*pooling*) successives entraînent une perte de précision irrémédiable qui ne peut pas être compensée par les couches denses."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "u5rCr8gKCEnp"
},
"source": [
"# Prédiction de cartes de chaleur"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ZrL2qpnoD0Lj"
},
"source": [
"Dans ce TP, nous allons utiliser une autre formulation du problème, présentée pendant le cours. Plutôt que de prédire directement la position pixellique des joints, nous allons prédire des cartes de probabilité de la position des joints, comme illustré ci-dessous. Pour ce faire, il nous faudra tester des architectures de réseau de neurones différentes, s'inspirant de celles utilisées en segmentation d'image.\n",
"\n",
"![Texte alternatif…](https://drive.google.com/uc?id=1B8BCwQ0Szg_T_H05mnfpXFemUT5xhfxX)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "4Pqj24fMz78h"
},
"source": [
"## Fonctions utiles"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "cyh-VbYvEppj"
},
"source": [
"La fonction suivante permet de créer une carte de chaleur de la dimension voulue, avec une gaussienne centrée en un point donné."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"id": "0u_t30vIEv1P"
},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"from scipy.ndimage import gaussian_filter\n",
"\n",
"def heat_point(ind_x, ind_y, heatmap_size):\n",
" heat_point=np.zeros((heatmap_size,heatmap_size))\n",
" heat_point[ind_x][ind_y] = 1\n",
"\n",
" return gaussian_filter(heat_point, round(heatmap_size/20))\n",
"\n",
"h_m = heat_point(14, 44, 64)\n",
"plt.imshow(h_m)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "a1vQKbeBGI9g"
},
"source": [
"On peut ensuite retrouver la position du point le plus \"chaud\", en utilisant la commande suivante : \n",
"```python\n",
"np.unravel_index(np.argmax(h_m), h_m.shape) \n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "kiLiDhPjGieb"
},
"source": [
"On peut donc définir les 2 fonctions suivantes permettant de générer les cartes de chaleur à partir des coordonnées de joints, et vice-versa."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"id": "fD3PoNusGhC2"
},
"outputs": [],
"source": [
"def coord2heatmap(y, heatmap_size):\n",
" heatmap = np.zeros((y.shape[0], 14, heatmap_size, heatmap_size))\n",
" for img in range(y.shape[0]):\n",
" for j in range(14):\n",
" ind_x = int(y[img][1][j])\n",
" ind_y = int(y[img][0][j])\n",
" #print(ind_x, ind_y)\n",
" if ind_x >= 0 and ind_y >= 0 and ind_x < heatmap_size and ind_y < heatmap_size:\n",
" heatmap[img][j] = heat_point(ind_x, ind_y, heatmap_size)\n",
" heatmap = np.transpose(heatmap, (0, 2, 3, 1))\n",
" heatmap = heatmap / np.max(heatmap)\n",
" return heatmap\n",
"\n",
"def heatmap2coord(heatmap):\n",
" y = np.ones((heatmap.shape[0], 3, 14))\n",
"\n",
" heatmap = np.transpose(heatmap, (0, 3, 1, 2))\n",
" for img in range(y.shape[0]):\n",
" for j in range(14): \n",
" max_heat = np.unravel_index(np.argmax(heatmap[img][j]),heatmap[img][j].shape) \n",
" y[img][0][j] = max_heat[1]\n",
" y[img][1][j] = max_heat[0]\n",
" if max_heat[0] == 0 and max_heat[1] == 0:\n",
" y[img][2][j] = 0 # Le joint est invisible\n",
" return y"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "TG0BlJ3LH2kP"
},
"source": [
"La fonction ci-dessous nous permettra d'afficher les cartes de chaleur associées à une image. On affichera d'abord la somme de toutes les cartes de chaleur, afin d'avoir une vue globale de la position de la personne, puis les cartes associées à 3 joints : tête, coude droit, et genou gauche (choix arbitraire, que vous pouvez aisément modifier si vous le voulez). "
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"id": "dCfWl8ncH5JQ"
},
"outputs": [],
"source": [
"def print_heatmap(x, y, rows=3):\n",
" hm = np.transpose(y, (0,3,1,2))\n",
"\n",
" for i in range(rows):\n",
" j=np.random.randint(1,x.shape[0])\n",
" plt.figure(figsize=(12, 12))\n",
" # Affichage de l'image\n",
" plt.subplot(rows,5,5*i+1)\n",
" plt.imshow(x[j])\n",
" plt.title('Image originale')\n",
" # Affichage simultané de tous les joints\n",
" plt.subplot(rows,5,5*i+2)\n",
" joints=np.zeros((y.shape[1], y.shape[2]))\n",
" for k in range(14):\n",
" joints+= hm[j][k]\n",
" plt.imshow(joints)\n",
" plt.title('Tous les joints')\n",
"\n",
" plt.subplot(rows, 5, 5*i+3)\n",
" plt.imshow(hm[j][13])\n",
" plt.title('Tête')\n",
" plt.subplot(rows, 5, 5*i+4)\n",
" plt.imshow(hm[j][7])\n",
" plt.title('Coude droit')\n",
" plt.subplot(rows, 5, 5*i+5)\n",
" plt.imshow(hm[j][4])\n",
" plt.title('Genou gauche')\n",
" plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "a9QKb9YLJRr4"
},
"source": [
"Les lignes suivantes vous permettront de démarrer simplement : "
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"id": "fwcCfcazJQL7"
},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 864x864 with 5 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAr8AAACiCAYAAABIzqWCAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAC3YElEQVR4nOz9edwk2X7WB35/55yIzHz32rfurq7uu/ZdtNwrXUkIgQUW+4BBZmQWY4zNB9v44zGy8TJgyxi82wiP7cHyDDsIsA0YGMY2ywghJLTc/V71vb1Wd+37u+USEeec3/xxTkTm+9ZbXdVbVXV3PNXZmW9mZGRk5smIJ57z/J6fqCo9evTo0aNHjx49enwQYB71BvTo0aNHjx49evTo8bDQk98ePXr06NGjR48eHxj05LdHjx49evTo0aPHBwY9+e3Ro0ePHj169OjxgUFPfnv06NGjR48ePXp8YNCT3x49evTo0aNHjx4fGPTk9yFDRHZF5Jl3etn7rOdHROQvvN319Lg/RORfEJGfeofX+dtF5P98wGX/vyLyu97J1+/xcCEiv0ZEbojIb3rU29Lj8cM7uY95O8cGEXkqH6PsO7EtPd7/EJE/IyJ/9FFvBzzG5FdEzovIr3zU2/FOQ1VXVPWVd3rZHnPkHXJ7iSIyXfj7tz/q7XuzUNW/qKo/8IDL/hpV/bMPsqyI/ISI/Etvb+t6vFncZ3z+LuDfBD4O/D4RObPwvP77eowhIr9NRH4hf49X8ono9z7q7Xq3oKqv52NUgH58thCRHxKRnxWRsYhcz7f/VRGRR71tPeZ4bMnv+w0i4h71NnxQkHfIK6q6ArwO/IaF+/7io96+Hh9s3Gd8/llV/QFVvamqv1pVLz3q7e1xf4jIHwB+FPhPgBPAU8D/APzGR7hZbwv9MevNQ0R+GPgTwH8JnCSNhd8H/BKgfISb1mMf3hPkN0/z/GMR+eMisikir4jI9+T7L+Szq9+1sPyvE5Evish2fvxH9q3vnxeR10Tkloj84UWVWUSMiPy7IvJyfvyvisjhN9i2f1lEXhKR2yLyN0Xk9MJjKiL/moi8CLy4cN+H8u0jIvK38nb+vIj80cXprH3L/hkR+e9F5P8jIjv5bPLZhWX/RH6v2yLyeRH5pW+wzd8lIj+dP8svi8gvf9Dv4r0MERmIyI+KyOV8+VERGeTH7ppK3Pf5/1oR+cX82V8SkX/rAV/zYyLyd/P4+KaI/NaFxx5onfu3LY/9nxeRrXz9PQuPdepL+zwR+a9E5I6IvCoivyY/9seAXwr8d1mp+u8k4Y/n39O2iHxVRD75oJ9vj7ePe/02D/q+8v33HF89Hg5EZB34I8C/pqp/TVXHqtqo6t9S1X87L/N29j1H8rFlW0R+Dnh237IPPAZE5JyI/MO8z/m7wNGFx57Or/t7ROR14B9IOh7+IUnHy+si8ufy+11c3t1rfH6QsDAO/lVV/V9UdUcTvqiqv11Vq7zcIO+TXxeRayLyJ0VklB/75SJyUUR+OH/eV0Tkdy++Rv4ObuTv5A+JiMmP7bGwLH4/99jeb5fEk3ZE5H8Wkb8i2ZIgIodE5G/n17mTbz+x8Nw9M/MHvPb3LuzHLojIv7Dw0ofk3jzm4e3PVPWxvADngV+Zb/8LgAd+N2CBP0pSTP57YAD8ALADrOTlfznwKRK5/zRwDfhN+bHngF3ge0lnYv8V0Cy81r8B/BPgibzu/xH48Xts4/cDN4Fvz8v+P4CfXHhcgb8LHAZGC/d9KN/+y/mylLfrAvBT+57fLvtngFvAdwIO+IvAX15Y9ncAR/JjPwxcBYb5sR8B/kK+fSav59fmz+efzn8fe9Tf+UMYR38kf7fHgWPATwP/8cIY+6l9z138/K8AvzTfPgR8+z1er1sPsJy/09+dv5dvy+PlubexzsPAHeB35nX+c/nvI/nxnwD+pYXnNcC/TPrd/CvAZUD2L5v//lXA54ENQEhT76ce9Xf4fr7sG59v+Ns84Pt6w/HVXx7ad/irSccn9wbLvJ19z18G/mr+vj8JXHrQfcwB2/EzwH9DOl59H+m42R4bns6v++fyekfAvwi8BDwDrAB/Dfjz+5Z3B43PD9rlQcZBXu6PA38z78tXgb8F/Kf5sV+e1/FHgCLvCybAofz4nwP+t/y8p4EXgN+TH/uR9rs86PvZtw0l8BqJ7xTAbwZq4I/mx48Av4XETVaB/xn4GwvPP0/eb+1/beBsHlf/XF73EeBb82N/hnvwmDc7lt/u5T2h/Ga8qqp/WpO/6K8ATwJ/RFUrVf0/SV/chwBU9SdU9auqGlX1K8CPA78sr+cHgb+lqj+lqjXwH5AGSIvfB/zfVfWipjO1HwF+8B5nT78d+FOq+oW87L8HfLeIPL2wzH+qqrdVdbr4RElFAr8F+A9VdaKqvwjcz6v511X151TVkwbNt7YPqOpfUNVbqupV9b8m7dw+esA6fgfwd1T17+TP5+8Cv0D6kb3f8dtJY+a6qt4A/iMSiXwQNMBzIrKmqndU9QsP8JxfD5zP49ar6heB/xX4Z9/GOn8d8KKq/vm8zh8HvgH8hnss/5qq/k/5d/NngVOkqbh7vcdV4GMkgvy8ql55gG3q8c7gzf427ze+ejwcHAFu5v3yvfCW9j0Lx4n/QJOi/DX2HiceeAyIyFPAdwB/OB83f5JEvPbjR/JrTfN2/zeq+oqq7pKOcT90LzXxA46j7BsHC+rnVES+T0QE+L3Av5l5wQ7JKvNDC+tpSGOlUdW/QxLrPprHwg8B/54mVfk88F/z4MewRXwXiWD+t/l1/hrwc+2DmUv8r5mb7AB/jDmHuh9+G/D3VPXH87pvqeqXFh6/F495qPuz9xL5vbZwewqgqvvvWwEQkc+JyP8vS/ZbJELbTu+cJp1dkNcxIZ2JtDgL/PU8YDeB54HAwYThNOnsqV3Xbl7XmYVlLux/UsYx0uC78ADLtri6cHtCfr8AIvJvicjzkqbCN4F1Fqa0FnAW+Gfb95eX/V4SKXq/Y8/3lW+fvsey+/FbSCTktTxt+N0P8JyzwOf2fda/neQFe6vr3P8eyH+fOWBZWBgzeazDwrhZhKr+A+C/I82oXBeRHxORtQfYph7vDN7sb/N+46vHw8Et4Oh9COFb3fccdJxYXM+bGQOngTuqOr7HulosvtZB2+249wn0Bxl3jQNV/R5V3ciPGdL3uQR8fuH7+t/z/d169p1Itcf6oyQldf/3ca99/xvhNHBJVReFv+57F5ElEfkfs7ViG/hJYEMeLNnjSeDlN3j8Xjzmoe7P3kvk983gL5GmFZ5U1XXgT5KmcSFNNS96V0akM/cWF4Bfo6obC5ehHlx4cpn0hbXrWs7rWlxW9z8p4wZpeuOJhfuefJA3tx+S/L1/EPitpOmRDWCL+XtexAXStNXi+1tW1f/srbz2ewx7vi9SUcrlfHtM2ikBICJ7fnCq+vOq+htJ05Z/gzQNeT9cAP7hvs96RVX/lbexzv3voX0fb6Uw6q6xqar/rap+hmTD+Qjwb7+F9fZ4a7jfb3P/9/WG46vHQ8PPABXwm95gmbe672mPE4vHhqcWbr+ZMXCF5Ldcvse6WiyOs4O227NXjDroeR9EtOPgjYocb5KEuk8sfF/rmopf74ebJFV4//fR7vv3jCPemDReAc5kJbrF4hj7YdLM8edUdY1kkYE5p3ij17rAPl/6A+Kh7s/er+R3FbitqjMR+U6SDN/ifwF+g6SioZJka1gcAH8S+GMichZARI6JyL0G848Dv1tEvlVS8cJ/Avxsno54Q+Rp6L8G/Eg+y/oY8M+/qXc5xypph3QDcCLyHwD3Uuz+Aun9/yoRsSIylGSyf+Iey7+f8OPAH8rf6VGS5aU16X8Z+ET+LoekcQGAiJSSsnbXVbUBtoH4AK/3t4GPiMjvFJEiX75DRD7+Ntb5d/I6f5ukQpP/K4mo/u0H/AwWcY3k5QMgb9vnRKQg7dxmD7hNPd4Z3O+3uef74g3G10Pf8g8wVHWLtC/570XkN+X9eSEpr/m/yIu9pX3PAceJ54DFHO8HHgOq+hrJRvMf5f3P93Jvu1SLHwf+TUmFc
"text/plain": [
"<Figure size 864x864 with 5 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 864x864 with 5 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"from sklearn.model_selection import train_test_split\n",
"\n",
"# Chargement des données : on choisit une dimension d'image et de carte de chaleur de 64x64\n",
"image_size = 64\n",
"heatmap_size = 64\n",
"\n",
"# Chargement de seulement 1000 images\n",
"# Chargement des données : 1000 images d'apprentissage, 100 de validation, 100 de test \n",
"x, y = load_data(image_size=image_size, num_images=1000) \n",
"# Normalisation des données\n",
"x = x/255\n",
"x_train, x_gen, y_train, y_gen = train_test_split(x, y, test_size=1/10, random_state=2)\n",
"x_val, x_test, y_val, y_test = train_test_split(x_gen, y_gen, test_size=1/2, random_state=1)\n",
"\n",
"# Calcul des cartes de chaleur pour chaque ensemble (prend un peu de temps)\n",
"y_hm_train = coord2heatmap(y_train, heatmap_size)\n",
"y_hm_val = coord2heatmap(y_val, heatmap_size)\n",
"y_hm_test = coord2heatmap(y_test, heatmap_size)\n",
"\n",
"# Affichage de quelques exemples\n",
"print_heatmap(x_train, y_hm_train)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "QZVbag1MOphZ"
},
"source": [
"Pour vous aider pour la suite, voici ci-dessous une implémentation du réseau UNet, vu en cours sur la segmentation.\n",
"\n",
"![Texte alternatif…](https://raw.githubusercontent.com/zhixuhao/unet/master/img/u-net-architecture.png)\n",
"\n",
"A vous de l'adapter afin qu'il soit pertinent pour le problème courant (dimensions d'entrée et de sortie, **fonction d'activation de sortie**)\n",
"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"id": "O_qMkG8ROoky"
},
"outputs": [],
"source": [
"import keras\n",
"from keras.layers import *\n",
"from keras import *\n",
"\n",
"def create_unet(image_size=572):\n",
" input_layer=Input((image_size, image_size, 3))\n",
"\n",
" conv1 = Conv2D(32, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(input_layer)\n",
" conv1 = Conv2D(32, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv1)\n",
" pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)\n",
" \n",
" conv2 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool1)\n",
" conv2 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv2)\n",
" pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)\n",
" \n",
" conv3 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool2)\n",
" conv3 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv3)\n",
" pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)\n",
" \n",
" conv4 = Conv2D(216, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool3)\n",
" conv4 = Conv2D(216, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv4)\n",
" drop4 = Dropout(0.5)(conv4)\n",
" pool4 = MaxPooling2D(pool_size=(2, 2))(drop4)\n",
"\n",
" conv5 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool4)\n",
" conv5 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv5)\n",
" drop5 = Dropout(0.5)(conv5)\n",
"\n",
" up6 = Conv2D(256, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(drop5))\n",
" merge6 = concatenate([drop4,up6], axis = 3)\n",
" conv6 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge6)\n",
" conv6 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv6)\n",
"\n",
" up7 = Conv2D(128, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv6))\n",
" merge7 = concatenate([conv3,up7], axis = 3)\n",
" conv7 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge7)\n",
" conv7 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv7)\n",
" \n",
" up8 = Conv2D(64, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv7))\n",
" merge8 = concatenate([conv2,up8], axis = 3)\n",
" conv8 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge8)\n",
" conv8 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv8)\n",
"\n",
" up9 = Conv2D(32, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv8))\n",
" merge9 = concatenate([conv1,up9], axis = 3)\n",
" conv9 = Conv2D(32, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge9)\n",
" conv9 = Conv2D(32, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv9)\n",
" conv10 = Conv2D(len(labels), 1, activation = 'sigmoid')(conv9)\n",
"\n",
" model = Model(input_layer, conv10)\n",
"\n",
" return model"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"id": "vgFsh0DRp1I3"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model: \"model\"\n",
"__________________________________________________________________________________________________\n",
" Layer (type) Output Shape Param # Connected to \n",
"==================================================================================================\n",
" input_1 (InputLayer) [(None, 64, 64, 3)] 0 [] \n",
" \n",
" conv2d (Conv2D) (None, 64, 64, 32) 896 ['input_1[0][0]'] \n",
" \n",
" conv2d_1 (Conv2D) (None, 64, 64, 32) 9248 ['conv2d[0][0]'] \n",
" \n",
" max_pooling2d (MaxPooling2D) (None, 32, 32, 32) 0 ['conv2d_1[0][0]'] \n",
" \n",
" conv2d_2 (Conv2D) (None, 32, 32, 64) 18496 ['max_pooling2d[0][0]'] \n",
" \n",
" conv2d_3 (Conv2D) (None, 32, 32, 64) 36928 ['conv2d_2[0][0]'] \n",
" \n",
" max_pooling2d_1 (MaxPooling2D) (None, 16, 16, 64) 0 ['conv2d_3[0][0]'] \n",
" \n",
" conv2d_4 (Conv2D) (None, 16, 16, 128) 73856 ['max_pooling2d_1[0][0]'] \n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2022-04-12 21:27:08.105989: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA\n",
"To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n",
"2022-04-12 21:27:08.962948: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1525] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 1538 MB memory: -> device: 0, name: Quadro K620, pci bus id: 0000:03:00.0, compute capability: 5.0\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
" \n",
" conv2d_5 (Conv2D) (None, 16, 16, 128) 147584 ['conv2d_4[0][0]'] \n",
" \n",
" max_pooling2d_2 (MaxPooling2D) (None, 8, 8, 128) 0 ['conv2d_5[0][0]'] \n",
" \n",
" conv2d_6 (Conv2D) (None, 8, 8, 216) 249048 ['max_pooling2d_2[0][0]'] \n",
" \n",
" conv2d_7 (Conv2D) (None, 8, 8, 216) 420120 ['conv2d_6[0][0]'] \n",
" \n",
" dropout (Dropout) (None, 8, 8, 216) 0 ['conv2d_7[0][0]'] \n",
" \n",
" max_pooling2d_3 (MaxPooling2D) (None, 4, 4, 216) 0 ['dropout[0][0]'] \n",
" \n",
" conv2d_8 (Conv2D) (None, 4, 4, 512) 995840 ['max_pooling2d_3[0][0]'] \n",
" \n",
" conv2d_9 (Conv2D) (None, 4, 4, 512) 2359808 ['conv2d_8[0][0]'] \n",
" \n",
" dropout_1 (Dropout) (None, 4, 4, 512) 0 ['conv2d_9[0][0]'] \n",
" \n",
" up_sampling2d (UpSampling2D) (None, 8, 8, 512) 0 ['dropout_1[0][0]'] \n",
" \n",
" conv2d_10 (Conv2D) (None, 8, 8, 256) 524544 ['up_sampling2d[0][0]'] \n",
" \n",
" concatenate (Concatenate) (None, 8, 8, 472) 0 ['dropout[0][0]', \n",
" 'conv2d_10[0][0]'] \n",
" \n",
" conv2d_11 (Conv2D) (None, 8, 8, 256) 1087744 ['concatenate[0][0]'] \n",
" \n",
" conv2d_12 (Conv2D) (None, 8, 8, 256) 590080 ['conv2d_11[0][0]'] \n",
" \n",
" up_sampling2d_1 (UpSampling2D) (None, 16, 16, 256) 0 ['conv2d_12[0][0]'] \n",
" \n",
" conv2d_13 (Conv2D) (None, 16, 16, 128) 131200 ['up_sampling2d_1[0][0]'] \n",
" \n",
" concatenate_1 (Concatenate) (None, 16, 16, 256) 0 ['conv2d_5[0][0]', \n",
" 'conv2d_13[0][0]'] \n",
" \n",
" conv2d_14 (Conv2D) (None, 16, 16, 128) 295040 ['concatenate_1[0][0]'] \n",
" \n",
" conv2d_15 (Conv2D) (None, 16, 16, 128) 147584 ['conv2d_14[0][0]'] \n",
" \n",
" up_sampling2d_2 (UpSampling2D) (None, 32, 32, 128) 0 ['conv2d_15[0][0]'] \n",
" \n",
" conv2d_16 (Conv2D) (None, 32, 32, 64) 32832 ['up_sampling2d_2[0][0]'] \n",
" \n",
" concatenate_2 (Concatenate) (None, 32, 32, 128) 0 ['conv2d_3[0][0]', \n",
" 'conv2d_16[0][0]'] \n",
" \n",
" conv2d_17 (Conv2D) (None, 32, 32, 64) 73792 ['concatenate_2[0][0]'] \n",
" \n",
" conv2d_18 (Conv2D) (None, 32, 32, 64) 36928 ['conv2d_17[0][0]'] \n",
" \n",
" up_sampling2d_3 (UpSampling2D) (None, 64, 64, 64) 0 ['conv2d_18[0][0]'] \n",
" \n",
" conv2d_19 (Conv2D) (None, 64, 64, 32) 8224 ['up_sampling2d_3[0][0]'] \n",
" \n",
" concatenate_3 (Concatenate) (None, 64, 64, 64) 0 ['conv2d_1[0][0]', \n",
" 'conv2d_19[0][0]'] \n",
" \n",
" conv2d_20 (Conv2D) (None, 64, 64, 32) 18464 ['concatenate_3[0][0]'] \n",
" \n",
" conv2d_21 (Conv2D) (None, 64, 64, 32) 9248 ['conv2d_20[0][0]'] \n",
" \n",
" conv2d_22 (Conv2D) (None, 64, 64, 14) 462 ['conv2d_21[0][0]'] \n",
" \n",
"==================================================================================================\n",
"Total params: 7,267,966\n",
"Trainable params: 7,267,966\n",
"Non-trainable params: 0\n",
"__________________________________________________________________________________________________\n"
]
}
],
"source": [
"model = create_unet(image_size=64)\n",
"model.summary()"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2022-04-12 21:27:32.068602: I tensorflow/stream_executor/cuda/cuda_dnn.cc:368] Loaded cuDNN version 8100\n",
"2022-04-12 21:27:32.858066: W tensorflow/stream_executor/gpu/asm_compiler.cc:111] *** WARNING *** You are using ptxas 10.1.243, which is older than 11.1. ptxas before 11.1 is known to miscompile XLA code, leading to incorrect results or invalid-address errors.\n",
"\n",
"You may not need to update to CUDA 11.1; cherry-picking the ptxas binary is often sufficient.\n",
"2022-04-12 21:27:35.131334: W tensorflow/core/common_runtime/bfc_allocator.cc:275] Allocator (GPU_0_bfc) ran out of memory trying to allocate 1.21GiB with freed_by_count=0. The caller indicates that this is not a failure, but may mean that there could be performance gains if more memory were available.\n",
"2022-04-12 21:27:40.157301: W tensorflow/core/common_runtime/bfc_allocator.cc:275] Allocator (GPU_0_bfc) ran out of memory trying to allocate 1.21GiB with freed_by_count=0. The caller indicates that this is not a failure, but may mean that there could be performance gains if more memory were available.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"28/29 [===========================>..] - ETA: 0s - loss: 0.7098 - accuracy: 0.0273"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2022-04-12 21:27:54.195414: W tensorflow/core/common_runtime/bfc_allocator.cc:275] Allocator (GPU_0_bfc) ran out of memory trying to allocate 1.09GiB with freed_by_count=0. The caller indicates that this is not a failure, but may mean that there could be performance gains if more memory were available.\n",
"2022-04-12 21:27:56.609297: W tensorflow/core/common_runtime/bfc_allocator.cc:275] Allocator (GPU_0_bfc) ran out of memory trying to allocate 1.09GiB with freed_by_count=0. The caller indicates that this is not a failure, but may mean that there could be performance gains if more memory were available.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"29/29 [==============================] - ETA: 0s - loss: 0.7096 - accuracy: 0.0273"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"2022-04-12 21:27:58.438753: W tensorflow/core/common_runtime/bfc_allocator.cc:275] Allocator (GPU_0_bfc) ran out of memory trying to allocate 1.15GiB with freed_by_count=0. The caller indicates that this is not a failure, but may mean that there could be performance gains if more memory were available.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"29/29 [==============================] - 31s 663ms/step - loss: 0.7096 - accuracy: 0.0273 - val_loss: 0.6456 - val_accuracy: 0.0313\n"
]
}
],
"source": [
"from tensorflow.keras import optimizers\n",
"\n",
"adam = optimizers.Adam(learning_rate=1e-4)\n",
"model.compile(optimizer=adam, loss=\"binary_crossentropy\", metrics=[\"accuracy\"])\n",
"history = model.fit(x_train, y_hm_train, validation_data=(x_val, y_hm_val), epochs=1)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"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 864x864 with 5 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 864x864 with 5 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 864x864 with 5 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.043383751471786976\n"
]
}
],
"source": [
"mae = history.history['accuracy']\n",
"val_mae = history.history['val_accuracy']\n",
"loss = history.history['loss']\n",
"val_loss = history.history['val_loss']\n",
"\n",
"epochs = range(len(loss))\n",
"\n",
"plt.plot(epochs, mae, 'b', linestyle=\"--\",label='Training accuracy')\n",
"plt.plot(epochs, val_mae, 'g', label='Validation accuracy')\n",
"plt.title('Training and validation accuracy')\n",
"plt.legend()\n",
"\n",
"plt.figure()\n",
"\n",
"plt.plot(epochs, loss, 'b', linestyle=\"--\",label='Training loss')\n",
"plt.plot(epochs, val_loss,'g', label='Validation loss')\n",
"plt.title('Training and validation loss')\n",
"plt.legend()\n",
"\n",
"plt.show()\n",
"\n",
"y_pred_hm = model.predict(x_train)\n",
"print_heatmap(x_train, y_pred_hm)\n",
"y_pred_coords = heatmap2coord(y_pred_hm)\n",
"pck = compute_PCK_alpha(y_train, y_pred_coords)\n",
"print(pck)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "LPamKJXZsCff"
},
"source": [
"## Travail à faire \n",
"\n",
"Commencez par adapter le réseau Unet à votre problème, puis à l'entraîner sur le petit ensemble de données x_train. \n",
"\n",
"Plusieurs remarques (**à lire attentivement**) : \n",
"\n",
"\n",
"\n",
"* Vous devriez observer beaucoup moins de sur-apprentissage ! Si vos prédictions sur l'ensemble de validation sont aberrantes, c'est que vous avez un bug !!\n",
"* Se pose la question de la formulation du problème : dans la mesure où \n",
"les cartes de chaleur sont assimilables à des cartes de probabilité (entre 0 et 1), on peut certes choisir de conserver une formulation du problème basée sur la régression, mais l'expérience montre que l'apprentissage se passe mieux si l'on formule le problème comme de la classification binaire.\n",
"* Il y a cependant toujours du sur-apprentissage. Vous pouvez donc augmenter la taille de la base de données à 10000, puis tester différentes possibilités pour diminuer ce sous-apprentissage, notamment l'augmentation de données. Les cellules suivantes vous fournissent des éléments permettant de mettre en place cette augmentation.\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "JzghttyGTPvq"
},
"source": [
"## Code fourni pour l'augmentation de données (à n'envisager que dans un second temps)\n",
"\n",
"Je vous fournis ici quelques éléments qui vous permettront de mettre en place de l'augmentation de données. \n",
"Attention l'augmentation rend l'apprentissage plus difficile et en fait plus lent, et vous devrez peut-être augmenter un peu la capacité de votre UNet et le nombre d'epochs pour éviter le sous-apprentissage."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "n2U4RIeNTmq_"
},
"source": [
"Albumentation est une librairie implémentant un grand nombre d'opérations d'augmentation de données. Dans le code suivant, deux types d'augmentation sont définies : des transformations spatiales (ShiftScaleRotate), et des transformations colorimétriques. "
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"id": "4E-o7eMQTtE5"
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/tmp/deepl/.env/lib/python3.8/site-packages/albumentations/augmentations/transforms.py:1826: FutureWarning: This class has been deprecated. Please use RandomBrightnessContrast\n",
" warnings.warn(\n",
"/tmp/deepl/.env/lib/python3.8/site-packages/albumentations/augmentations/transforms.py:1800: FutureWarning: This class has been deprecated. Please use RandomBrightnessContrast\n",
" warnings.warn(\n"
]
}
],
"source": [
"import cv2 as cv\n",
"from albumentations import (Compose, RandomBrightness, RandomContrast, RandomGamma, ShiftScaleRotate)\n",
"\n",
"AUGMENTATIONS_TRAIN = Compose([\n",
" ShiftScaleRotate(p=0.5),\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",
"])"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Ac98mnGJTxNu"
},
"source": [
"La classe Sequence permet de définir l'accès aux données d'entraînement de manière personnalisée, afin par exemple d'implanter des augmentations particulières (c'est le cas ici), ou d'avoir un contrôle plus fin sur la manière de constituer les *mini-batches*.\n"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"id": "XaGczO0QT0H8"
},
"outputs": [],
"source": [
"from tensorflow.keras.utils import Sequence\n",
"\n",
"class LSPDSequence(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 # Données et labels d'apprentissage \n",
" self.batch_size = batch_size # Taille de mini-batch\n",
" self.augment = augmentations # Fonction d'augmentation à appliquer\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 retirés aléatoirement à chaque epoch pour varier \n",
" # la composition 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",
" # Application de l'augmentation de données à chaque image du batch et aux\n",
" # cartes de probabilités associées\n",
" def apply_augmentation(self, bx, by):\n",
"\n",
" batch_x = np.zeros(bx.shape)\n",
" batch_y = np.zeros(by.shape)\n",
" # Pour chaque image du batch\n",
" for i in range(len(bx)):\n",
" masks = []\n",
" # Les 14 masques associés à l'image sont rangés dans une liste pour \n",
" # pouvoir être traités par la librairie Albumentation\n",
" for n in range(by.shape[3]):\n",
" masks.append(by[i,:,:,n])\n",
"\n",
" img = bx[i]\n",
" # Application de l'augmentation à l'image et aux masques\n",
" transformed = self.augment(image=img, masks=masks)\n",
" batch_x[i] = transformed['image']\n",
" batch_y_list = transformed['masks']\n",
"\n",
" # Reconstitution d'un tenseur à partir des masques augmentés\n",
" for k in range(by.shape[3]):\n",
" batch_y[i,:,:,k] = batch_y_list[k]\n",
"\n",
" return batch_x, batch_y\n",
"\n",
" # Fonction appelée pour 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",
" \n",
" batch_x, batch_y = self.apply_augmentation(batch_x, batch_y)\n",
"\n",
" return np.array(batch_x), np.array(batch_y)\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)"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {
"id": "NGBI2gXVT399"
},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 864x864 with 5 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAr8AAACiCAYAAABIzqWCAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAACeEElEQVR4nOz9ebglWXrWh/6+tVZE7L3PkCeHGrqrq6s1ISEEFuJKzKAHc5m58BjMFQgsMLYezPD4gjAYX8AyBtvYBgQXfLGwmUFiBoF1fRl8BQ+zJJCQJaHuVnfXXJmVmWfYZ+8dw1rru3+sFbHjnMysOlldnZWZJ96qnXufHXPE2hHv+tb7vZ+oKhMmTJgwYcKECRMmXAaYD3oHJkyYMGHChAkTJkx4VJjI74QJEyZMmDBhwoRLg4n8TpgwYcKECRMmTLg0mMjvhAkTJkyYMGHChEuDifxOmDBhwoQJEyZMuDSYyO+ECRMmTJgwYcKES4OJ/D5iiMipiHz++z3vu6znG0Xkz3+265nw7hCRXy0i//h9XufXisjfveC8/x8R+br3c/sTHi1E5OeKyNsi8os/6H2Z8Pjh/bzHfDbPBhH5aH5G2fdjXyY8/RCRPy0iv/eD3g94jMmviHxGRH7mB70f7zdUdVdVP/V+zzthi3xD7l9RRDajv7/2g96/h4Wq/gVV/VkXnPfnquqfuci8IvIdIvIffXZ7N+Fh8S7t8+uA3wz8SODXicgLo+Wm6/UYQ0R+hYh8V76Ob+aO6E/5oPfrcwVVfSU/owJM7bOHiHyNiPwLEVmJyK38+deLiHzQ+zZhi8eW/D5tEBH3Qe/DZUG+Ie+q6i7wCvALR9/9hQ96/yZcbrxL+/wzqvqzVPW2qv4cVX39g97fCe8OEfktwDcB/w3wHPBR4H8CftEHuFufFaZn1sNDRL4B+MPA/wA8T2oLvw74yUD5Ae7ahHN4IshvHub5JyLyh0TkSEQ+JSI/KX//au5dfd1o/p8vIv9aRE7y9G88t77/QEReFpE7IvK7xlFmETEi8p+LyA/n6X9ZRK69w779xyLySRG5KyLfJiIfHk1TEfkNIvIJ4BOj774wf74uIn877+d3isjvHQ9nnZv3T4vIHxOR/01Elrk3+QWjef9wPtYTEfluEfmp77DPP0FE/mk+l98rIl990WvxJENEKhH5JhF5I7++SUSqPO2eocRz5//nicgP5HP/uoj81gtu80tE5O/l9vFDIvLLRtMutM7z+5bb/neKyHF+/0mjaUP0pV9ORP5HETkUkU+LyM/N034f8FOBP5ojVX9UEv5Q/j2diMj3iciXXfT8Tvjs8aDf5v2uV/7+ge1rwqOBiFwBfg/wG1T1r6vqSlU7Vf3bqvqf5Xk+m3vP9fxsORGRfwl8wbl5L9wGROTzROQf5nvO3wNujKZ9LG/314rIK8D/Iel5+DslPS9vicifzcc7nt89qH1eJozawa9X1b+qqktN+Neq+rWq2uT5qnxPfkVEborIHxeReZ721SLymoh8Qz7fb4rIrxlvI1+Dt/M1+Z0iYvK0MxKW8fV5wP5+hSSetBSRvyIif0myJEFErorI38nbOcyfPzJa9szI/H22/VNG97FXReRXjzZ9VR7MYx7d/UxVH8sX8BngZ+bPvxrwwK8BLPB7SRGTPwZUwM8ClsBunv+rgR9NIvc/BrgJ/OI87UuBU+CnkHpi/yPQjbb1nwL/HPhIXvf/DHzLA/bxZwC3ga/I8/6/gH80mq7A3wOuAfPRd1+YP39rfi3yfr0K/ONzy/fz/mngDvBVgAP+AvCto3l/JXA9T/sG4C1glqd9I/Dn8+cX8np+Xj4//9f89zMf9DV/BO3o9+Rr+yzwDPBPgf961Mb+8bllx+f/TeCn5s9Xga94wPaG9QA7+Zr+mnxdfmxuL1/6WazzGnAI/Kq8zl+e/76ep38H8B+NluuA/5j0u/lPgDcAOT9v/vtnA98NHABCGnr/0Ad9DZ/m17n2+Y6/zftcr3dsX9PrkV3Dn0N6Prl3mOezufd8K/CX8/X+MuD1i95j7rMf/wz4g6Tn1U8jPTf7Z8PH8nb/bF7vHPgPgU8Cnw/sAn8d+HPn5nf3a5+X7XWRdpDn+0PAt+V7+R7wt4H/Nk/76ryO3wMU+V6wBq7m6X8W+Ft5uY8BHwd+bZ72jf21vN/1ObcPJfAyie8UwL8HtMDvzdOvA7+ExE32gL8C/M3R8p8h37fObxt4KberX57XfR348jztT/MAHvOwbfmzfT0Rkd+MT6vqn9KkL/pLwIvA71HVRlX/LunCfSGAqn6Hqn6fqkZV/TfAtwA/Pa/nlwJ/W1X/saq2wO8mNZAevw74f6rqa5p6at8I/NIH9J6+FviTqvqv8ry/A/iJIvKx0Tz/rareVdXNeEFJSQK/BPgvVXWtqj8AvJtW82+o6r9UVU9qNF/eT1DVP6+qd1TVq+ofIN3cvvg+6/iVwLer6rfn8/P3gO8i/ciednwtqc3cUtW3gf+KRCIvgg74UhHZV9VDVf1XF1jmFwCfye3Wq+q/Bv4a8O9/Fuv8+cAnVPXP5XV+C/BvgV/4gPlfVtU/kX83fwb4EGko7kHHuAd8CYkg/6CqvnmBfZrw/uBhf5vv1r4mPBpcB27n+/KD8J7uPaPnxO/WFFH+Pzn7nLhwGxCRjwJfCfyu/Nz8RyTidR7fmLe1yfv9B1X1U6p6SnrGfc2DoomXHDc41w5G0c+NiPw0ERHg64HfnHnBkiSV+ZrRejpSW+lU9dtJwbovzm3ha4DfoSmq/BngD3DxZ9gYP4FEMP9I3s5fB/5lPzFzib+WuckS+H1sOdS74VcAf19VvyWv+46qfs9o+oN4zCO9nz1J5Pfm6PMGQFXPf7cLICI/XkT+fzlkf0witP3wzodJvQvyOtaknkiPl4C/kRvsEfCDQOD+hOHDpN5Tv67TvK4XRvO8en6hjGdIje/VC8zb463R5zX5eAFE5LeKyA9KGgo/Aq4wGtIa4SXg3++PL8/7U0ik6GnHmeuVP3/4AfOexy8hkZCX87DhT7zAMi8BP/7cuf5akhbsva7z/DGQ/37hPvPCqM3ktg6jdjOGqv4fwB8ljajcEpFvFpH9C+zThPcHD/vbfLf2NeHR4A5w410I4Xu999zvOTFez8O0gQ8Dh6q6esC6eoy3db/9djy4A32ZcU87UNWfpKoHeZohXc8F8N2j6/W/5++H9ZzrSPXP+hukSOr56/Gge/874cPA66o6DvwN111EFiLyP2dpxQnwj4ADuZizx4vAD7/D9AfxmEd6P3uSyO/D4C+ShhVeVNUrwB8nDeNCGmoea1fmpJ57j1eBn6uqB6PXTO+fePIG6YL169rJ6xrPq+cXynibNLzxkdF3L17k4M5Dkr73twG/jDQ8cgAcsz3mMV4lDVuNj29HVf+797LtJwxnrhcpKeWN/HlFuikBICJnfnCq+p2q+otIw5Z/kzQM+W54FfiH5871rqr+J5/FOs8fQ38c7yUx6p62qap/RFV/HEmG8yOA/+w9rHfCe8O7/TbPX693bF8THhn+GdAAv/gd5nmv957+OTF+Nnx09Plh2sCbJL3lzgPW1WPczu63356zwaj7LXcZ0beDd0pyvE0K1P2o0fW6oin59d1wmxQVPn89+nv/mXbEO5PGN4EXciS6x7iNfQNp5PjHq+o+SSIDW07xTtt6lXO69Avikd7PnlbyuwfcVdVaRL6KFIbv8VeBXygpaagkyRrGDeCPA79PRF4CEJFnRORBjflbgF8jIl8uKXnhvwH+RR6OeEfkYei/Dnxj7mV9CfAfPNRRbrFHuiG9DTgR+d3AgyJ2f550/D9bRKyIzCSJ7D/ygPmfJnwL8DvzNb1Bkrz0Iv3vBX5UvpYzUrsAQERKSV67V1S1A06AeIHt/R3gR4jIrxKRIr++UkR+5Gexzm/P6/wVkhJN/u8kovp3LngOxrhJ0vIBkPftx4tIQbq51RfcpwnvD97tt3nmevEO7euR7/klhqoek+4lf0xEfnG+nxeS/Jr/+zzbe7r33Oc58aXA2Mf7wm1AVV8myWj+q3z/+Sk8WC7V41uA3ywpU
"text/plain": [
"<Figure size 864x864 with 5 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 864x864 with 5 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# Instanciation d'une Sequence\n",
"train_gen = LSPDSequence(x_train.astype(np.float32), y_hm_train.astype(np.float32), 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[0]\n",
"\n",
"print_heatmap(batch_x, batch_y)"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"id": "yT-ySEuOUCyh"
},
"outputs": [],
"source": [
"import keras\n",
"from keras.layers import *\n",
"from keras import *\n",
"\n",
"def create_unet(image_size=572):\n",
" input_layer=Input((image_size, image_size, 3))\n",
"\n",
" conv1 = Conv2D(32, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(input_layer)\n",
" conv1 = Conv2D(32, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv1)\n",
" pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)\n",
" \n",
" conv2 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool1)\n",
" conv2 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv2)\n",
" pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)\n",
" \n",
" conv3 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool2)\n",
" conv3 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv3)\n",
" pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)\n",
" \n",
" conv4 = Conv2D(216, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool3)\n",
" conv4 = Conv2D(216, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv4)\n",
" drop4 = Dropout(0.5)(conv4)\n",
" pool4 = MaxPooling2D(pool_size=(2, 2))(drop4)\n",
"\n",
" conv5 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(pool4)\n",
" conv5 = Conv2D(512, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv5)\n",
" drop5 = Dropout(0.5)(conv5)\n",
"\n",
" up6 = Conv2D(256, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(drop5))\n",
" merge6 = concatenate([drop4,up6], axis = 3)\n",
" conv6 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge6)\n",
" conv6 = Conv2D(256, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv6)\n",
"\n",
" up7 = Conv2D(128, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv6))\n",
" merge7 = concatenate([conv3,up7], axis = 3)\n",
" conv7 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge7)\n",
" conv7 = Conv2D(128, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv7)\n",
" \n",
" up8 = Conv2D(64, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv7))\n",
" merge8 = concatenate([conv2,up8], axis = 3)\n",
" conv8 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge8)\n",
" conv8 = Conv2D(64, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv8)\n",
"\n",
" up9 = Conv2D(32, 2, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv8))\n",
" merge9 = concatenate([conv1,up9], axis = 3)\n",
" conv9 = Conv2D(32, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(merge9)\n",
" conv9 = Conv2D(32, 3, activation = 'relu', padding = 'same', kernel_initializer = 'he_normal')(conv9)\n",
" conv10 = Conv2D(len(labels), 1, activation = 'sigmoid')(conv9)\n",
"\n",
" model = Model(input_layer, conv10)\n",
"\n",
" return model"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model: \"model_1\"\n",
"__________________________________________________________________________________________________\n",
" Layer (type) Output Shape Param # Connected to \n",
"==================================================================================================\n",
" input_2 (InputLayer) [(None, 64, 64, 3)] 0 [] \n",
" \n",
" conv2d_23 (Conv2D) (None, 64, 64, 32) 896 ['input_2[0][0]'] \n",
" \n",
" conv2d_24 (Conv2D) (None, 64, 64, 32) 9248 ['conv2d_23[0][0]'] \n",
" \n",
" max_pooling2d_4 (MaxPooling2D) (None, 32, 32, 32) 0 ['conv2d_24[0][0]'] \n",
" \n",
" conv2d_25 (Conv2D) (None, 32, 32, 64) 18496 ['max_pooling2d_4[0][0]'] \n",
" \n",
" conv2d_26 (Conv2D) (None, 32, 32, 64) 36928 ['conv2d_25[0][0]'] \n",
" \n",
" max_pooling2d_5 (MaxPooling2D) (None, 16, 16, 64) 0 ['conv2d_26[0][0]'] \n",
" \n",
" conv2d_27 (Conv2D) (None, 16, 16, 128) 73856 ['max_pooling2d_5[0][0]'] \n",
" \n",
" conv2d_28 (Conv2D) (None, 16, 16, 128) 147584 ['conv2d_27[0][0]'] \n",
" \n",
" max_pooling2d_6 (MaxPooling2D) (None, 8, 8, 128) 0 ['conv2d_28[0][0]'] \n",
" \n",
" conv2d_29 (Conv2D) (None, 8, 8, 216) 249048 ['max_pooling2d_6[0][0]'] \n",
" \n",
" conv2d_30 (Conv2D) (None, 8, 8, 216) 420120 ['conv2d_29[0][0]'] \n",
" \n",
" dropout_2 (Dropout) (None, 8, 8, 216) 0 ['conv2d_30[0][0]'] \n",
" \n",
" max_pooling2d_7 (MaxPooling2D) (None, 4, 4, 216) 0 ['dropout_2[0][0]'] \n",
" \n",
" conv2d_31 (Conv2D) (None, 4, 4, 512) 995840 ['max_pooling2d_7[0][0]'] \n",
" \n",
" conv2d_32 (Conv2D) (None, 4, 4, 512) 2359808 ['conv2d_31[0][0]'] \n",
" \n",
" dropout_3 (Dropout) (None, 4, 4, 512) 0 ['conv2d_32[0][0]'] \n",
" \n",
" up_sampling2d_4 (UpSampling2D) (None, 8, 8, 512) 0 ['dropout_3[0][0]'] \n",
" \n",
" conv2d_33 (Conv2D) (None, 8, 8, 256) 524544 ['up_sampling2d_4[0][0]'] \n",
" \n",
" concatenate_4 (Concatenate) (None, 8, 8, 472) 0 ['dropout_2[0][0]', \n",
" 'conv2d_33[0][0]'] \n",
" \n",
" conv2d_34 (Conv2D) (None, 8, 8, 256) 1087744 ['concatenate_4[0][0]'] \n",
" \n",
" conv2d_35 (Conv2D) (None, 8, 8, 256) 590080 ['conv2d_34[0][0]'] \n",
" \n",
" up_sampling2d_5 (UpSampling2D) (None, 16, 16, 256) 0 ['conv2d_35[0][0]'] \n",
" \n",
" conv2d_36 (Conv2D) (None, 16, 16, 128) 131200 ['up_sampling2d_5[0][0]'] \n",
" \n",
" concatenate_5 (Concatenate) (None, 16, 16, 256) 0 ['conv2d_28[0][0]', \n",
" 'conv2d_36[0][0]'] \n",
" \n",
" conv2d_37 (Conv2D) (None, 16, 16, 128) 295040 ['concatenate_5[0][0]'] \n",
" \n",
" conv2d_38 (Conv2D) (None, 16, 16, 128) 147584 ['conv2d_37[0][0]'] \n",
" \n",
" up_sampling2d_6 (UpSampling2D) (None, 32, 32, 128) 0 ['conv2d_38[0][0]'] \n",
" \n",
" conv2d_39 (Conv2D) (None, 32, 32, 64) 32832 ['up_sampling2d_6[0][0]'] \n",
" \n",
" concatenate_6 (Concatenate) (None, 32, 32, 128) 0 ['conv2d_26[0][0]', \n",
" 'conv2d_39[0][0]'] \n",
" \n",
" conv2d_40 (Conv2D) (None, 32, 32, 64) 73792 ['concatenate_6[0][0]'] \n",
" \n",
" conv2d_41 (Conv2D) (None, 32, 32, 64) 36928 ['conv2d_40[0][0]'] \n",
" \n",
" up_sampling2d_7 (UpSampling2D) (None, 64, 64, 64) 0 ['conv2d_41[0][0]'] \n",
" \n",
" conv2d_42 (Conv2D) (None, 64, 64, 32) 8224 ['up_sampling2d_7[0][0]'] \n",
" \n",
" concatenate_7 (Concatenate) (None, 64, 64, 64) 0 ['conv2d_24[0][0]', \n",
" 'conv2d_42[0][0]'] \n",
" \n",
" conv2d_43 (Conv2D) (None, 64, 64, 32) 18464 ['concatenate_7[0][0]'] \n",
" \n",
" conv2d_44 (Conv2D) (None, 64, 64, 32) 9248 ['conv2d_43[0][0]'] \n",
" \n",
" conv2d_45 (Conv2D) (None, 64, 64, 14) 462 ['conv2d_44[0][0]'] \n",
" \n",
"==================================================================================================\n",
"Total params: 7,267,966\n",
"Trainable params: 7,267,966\n",
"Non-trainable params: 0\n",
"__________________________________________________________________________________________________\n"
]
}
],
"source": [
"model = create_unet(image_size=64)\n",
"model.summary()"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1/100\n",
"57/57 [==============================] - 16s 260ms/step - loss: 0.0492 - accuracy: 0.0355\n",
"Epoch 2/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0311 - accuracy: 0.0376\n",
"Epoch 3/100\n",
"57/57 [==============================] - 15s 259ms/step - loss: 0.0276 - accuracy: 0.0376\n",
"Epoch 4/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0249 - accuracy: 0.0408\n",
"Epoch 5/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0230 - accuracy: 0.0474\n",
"Epoch 6/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0221 - accuracy: 0.0686\n",
"Epoch 7/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0220 - accuracy: 0.0830\n",
"Epoch 8/100\n",
"57/57 [==============================] - 15s 259ms/step - loss: 0.0209 - accuracy: 0.1399\n",
"Epoch 9/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0205 - accuracy: 0.2018\n",
"Epoch 10/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0202 - accuracy: 0.2163\n",
"Epoch 11/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0201 - accuracy: 0.2323\n",
"Epoch 12/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0196 - accuracy: 0.2354\n",
"Epoch 13/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0196 - accuracy: 0.2590\n",
"Epoch 14/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0194 - accuracy: 0.2388\n",
"Epoch 15/100\n",
"57/57 [==============================] - 15s 259ms/step - loss: 0.0192 - accuracy: 0.2503\n",
"Epoch 16/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0191 - accuracy: 0.2396\n",
"Epoch 17/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0191 - accuracy: 0.2664\n",
"Epoch 18/100\n",
"57/57 [==============================] - 15s 259ms/step - loss: 0.0190 - accuracy: 0.2490\n",
"Epoch 19/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0190 - accuracy: 0.2233\n",
"Epoch 20/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0189 - accuracy: 0.2491\n",
"Epoch 21/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0187 - accuracy: 0.2485\n",
"Epoch 22/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0189 - accuracy: 0.2488\n",
"Epoch 23/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0189 - accuracy: 0.2710\n",
"Epoch 24/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0187 - accuracy: 0.2643\n",
"Epoch 25/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0187 - accuracy: 0.2373\n",
"Epoch 26/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0187 - accuracy: 0.2581\n",
"Epoch 27/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0187 - accuracy: 0.2337\n",
"Epoch 28/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0186 - accuracy: 0.2480\n",
"Epoch 29/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0187 - accuracy: 0.2294\n",
"Epoch 30/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0184 - accuracy: 0.2626\n",
"Epoch 31/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0184 - accuracy: 0.2467\n",
"Epoch 32/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0186 - accuracy: 0.2497\n",
"Epoch 33/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0183 - accuracy: 0.2340\n",
"Epoch 34/100\n",
"57/57 [==============================] - 15s 262ms/step - loss: 0.0183 - accuracy: 0.2401\n",
"Epoch 35/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0183 - accuracy: 0.2517\n",
"Epoch 36/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0184 - accuracy: 0.2479\n",
"Epoch 37/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0183 - accuracy: 0.2323\n",
"Epoch 38/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0182 - accuracy: 0.2647\n",
"Epoch 39/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0182 - accuracy: 0.2566\n",
"Epoch 40/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0183 - accuracy: 0.2436\n",
"Epoch 41/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0182 - accuracy: 0.2486\n",
"Epoch 42/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0182 - accuracy: 0.2625\n",
"Epoch 43/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0181 - accuracy: 0.2717\n",
"Epoch 44/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0181 - accuracy: 0.2351\n",
"Epoch 45/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0182 - accuracy: 0.2538\n",
"Epoch 46/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0181 - accuracy: 0.2486\n",
"Epoch 47/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0179 - accuracy: 0.2432\n",
"Epoch 48/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0180 - accuracy: 0.2379\n",
"Epoch 49/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0181 - accuracy: 0.2535\n",
"Epoch 50/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0179 - accuracy: 0.2460\n",
"Epoch 51/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0179 - accuracy: 0.2618\n",
"Epoch 52/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0179 - accuracy: 0.2349\n",
"Epoch 53/100\n",
"57/57 [==============================] - 15s 259ms/step - loss: 0.0178 - accuracy: 0.2481\n",
"Epoch 54/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0179 - accuracy: 0.2255\n",
"Epoch 55/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0179 - accuracy: 0.2463\n",
"Epoch 56/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0177 - accuracy: 0.2260\n",
"Epoch 57/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0179 - accuracy: 0.2415\n",
"Epoch 58/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0178 - accuracy: 0.2606\n",
"Epoch 59/100\n",
"57/57 [==============================] - 15s 259ms/step - loss: 0.0177 - accuracy: 0.2402\n",
"Epoch 60/100\n",
"57/57 [==============================] - 15s 259ms/step - loss: 0.0176 - accuracy: 0.2527\n",
"Epoch 61/100\n",
"57/57 [==============================] - 15s 259ms/step - loss: 0.0177 - accuracy: 0.2505\n",
"Epoch 62/100\n",
"57/57 [==============================] - 15s 261ms/step - loss: 0.0176 - accuracy: 0.2685\n",
"Epoch 63/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0178 - accuracy: 0.2562\n",
"Epoch 64/100\n",
"57/57 [==============================] - 15s 259ms/step - loss: 0.0177 - accuracy: 0.2271\n",
"Epoch 65/100\n",
"57/57 [==============================] - 15s 259ms/step - loss: 0.0176 - accuracy: 0.2306\n",
"Epoch 66/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0176 - accuracy: 0.2553\n",
"Epoch 67/100\n",
"57/57 [==============================] - 15s 259ms/step - loss: 0.0176 - accuracy: 0.2250\n",
"Epoch 68/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0175 - accuracy: 0.2556\n",
"Epoch 69/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0174 - accuracy: 0.2524\n",
"Epoch 70/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0175 - accuracy: 0.2578\n",
"Epoch 71/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0175 - accuracy: 0.2579\n",
"Epoch 72/100\n",
"57/57 [==============================] - 15s 261ms/step - loss: 0.0174 - accuracy: 0.2663\n",
"Epoch 73/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0173 - accuracy: 0.2718\n",
"Epoch 74/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0176 - accuracy: 0.2350\n",
"Epoch 75/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0172 - accuracy: 0.2704\n",
"Epoch 76/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0173 - accuracy: 0.2347\n",
"Epoch 77/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0173 - accuracy: 0.2553\n",
"Epoch 78/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0174 - accuracy: 0.2309\n",
"Epoch 79/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0173 - accuracy: 0.2484\n",
"Epoch 80/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0174 - accuracy: 0.2431\n",
"Epoch 81/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0173 - accuracy: 0.2418\n",
"Epoch 82/100\n",
"57/57 [==============================] - 15s 261ms/step - loss: 0.0172 - accuracy: 0.2434\n",
"Epoch 83/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0172 - accuracy: 0.2410\n",
"Epoch 84/100\n",
"57/57 [==============================] - 15s 261ms/step - loss: 0.0171 - accuracy: 0.2544\n",
"Epoch 85/100\n",
"57/57 [==============================] - 15s 261ms/step - loss: 0.0170 - accuracy: 0.2382\n",
"Epoch 86/100\n",
"57/57 [==============================] - 15s 261ms/step - loss: 0.0171 - accuracy: 0.2422\n",
"Epoch 87/100\n",
"57/57 [==============================] - 15s 261ms/step - loss: 0.0171 - accuracy: 0.2537\n",
"Epoch 88/100\n",
"57/57 [==============================] - 15s 261ms/step - loss: 0.0170 - accuracy: 0.2672\n",
"Epoch 89/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0169 - accuracy: 0.2552\n",
"Epoch 90/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0170 - accuracy: 0.2544\n",
"Epoch 91/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0171 - accuracy: 0.2409\n",
"Epoch 92/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0169 - accuracy: 0.2201\n",
"Epoch 93/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0169 - accuracy: 0.2288\n",
"Epoch 94/100\n",
"57/57 [==============================] - 15s 261ms/step - loss: 0.0167 - accuracy: 0.2568\n",
"Epoch 95/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0169 - accuracy: 0.2724\n",
"Epoch 96/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0166 - accuracy: 0.2498\n",
"Epoch 97/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0168 - accuracy: 0.2345\n",
"Epoch 98/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0167 - accuracy: 0.2457\n",
"Epoch 99/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0168 - accuracy: 0.2588\n",
"Epoch 100/100\n",
"57/57 [==============================] - 15s 260ms/step - loss: 0.0167 - accuracy: 0.2716\n"
]
}
],
"source": [
"from tensorflow.keras import optimizers\n",
"\n",
"adam = optimizers.Adam(learning_rate=1e-4)\n",
"model.compile(optimizer=adam, loss=\"binary_crossentropy\", metrics=[\"accuracy\"])\n",
"history = model.fit(train_gen, epochs=100)"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"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": "iVBORw0KGgoAAAANSUhEUgAAAr8AAACiCAYAAABIzqWCAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAADdgElEQVR4nOz9ebQt2bbWhf76GBExi1XtMuuTJ0997rmAl0spXoqmiKAiNEEeggiI0lCxvadYP1BEsFbApzbE9xQQBBRBgcdTQSopLly4XLjlKe45J8td773KWUTEGP390ceIiDnXXGuvnZlnZ+bO1bOt3LOIGREzos8xvvH1r/cuqsqlXdqlXdqlXdqlXdqlXdrHwdwHfQKXdmmXdmmXdmmXdmmXdmlPyy7B76Vd2qVd2qVd2qVd2qV9bOwS/F7apV3apV3apV3apV3ax8Yuwe+lXdqlXdqlXdqlXdqlfWzsEvxe2qVd2qVd2qVd2qVd2sfGLsHvpV3apV3apV3apV3apX1s7BL8PmUTkWMR+fT7ve1j9vObReT3v9f9XNrjTUR+lYj8pfd5n79cRP6PC277/xORX/l+Hv/Snq6JyM8TkXsi8gs/6HO5tA+fvZ9jzHuZG0Tk1TRH+ffjXC7t2TcR+T0i8ls/6POADzH4FZFvisjP/qDP4/02Vd1W1a+/39teWm9pQM5/UUTmg+e//IM+vyc1Vf0DqvpzLrjtz1PV33uRbUXkz4vIP/3ezu7SntQe45+/EvgXgW8Dfp2IvDz43OX9+hCbiPwyEfkb6T7eSgvR7/qgz+tbZar6RpqjAlz6ZzYR+aUi8tdE5ERE7qbH/5yIyAd9bpfW24cW/D5rJiLFB30OHxdLA/K2qm4DbwA/f/DaH/igz+/SPt72GP/8var6c1T1vqr+XFV9+4M+30t7vInIvwT8DuDfA54HXgX+K+AXfICn9Z7scs56chOR3wD8TuA/Bl7AfOHXAX8PUH2Ap3Zpa/aRAL8pzPOXReS3i8i+iHxdRH5aev3NtLr6lYPt/yER+Vsicpje/81r+/snReR1EXkgIr9pyDKLiBORf11EfjS9/z+KyLVzzu2fEZGvichDEfnjIvLS4D0VkX9eRL4KfHXw2mfT4+si8ifSeX6PiPzWYThrbdvfIyL/pYj8f0XkKK0mPzPY9nem73ooIn9TRH76Oef8U0Xkr6Rr+bdF5Gdd9F58lE1ERiLyO0TknfT3O0RklN47FUpcu/7/oIj8ULr2b4vIv3zBY35RRP508o8vi8gvGbx3oX2un1vy/e8RkYP0708bvNexL/lzIvKfiMgjEfmGiPy89N5vA3468F8kpuq/ELPfnn5PhyLy/SLyYy56fS/tvdtZv81N9yu9fqZ/XdrTMRHZA34L8M+r6h9V1RNVbVT1T6jqv5K2eS9jz/U0txyKyF8HPrO27YV9QEQ+JSJ/IY05fxq4MXjvtXTcXyMibwB/Vmw+/I1i8+VdEfl96fsOty/O8s+Pkw384J9T1T+iqkdq9rdU9Zer6jJtN0pj8hsickdEfpeITNJ7P0tE3hKR35Cu9y0R+dXDY6R7cC/dk98oIi69tyJhGd6fM873O8Vw0pGI/E8i8oclSRJE5KqI/Ml0nEfp8SuDz65E5jcc+7sG49ibIvKrBoe+KmfjmKc3nqnqh/IP+Cbws9PjXwW0wK8GPPBbMcbkvwRGwM8BjoDttP3PAn4sBu5/HHAH+IXpvS8Bx8B3YSux/wRoBsf6vwPfDbyS9v1fA3/wjHP8e4H7wHembf9fwF8cvK/AnwauAZPBa59Nj/9Q+pum83oT+Etrn8/b/h7gAfCTgQL4A8AfGmz7TwDX03u/AbgNjNN7vxn4/enxy2k//2C6Pn9/en7zg77nT8GPfku6t88BN4G/Avy7Ax/7S2ufHV7/W8BPT4+vAt95xvG6/QBb6Z7+6nRffnzyly+9h31eAx4BvyLt8x9Pz6+n9/888E8PPtcA/wz2u/lngXcAWd82Pf8HgL8JXAEEC72/+EHfw2f5b80/z/1tbrhf5/rX5d9Tu4c/F5ufinO2eS9jzx8C/sd0v38M8PZFx5gN5/FXgf8Mm69+BjZv5rnhtXTc35f2OwH+KeBrwKeBbeCPAv/92vbFJv/8uP1dxA/Sdr8d+ONpLN8B/gTw76f3flbax28ByjQWzICr6f3fB/yv6XOvAV8Bfk167zfne7np/qydQwW8juGdEvhHgRr4ren968AvwrDJDvA/Af/L4PPfJI1b68cGPpn86h9P+74OfEd67/dwBo55Ul9+r38fCeY32TdU9b9T0xf9YeATwG9R1aWq/h/YjfssgKr+eVX9flWNqvp3gD8I/My0n18M/AlV/UuqWgP/FuYg2X4d8P9U1bfUVmq/GfjFZ6yefjnw36rq96Zt/w3g7xaR1wbb/Puq+lBV58MPiiUJ/CLg31bVmar+EPA4reYfU9W/rqot5jTfkd9Q1d+vqg9UtVXV/xQb3L6wYR//BPCnVPVPpevzp4G/gf3InnX75ZjP3FXVe8C/g4HIi1gDfElEdlX1kap+7wU+8w8D30x+26rq3wL+Z+Afew/7/IeAr6rqf5/2+QeBHwF+/hnbv66q/0363fxe4EUsFHfWd9wBvogB5B9W1VsXOKdLe3/sSX+bj/OvS3s6dh24n8bls+xdjT2DeeLfUmOUf4DVeeLCPiAirwI/CfhNad78ixjwWrffnI41T+f9n6nq11X1GJvjfulZbOLH3G6w5gcD9nMuIj9DRAT4tcC/mHDBESaV+aWD/TSYrzSq+qcwsu4LyRd+KfBvqLHK3wT+Uy4+hw3tp2IA8z9Px/mjwF/PbyYs8T8nbHIE/DZ6DPU4+2XAn1HVP5j2/UBVv2/w/lk45qmOZx8l8Htn8HgOoKrrr20DiMhPEZE/lyj7AwzQ5vDOS9jqgrSPGbYSyfZJ4I8lh90HfhgIbAYML2Grp7yv47SvlwfbvLn+oWQ3Med78wLbZrs9eDwjfV8AEfmXReSHxULh+8Aeg5DWwD4J/GP5+6VtvwsDRc+6rdyv9PilM7Zdt1+EgZDXU9jw777AZz4J/JS1a/3LMS3Yu93n+ncgPX95w7Yw8Jnk6zDwm6Gp6p8F/gssonJXRH63iOxe4Jwu7f2xJ/1tPs6/Lu3p2APgxmMA4bsdezbNE8P9PIkPvAQ8UtWTM/aVbXisTeddcPYC+uNsp/xAVX+aql5J7znsfk6Bvzm4X/9ber3bz9pCKs/1NzAmdf1+nDX2n2cvAW+r6pD46+67iExF5L9O0opD4C8CV+RilT0+AfzoOe+fhWOe6nj2UQK/T2L/AxZW+ISq7gG/CwvjgoWah9qVCbZyz/Ym8PNU9crgb6ybE0/ewW5Y3tdW2tdwW13/ULJ7WHjjlcFrn7jIl1s3MX3vvwr8Eiw8cgU4oP/OQ3sTC1sNv9+Wqv4H7+bYHzFbuV9YUso76fEJNigBICIrPzhV/R5V/QVY2PJ/wcKQj7M3gb+wdq23VfWffQ/7XP8O+Xu8m8SoU76pqv+5qv4ETIbzeeBfeRf7vbR3Z4/7ba7fr3P969Kemv1VYAn8wnO2ebdjT54nhnPDq4PHT+IDtzC95dYZ+8o29LNN592ySkZt+tzH0bIfnJfkeB8j6r59cL/21JJfH2f3MVZ4/X7ksX/FjzgfNN4CXk5MdLahj/0GLHL8U1R1F5PIQI8pzjvWm6zp0i9oT3U8e1bB7w7wUFUXIvKTMRo+2x8Bfr5Y0lCFyRqGDvC7gN8mIp8EEJGbInKWM/9B4FeLyHeIJS/8e8BfS+GIcy2Fof8o8JvTKuuLwD/5RN+ytx1sQLoHFCLybwFnMXa/H/v+/4CIeBEZi4nsXzlj+2fJ/iDwG9M9vYFJXrJI/28D357u5RjzCwBEpBKrtbunqg1wCMQLHO9PAp8XkV8hImX6+0ki8m3vYZ9/Ku3zl4klmvzfMKD6Jy94DYZ2B9PyAZDO7aeISIkNbosLntOlvT/2uN/myv3iHP966mf+MTZVPcDGkv9SRH5hGs9LsXrN/1Ha7F2NPRvmiS8BwzreF/YBVX0dk9H8O2n8+S7Ol
"text/plain": [
"<Figure size 864x864 with 5 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 864x864 with 5 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 864x864 with 5 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.33928086224073906\n"
]
}
],
"source": [
"mae = history.history['accuracy']\n",
"# val_mae = history.history['val_accuracy']\n",
"loss = history.history['loss']\n",
"# val_loss = history.history['val_loss']\n",
"\n",
"epochs = range(len(loss))\n",
"\n",
"plt.plot(epochs, mae, 'b', linestyle=\"--\",label='Training accuracy')\n",
"# plt.plot(epochs, val_mae, 'g', label='Validation accuracy')\n",
"plt.title('Training and validation accuracy')\n",
"plt.legend()\n",
"\n",
"plt.figure()\n",
"\n",
"plt.plot(epochs, loss, 'b', linestyle=\"--\",label='Training loss')\n",
"# plt.plot(epochs, val_loss,'g', label='Validation loss')\n",
"plt.title('Training and validation loss')\n",
"plt.legend()\n",
"\n",
"plt.show()\n",
"\n",
"y_pred_hm = model.predict(x_train)\n",
"print_heatmap(x_train, y_pred_hm)\n",
"y_pred_coords = heatmap2coord(y_pred_hm)\n",
"pck = compute_PCK_alpha(y_train, y_pred_coords)\n",
"print(pck)"
]
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"collapsed_sections": [],
"machine_shape": "hm",
"name": "TP5_Estimation_de_Posture_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": "e7370f93d1d0cde622a1f8e1c04877d8463912d04d973331ad4851f04de6915a"
}
}
},
"nbformat": 4,
"nbformat_minor": 0
}