1693 lines
1.1 MiB
Plaintext
1693 lines
1.1 MiB
Plaintext
|
{
|
|||
|
"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": "iVBORw0KGgoAAAANSUhEUgAAAr8AAACiCAYAAABIzqWCAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAACXkElEQVR4nOz9ebQsW3rVh/6+tVZEZObuTnvb6iTUFCUkgzASjZA1gEeP0TAYCwQWGFsDYxh+IEzjB1jmCRtsA4IHfljY9CDRt9bzQwKE0EMIqVBTElUqVXP7e0+322wiYjXf+2OtyJ1733Pu2bepc+ucE/OOvHufzIjIyIi1I2d8a35ziqoyYsSIESNGjBgxYsTjAPNu78CIESNGjBgxYsSIEQ8KI/kdMWLEiBEjRowY8dhgJL8jRowYMWLEiBEjHhuM5HfEiBEjRowYMWLEY4OR/I4YMWLEiBEjRox4bDCS3xEjRowYMWLEiBGPDUby+4AhInMR+dx3etn7bOcbReSvvt3tjLg/ROQ3isj3vMPb/FoR+ScXXPb/IyJf906+/4gHCxH5JSJyS0S++t3elxGffXgnrzFv57tBRN5XvqPsO7EvIx59iMhfFJFverf3Az6Lya+IPCciv+Dd3o93Gqq6raqfeqeXHXGKckEeHklEVhv//tp3e//eLFT1r6nqL7zgsr9EVf/SRZYVke8Skf/87e3diDeL+4zPrwN+B/CTgd8iIs9urDeer89iiMivE5EfKOfx1XIj+hXv9n59pqCqL5TvqAjj+BwgIl8jIt8nIgsRuVl+/60iIu/2vo04xWct+X3UICLu3d6HxwXlgrytqtvAC8Cv2Hjur73b+zfi8cZ9xudfUtVfqKq3VfUXq+rL7/b+jrg/ROR3At8M/A/Ak8D7gP8V+JXv4m69LYzfWW8eIvINwJ8E/mfgKfJY+C3AzwHqd3HXRpzDQ0F+yzTP/09E/oSIHIrIp0TkZ5fnXyx3V1+3sfwvE5EfFJHj8vo3ntvefyoiz4vIHRH5A5tVZhExIvJ7ReST5fW/KSJX3mDf/gsR+YSI7IvIPxSRZzZeUxH5r0TkJ4Cf2Hju88rvV0XkH5X9/H4R+abN6axzy/5FEfkzIvJ/ishJuZv8SRvL/snyWY9F5MMi8nPfYJ9/poj8q3Isf1hEvuqi5+Jhhog0IvLNIvJKeXyziDTltddNJZ47/r9URP5dOfYvi8jvuuB7flBEvqOMjx8XkV+z8dqFtnl+38rY/34ROSo/f/bGa+vqy7CeiPwvInIgIp8WkV9SXvvDwM8F/nSpVP1pyfgT5e/pWEQ+IiI/5aLHd8Tbx73+Nu92vsrz9xxfIx4MRGQP+EPAf6Wqf1dVF6rqVfUfqep/U5Z5O9eeq+W75VhE/g3wk84te+ExICKfIyL/olxzvgO4tvHaB8r7/mYReQH4Z5K/D3+/5O/LmyLyl8vn3Vze3Wt8Pk7YGAe/VVX/tqqeaMYPqurXqmpXlmvKNfkFEbkhIn9WRKblta8SkZdE5BvK8X5VRH7T5nuUc3CrnJPfLyKmvHZGwrJ5fu6xv18qmSediMjfEpG/IUWSICKXReQfl/c5KL+/Z2PdMzPzd3nvr9i4jr0oIr9x460vy715zIO7nqnqZ+UDeA74BeX33wgE4DcBFvgmcsXkzwAN8AuBE2C7LP9VwBeTyf2XADeAry6vfQiYA19BvhP7XwC/8V7/NfCvgfeUbf9vwLfeYx9/HnAb+NKy7P8L+O6N1xX4DuAKMN147vPK799WHrOyXy8C33Nu/WHZvwjcAb4McMBfA75tY9lfD1wtr30D8BowKa99I/BXy+/Plu380nJ8/m/l39ff7XP+AMbRHyrn9gngOvCvgP/nxhj7nnPrbh7/V4GfW36/DHzpPd5vvR1gq5zT31TOy08r4+VDb2ObV4AD4DeUbf7a8u+r5fXvAv7zjfU88F+Q/27+S+AVQM4vW/79i4APA5cAIU+9P/1un8NH+XFufL7h3+Zdztcbjq/x8cDO4S8mfz+5N1jm7Vx7vg34m+V8/xTg5YteY+6yH98L/HHy99VXkr83h++GD5T3/ctlu1PgPwM+AXwusA38XeCvnFve3W18Pm6Pi4yDstyfAP5huZbvAP8I+B/La19VtvGHgKpcC5bA5fL6Xwb+QVnvA8DHgd9cXvvG4Vze7fyc24caeJ7MdyrgPwJ64JvK61eBX0XmJjvA3wL+/sb6z1GuW+ffG3h/GVe/tmz7KvBTy2t/kXvwmDc7lt/u46Go/BZ8WlX/gmZ90d8A3gv8IVXtVPWfkE/c5wGo6nep6kdUNanqjwDfCvwHZTu/GvhHqvo9qtoDf5A8QAb8FuD/oaovab5T+0bgV9/j7ulrgT+vqv+2LPv7gJ8lIh/YWOZ/VNV9VV1trii5SeBXAf+dqi5V9d8B99Nq/j1V/TeqGsiD5qcOL6jqX1XVO6oaVPWPkS9uX3iXbfx64NtV9dvL8fkO4AfIf2SPOr6WPGZuquot4L8nk8iLwAMfEpFdVT1Q1X97gXV+OfBcGbdBVX8Q+DvAf/w2tvnLgJ9Q1b9StvmtwMeAX3GP5Z9X1T9X/m7+EvA0eSruXp9xB/ggmSB/VFVfvcA+jXhn8Gb/Nu83vkY8GFwFbpfr8r3wlq49G98Tf1BzRflHOfs9ceExICLvA34G8AfK9+Z3k4nXeXxjea9V2e8/rqqfUtU5+Tvua+5VTXzMcY1z42Cj+rkSka8UEQG+HvgdhReckKUyX7OxHU8eK15Vv51crPvCMha+Bvh9mqvKzwF/jIt/h23iZ5IJ5p8q7/N3gX8zvFi4xN8p3OQE+MOccqj74dcB36mq31q2fUdVf2jj9XvxmAd6PXuYyO+Njd9XAKp6/rltABH5chH556Vkf0QmtMP0zjPkuwvKNpbkO5EB7wf+Xhmwh8BHgcjdCcMz5LunYVvzsq1nN5Z58fxKBdfJg+/FCyw74LWN35eUzwsgIr9LRD4qeSr8ENhjY0prA+8H/uPh85Vlv4JMih51nDlf5fdn7rHsefwqMgl5vkwb/qwLrPN+4MvPHeuvJWvB3uo2z38Gyr+fvcuysDFmyliHjXGzCVX9Z8CfJs+o3BSRbxGR3Qvs04h3Bm/2b/N+42vEg8Ed4Np9COFbvfbc7XticztvZgw8Axyo6uIe2xqw+V5322/HvW+gH2e8bhyo6s9W1UvlNUM+nzPgwxvn6/8qz6+3c+5Gaviuv0aupJ4/H/e69r8RngFeVtXNwt/6vIvITET+tyKtOAa+G7gkF3P2eC/wyTd4/V485oFezx4m8vtm8NfJ0wrvVdU94M+Sp3EhTzVvalem5Dv3AS8Cv0RVL208Jnr3xpNXyCds2NZW2dbmsnp+pYJb5OmN92w8996LfLjzkKzv/d3AryFPj1wCjjj9zJt4kTxttfn5tlT1j7yV937IcOZ8kZtSXim/L8gXJQBE5MwfnKp+v6r+SvK05d8nT0PeDy8C/+Lcsd5W1f/ybWzz/GcYPsdbaYx63dhU1T+lqj+dLMP5AuC/eQvbHfHWcL+/zfPn6w3H14gHhu8FOuCr32CZt3rtGb4nNr8b3rfx+5sZA6+S9ZZb99jWgM1xdrf9DpwtRt1tvccRwzh4oybH2+RC3RdtnK89zc2v98NtclX4/PkYrv1nxhFvTBpfBZ4tlegBm2PsG8gzx1+uqrtkiQyccoo3eq8XOadLvyAe6PXsUSW/O8C+qrYi8mXkMvyAvw38CslNQzVZ1rA5AP4s8IdF5P0AInJdRO41mL8V+E0i8lMlNy/8D8D3lemIN0SZhv67wDeWu6wPAv/pm/qUp9ghX5BuAU5E/iBwr4rdXyV//l8kIlZEJpJF9u+5x/KPEr4V+P3lnF4jS14Gkf4PA19UzuWEPC4AEJFastfunqp64BhIF3i/fwx8gYj8BhGpyuNniMhPfhvb/PayzV8nudHkPyET1X98wWOwiRtkLR8AZd++XEQq8sWtveA+jXhncL+/zTPnizcYXw98zx9jqOoR+VryZ0Tkq8v1vJLs1/w/lcXe0rXnLt8THwI2fbwvPAZU9XmyjOa/L9efr
|
|||
|
"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"
|
|||
|
}
|
|||
|
],
|
|||
|
"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": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAEICAYAAABRSj9aAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAfyUlEQVR4nO3de5xVdf3v8dc7QIgGFQS8MCj4+4GmgjOwgZRUqEy8JEpm8POk/DjhpeyCqWFWcjDPo5Jz8vgIK6zUOtroz37xmFLDGwTeigFJHQRFwOOQGo5cQxToc/7Yi/ntGeeyZ2bPbfl+Ph77wV7f9V1rf75763uv+a6911ZEYGZm6fWhji7AzMzaloPezCzlHPRmZinnoDczSzkHvZlZyjnozcxSzkFvzSLpIUmXFLpvR5K0UdKn2mC/Ielfk/s/lfSdfPq24HEukvRwS+tsZL8TJFUVer/W/rp3dAHW9iTtzFnsDbwL7EuWL4uIu/PdV0Sc2RZ90y4iLi/EfiQNATYAPSJib7Lvu4G8X0P74HHQfwBERNH++5I2Al+MiEfr9pPUfX94mFl6eOrmA2z/n+aSvinpDeAOSX0l/UHSZklbkvvFOdsskfTF5P50SU9Impf03SDpzBb2HSppqaQdkh6VNF/S/22g7nxqvFHSk8n+HpbUP2f9FyS9Kqla0vWNPD/jJL0hqVtO2/mSnkvuj5X0tKStkl6X9GNJBzSwrzslfS9n+Zpkm79JmlGn79mSnpW0XdJrkubkrF6a/LtV0k5JJ+1/bnO2P1nScknbkn9Pzve5aYykjybbb5VUKencnHVnSVqd7HOTpKuT9v7J67NV0tuSlkly7rQzP+F2GNAPOAq4lOx/E3cky0cC7wA/bmT7ccBaoD/wQ+AXktSCvvcAfwEOAeYAX2jkMfOp8d+AfwcGAgcA+4PnOOAnyf6PSB6vmHpExJ+BfwCfqLPfe5L7+4BZyXhOAj4JfKmRuklqmJTUczowDKh7fuAfwMXAwcDZwBWSzkvWnZr8e3BEFEXE03X23Q94ALg1Gdv/Bh6QdEidMbzvuWmi5h7A74GHk+2+Atwt6Zikyy/ITgP2AU4AHk/avwFUAQOAQ4FvAb7uSjtz0Ns/gRsi4t2IeCciqiPitxGxKyJ2ADcBpzWy/asRcXtE7APuAg4n+z903n0lHQmMAb4bEe9FxBNAeUMPmGeNd0TESxHxDnAfUJK0XwD8ISKWRsS7wHeS56AhvwGmAUjqA5yVtBERKyLimYjYGxEbgZ/VU0d9LkzqeyEi/kH2jS13fEsi4vmI+GdEPJc8Xj77hewbw8sR8eukrt8Aa4DP5PRp6LlpzMeAIuD7yWv0OPAHkucG2AMcJ+nAiNgSEStz2g8HjoqIPRGxLHyBrXbnoLfNEbF7/4Kk3pJ+lkxtbCc7VXBw7vRFHW/svxMRu5K7Rc3sewTwdk4bwGsNFZxnjW/k3N+VU9MRuftOgra6occie/Q+RVJPYAqwMiJeTeoYnkxLvJHU8T/JHt03pVYNwKt1xjdO0uJkamobcHme+92/71frtL0KDMpZbui5abLmiMh9U8zd72fJvgm+KulPkk5K2m8G1gEPS1ovaXZ+w7BCctBb3aOrbwDHAOMi4kD+a6qgoemYQngd6Cepd07b4Eb6t6bG13P3nTzmIQ11jojVZAPtTGpP20B2CmgNMCyp41stqYHs9FOue8j+RTM4Ig4Cfpqz36aOhv9Gdkor15HApjzqamq/g+vMr9fsNyKWR8RkstM6C8n+pUBE7IiIb0TE0cC5wFWSPtnKWqyZHPRWVx+yc95bk/neG9r6AZMj5ApgjqQDkqPBzzSySWtqvB84R9LHkxOnc2n6/4N7gK+RfUP5jzp1bAd2SjoWuCLPGu4Dpks6LnmjqVt/H7J/4eyWNJbsG8x+m8lONR3dwL4fBIZL+jdJ3SV9HjiO7DRLa/yZ7NH/tZJ6SJpA9jUqS16ziyQdFBF7yD4n/wSQdI6kf03OxWwje16jsakyawMOeqvrFuDDwFvAM8Af2+lxLyJ7QrMa+B5wL9nP+9fnFlpYY0RUAl8mG96vA1vInixszP458scj4q2c9qvJhvAO4Pak5nxqeCgZw+NkpzUer9PlS8BcSTuA75IcHSfb7iJ7TuLJ5JMsH6uz72rgHLJ/9VQD1wLn1Km72SLiPbLBfibZ5/024OKIWJN0+QKwMZnCupzs6wnZk82PAjuBp4HbImJxa2qx5pPPi1hnJOleYE1EtPlfFGZp5yN66xQkjZH0L5I+lHz8cDLZuV4zayV/M9Y6i8OA/yR7YrQKuCIinu3YkszSwVM3ZmYp56kbM7OU63RTN/37948hQ4Z0dBlmZl3KihUr3oqIAfWt63RBP2TIECoqKjq6DDOzLkVS3W9E1/DUjZlZyjnozcxSzkFvZpZynW6O3sza3549e6iqqmL37t1Nd7YO1atXL4qLi+nRo0fe2+QV9Mk3Ff8P0A34eUR8v876HwETk8XewMCIODhZ90ey17J+IiLOybsyM2s3VVVV9OnThyFDhtDw78ZYR4sIqqurqaqqYujQoXlv12TQJ9f4nk/213CqgOWSypPLt+5/8Fk5/b8ClObs4may4X9Z3lWZWbvavXu3Q74LkMQhhxzC5s2bm7VdPnP0Y4F1EbE+uYJdGdnrkDRkGskv8ABExGNkr+5nZp2YQ75raMnrlE/QD6L2r+FUUfvXanILOAoYyvsvu9ooSZdKqpBU0dx3KjMza1yhP3UzFbg/+U3QvEXEgojIRERmwIB6v9hlZilWXV1NSUkJJSUlHHbYYQwaNKhm+b333mt024qKCr761a82+Rgnn3xyQWpdsmQJ55zTtU435nMydhO1f/asmIZ/lmwq2R91MDPL2yGHHMKqVasAmDNnDkVFRVx99dU16/fu3Uv37vXHVSaTIZPJNPkYTz31VEFq7YryOaJfDgyTNDT56bWpZH/Pspbkp9T6kv0VGTOzVpk+fTqXX34548aN49prr+Uvf/kLJ510EqWlpZx88smsXbsWqH2EPWfOHGbMmMGECRM4+uijufXWW2v2V1RUVNN/woQJXHDBBRx77LFcdNFF7L+K74MPPsixxx7L6NGj+epXv9rkkfvbb7/Neeedx8iRI/nYxz7Gc889B8Cf/vSnmr9ISktL2bFjB6+//jqnnnoqJSUlnHDCCSxbtqzgz1lDmjyij4i9kq4EFpH9eOUvI6JS0lygIiL2h/5UoCzqXPdY0jLgWKBIUhXw3yNiUUFHYWYFNWHC+9suvBC+9CXYtQvOOuv966dPz97eegsuuKD2uiVLWlZHVVUVTz31FN26dWP79u0sW7aM7t278+ijj/Ktb32L3/72t+/bZs2aNSxevJgdO3ZwzDHHcMUVV7zvM+fPPvsslZWVHHHEEYwfP54nn3ySTCbDZZddxtKlSxk6dCjTpk1rsr4bbriB0tJSFi5cyOOPP87FF1/MqlWrmDdvHvPnz2f8+PHs3LmTXr16sWDBAs444wyuv/569u3bx65du1r2pLRAXp+jj4gHyf7ocG7bd+ssz2lg21NaWpyZfbB97nOfo1u3bgBs27aNSy65hJdffhlJ7Nmzp95tzj77bHr27EnPnj0ZOHAgb775JsXFxbX6jB07tqatpKSEjRs3UlRUxNFHH13z+fRp06axYMGCRut74oknat5sPvGJT1BdXc327dsZP348V111FRdddBFTpkyhuLiYMWPGMGPGDPbs2cN5551HSUlJa56aZvE3Y83sfRo7Au/du/H1/fu3/Ai+ro985CM197/zne8wceJEfve737Fx40Ym1PdnB9CzZ8+a+926dWPv3r0t6tMas2fP5uyzz+bBBx9k/PjxLFq0iFNPPZWlS5fywAMPMH36dK666iouvvjigj5uQ3ytGzPrErZt28agQdlPdt95550F3/8xxxzD+vXr2bhxIwD33ntvk9uccsop3H333UB27r9///4ceOCBvPLKK4wYMYJvfvObjBkzhjVr1vDqq69y6KGHMnPmTL74xS+ycuXKgo+hIQ56M+sSrr32Wq677jpKS0sLfgQO8OEPf
|
|||
|
"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": "iVBORw0KGgoAAAANSUhEUgAAAr8AAACiCAYAAABIzqWCAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAEAAElEQVR4nOz9abQty3YWBn4zIjPX2s1pb/fufa0khCQwbRXIxgIzZExjmyGGBVggMGBsBsYwqkA2xi7AMkY2bgBBgYcQZRqBEGDTGCiVCygbMyjTmcamsDAC6T1ec997tzvNbtbKjIhZP+acETNzrb3POfeevZ/07o47zl1r58qMjGbGjC9mS8yMm3JTbspNuSk35abclJtyU94PJXyhG3BTbspNuSk35abclJtyU27KdZUb8HtTbspNuSk35abclJtyU9435Qb83pSbclNuyk25KTflptyU9025Ab835abclJtyU27KTbkpN+V9U27A7025KTflptyUm3JTbspNed+UG/B7U27KTbkpN+Wm3JSbclPeN+UG/F5zIaITIvrS533vE+r5ZiL6w++1npvy5EJEv5iI/spzrvMbiejPP+W9/y8i+kXP8/035XoLEf0MInqDiH7WF7otN+UHXnmePOa97A1E9BHdo+LzaMtN+eIvRPQHiOg3f6HbAfwABr9E9HEi+ilf6HY878LMx8z8fc/73pvSijJk+1eI6Nz9/Y1f6PY9a2Hm72Tmn/qU9/4MZv6DT3MvEf0lIvo33lvrbsqzlifQ5y8C8KsBfBWAX05EH3TP3czXD+BCRD+fiP4XncfX9SD6NV/odl1VYeZ/ontUBm7o0woRfQMR/XUiOiWiz+v3X0FE9IVu201p5Qcs+P1iK0TUfaHb8H4pypCPmfkYwD8B8DPdte/8Qrfvpry/yxPo8w8y809l5jeZ+acz86e/0O29KU8uRPRrAHwrgP8EwCsAPgLgvwLwdV/AZr2ncrNnPXshom8C8DsA/BcAPgChhV8O4J8FMHwBm3ZTFuUHBfhVNc//l4h+OxE9IKLvI6KfoNc/qaerX+Tu/5eI6O8Q0SP9/ZsX9f1rRPQJInqLiH6DlzITUSCiX0dE/1h//+NEdP+Stv2bRPSPiOhtIvozRPSa+42J6N8mou8F8L3u2g/R7y8Q0Z/Vdv5NIvrNXp21uPcPENHvJqL/JxE91tPkl7l7f4f29RER/S0i+omXtPmfJqL/WcfyfyWin/y0c/GDuRDRioi+lYg+o/++lYhW+tuOKnEx/v8iEf3vOvafJqJ/5ynf+ZVE9BeUPv4PIvq57renqnPZNqX9v0lED/XzJ7jfqvTFniOi/5KI3iGi7yein6G/fQuAnwjgd6mk6neRlN+u6+kREf09IvqnnnZ8b8p7LxetzX3zpdcvpK+bcj2FiO4A+E0A/m1m/pPMfMrMEzP/WWb+d/We98J7XtC95RER/Q0AX7a496lpgIi+hIj+J+U5fwHAi+63j+l7fykR/RMA/wPJfvjrSfbLzxPRd2h//f3dRfT5fiqODn4FM/+3zPyYpfwdZv5GZt7qfSvlyf+EiD5HRN9GRAf6208mok8R0TfpeL9ORL/Ev0Pn4A2dk19PREF/m5mw+Pm5oL0/lgQnPSai/4aI/hipSQIR3SOiP6fveUe/f8g9O9PM73n31zg+9kki+sXu1ffoYhxzffyMmX9A/gPwcQA/Rb//YgAJwC8BEAH8ZojE5HcDWAH4qQAeAzjW+38ygB8BAfc/EsDnAPws/e2HATgB8DWQk9h/CWBy7/q/APhrAD6kdf8eAN91QRu/FsCbAH6s3vt/B/CX3e8M4C8AuA/gwF37Ifr9j+q/Q23XJwH8lcXzdu8fAPAWgB8PoAPwnQD+qLv3FwB4QX/7JgCfBbDW374ZwB/W7x/Uev5FHZ9/Qf9+6Qs959dAR79J5/ZlAC8B+J8B/MeOxv7K4lk//q8D+In6/R6AH3vB+2o9AI50Tn+JzsuPUXr5Ye+hzvsA3gHwC7XOn6d/v6C//yUA/4Z7bgLwb0LWzb8F4DMAaHmv/v3TAPwtAHcBEET1/uoXeg6/mP8t6PPStblnvi6lr5t/1zaHPx2yP3WX3PNeeM8fBfDHdb7/KQCffloes6cdfxXAb4PsVz8Jsm/a3vAxfe93aL0HAP51AP8IwJcCOAbwJwH8ocX93T76fL/9exo60Pt+O4A/o7z8FoA/C+A/1d9+stbxmwD0ygvOANzT378DwH+nz30MwD8E8Ev1t2+2udw3P4s2DAA+AcE7PYB/BcAI4Dfr7y8A+HoINrkF4L8B8Kfd8x+H8q3luwF8VOnq52ndLwD40frbH8AFOOZZafm9/vtBIfnV8v3M/PtZ7Iv+GIAPA/hNzLxl5j8PmbgfAgDM/JeY+e8xc2Hm/w3AdwH457Senw3gzzLzX2HmEcBvhBCIlV8O4P/GzJ9iOal9M4CffcHp6RsB/D5m/tt6778P4J8hoo+5e/5TZn6bmc/9gyROAl8P4D9k5jNm/t8BPMlW808x899g5gQhmh9tPzDzH2bmt5g5MfNvhTC3r9hTxy8A8N3M/N06Pn8BwP8CWWRf7OUbITTzeWZ+A8B/BAGRT1MmAD+MiG4z8zvM/Lef4pl/GcDHlW4TM/8dAH8CwM95D3X+SwC+l5n/kNb5XQD+AYCfecH9n2Dm36vr5g8CeBWiiruoj7cAfCUEIH8PM7/+FG26Kc+nPOvafBJ93ZTrKS8AeFP58kXlXfEet0/8RhaJ8v8P833iqWmAiD4C4McB+A26b/5lCPBalm/Wd51ru38bM38fM59A9rhvuEia+D4vL2JBB076eU5EP4mICMAvA/CrFRc8hpjKfIOrZ4LQysTM3w0R1n2F0sI3APj3WaTKHwfwW/H0e5gv/zQEYP5Ofc+fBPA37EfFEn9CscljAN+ChqGeVH4+gL/IzN+ldb/FzH/X/X4RjrlWfvaDCfx+zn0/BwBmXl47BgAi+moi+h9VZP8QAmhNvfMa5HQBreMMchKx8lEAf0oJ9gGA7wGQsR8wvAY5PVldJ1rXB909n1w+pOUlCPF98inutfJZ9/0M2l8AIKJ/h4i+h0QV/gDAHTiVlisfBfBzrH9679dAQNEXe5nNl35/7YJ7l+XrISDkE6o2/Gee4pmPAvjqxVh/I8QW7N3WuewD9O8P7rkXcDSjtA44uvGFmf8HAL8LolH5PBF9OxHdfoo23ZTnU551bT6Jvm7K9ZS3ALz4BED4bnnPvn3C1/MsNPAagHeY+fSCuqz4d+1rd4eLD9Dv57JDB8z8E5j5rv4WIPN5COBvufn67/V6rWdxkLK9/kWIJHU5Hxfx/svKawA+zcxe8FfnnYgOiej3qGnFIwB/GcBderrIHh8G8I8v+f0iHHOt/OwHE/h9lvJHIGqFDzPzHQDfBlHjAqJq9rYrB5CTu5VPAvgZzHzX/VvzfseTz0AmzOo60rr8vbx8SMsbEPXGh9y1Dz9N55aFxL731wL4uRD1yF0AD9H67MsnIWor378jZv4t7+bdP8jKbL4gTimf0e+nEKYEACCi2YJj5r/JzF8HUVv+aYga8knlkwD+p8VYHzPzv/Ue6lz2wfrxbhyjdmiTmX8nM/+fIGY4PxTAv/su6r0p7648aW0u5+tS+rop11b+KoAtgJ91yT3vlvfYPuH3ho+4789CA69D7C2PLqjLiqezfe1OmAuj9j33fixGB5c5Ob4JEdT9cDdfd1icX59U3oRIhZfzYbx/Rke4HDS+DuCDKom24mnsmyCa469m5tsQExmgYYrL3vVJLOzSn7JcKz/7YgW/twC8zcwbIvrxEDG8lf8WwM8kcRoaIGYNngC+DcC3ENFHAYCIXiKii4j5uwD8EiL60STOC/8JgL+u6ohLi6qh/ySAb9ZT1lcC+NeeqZet3IIwpDcAdET0GwFcJLH7w5D+/zQiikS0JjGy/9AF938xle8C8Ot1Tl+EmLyYkf7/CuCH61yuIXQBACCigSTW7h1mngA8AlCe4n1/DsAPJaJfSES9/vtxRPRV76HO79Y6fz6Jo8m/CgGqf+4px8CXz0Fs+QAA2ravJ
|
|||
|
"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": "iVBORw0KGgoAAAANSUhEUgAAAr8AAACiCAYAAABIzqWCAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAACZTklEQVR4nOz9ebgk23rWB/6+tWLIYU81nPmee6/u1YDEaBokRqPGNDMND2AMCAwYmwczPG4QBuMGLGOwjW1A0ODGwmYGMc9N2wxu4JENQggkBAhJdz73jDXtKTNjWGt9/cdaERmZO3dVnXOqdtWpE289WTszMoYVESsj3njX+32fqCojRowYMWLEiBEjRnwYYJ50A0aMGDFixIgRI0aMuCqM5HfEiBEjRowYMWLEhwYj+R0xYsSIESNGjBjxocFIfkeMGDFixIgRI0Z8aDCS3xEjRowYMWLEiBEfGozkd8SIESNGjBgxYsSHBiP5vWKIyLmIfOJRz/uA9XyDiPyp97ueEQ+GiPxSEfmWR7zOrxORv/2Q8/5/ReSXPMrtj7haiMhPEZFbIvKznnRbRjx9eJTXmPdzbxCRj6Z7lH0UbRnx7ENE/piI/I4n3Q54ismviHxORH7Ck27Ho4aq7qnqZx71vCPWSBfk7hVEZDX4/HVPun3vFqr6p1X1Jz7kvD9FVf/4w8wrIn9fRP7D99e6Ee8WD+ifvwT4dcBXAr9SRF4ZLDeer6cYIvILReSfpvP4ZnoQ/TFPul2PC6r6hXSP8jD2zw4i8vNF5FtFZCEi76T3v0pE5Em3bcQaTy35fdYgItmTbsOHBemCvKeqe8AXgJ8xmPann3T7Rny48YD++cdV9Seq6m1V/cmq+vqTbu+IB0NEfj3wjcB/DbwAfBT4H4Gf+QSb9b4w3rPePUTk64HfB/z3wIvEvvArgR8NFE+waSO28IEgv2mY5/8Qkd8rIsci8hkR+VFp+mvp6eqXDOb/aSLyz0XkNH3/DVvr+/dF5PMickdEfutQZRYRIyL/mYh8On3/50Xk+n3a9h+JyKdE5K6I/HUReXnwnYrIrxaR7wO+bzDtS9P7GyLyN1I7v01EfsdwOGtr3j8mIn9QRP4/InKWniY/OZj396V9PRWRbxeRH3ufNv8IEfk/07H8ThH52oc9Fx9kiEgpIt8oIm+k1zeKSJm+uzCUuHX8f6qI/Ot07F8Xkd/wkNv8fiLyd1L/+B4R+XmD7x5qndttS33/20TkJP39UYPvevWlW05E/gcRuScinxWRn5K++53AjwX+QFKq/oBE/N70ezoVke8SkR/wsMd3xPvHZb/NXecrTb+0f424GojIIfDbgV+tqn9ZVReq2qrq31DV/zTN836uPTfSveVURP4J8MmteR+6D4jIl4jIP0jXnL8D3Bx89/G03V8uIl8A/neJ98PfIvF++Y6I/Im0v8P5s8v654cJg37wq1T1L6rqmUb8c1X9OlWt03xluiZ/QUTeFpE/JCLT9N3XisgXReTr0/F+U0R+2XAb6RzcSufkt4iISd9tWFiG5+eS9v5QiTzpTET+goj8OUmWBBG5JiJ/M23nXnr/kcGyGyPzO7b9YwbXsddE5JcONn1NLucxV3c9U9Wn8gV8DvgJ6f0vBRzwywAL/A6iYvIHgRL4icAZsJfm/1rgBxLJ/Q8C3gZ+Vvruq4Bz4McQn8T+B6AdbOs/Af4x8JG07v8J+OZL2vjjgdvAD03z/r+Afzj4XoG/A1wHpoNpX5re/9n0mqV2vQZ8y9by3bx/DLgDfDWQAX8a+LODeX8RcCN99/XAW8AkffcNwJ9K719J6/mp6fj839Ln5570Ob+CfvTb07l9HngO+D+B/2rQx75la9nh8X8T+LHp/TXgh16yvX49wDyd01+Wzsu/lfrLV72PdV4H7gG/OK3zF6TPN9L3fx/4DwfLtcB/RPzd/MfAG4Bsz5s+/yTg24EjQIhD7y896XP4LL+2+ud9f5s7ztd9+9f4urJz+JOJ96fsPvO8n2vPnwX+fDrfPwB4/WGvMTva8Y+A30O8X/3bxPtmd2/4eNrun0jrnQL/AfAp4BPAHvCXgT+5NX+2q39+2F4P0w/SfL8X+OvpWr4P/A3gv0nffW1ax28H8nQtWALX0vd/AvhrabmPA98L/PL03Td053LX+dlqQwF8nsh3cuBnAw3wO9L3N4CfQ+Qm+8BfAP7qYPnPka5b29sGPpb61S9I674B/JD03R/jEh7zbvvy+319IJTfhM+q6h/V6C/6c8CrwG9X1VpV/zbxxH0pgKr+fVX9LlUNqvovgG8Gflxaz88F/oaqfouqNsBvI3aQDr8S+H+q6hc1Pql9A/BzL3l6+jrgj6jqP0vz/mbgR4rIxwfz/DeqeldVV8MFJQYJ/Bzgv1DVpar+a+BBXs2/oqr/RFUdsdP8kO4LVf1TqnpHVZ2q/m7ixe0rdqzjFwF/S1X/Vjo+fwf4p8Qf2bOOryP2mXdU9RbwXxJJ5MOgBb5KRA5U9Z6q/rOHWOanA59L/dap6j8H/hLw776Pdf404PtU9U+mdX4z8G+An3HJ/J9X1T+cfjd/HHiJOBR32T7uA9+PSJC/W1XffIg2jXg0eLe/zQf1rxFXgxvA7XRdvgzv6dozuE/8No2K8r9k8z7x0H1ARD4K/HDgt6b75j8kEq9tfEPa1iq1+/eo6mdU9Zx4j/v5l6mJH3LcZKsfDNTPlYj82yIiwK8Afl3iBWdEq8zPH6ynJfaVVlX/FlGs+4rUF34+8Js1qsqfA343D38PG+JHEAnm70/b+cvAP+m+TFziLyVucgb8TtYc6kH4hcDfVdVvTuu+o6rfMfj+Mh5zpdezDxL5fXvwfgWgqtvT9gBE5GtE5P+XJPsTIqHthndeJj5dkNaxJD6JdPgY8FdShz0Gvhvw7CYMLxOfnrp1nad1vTKY57XthRKeI3a+1x5i3g5vDd4vSfsLICK/QUS+W+JQ+DFwyGBIa4CPAf9ut39p3h9DJEXPOjbOV3r/8iXzbuPnEEnI59Ow4Y98iGU+BnzN1rH+OqIX7L2uc3sfSJ9f2TEvDPpM6usw6DdDqOr/DvwB4ojKOyLyTSJy8BBtGvFo8G5/mw/qXyOuBneAmw8ghO/12rPrPjFcz7vpAy8D91R1ccm6Ogy3tavdGZc/QH+YcaEfqOqPUtWj9J0hns8Z8O2D8/W/pun9erYepLp7/U2ikrp9Pi679t8PLwOvq+pQ+OvPu4jMROR/StaKU+AfAkfycJk9XgU+fZ/vL+MxV3o9+yCR33eDP0McVnhVVQ+BP0QcxoU41Dz0rkyJT+4dXgN+iqoeDV4T3R148gbxhHXrmqd1DefV7YUSbhGHNz4ymPbqw+zcNiT6e38j8POIwyNHwAnrfR7iNeKw1XD/5qr6376XbX/AsHG+iEEpb6T3C+JFCQAR2fjBqeq3qerPJA5b/lXiMOSD8BrwD7aO9Z6q/sfvY53b+9Dtx3sJjLrQN1X196vq/4Vow/ly4D99D+sd8d7woN/m9vm6b/8acWX4R0AN/Kz7zPNerz3dfWJ4b/jo4P276QNvEv2W80vW1WHYz3a127EpRu1a7sOIrh/cL8jxNlGo+/6D83WoMfj1QbhNVIW3z0d37d/oR9yfNL4JvJKU6A7DPvb1xJHjr1HVA6JFBtac4n7beo0tX/pD4kqvZ88q+d0H7qpqJSJfTZThO/xF4GdIDBoqiLaGYQf4Q8DvFJGPAYjIcyJyWWf+ZuCXicgPkRi88F8D35qGI+6LNAz9l4FvSE9Z3w/499/VXq6xT7wg3QIyEfltwGWK3Z8i7v9PEhErIhOJJvuPXDL/s4RvBn5LOqc3iZaXzqT/ncD3T+dyQuwXAIhIITHX7qGqtsApEB5ie38T+HIR+cUikqfXDxeRr3wf6/xbaZ2/UGKgyb9HJKp/8yGPwRBvE718AKS2fY2I5MSLW/WQbRrxaPCg3+bG+eI+/evKW/4hhqqeEK8lf1BEfla6nucS8zX/d2m293Tt2XGf+CpgmMf7ofuAqn6eaKP5L9P158dwuV2qwzcDv05ioNwe8R735y6xeGz3zw8VVPWYa
|
|||
|
"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"
|
|||
|
}
|
|||
|
],
|
|||
|
"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
|
|||
|
}
|