TP-reseaux-profond/TP1.ipynb
2023-06-22 20:35:38 +02:00

2105 lines
303 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "5b3pjAUEk2LQ"
},
"source": [
"# Construire et entraîner un perceptron multi-couches - étape par étape\n",
"\n",
"Dans ce TP, vous allez mettre en œuvre l'entraînement d'un réseau de neurones (perceptron multi-couches) à l'aide de la librairie **numpy**. Pour cela nous allons procéder par étapes successives. Dans un premier temps nous allons traiter le cas d'un perceptron mono-couche, en commençant par la passe _forward_ de prédiction d'une sortie à partir d'une entrée et des paramètres du perceptron, puis en implémentant la passe _backward_ de calcul des gradients de la fonction objectif par rapport aux paramètrès. A partir de là, nous pourrons tester l'entraînement à l'aide de la descente de gradient stochastique.\n",
"\n",
"Une fois ces étapes achevées, nous pourrons nous atteler à la construction d'un perceptron multi-couches, qui consistera pour l'essentiel en la composition de perceptrons mono-couche.\n",
"\n",
"Dans ce qui suit, nous adoptons les conventions de notation suivantes :\n",
"\n",
"- $(x, y)$ désignent un couple donnée/label de la base d'apprentissage ; $\\hat{y}$ désigne quant à lui la prédiction du modèle sur la donnée $x$.\n",
"\n",
"- L'indice $i$ indique la $i^{\\text{ème}}$ dimension d'un vecteur ⇒ $a_i$\n",
"\n",
"- L'exposant $(k)$ désigne un objet associé au $k^{\\text{ème}}$ exemple ⇒ $a_i^{(k)}$\n",
"\n",
"- L'exposant $[l]$ désigne un objet associé à la $l^{\\text{ème}}$ couche ⇒ $a_i^{(k)[l]}$\n",
"\n",
"Exemple:\n",
"\n",
"- $a_5^{(2)[3]}$ indique la $5^{\\text{ème}}$ dimension du vecteur d'activation du $2^{\\text{ème}}$ exemple d'entraînement (2), de la $3^{\\text{ème}}$ couche [3].\n",
"\n",
"Commençons par importer tous les modules nécessaires :\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"id": "R6LBs_NLla1a"
},
"outputs": [],
"source": [
"import numpy as np\n",
"import math\n",
"import matplotlib.pyplot as plt\n",
"\n",
"from sklearn.model_selection import train_test_split\n",
"from sklearn import datasets\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "3JZIXefJlXSV"
},
"source": [
"# Perceptron mono-couche\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "azdcz3QV_k-r"
},
"source": [
"### Perceptron mono-couche - passe _forward_\n",
"\n",
"Un perceptron mono-couche est un modèle liant une couche d'entrée (en vert, qui n'effectue pas d'opération) à une couche de sortie. Les neurones des deux couches sont connectés par des liaisons pondérées (les poids synaptiques) $W_{xy}$, et les neurones de la couche de sortie portent chacun un biais additif $b_y$. Enfin, une fonction d'activation $f$ est appliquée à l'issue de ces opérations pour obtenir la prédiction du réseau $\\hat{y}$.\n",
"\n",
"On a donc :\n",
"\n",
"$$\\hat{y} = f ( W_{xy} x + b_y )$$\n",
"\n",
"On posera pour la suite :\n",
"$$ z = W\\_{xy} x + b_y $$\n",
"\n",
"La figure montre une représentation de ces opérations sous forme de réseau de neurones (à gauche), mais aussi sous une forme fonctionnelle (à droite) qui permet de bien visualiser l'ordre des opérations.\n",
"\n",
"<img src=\"https://drive.google.com/uc?id=1RZeiaKue0GLXJr3HRtKkuP6GD8r6I1_Q\" height=300>\n",
"<img src=\"https://drive.google.com/uc?id=1dnQ6SSdpEX1GDTgoNTrUwA3xjiP9rTYU\" height=250>\n",
"\n",
"Notez que les paramètres du perceptron, que nous allons ajuster par un processus d'optimisation, sont donc les poids synaptiques $W_{xy}$ et les biais $b_y$. Par commodité dans le code, nous considérerons également comme un paramètre le choix de la fonction d'activation.\n",
"\n",
"**Remarque importante** : En pratique, on traite souvent les données par _batch_, c'est-à-dire que les prédictions sont faites pour plusieurs données simultanément. Ici pour une taille de _batch_ de $m$, cela signifie en fait que :\n",
"\n",
"$$ x \\in \\mathbb{R}^{4 \\times m} \\text{ et } y \\in \\mathbb{R}^{5 \\times m}$$\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "RBtX2euQDSCS"
},
"source": [
"Complétez la fonction _dense_layer_forward_ qui calcule la prédiction d'un perceptron mono-couche pour une entrée $x$.\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"id": "YGYbWrRfmIwx"
},
"outputs": [],
"source": [
"def dense_layer_forward(x, Wxy, by, activation):\n",
" \"\"\"\n",
" Réalise une unique étape forward de la couche dense telle que décrite dans la figure précédente\n",
"\n",
" Arguments:\n",
" x -- l'entrée, tableau numpy de dimension (n_x, m).\n",
" Wxy -- Matrice de poids multipliant l'entrée, tableau numpy de shape (n_y, n_x)\n",
" by -- Biais additif ajouté à la sortie, tableau numpy de dimension (n_y, 1)\n",
" activation -- Chaîne de caractère désignant la fonction d'activation choisie : 'linear', 'sigmoid' ou 'relu'\n",
"\n",
" Retourne :\n",
" y_pred -- prédiction, tableau numpy de dimension (n_y, m)\n",
" cache -- tuple des valeurs utiles pour la passe backward (rétropropagation du gradient), contient (x, z)\n",
" \"\"\"\n",
"\n",
" # calcul de z\n",
" z = np.matmul(Wxy, x) + by\n",
" # calcul de la sortie en appliquant la fonction d'activation\n",
" if activation == \"relu\":\n",
" y_pred = np.where(z > 0, z, 0)\n",
" elif activation == \"sigmoid\":\n",
" y_pred = 1 / (1 + np.exp(-z))\n",
" elif activation == \"linear\":\n",
" y_pred = z\n",
" else:\n",
" print(\"Erreur : la fonction d'activation n'est pas implémentée.\")\n",
"\n",
" # sauvegarde du cache pour la passe backward\n",
" cache = (x, z)\n",
"\n",
" return y_pred, cache\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "1dCFTHOqD_Tp"
},
"source": [
"Exécutez les lignes suivantes pour vérifier la validité de votre code :\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"id": "B6wlVU37on1k"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"y_pred.shape = \n",
" (2, 10)\n",
"----------------------------\n",
"activation relu : y_pred[1] =\n",
" [0. 2.11983968 0.88583246 1.39272594 0. 2.92664609\n",
" 0. 1.47890228 0. 0.04725575]\n",
"----------------------------\n",
"activation sigmoid : y_pred[1] =\n",
" [0.10851642 0.89281659 0.70802939 0.80102707 0.21934644 0.94914804\n",
" 0.24545321 0.81440672 0.48495927 0.51181174]\n",
"----------------------------\n",
"activation linear : y_pred[1] =\n",
" [-2.10598556 2.11983968 0.88583246 1.39272594 -1.26947904 2.92664609\n",
" -1.12301093 1.47890228 -0.06018107 0.04725575]\n"
]
}
],
"source": [
"np.random.seed(1)\n",
"x_tmp = np.random.randn(3, 10)\n",
"Wxy = np.random.randn(2, 3)\n",
"by = np.random.randn(2, 1)\n",
"\n",
"activation = \"relu\"\n",
"y_pred_tmp, cache_tmp = dense_layer_forward(x_tmp, Wxy, by, activation)\n",
"print(\"y_pred.shape = \\n\", y_pred_tmp.shape)\n",
"\n",
"print(\"----------------------------\")\n",
"\n",
"print(\"activation relu : y_pred[1] =\\n\", y_pred_tmp[1])\n",
"\n",
"print(\"----------------------------\")\n",
"\n",
"activation = \"sigmoid\"\n",
"y_pred_tmp, cache_tmp = dense_layer_forward(x_tmp, Wxy, by, activation)\n",
"print(\"activation sigmoid : y_pred[1] =\\n\", y_pred_tmp[1])\n",
"\n",
"print(\"----------------------------\")\n",
"\n",
"activation = \"linear\"\n",
"y_pred_tmp, cache_tmp = dense_layer_forward(x_tmp, Wxy, by, activation)\n",
"print(\"activation linear : y_pred[1] =\\n\", y_pred_tmp[1])\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "YYbiDw8TptiN"
},
"source": [
"**Affichage attendu**:\n",
"\n",
"```Python\n",
"y_pred.shape =\n",
" (2, 10)\n",
"----------------------------\n",
"activation relu : y_pred[1] =\n",
" [0. 2.11983968 0.88583246 1.39272594 0. 2.92664609\n",
" 0. 1.47890228 0. 0.04725575]\n",
"----------------------------\n",
"activation sigmoid : y_pred[1] =\n",
" [0.10851642 0.89281659 0.70802939 0.80102707 0.21934644 0.94914804\n",
" 0.24545321 0.81440672 0.48495927 0.51181174]\n",
"----------------------------\n",
"activation linear : y_pred[1] =\n",
" [-2.10598556 2.11983968 0.88583246 1.39272594 -1.26947904 2.92664609\n",
" -1.12301093 1.47890228 -0.06018107 0.04725575]\n",
"\n",
"```\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "GypgZ8jBqooR"
},
"source": [
"### Perceptron mono-couche - passe _backward_\n",
"\n",
"Dans les librairies d'apprentissage profond actuelles, il suffit d'implémenter la passe _forward_, et la passe _backward_ est réalisée automatiquement, avec le calcul des gradients (différentiation automatique) et la mise à jour des paramètres. Il est cependant intéressant de comprendre comment fonctionne la passe _backward_, en l'implémentant sur un exemple simple.\n",
"\n",
"<img src=\"https://drive.google.com/uc?id=1MC8Nxu6BQnpB7cGLwunIbgx9s1FaGw81\" height=350>\n",
"\n",
"Il faut calculer les dérivées de la fonction objectif par rapport aux différents paramètres, pour ensuite mettre à jour ces derniers pendant la descente de gradient. Les équations de calcul des gradients sont données ci-dessous (c'est un bon exercice que de les calculer à la main).\n",
"\n",
"\\begin{align}\n",
"\\displaystyle dx &= \\frac{\\partial J}{\\partial x} &= { W*{xy}}^T \\: \\left( d\\hat{y} * \\frac{\\partial \\hat{y}}{\\partial z} \\right) \\\\[8pt]\n",
"\\displaystyle {dW*{xy}} &= \\frac{\\partial J}{\\partial W*{xy}} &= \\left( d\\hat{y} * \\frac{\\partial \\hat{y}}{\\partial z} \\right) \\: x^{T} \\\\[8pt]\n",
"\\displaystyle db*{y} &= \\frac{\\partial J}{\\partial b*y} &= \\sum*{batch} \\left( d\\hat{y} * \\frac{\\partial \\hat{y}}{\\partial z} \\right) \\\\[8pt]\n",
"\\end{align}\n",
"\n",
"Ici, $*$ indique une multiplication élément par élément tandis que l'absence de symbole indique une multiplication matricielle. Par ailleurs $d\\hat{y}$ désigne $\\frac{\\partial J}{\\partial \\hat{y}}$, $dW_{xy}$ désigne $\\frac{\\partial J}{\\partial W_{xy}}$, $db_y$ désigne $\\frac{\\partial J}{\\partial b_y}$ et $dx$ désigne $\\frac{\\partial J}{\\partial x}$ (ces noms ont été choisis pour être utilisables dans le code).\n",
"\n",
"Il vous reste à déterminer, par vous même, le terme $\\frac{\\partial \\hat{y}}{\\partial z}$, qui constitue en fait la dérivée de la fonction d'activation évaluée en $z$. Par exemple, pour la fonction d'activation linéaire (l'identité), la dérivée est égale à 1 pour tout $z$. A vous de déterminer, et d'implémenter, la dérivée des fonctions _sigmoid_ et _relu_. **Attention aux dimensions : $\\frac{\\partial \\hat{y}}{\\partial z}$ est de même dimension que $z$ et $\\hat{y}$ !**\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"id": "wEi_y3W_rCMc"
},
"outputs": [],
"source": [
"def dense_layer_backward(dy_hat, Wxy, by, activation, cache):\n",
" \"\"\"\n",
" Implémente la passe backward de la couche dense.\n",
"\n",
" Arguments :\n",
" dy_hat -- Gradient de la fonction objectif par rapport à la sortie ŷ, de dimension (n_y, m)\n",
" Wxy -- Matrice de poids multipliant l'entrée, tableau numpy de shape (n_y, n_x)\n",
" by -- Biais additif ajouté à la sortie, tableau numpy de dimension (n_y, 1)\n",
" cache -- dictionnaire python contenant des variables utiles (issu de dense_layer_forward())\n",
"\n",
" Retourne :\n",
" gradients -- dictionnaire python contenant les gradients suivants :\n",
" dx -- Gradient de la fonction objectif par rapport aux entrées, de dimension (n_x, m)\n",
" dby -- Gradient de la fonction objectif par rapport aux biais, de dimension (n_y, 1)\n",
" dWxy -- Gradient de la fonction objectif par rapport aux poids synaptiques Wxy, de dimension (n_y, n_x)\n",
" \"\"\"\n",
"\n",
" # Récupérer les informations du cache\n",
" (x, z) = cache\n",
"\n",
" # calcul de la sortie en appliquant l'activation\n",
" if activation == \"relu\":\n",
" dyhat_dz = np.where(z > 0, 1, 0)\n",
" elif activation == \"sigmoid\":\n",
" dyhat_dz = 1 / (1 + np.exp(-z)) * (1 - 1 / (1 + np.exp(-z)))\n",
" elif activation == \"linear\":\n",
" dyhat_dz = np.ones(z.shape)\n",
" else:\n",
" print(\"Erreur : la fonction d'activation n'est pas implémentée.\")\n",
"\n",
" # calculer le gradient de la perte par rapport à x\n",
" dx = np.matmul(Wxy.T, dy_hat * dyhat_dz)\n",
"\n",
" # calculer le gradient de la perte par rapport à Wxy\n",
" dWxy = np.matmul(dy_hat * dyhat_dz, x.T)\n",
"\n",
" # calculer le gradient de la perte par rapport à by\n",
" # Attention, dby doit être de dimension (n_y, 1), pensez à positionner l'attribut\n",
" # keepdims de la fonction numpy.sum() à True !\n",
" dby = np.sum(dy_hat * dyhat_dz, axis=1, keepdims=True)\n",
"\n",
" # Stocker les gradients dans un dictionnaire\n",
" gradients = {\"dx\": dx, \"dby\": dby, \"dWxy\": dWxy}\n",
"\n",
" return gradients\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "qQGZTgx20JVm"
},
"source": [
"Exécutez la cellule suivante pour vérifier la validité de votre code :\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"id": "gGxKksOd0N2F"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"dimensions des différents gradients :\n",
"dx : (3, 10)\n",
"dby : (2, 1)\n",
"dWxy : (2, 3)\n",
"----------------------------\n",
"activation relu : gradients =\n",
" {'dx': array([[ 0. , -0.52166355, -0.25370565, 0.29772356, 0. ,\n",
" -0.87533798, 0. , -0.05523234, 0. , -0.78697273],\n",
" [ 0. , -0.4142952 , -0.20148817, 0.23644635, 0. ,\n",
" -0.43699238, 0. , -0.14103828, 0. , -0.62499867],\n",
" [ 0. , -0.00781663, -0.00380154, 0.0044611 , 0. ,\n",
" -1.15858431, 0. , 0.43029667, 0. , -0.01179203]]), 'dby': array([[1.05545895],\n",
" [1.73350613]]), 'dWxy': array([[-3.41036427, -1.30232405, -0.56109731],\n",
" [-0.03287152, -0.82109488, 0.98388063]])}\n",
"----------------------------\n",
"activation sigmoid : gradients =\n",
" {'dx': array([[-0.12452463, -0.16508708, -0.02939735, 0.18918939, 0.19365898,\n",
" -0.17366309, 0.02947078, 0.03090249, -0.20097835, -0.40773826],\n",
" [-0.07359731, -0.10570831, -0.02843055, 0.1189895 , 0.14755739,\n",
" -0.09647417, 0.02411729, 0.00119749, -0.15435059, -0.27725739],\n",
" [-0.1141027 , -0.11516714, 0.02211421, 0.14152872, 0.03059908,\n",
" -0.18648155, -0.00271799, 0.10403474, -0.02635951, -0.21268142]]), 'dby': array([[0.51620418],\n",
" [0.3562789 ]]), 'dWxy': array([[-0.19619895, -0.04346631, -0.0522999 ],\n",
" [-0.2464412 , -0.23312061, -0.09313104]])}\n",
"----------------------------\n",
"activation linear : gradients =\n",
" {'dx': array([[-1.24957905, -1.03490637, -0.12102053, 0.91166167, 1.48244289,\n",
" -0.87533798, 0.14141685, -0.05523234, -0.84116226, -2.23963678],\n",
" [-0.7391886 , -0.70870384, -0.12537673, 0.58861627, 1.06334861,\n",
" -0.43699238, 0.12006129, -0.14103828, -0.63891076, -1.4582823 ],\n",
" [-1.14209251, -0.51772912, 0.12802262, 0.61441549, 0.52789632,\n",
" -1.15858431, -0.03226814, 0.43029667, -0.1418173 , -1.45503003]]), 'dby': array([[3.97266086],\n",
" [1.34123607]]), 'dWxy': array([[-1.13528086, 0.37477333, -1.77404551],\n",
" [-0.92324845, -1.86932585, -0.37669553]])}\n"
]
}
],
"source": [
"np.random.seed(1)\n",
"x_tmp = np.random.randn(3, 10)\n",
"Wxy = np.random.randn(2, 3)\n",
"by = np.random.randn(2, 1)\n",
"dy_hat = np.random.randn(2, 10)\n",
"activation = \"relu\"\n",
"y_pred_tmp, cache_tmp = dense_layer_forward(x_tmp, Wxy, by, activation)\n",
"gradients = dense_layer_backward(dy_hat, Wxy, by, activation, cache_tmp)\n",
"print(\"dimensions des différents gradients :\")\n",
"print(\"dx : \", gradients[\"dx\"].shape)\n",
"print(\"dby : \", gradients[\"dby\"].shape)\n",
"print(\"dWxy : \", gradients[\"dWxy\"].shape)\n",
"\n",
"print(\"----------------------------\")\n",
"\n",
"print(\"activation relu : gradients =\\n\", gradients)\n",
"\n",
"print(\"----------------------------\")\n",
"\n",
"activation = \"sigmoid\"\n",
"gradients = dense_layer_backward(dy_hat, Wxy, by, activation, cache_tmp)\n",
"print(\"activation sigmoid : gradients =\\n\", gradients)\n",
"\n",
"print(\"----------------------------\")\n",
"\n",
"activation = \"linear\"\n",
"gradients = dense_layer_backward(dy_hat, Wxy, by, activation, cache_tmp)\n",
"print(\"activation linear : gradients =\\n\", gradients)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5-_jk20X0QIt"
},
"source": [
"**Affichage attendu**:\n",
"\n",
"```Python\n",
"dimensions des différents gradients :\n",
"dx : (3, 10)\n",
"dby : (2, 1)\n",
"dWxy : (2, 3)\n",
"----------------------------\n",
"activation relu : gradients =\n",
" {'dx': array([[ 0. , -0.52166355, -0.25370565, 0.29772356, 0. ,\n",
" -0.87533798, 0. , -0.05523234, 0. , -0.78697273],\n",
" [ 0. , -0.4142952 , -0.20148817, 0.23644635, 0. ,\n",
" -0.43699238, 0. , -0.14103828, 0. , -0.62499867],\n",
" [ 0. , -0.00781663, -0.00380154, 0.0044611 , 0. ,\n",
" -1.15858431, 0. , 0.43029667, 0. , -0.01179203]]), 'dby': array([[1.05545895],\n",
" [1.73350613]]), 'dWxy': array([[-3.41036427, -1.30232405, -0.56109731],\n",
" [-0.03287152, -0.82109488, 0.98388063]])}\n",
"----------------------------\n",
"activation sigmoid : gradients =\n",
" {'dx': array([[-0.12452463, -0.16508708, -0.02939735, 0.18918939, 0.19365898,\n",
" -0.17366309, 0.02947078, 0.03090249, -0.20097835, -0.40773826],\n",
" [-0.07359731, -0.10570831, -0.02843055, 0.1189895 , 0.14755739,\n",
" -0.09647417, 0.02411729, 0.00119749, -0.15435059, -0.27725739],\n",
" [-0.1141027 , -0.11516714, 0.02211421, 0.14152872, 0.03059908,\n",
" -0.18648155, -0.00271799, 0.10403474, -0.02635951, -0.21268142]]), 'dby': array([[0.51620418],\n",
" [0.3562789 ]]), 'dWxy': array([[-0.19619895, -0.04346631, -0.0522999 ],\n",
" [-0.2464412 , -0.23312061, -0.09313104]])}\n",
"----------------------------\n",
"activation linear : gradients =\n",
" {'dx': array([[-1.24957905, -1.03490637, -0.12102053, 0.91166167, 1.48244289,\n",
" -0.87533798, 0.14141685, -0.05523234, -0.84116226, -2.23963678],\n",
" [-0.7391886 , -0.70870384, -0.12537673, 0.58861627, 1.06334861,\n",
" -0.43699238, 0.12006129, -0.14103828, -0.63891076, -1.4582823 ],\n",
" [-1.14209251, -0.51772912, 0.12802262, 0.61441549, 0.52789632,\n",
" -1.15858431, -0.03226814, 0.43029667, -0.1418173 , -1.45503003]]), 'dby': array([[3.97266086],\n",
" [1.34123607]]), 'dWxy': array([[-1.13528086, 0.37477333, -1.77404551],\n",
" [-0.92324845, -1.86932585, -0.37669553]])}\n",
"\n",
"```\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "E5KeDgyO-ZPJ"
},
"source": [
"On peut maintenant créer une classe _DenseLayer_, qui comprend en attribut toutes les informations nécessaires à la description d'une couche dense, c'est-à-dire :\n",
"\n",
"- Le nombre de neurones en entrée de la couche dense (input_size)\n",
"- Le nombre de neurones en sortie de la couche dense (output_size)\n",
"- La fonction d'activation choisie sur cette couche (activation)\n",
"- Les poids synaptiques de la couche dense, stockés dans une matrice de taille (output_size, input_size) (Wxy)\n",
"- Les biais de la couche dense, stockés dans un vecteur de taille (output_size, 1) (by)\n",
"\n",
"On ajoute également un attribut cache qui permettra de stocker les entrées de la couche dense (x) ainsi que les calculs intermédiaires (z) réalisés lors de la passe _forward_, afin d'être réutilisés pour la basse _backward_.\n",
"\n",
"A vous de compléter les 4 jalons suivants :\n",
"\n",
"- **L'initialisation des paramètres** Wxy et by : Wxy doit être positionnée suivant [l'initialisation de Glorot](https://www.tensorflow.org/api_docs/python/tf/keras/initializers/GlorotUniform), et by est initialisée par un vecteur de zéros de taille (output_size, 1).\n",
"- **La fonction _forward_**, qui consiste simplement en un appel de la fonction _dense_layer_forward_ implémentée précédemment.\n",
"- **La fonction _backward_**, qui consiste simplement en un appel de la fonction _dense_layer_backward_ implémentée précédemment.\n",
"- Et enfin **la fonction _update_parameters_** qui applique la mise à jour de la descente de gradient en fonction d'un taux d'apprentissage (_learning_rate_) et des gradients calculés dans la passe _forward_.\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"id": "u2K9dp1IL3yM"
},
"outputs": [],
"source": [
"class DenseLayer:\n",
" def __init__(self, input_size, output_size, activation):\n",
" self.input_size = input_size\n",
" self.output_size = output_size\n",
" self.activation = activation\n",
" self.cache = None # Le cache sera mis à jour lors de la passe forward\n",
" limit = np.sqrt(6 / (input_size + output_size))\n",
" self.Wxy = np.random.uniform(-limit, limit, (output_size, input_size))\n",
" self.by = np.zeros((output_size, 1))\n",
"\n",
" def forward(self, x_batch):\n",
" y, cache = dense_layer_forward(x_batch, self.Wxy, self.by, self.activation)\n",
" self.cache = cache\n",
" return y\n",
"\n",
" def backward(self, dy_hat):\n",
" return dense_layer_backward(\n",
" dy_hat, self.Wxy, self.by, self.activation, self.cache\n",
" )\n",
"\n",
" def update_parameters(self, gradients, learning_rate):\n",
" self.Wxy -= learning_rate * gradients[\"dWxy\"]\n",
" self.by -= learning_rate * gradients[\"dby\"]\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "9GlEB8K3Lani"
},
"source": [
"### Fonction de coût : erreur quadratique moyenne\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2KMcQzlskdI1"
},
"source": [
"Pour entraîner notre modèle, nous devons mettre en place un optimiseur. Nous implémenterons la descente de gradient stochastique avec mini-batch. Il nous faut cependant au préalable implanter la fonction de coût que nous utiliserons pour évaluer la qualité de nos prédictions.\n",
"\n",
"Pour le moment, nous allons nous contenter d'une erreur quadratique moyenne, qui associée à une fonction d'activation linéaire (l'identité) permet de résoudre les problèmes de régression.\n",
"\n",
"La fonction de coût prend en entrée deux paramètres : la vérité-terrain _y_true_ et la prédiction du modèle _y_pred_ ($\\hat{y}$). Ces deux matrices sont de dimension $output\\_ size \\times bs$. La fonction retourne deux grandeurs : _loss_ qui correspond à l'erreur quadratique moyenne des prédictions par rapport aux vérités-terrains, et $d\\hat{y}$ au gradient de l'erreur quadratique moyenne par rapport aux prédictions. Autrement dit :\n",
"$$ d\\hat{y} = \\frac{\\partial J\\_{mb}}{\\partial \\hat{y}}$$\n",
"\n",
"où $\\hat{y}$ correspond à _y_pred_, et $J_{mb}$ à la fonction objectif calculée sur un mini-batch $mb$ de données.\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"id": "FRDUnhJma6jf"
},
"outputs": [],
"source": [
"def mean_square_error(y_true, y_pred):\n",
" \"\"\"\n",
" Erreur quadratique moyenne entre prédiction et vérité-terrain\n",
"\n",
" Arguments :\n",
" y_true -- labels à prédire (vérité-terrain), de dimension (m, n_y)\n",
" y_pred -- prédictions du modèle, de dimension (m, n_y)\n",
" Retourne :\n",
" loss -- l'erreur quadratique moyenne entre y_true et y_pred, scalaire\n",
" dy_hat -- dérivée partielle de la fonction objectif par rapport à y_pred, de dimension (m, n_y)\n",
" \"\"\"\n",
" batch_size = y_true.shape[0]\n",
" loss = np.mean(np.square(y_true - y_pred))\n",
" dy_hat = -2 * (y_true - y_pred) / batch_size\n",
" return loss, dy_hat\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "eNbVKV5K0hWp"
},
"source": [
"Testez votre implémentation avec ce bloc de code :\n"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"id": "Wt-ensXM0jL1"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"loss = 2.0281433227730186\n",
"dy_hat = \n",
" [[-0.46320122 0.04300058 -0.03180019]\n",
" [ 0.0455526 -0.30733075 0.45777482]\n",
" [-0.57242442 0.19912452 0.26815262]\n",
" [ 0.19828291 -0.3307887 0.23450235]\n",
" [-0.08494822 0.41530179 -0.21659234]\n",
" [ 0.09257912 0.07266874 0.59562271]\n",
" [ 0.01558904 0.00687758 0.2801579 ]\n",
" [-0.29939471 -0.40882178 -0.17036741]\n",
" [-0.22195004 0.25407021 0.19237473]\n",
" [ 0.3733743 0.11069508 0.07095714]]\n"
]
}
],
"source": [
"np.random.seed(1)\n",
"y_true = np.random.randn(10, 3)\n",
"y_pred = np.random.randn(10, 3)\n",
"\n",
"loss, dy_hat = mean_square_error(y_true, y_pred)\n",
"print(\"loss = \", loss)\n",
"print(\"dy_hat = \\n\", dy_hat)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2RcgS5JJ0lcY"
},
"source": [
"**Affichage attendu**:\n",
"\n",
"```Python\n",
"loss = 2.0281433227730186\n",
"dy_hat =\n",
" [[-0.46320122 0.04300058 -0.03180019]\n",
" [ 0.0455526 -0.30733075 0.45777482]\n",
" [-0.57242442 0.19912452 0.26815262]\n",
" [ 0.19828291 -0.3307887 0.23450235]\n",
" [-0.08494822 0.41530179 -0.21659234]\n",
" [ 0.09257912 0.07266874 0.59562271]\n",
" [ 0.01558904 0.00687758 0.2801579 ]\n",
" [-0.29939471 -0.40882178 -0.17036741]\n",
" [-0.22195004 0.25407021 0.19237473]\n",
" [ 0.3733743 0.11069508 0.07095714]]\n",
"\n",
"```\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "uZRnPbBjQvZc"
},
"source": [
"### Descente de gradient stochastique\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "w2XnUBj2n-Df"
},
"source": [
"La descente de gradient stochastique prend en entrée les paramètres suivants :\n",
"\n",
"- _x_train_ et _y_train_ respectivement les données et labels de l'ensemble d'apprentissage (que l'on suppose de taille $N$).\n",
"- _model_ une instance du modèle que l'on veut entraîner (qui doit implanter les 3 fonctions vues précédemment _forward_, _backward_ et _update_parameters_).\n",
"- _loss_function_ peut prendre deux valeurs : 'mse' (erreur quadratique moyenne) ou 'bce' (entropie croisée binaire, que nous implémenterons par la suite).\n",
"- _learning_rate_ le taux d'apprentissage choisi pour la descente de gradient.\n",
"- _epochs_ le nombre de parcours complets de l'ensemble d'apprentissage que l'on veut réaliser.\n",
"- _batch_size_ la taille de mini-batch désirée pour la descente de gradient stochastique.\n",
"\n",
"L'algorithme à implémenter est rappelé ci-dessous :\n",
"\n",
"```\n",
"N_batch = floor(N/batch_size)\n",
"\n",
"Répéter epochs fois\n",
"\n",
" Pour b de 1 à N_batch Faire\n",
"\n",
" - Sélectionner les données x_train_batch et labels y_train_batch du b-ème mini-batch\n",
" - Calculer la prédiction y_pred_batch du modèle pour ce mini-batch\n",
" - Calculer la perte batch_loss et le gradient de la perte batch_grad par rapport aux prédictions sur ce mini-batch\n",
" - Calculer les gradients de la perte par rapport à chaque paramètre du modèle\n",
" - Mettre à jour les paramètres du modèle\n",
"\n",
" Fin Pour\n",
"\n",
"Fin Répéter\n",
"\n",
"```\n",
"\n",
"Deux remarques additionnelles :\n",
"\n",
"1. A chaque _epoch_, les _mini-batches_ doivent être différents (les données doivent être réparties dans différents _mini-batches_).\n",
"2. Il est intéressant de calculer (et d'afficher !) la perte moyennée sur l'ensemble d'apprentissage à chaque _epoch_. Pour cela, on peut accumuler les pertes de chaque _mini-batch_ sur une _epoch_ et diviser l'ensemble par le nombre de _mini-batches_.\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"id": "lk3lypUOLXbv"
},
"outputs": [],
"source": [
"def SGD(\n",
" x_train, y_train, model, loss_function, learning_rate=0.03, epochs=10, batch_size=10\n",
"):\n",
" \"\"\"\n",
" Implémente la descente de gradient stochastique\n",
"\n",
" Arguments :\n",
" x_train -- Les données d'apprentissage, de dimension (N, n_x) ; ATTENTION ces\n",
" dimensions sont inversées par rapport aux premiers exercices\n",
" y_train -- Les labels d'apprentissage, de dimension (N, n_y)\n",
" model -- Le modèle initialisé, à optimiser.\n",
" loss_function -- la fonction de coût à utiliser pour l'optimisation, qui pourra\n",
" être 'mse' (erreur quadratique moyenne) ou 'bce' (entropie croisée binaire)\n",
" learning_rate -- le taux d'apprentissage pour la descente de gradient\n",
" epochs -- le nombre de parcours complets de l'ensemble d'apprentissage\n",
" batch_size -- le nombre d'éléments considérés dans chaque mini-batch de données\n",
"\n",
" Retourne :\n",
" model -- le modèle obtenu à la fin du processus d'optimisation\n",
" \"\"\"\n",
" # Nombre de batches par epoch\n",
" nb_batches = math.floor(x_train.shape[0] / batch_size)\n",
"\n",
" # Pour gérer le tirage aléatoire des batches parmi les données d'entraînement...\n",
" indices = np.arange(x_train.shape[0])\n",
"\n",
" for e in range(epochs):\n",
"\n",
" running_loss = 0\n",
"\n",
" # Nouvelle permutation des indices pour la prochaine epoch\n",
" indices = np.random.permutation(indices)\n",
"\n",
" for b in range(nb_batches):\n",
"\n",
" # Sélection des données du batch courant\n",
" x_train_batch = x_train[indices[b * batch_size : (b + 1) * batch_size]]\n",
" y_train_batch = y_train[indices[b * batch_size : (b + 1) * batch_size]]\n",
"\n",
" # Prédiction du modèle pour le batch courant\n",
" # ATTENTION, le batch est de dimension (batch_size, n_x) !!!\n",
" y_pred_batch = model.forward(x_train_batch.T)\n",
"\n",
" # Calcul de la fonction objectif et de son gradient sur le batch courant\n",
" if loss_function == \"mse\":\n",
" batch_loss, batch_dy_hat = mean_square_error(\n",
" y_train_batch, y_pred_batch\n",
" )\n",
" elif loss_function == \"bce\":\n",
" batch_loss, batch_dy_hat = binary_cross_entropy(\n",
" y_train_batch, y_pred_batch\n",
" )\n",
"\n",
" running_loss += batch_loss\n",
"\n",
" # Calcul du gradient de la perte par rapport aux paramètres du modèle\n",
" param_updates = model.backward(batch_dy_hat)\n",
"\n",
" # Mise à jour des paramètres du modèle\n",
" model.update_parameters(param_updates, learning_rate)\n",
"\n",
" print(f\"Epoch {e:4d} : Loss {running_loss/nb_batches:.4f}\")\n",
"\n",
" return model\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "9bybDhHivjXq"
},
"source": [
"### Test sur un problème de régression\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "N7q44eS0vrrZ"
},
"source": [
"Le bloc de code suivant permet de générer et d'afficher un ensemble de données pour un problème de régression linéaire classique.\n"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"id": "nGcIVuALraDG"
},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAXkAAAD4CAYAAAAJmJb0AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAArt0lEQVR4nO2deZRU9bXvv7uqBzAS9TYaom2LSSRGaGRoSHqhpglEUFGukmh8GBSRNkSMXIwDMbmy4oBXXUpQ4qN9gUfHvKgLjegLPgikm4uLSkjjRBQHVETQRGiHgNgM3fv98avTdbr6nKpTVaemU9/PWr2q64z79PD97dq//dtbVBWEEEKCSSjfBhBCCMkeFHlCCAkwFHlCCAkwFHlCCAkwFHlCCAkwZfk2wE7//v114MCB+TaDEEKKis2bN+9R1WOd9hWUyA8cOBBtbW35NoMQQooKEXnXbR/DNYQQEmAo8oQQEmAo8oQQEmAKKibvxKFDh7Bz5050dHTk2xRCetCnTx9UV1ejvLw836YQ4krBi/zOnTvRr18/DBw4ECKSb3MIAQCoKtrb27Fz506cfPLJ+TaHEFcKPlzT0dGBqqoqCjwpKEQEVVVV/IRJCp6CF3kAFHhSkPDvsjSJRIAFC8xrMVDw4RpCCCkUIhFg3Djg4EGgogJYtw6or8+3VYkpCk8+34TDYQwbNqz766677sq5DfPnz8e9997ba/v27dsxZMgQX657xRVXoLW1Ne1rZYuFCxdi//793e/PPfdcfPLJJ/kziJQsra1G4Ds7zWsB/rv0gp68B/r27YsXX3wx32YUPYcPH0ZZWep/cgsXLsRll12GI444AgCwatUqv00jxBMNDcaDtzz5hoZ8W5ScQHryuYqZDRw4ELfeeitGjBiB2tpavPbaawCA9evXd3v9w4cPx969ewEA99xzD0aNGoWhQ4fi1ltvBWA88VNPPRVXXHEFBg0ahKlTp2Lt2rUYM2YMTjnlFGzatKn7fi+99BLq6+txyimn4OGHH+5lT2dnJ2644YbueyxZssTR7jvuuAODBg3CGWecgddff717+1FHHYWKigoAwC9/+UuMGjUKQ4YMQWNjI6wOYg0NDbjuuuswbNgwDBkypNu++fPn44c//GEv+1pbW3HmmWfiggsuwGmnneZqY2trKxoaGvC9730Pp556KqZOnQpVxaJFi/D+++9j7NixGDt2bPfPfc+ePfjss89w3nnn4fTTT8eQIUPw2GOPAQBuvvlmnHbaaRg6dCh++tOfAgCeeeYZfPOb38Tw4cMxfvx4/POf/wQA7N69G9/97ncxePBgXHXVVTjppJOwZ88eAMAjjzyC0aNHY9iwYbj66qvR2dmZwl8HCSL19SZEc9ttxRGqAWBSwQrla+TIkRrPq6++2mtbIjZuVO3bVzUcNq8bN6Z0uiOhUEhPP/307q9HH31UVVVPOukkXbRokaqqLl68WGfMmKGqqpMmTdLnnntOVVX37t2rhw4d0tWrV+vMmTO1q6tLOzs79bzzztP169frO++8o+FwWF9++WXt7OzUESNG6PTp07Wrq0ufeuopnTx5sqqq3nrrrTp06FDdv3+/7t69W6urq3XXrl36zjvv6ODBg1VVdcmSJXrbbbepqmpHR4eOHDlS33777R7P0tbWpkOGDNHPPvtMP/30U/3qV7+q99xzT69nbm9v7/7+sssu06efflpVVb/97W/rVVddpaqq69ev7763m30tLS16xBFHdNvhZmNLS4t+8Ytf1Pfee087Ozv1W9/6lm7YsKH757x79+5ue6z3K1as6LZFVfWTTz7RPXv26KBBg7Srq0tVVT/++GNVVf3oo4+6tz388MM6d+5cVVW95ppr9M4771RV1WeffVYB6O7du/XVV1/VSZMm6cGDB1VVddasWbp8+fJeP6dU/z4JyQYA2tRFVwMXrnGKmWU62iYK11x00UUAgJEjR+LJJ58EAIwZMwZz587F1KlTcdFFF6G6uhpr1qzBmjVrMHz4cADAvn378Oabb6KmpgYnn3wyamtrAQCDBw/GuHHjICKora3F9u3bu+81efJk9O3bF3379sXYsWOxadMmDBs2rHv/mjVr8PLLL2PFihUAgE8//RRvvvlmjzzuDRs24MILL+wOfVxwwQWOz9XS0oK7774b+/fvx0cffYTBgwfj/PPPBwBceumlAICzzjoL//rXv7rj4072HX300Rg9enS3DW42VlRUYPTo0aiurgYADBs2DNu3b8cZZ5zh+nupra3F9ddfj5tuugmTJk3CmWeeicOHD6NPnz6YMWMGJk2ahEmTJgEw6y0uueQSfPDBBzh48GC3Pc899xz+8Ic/AAAmTpyIY445BgCwbt06bN68GaNGjQIAfP755zjuuONcbSGkUAmcyOc6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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"x, y = datasets.make_regression(\n",
" n_samples=250, n_features=1, n_targets=1, random_state=1, noise=10\n",
")\n",
"\n",
"plt.plot(x, y, \"b.\", label=\"Ensemble d'apprentissage\")\n",
"\n",
"plt.legend()\n",
"plt.show()\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "q7lfdRFMRFZH"
},
"source": [
"A vous de déterminer le nombre de neurones à positionner en entrée et en sortie du perceptron monocouche pour résoudre ce problème. Une fois ceci fait, le code ci-après affiche également la prédiction de votre modèle.\n"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"id": "GKFJ3c2MmomL"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 0 : Loss 216.6618\n",
"Epoch 1 : Loss 93.8775\n",
"Epoch 2 : Loss 95.6949\n",
"Epoch 3 : Loss 93.6449\n",
"Epoch 4 : Loss 93.2614\n",
"Epoch 5 : Loss 92.0452\n",
"Epoch 6 : Loss 91.8134\n",
"Epoch 7 : Loss 94.1573\n",
"Epoch 8 : Loss 95.9175\n",
"Epoch 9 : Loss 89.3419\n"
]
},
{
"data": {
"image/png": "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wLZt2/jpp5+oWbMmM2bMoEyZMmzevJmEhARatGhB+/bt2b59O/v27WP37t389ddf1K5dm969e2e47okTJ+jbty/r1q2jZs2anD59mvLlyzNgwABKlSqVVhN99erVaef07NmTyZMn07p1a1599VVGjx7NpEmT0tq5adMmli5dyujRo1m1alWG+3311VfZtik7P/30E9u3byc+Pp7rr7+eCRMmsH37dp577jnmz5/P4MGD3bbxySefZMqUKbRq1YqhQ4emXXP27NlcccUVbN68mfj4eG677TbuvPNOgoKCMhzj6ufsWGlTKchdscKTl07y3PLn+PjHj6ldsTYbozcS89GtLPinYEsjeJM3gnwI0Bh4RkR+MMa8h5WaSSMiYoxxuepKRGYAM8BaDOWF9nidY+2ali1bEh0dzcaNGz0qobtu3ToeeeQRgoODqVy5MnfccUem63///fe0atUq7Vrly5fPsj3nzp3j7NmztG7dGoBevXrRvXv3tNcdyx871rax86RN2WnTpg2lS5emdOnSlClTJq0Mcb169fjxxx/dtvHs2bOcPXuWVq1aAfD444/z7bffAtbP8ODBg2kfZomJiRw4cIDrr78+7b6elFNWCnK22lVE+GL3FwxaOogz8Wd4tdWrvNzyZcJDwpGogq1s623eCPJHgCMi8kPq4wVYQf4vY8zVInLMGHM1kLOSiy542uP2Nnf15D0poeuLrepclT/2VEhICDabDSBDeWF394CsyyPnhIgwZsyYtL+U7Bw/qNz9nJVyxZNihX9e+JOn//c0i/YtomnlpqzuupqLB+ox8a30D4eCKI2QX/KckxeR48AfxpgbU59qC+wGFgO9Up/rBSzK6738mbsSuq1ateKzzz4jJSWFY8eOZaiiaHfrrbeybt26tMqI9py2uxK7ZcqUoVy5cmn59o8++iitx+yJrNpUo0YNtm7dCsDChbnfWNhdG8uWLUvZsmXZsGEDAJ988knaOR06dGDatGlpP8N9+/ZlKkOcm1LFRVFBbYHpC956byLCrG2zqD21Nst/W87bd75NXHQcFw/Uy1SeODIShg8vfAEevDe75hngk9SZNQeAJ7E+QD43xkQDvwMPeulefsldCd17772XNWvWULt2bapVq5ZWathRxYoVmTFjBvfddx82m41KlSqxcuVKunTpwgMPPMCiRYuYPHlyhnPmzZvH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",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"model = DenseLayer(1, 1, \"linear\")\n",
"model = SGD(x, y, model, \"mse\", learning_rate=0.1, epochs=10, batch_size=20)\n",
"\n",
"plt.plot(x, y, \"b.\", label=\"Ensemble d'apprentissage\")\n",
"\n",
"x_gen = np.expand_dims(np.linspace(-3, 3, 10), 1)\n",
"y_gen = np.transpose(model.forward(np.transpose(x_gen)))\n",
"\n",
"plt.plot(x_gen, y_gen, \"g-\", label=\"Prédiction du modèle\")\n",
"plt.legend()\n",
"plt.show()\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "mA9-6PqLwff4"
},
"source": [
"### Test sur un problème de classification binaire\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "K9AHAgGBwjro"
},
"source": [
"Afin de pouvoir tester notre perceptron mono-couche sur un problème de classification binaire (i.e. effectuer une régression logistique), il est d'abord nécessaire d'implémenter l'entropie croisée binaire.\n",
"\n",
"Rappel : \n",
"$$ bce(y, \\hat{y}) = -y log(\\hat{y}) - (1-y) log(1-\\hat{y}) $$\n"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"id": "_xCXP-pQb2oL"
},
"outputs": [],
"source": [
"def binary_cross_entropy(y_true, y_pred):\n",
" batch_size = y_true.shape[0]\n",
" loss = np.mean(-y_true * np.log(y_pred) - (1 - y_true) * np.log(1 - y_pred))\n",
" # grad = (y_pred - y_true) / (y_pred - np.square(y_true)) / batch_size\n",
" grad = (-y_true / y_pred + (1 - y_true) / (1 - y_pred)) / batch_size\n",
"\n",
" return loss, grad\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "0L3pPIpfSVU7"
},
"source": [
"Le bloc de code suivant permet de générer et d'afficher un ensemble de données pour un problème de classification binaire classique.\n"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"id": "4AxQRaegdntx"
},
"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 sklearn.model_selection import train_test_split\n",
"from sklearn import datasets\n",
"import matplotlib.pyplot as plt\n",
"\n",
"x, y = datasets.make_blobs(\n",
" n_samples=250, n_features=2, centers=2, center_box=(-3, 3), random_state=1\n",
")\n",
"\n",
"plt.plot(x[y == 0, 0], x[y == 0, 1], \"b.\")\n",
"plt.plot(x[y == 1, 0], x[y == 1, 1], \"r.\")\n",
"\n",
"plt.show()\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "X7o-u0kcSk_l"
},
"source": [
"A nouveau, vous devez déterminer le nombre de neurones à positionner en entrée et en sortie du perceptron monocouche pour résoudre ce problème. Une fois ceci fait, le code ci-après affiche également la prédiction de votre modèle.\n"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"id": "TdyntT9zSrum"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 0 : Loss 0.2542\n",
"Epoch 1 : Loss 0.1595\n",
"Epoch 2 : Loss 0.1338\n",
"Epoch 3 : Loss 0.1184\n",
"Epoch 4 : Loss 0.1177\n",
"Epoch 5 : Loss 0.1132\n",
"Epoch 6 : Loss 0.1035\n",
"Epoch 7 : Loss 0.1009\n",
"Epoch 8 : Loss 0.0909\n",
"Epoch 9 : Loss 0.0946\n",
"Epoch 10 : Loss 0.0869\n",
"Epoch 11 : Loss 0.0920\n",
"Epoch 12 : Loss 0.0801\n",
"Epoch 13 : Loss 0.0883\n",
"Epoch 14 : Loss 0.0847\n",
"Epoch 15 : Loss 0.0839\n",
"Epoch 16 : Loss 0.0796\n",
"Epoch 17 : Loss 0.0812\n",
"Epoch 18 : Loss 0.0788\n",
"Epoch 19 : Loss 0.0773\n",
"Epoch 20 : Loss 0.0772\n",
"Epoch 21 : Loss 0.0776\n",
"Epoch 22 : Loss 0.0771\n",
"Epoch 23 : Loss 0.0749\n",
"Epoch 24 : Loss 0.0678\n",
"Epoch 25 : Loss 0.0735\n",
"Epoch 26 : Loss 0.0749\n",
"Epoch 27 : Loss 0.0752\n",
"Epoch 28 : Loss 0.0741\n",
"Epoch 29 : Loss 0.0726\n",
"Epoch 30 : Loss 0.0710\n",
"Epoch 31 : Loss 0.0718\n",
"Epoch 32 : Loss 0.0712\n",
"Epoch 33 : Loss 0.0704\n",
"Epoch 34 : Loss 0.0704\n",
"Epoch 35 : Loss 0.0715\n",
"Epoch 36 : Loss 0.0703\n",
"Epoch 37 : Loss 0.0713\n",
"Epoch 38 : Loss 0.0702\n",
"Epoch 39 : Loss 0.0679\n",
"Epoch 40 : Loss 0.0628\n",
"Epoch 41 : Loss 0.0691\n",
"Epoch 42 : Loss 0.0700\n",
"Epoch 43 : Loss 0.0696\n",
"Epoch 44 : Loss 0.0689\n",
"Epoch 45 : Loss 0.0689\n",
"Epoch 46 : Loss 0.0686\n",
"Epoch 47 : Loss 0.0666\n",
"Epoch 48 : Loss 0.0669\n",
"Epoch 49 : Loss 0.0681\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAXIAAAD4CAYAAADxeG0DAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAzoElEQVR4nO2deXgU1dLG30pCwiL3IhFFAUU0ILJLRONGkN0NlIvXFQUVgsAjKOpFXAbBgAgaL2AIyCKuKCgqoiCyCCaKQfYdBERAjApIuEBIpr4/OvMxhJlMz/Ryumfq9zz9TGbS3ae6e+bt6jp16hAzQxAEQXAvcaoNEARBEIwhQi4IguByRMgFQRBcjgi5IAiCyxEhFwRBcDkJKho955xzuG7duiqaFgRBcC0rV678g5lrlP1ciZDXrVsX+fn5KpoWBEFwLUS0O9DnEloRBEFwOSLkgiAILkeEXBAEweWIkAuCILgcEXJBEASXI0IuCILgckTIBUEQXI6rhHzRzkV4/fvXcbLkpGpTBEEQHINpQk5E8US0iojmmrXPsny86WMMnD8QTbKbYN62eVY1IwiC4CrM9MgfA7DJxP2dwbjO4/D53Z/Dy17c/N7N6PxuZ2wqsLRJQRAEx2OKkBNRbQA3A3jTjP2V0w5uqX8L1j+6HmM7jEXenjw0yW6Cx758DH8d+8vKpgVBEByLWR55FoCnAHhN2l+5JMYn4vG0x7FtwDY8csUjGP/jeKSMS8H4FeNR7C22wwRBEATHYFjIiegWAL8z88oQ6/Umonwiyi8oKDDaLACgRpUayL4lG6v6rELzms0x4MsBaDaxGRbsWGDK/gVBENyAGR75tQBuI6JdAD4AcCMRvVN2JWaexMypzJxao8YZVRgN0fS8plh4/0LM+fccnCg+gY7vdMSt79+KLX9sMbUdQRAEJ2JYyJl5CDPXZua6AO4CsIiZ7zNsWZgQEbpc1gUbHt2A0e1GY+mupWic3RiPz38ch44fstscQRAE23BVHrkekhKS8OS1T2LbgG3o2bwnsr7PQsq4FEzMnyjxc8EU8vKAkSO1V0FwAsTMtjeamprKdk0ssfq31Rj41UAs3b0Ujc9tjKyOWWhbr60tbQvRR14e0LYtUFQEJCYC33wDpKWptkqIFYhoJTOnlv086jzysjSv2RyLH1iMWd1nobCoEO3eboeuH3TF9r+2qzZNcCFLlmgiXlKivS5ZotoiQYgBIQe0+Hm3y7thU79NyLwxE9/s/AaXT7gcTy54EoePH1ZtnuAi0tM1Tzw+XntNT1dtkSDEQGglEPuP7MfQRUMxffV01KhSAyPajECvFr0QHxevzCbBPeTlaZ54erqEVQR7CRZaiUkh97Fy30o89tVj+G7Pd2h2XjNkdcpCet101WYJgiAEJGZj5OXR8oKWWNZzGWb+ayYOHj+INm+1QbcPu+Hngz+rNk0QBEE3MS3kgBY/v7PRndjcbzOGtxmOr7Z/hYYTGmLIwiE4cuKIavMEIWaQtM7IienQSiD2/r0Xzyx6BjPWzMB5Vc5DZttMPNj8QcRRzN/zBMEyJK1THxJa0Umtf9TCW13fwg8P/4B6Z9fDQ589hCsnX4llu5epNk0QLEWlRyxpncYQIQ9Cq1qt8F2v7/DuHe/i96O/44bpN+Dfs/6NXYd2qTZNEEzH5xE/95z2areYS1qnMUTIy4GIcE+Te7Cl/xZ4Wnvw+ZbPcdn4y/DsomdRWFSo2jxBMA3VHnFamhZOGT5cwiqRIDHyMNhzeA/+881/8N6693BB1Qswsu1I3Nf0PomfxzhW5JXbnavulhh1rOfwSx65ieTtycPA+QOxYu8KXHnBlcjqlIVr6lyj2ixBAVYIoCpRdbpIuuVmYyXS2WkiaXXSkPdQHmZ0nYG9R/bi2qnX4p7Z92DP4T2qTRNsxoqQhKowR1oaMGSIc8VRdfjHyYiQR0gcxeH+ZvdjS/8teO6G5/DJ5k/QYHwDeJZ48L+T/1NtnmATVnTSScdfYOS8BEdCKyax+9BuPL3waczcMBO1/1Ebo9qOwj1N7gERqTZNsJhoiJGbiZW2u/m8mIHEyG1i+S/LMfCrgVi5fyWurn01Xu/0OlrVaqXaLEGwBYljW4tlMXIiqkhEK4hoDRFtIKJhRvfpZq678DqseGQFpnWZhl2HduGqN69Cj096YO/fe1WbJgiWI3FsNZgRIz8B4EZmbgagOYBORHS1Cft1LXEUhwebP4it/bdiyHVD8OGGD1F/fH0MXzocx04eU22e4BCisbaIxLHVYGpohYgqA1gOoC8z/xBsvWgOrQRi58GdePLrJzF702xc+M8LMbrdaNzZ6E6Jn8cw0RyCiPU4tpVYmn5IRPFEtBrA7wC+DiTiRNSbiPKJKL+goMCMZl3DxWdfjFl3zsKSB5ageqXquGv2Xbh+2vXI3xc7NzPhdKI5BOH0NMZoxBQhZ+YSZm4OoDaAVkTUOMA6k5g5lZlTa9SoYUazrqN13dbIfyQfk2+djG1/bUOrya3Q89Oe2H9kv2rTBJuREIRgJqbmkTPzIQCLAXQyc7/RRHxcPB6+4mFsG7ANT17zJN5b9x5SxqUgc1kmjhcfV22eYBNSWyQ00diHYBWGY+REVAPASWY+RESVACwA8DIzzw22TazFyMtjx187MPjrwZizeQ7qVquLV9q/gm4Nu0n8XIhporkPwQhWxsjPB7CYiNYC+BFajDyoiAunc0n1S/DJvz/BNz2+QdXEquj+UXekv5WOVftXqTZNEJQRzX0IVmBYyJl5LTO3YOamzNyYmV80w7BY48aLb8SqPqsw8eaJ2FiwES0ntcTDnz2MA4UHVJsmCLYjfQjhISM7Hcih44cwfOlw/HfFf1EpoRKeveFZPHbVY0hKSFJtmiDYhqQxnokM0XchW//cisELBuPzrZ+j3tn1MKb9GHS9rKvEzwVHIEJrP1LG1oXUT66Pz+7+DPPvm49KCZVwx4d3oO2Mtlh7YK1q0wQTcHNWhuqp4YTTESF3AR0u6YDVGasxvvN4rDmwBi1yWqDP531QcDS2BlbpxQ0CGYkQOum4pDPSWYiQu4SEuAT0a9UP2wZsw4BWAzB19VSkjEvB2NyxKCopUm2eY3CLpxiuEDrtuKQz0lmIkLuM6pWqI6tTFtb1XYdr6lyDwV8PRuM3GuPzLZ9DRX+H01DlKYbrLYcrhFYdV6RevgxochjMbPvSsmVLFsxh3tZ5fNn4yxgecPsZ7XndgXWqTVJKbi5zpUrM8fHaa26uc9vMzWXOzNS3vhXHpeJcOZ1wrokKAORzAE1NUH0jEYzROaUz2tVrh+z8bLyw5AU0m9gMGS0zMKzNMJxT+RzV5tmOz1O0M5sikLesp920NP32WXFckdodCW7IcHH1aNJA6m71Ih65Nfxx9A/u90U/jh8Wz9VGVeOsvCwuKi5SbVbU41bP1i673XJ+MjM1GwHtNTNTtUVngiAeucTIo4jkyskYf9N4rMlYg1a1WmHg/IFokt0E87bNU21aVOPWeLFddrslw8XNHbgyIChKYWZ8se0LPD7/cWz7axs6XdoJr3Z4FQ1rNFRtmhBj+Ics4uOBXr2AHj2cecNzeghIRnbGKEUlRZiwYgKGLR2GwqJCPHrlo/Cke1C9UnXVpgllUCkigdo20568PGDGDGDaNKC42IUxaIcQTMilszPKSYxPxKC0Qbiv6X14fvHzmPDjBLy77l0MSx+GjNQMJMTJVyBcfKIEmOdZquxoC9Q2YK49aWnaTaG42J7O1VhDYuQxQo0qNZB9SzZW9VmF5jWbY8CXA9BsYjPM3z5ftWm2YnR0ZF4e0KYNMHGitqSnmzM4J5w4sv8xmDHaM1DbVsS13RyDdjrijsUYTc9rioX3L8RnWz7DEwueQKd3O+HmlJsxtsNYNDingWrzLMUMr9cncD5OnjTHs/SJnM+2YCJXNt5MZDxU4d92QgLwyy9Aixb67AkHFamhsYJhj5yI6hDRYiLaSEQbiOgxMwwTrIOI0OWyLtjw6AaMbjca3+7+Fo2zG+Px+Y/j4LGDqs2zDDO8TJ/o+ahQwVyRC5VB4n8MJ0+a4zX72n7kEYAZmDwZGDgQyMoyP6MlLU07X0uW2F9mwEm1akwnUE5iOAu0GYKuKP27KoCtAC4vbxvJI3cWvx35jR/57BEmD3Hyy8n8xoo3+GTJSdVmmY5Z+cy5ucwZGdoSzj70jBoMtY7/MSQmMiclmZef7Z9HTaQdn9moyil3Sy57KBAkj9z0wT4APgXQvrx1RMidyar9q7j1tNYMD7jxG4154Y6Fqk0yHVVDsPUIiV6x8T8GM48nN1e7OWh+uXaTMPs8qRp044bBPnoIJuSmdnYSUV0ALQD8EOB/vYkon4jyCwqk/KoTaV6zORY/sBizus9CYVEh2r3dDl0+6ILtf21XbZpppKUBQ4bYH5/VE9bRG/rxPwYjx5OXB/Ttqy15edo+evXS4u6AFnv3t8GM0ISqDs+o72gNpO6RLADOArASwB2h1hWP3PkcO3mMRy4byWdlnsUVXqzAg+cP5kPHDqk2yxFE4gWb6ZEbtc0XGqpQ4ZT3nZh4ysMPZIOZoQmVT0VOLoilB1gZWgFQAcB8AI/rWV+E3D3s+3sf95rTi8lDXGN0DZ6UP4mLS4pVm6UMI4JmRoy8vO0yMkLHzH32E50ScV9M3BduCGRDtIQm3I5lQg6AAMwAkKV3GxFy95G/N5+vm3odwwNult2MF+9crNokJThR0AKJczDb/O33X3weeag2zOostNM7jgZP3IeVQn4dAAawFsDq0uWm8rYRIXcnXq+XZ66fyRe9dhHDA75j5h28468dqs2yFSdmP5QVZyJ94ZukJOauXfVn35gliHaeQydeLyMEE3LDA4KYeXmpVy5EOUSEOxvdiVvr34pX817FyOUjMXfrXAy6ehCGXj8UVZOqqjbRcpw4qMV/QE+oolTl2R+qtkqo+ul6a7PoqYNuVp0XO2uuKyWQulu9iEceHez9ey/3+KQHwwM+75XzeMpPU2I6fm4Eo96uGdsb8VzD2T7UumWfGsLN14/ULjcAu/LI9Swi5NHFD7/+wGlvpjE84BYTW/C3u75VbZJpWJWzXbYN1WJjNPYf7vblnctwQkV6yMlh7tBBe3U7IuSCpXi9Xn5v7Xtc+9XaDA+4+4fdeefBnarNMoSVoyj9cUIHqp0eud596em8tdMuJxBMyKX6oWAKRIS7m9yNLf23YFj6MMzdOheXjb8MQ78ZisKiQtXmRYTeuiZGB8o4YbCKkdmCfPFss2qz+Gzp08f4eXHL7ESGCaTuVi/ikUc/ew7v4Xtn38vwgM8fcz5PXzWdS7wlqs0KCz0euZn1W5ySIheOLVYPYoq0ro2Z9jkJSGhFUEHenjxuNbkVwwNOnZTKy3cvV21SWISKkdtRaMpOwhU+o2GhcDo+rRzt6haCCbmEVgRLubr21ch7KA9v3/429h3Zh+umXYe7Z9+NXw7/oto0XYSqa5KertXwBrRo7tSp7i2TmpcHeDzAiRP6QxHJyUBcnLZEEv4IFfrQExoJFtryfQ6oqa9jK4HU3epFPPLYpPBEIT+36DmuOKIiVxpRiZ9f9DwXnihUbZZhMjJOdcw5ZbRnuPg837g47Tji4oJ7yP5PKL5tEhIiywox6pHbURvGSUA8ckE1VRKr4MU2L2JL/y3oclkXvPjti2gwvgHeWfsOvOxVbV7E9OgBVKxof2elmVO++Txfr1fzrtu1O7PT0jc70XPPaa8zZpzahhn48099tvoTqpM11P+Deewx08npI5C6W72IRy4wMy/fvZxb5rRkeMBXTb6Kv9/zvWqTIsbuAT1mp0bq8WDLxsMzMvTXT7fKOxaPXDo7BQdQ4i3h6aum8/ljzmd4wPd9fB/vObxHtVm2EonolO1kNSO0E+pmEshOPTcgq/Pkg9kQTZ2cPoIJOWn/s5fU1FTOz8+3vV3BuRQWFWLkspEYmzcW8XHxePrapzH4msGoXKGyatMsZ+RILVxRUqKFZ4YP1zrnyqO8SZizsrQwh5E6JcFqnUyaBMyeDTRvDlSrpq8NMya9FjSIaCUzp57xuQi54CR2HtyJpxc+jY82foQ6/6iD0e1H49+N/g2i6K3LFqnQ+YstoP2dnKxNnKyngFa49vg+P3HiVCw9KUmfvWYVwYp1ggm5hFYER7J011JuMbEFwwO+Zso1vOLXFapNshSzwgBm1CkJFgoJVMs8Ls6dWTpuBZK1IriJGy66AT8+8iPevPVNbP9rO1q92QoPzHkA+47sU22a6QTzVsPNRMnLA375Rctr9z3AMIdfUiBYyQDf53F+quH1ak8BgloM1yMXBKuIj4vHQ1c8hO6NuiNzWSZe+/41zN44G0OuG4LH0x5HpQqVVJtomFBhjPLCLWVDK/4x8y5dgC+/PBU3962jZ7/+NcuTk0/dBHyfezzA119rN4m4uPLTDoXTsSrEZIpHTkRTieh3Ilpvxv4EwZ9/JP0Do9qNwsZHN6LDJR3w7OJn0XBCQ3y04SMt9crF6MmDPnFCE09/DzpYTndJiba0agUsXnxm/rXekZL+8XZfG3l52n48Hi1v3jeiU4VHbjRvXgVlr5mptgeKt4S7ALgBwBUA1utZX2LkghEW/byIm2Y3ZXjA10+9nlfuW6nMFqsmdAg10tKqnG7///vHw8umDebkMFeoEHgEqNVpf27NETcjDRNW55EDqCtCLthFcUkx5+TncI3RNZg8xL3m9OL9R/bbaoPVlQ9zc7UJEXxi7v/jz83VBgIRnZo4Wa+AhjOpQ7DJmYOJkh0i64T67ZFgxrkJJuS2dXYSUW8iyiei/IKCAruaFZyGSc/E8XHx6N2yN7YN2IYn0p7A22vfRsq4FIxaPgrHi4+bZGz5WD0M3BfGSEoKPPzf16Hpew1U1CvYfoOt5+vQ9M/2JNLSGMsWCyvbIRpJ0a1IcEL99kgwUvM9JIHUPZIF4pHHNnrcQQvdta1/bOXb3r+N4QFfnHUxz944m71er2n7D4RZJVZD7SNU+VyzvVJfDfDERP125eZqZQL80xKtDHtE46hNPUBCK4Jl6FU0G56Jv97xNTea0IjhAadPT+dV+1eFvY9wJ1YwIiiRnhI7QhjhHFtGxumhmFatYk9k7SCYkEv6oWCcQDGG8p7bfblvFjwTt6vXDqszVmPyysl4bvFzuCLnCjx8xcMYceMInFvl3JDbhzvK0lenPFIiPSX+KYJWjZY0cmxXXCEjOO3ErPTD9wHkAWhARL8S0UNm7Dds3JiTFA3oDVpaGiQ8RUJcAvpe2RfbBmzDY1c9hmmrpyFlXArG5I5BUUlRudvaXf7UyCnRGxO3gx49TsXWExO190aQn3J4RE+tFanMoxYHF9PY/MdmDF4wGF9s+wKXVr8UY9qPwW0NbgtYv8UNX6NQpzpQDZZAo0bNvlzl7TOc9txwDVQR/bVW3JqTFI04tCfqq21fccPxDRkecNu32vLa39YGXM+MND6rCCcPPCkpcIel3XnYds8DGs0g6mPkNsRfBR042J3qeGlHrDmQg4mLR+OFPUvRPKc5+rTsg2Hpw1CjSo3/X09PbFjVYYbqjvD/v7d00iXm09fV26Vhpc2+zwN56PJTDp/oKZplU/zVVtwYKLQryBzJucnLQ4X2HTHA8yW2jz2JfnXuwKSVk5AyLgWv5b0WMn7uj6qpxEJ1R5T9f4UKwYtf2ZWHXba95OTyh6rb8VN240+rXAK56VYvkn6oA7eOQ7YrLy6SNgI8s2/4fQN3fLsjwwOuP64+z90yN3D+eZk4isrLo2cmH//87lB/222z6tCJW39azDbkkYeziJDrQPW33QhWq4TJydder5fnbpnL9cfVZ3jAHd7uwBt+3xByOzMPM5bqk6i2xc0/rWBCHj0x8mjDbYHCsmkJVoa2TE6+JiLcXP9mtL+kPd748Q0MWzoMTbObom9qX3jSPUgOElQ26zDNjrcHyhCxOy4eyjYzpqOLFLf9tHQRSN2tXsQj14lDsz/OwN/FSkzUhvnZkQoR4bkJtWnB0QLuO7cvxw2L47NHnc3//WAQF1WpaJkLaaaHmJPDnJBw5hB51V6wU2zwt8UNP62yQEIrgmWYMb+YTeTmMrdOzOVnKJNbJ+aWa+K6A+u43Yx2DA+44St1+csRD1pyTGZWUaxQ4fTL0KHD6WKuIl3SKbHxaECEXLAOnxIRnVIRh/5S38rI5aOoxCcRz0dRid/KKF/VvF4vf7r5U770v5cyPOCb3r2JNxdsNt2u8krZ6hXfzMxTJW/tKl5VHmVvUDk5zvHI3UowIY+e9EPBXvzzt3yx5z59gtdcdQitsQSJKEICSlABRWiNJeWuT0S4rcFtWN93Pca0H4PlvyxH4+zGGPTVIBw8dtA0uwINtw93Rpn0dO30+2buIdJyye1Mj/SnbFz+zz+jL0PYMQRSd6sX8chdTnmxAKcHH3NzuTipEhdTPBcnhe8WHig8wL0/683kIU5+OZknrJjAJ0tOWmKqv4etd7Z63+l3gvfrpJh4tADJWhFMI1gKhIPrrfw/aWmIXxx52cBzq5yLnFtz8OiVj2Lg/IHoN68fsvOz8VrH19CuXjtTTU1OPjU6U+9s9f6ZNE2anHmYdl4ioxUa3fB1cgyB1N3qRTxyk1ExuqOsqxWD7pfX6+WPN37M9V6vx/CAb33vVt76x1bT9h+JR14eZl8iK792Mfh10gUkRh6lWDo1dxACjaFWNWZdIUSE2xvejg2PbsCotqOweNdiNHqjEQYvGIzDxw8b3r8v5h0fr70a7XIw8xJZ/bWLwa+TIUTI3Y6Kb3ygZ163TqRoAhUTKuLp657GtgHbcH/T+/Fq3qtIGZeCnPwclHhLIt6v0ZojZeuJmHmJrP7axfDXKTICuenhLgA6AdgCYDuA/4RaX0IrOginlqpTapLaMc7cyR2ppazct5Kvn3o9wwNumt2UF/28yHYbgl0ms06hXSV1XHC5bQVW5ZEDiAewA0A9AIkA1gC4vLxtRMhDEO6vxIxvvN59WDWqQ08lKBcFTb1eL3+4/kO+6LWLGB7w7R/czjv+2mFb+2ZeJjNy3J2K247BSiFPAzDf7/0QAEPK20aEPAR2D4ELRyRDrRvJL0NP+y4dFnjs5DF+6duXuMpLVThxeCI/teApPnz8sCn7Lu9Umzla1EX3z7Bw47EFE3IzYuS1AOzxe/9r6WenQUS9iSifiPILCgpMaDaKsStA6AuizphRfsAz0OCfQIHbSHvA9ARcy56TQ4eAjh2BSZMiOvSIiKCIdcWEinjm+mewdcBW3N34bozOHY364+pjyk9TDMXPQ53qYJcp3EOI5k5Ho8fmqJrmgdQ9nAXAvwC86ff+fgDjy9tGPHId2FnXNNicYGXXC+W2mFxeNuB6mZnMTz3Fp41Dz8nRf9yRYpL79uPeH/maKdcwPOAWE1vw0l1LI9pPJKc6kkNwo9eqFyPHpuq8wEKPfC+AOn7va5d+JhjB6inS/d2R4mKgV6/AXnY4bkukTxJ60zN852T16tM/nzJFXztGMMk1Tb0gFct7Lsf73d7HH//7A62nt0b3j7pj58GdYe0nklMdySFE48RbPowcm+OeVAKpezgLgAQAPwO4GKc6OxuVt4145IrJzdVKzSYl6fOC7e54DUVOzukeeYUKarN1IuRo0VEetmQYV36pMicNT+IhC4fw38f/DsukcE51NHvXduM0j9ywkGv7xk0AtkLLXhkaan0RcoX4fwP11A73ib4dNcbDoWvXU0LuH1uwerihBfvec3gP3/fxfQwPuOaYmjxt1TQu8ZaY2oYPt2VpOBkV59JSIQ93iQkhd+ovJpzgql1uh1mZLkZz3BVfs7w9eXzV5KsYHnDqpFRevnu5aft26tdRCA8Rcjtx8jOsHZ2XVtkTaFt/dQpmr542HHLNSrwl/M6ad7jW2FoMD/iuWXfx7kO7De1TxZgxuWlYQzAhlyH6VuC4nhA/wunhMZIGqTc3y8i5KtshHMxePW045JrFURzubXovtvTfgudveB5zNs9Bg/EN8Pzi53G06GhE+7T00MpcZxWlfwSIR24JTvDuzByLbcUAn0jW1WNToP+5yCMvy+5Du/nuWXczPOBaY2vx22veDjt+btmhBdixS8dtuQZIaMVmVD5f6hUuK+zLzdUmivTVX9Xzaw7HlkhVyUCM3Amhgu9++Y5TJ6UyPOCrJl/FeXvywtrekmMIoNoOvR9GDSLkqrFTDUK5RVb92nz79S+ibfav2WaXz0nCVOIt4emrpvP5Y85neMD3zr6X9xzeo86gICfHCTe+aEWEXCUqepvKa89fDOPiTp9q3QhW7dcfm8+lE0MFR04c4aHfDOWk4UlcaUQl9iz28NGio2qMEdW2FRFylahQg1BxZCs852Aia/aP3Wrx8Nu/kzzysuw8uJO7f9id4QHXebUOv7f2PfZ6varNihkkjzzWhFy1GgTrAAw3lh1JW6qPPVwC2BvWDzbSX7eBGP7SXUu5xcQWDA847c00XvHrivDaFsJG1ddahFw1qh5BQw2Ssfrb6MTYRHkYsddIR6zBrJrikmKe8tMUPu+V8xgecI9PevDev/fqt10IC1Vf62BCLnnkdmF1EaxglJdEHG7VoEjqdrptzi4j9kaasG1Cnnt8XDx6teiFrQO24ulrn8YH6z9A/XH18dK3L+HYyWP6j6EMjirV6iAc97UOpO5WLzHpkavCLK/bfz96arSU3dZNHWJGwiOKPPKy7PhrB98x8w6GB3zRaxfxzPUzw46fuzEqZufXTGLkIuT2YsY3zv9ZEmAmcsev224UxMjLY/HOxdwsuxnDA75+6vW8ct9K3du6KSrmtptOpAQTctL+Zy+pqamcn59ve7uWE2h2+WjBN/b6+HFNygHtufKRR4ALL4zOY44SSrwlmLpqKoYuGoo//vcHHmz+IDLbZqLmWTXL3c53yYuKtPCBk+uRjxyplQUoKdG+lsOHa5HMaIOIVjJz6hmfi5CbhJu+9ZEyaRKQlQVs2aK9r1BBE/WSEmccczTfSE3g8PHDGPHtCLz+w+tISkjC0OuHYuDVA1ExoWLQbdxySmPh5wcEF3IJrZiFm55DIyE3V4uN+9cA79rVOcdsxbO122L7Otn6x1bu8n4Xhgd8cdbFPGvDrKjIP4/Sy3UasCJrhYi6E9EGIvIS0Zl3iVjCcd3YJrNkCXDy5Kn3Xi9Qs6b1x2xHFcVg7UZpGb+U5BTMuWsOFt6/EFUSq+BfH/0Lbd5qg9W/rVZtmiFUJYY5AaPph+sB3AHgWxNscTfRPLkhoIl0hQqn3icmAj16GDvmUCIdjpiafSN1SFlbK2lbry1W9VmF7Juzsf739bgi5wr0/rw3DhQesLRdSWm0gEBuergLgCUAUvWuH5WhlVggN9e8ad9ycpgTEsovDxBuuMrMZ+tYSYMo5eCxgzzoq0Gc8GICV82syqOXj+bjJ4+b3k6MnVbTgcVzdoqQC/rJzdUmTPbF2+PiAou06l99LARdy7C5YDPf/O7NDA/4ktcv4U82fWJq/Dzau5KsJpiQhwytENFCIlofYOkSjudPRL2JKJ+I8gsKCsJ9cBAAfaEIO55ZjbazZIkWsvARFxc4FKI6XOWCoKvZl7zBOQ0w9565+Orer5CUkITbZ96O9m+3x7oD60zZf7R3JSkjkLqHu0A8cv1YNWrQLu/VjHb8qy9WqKCFWezErZ52GbutvuQnS07y+B/Gc/WXq3PcsDjO+DyDfy/83fB+3Xr6nQCCeOQJSu8isYaRZNdAnW/+2y5ZApw4oWWTnDhx5v/NIpQdgSibjOzztFUkKLs14TiA3UuWpIV9KcIhIS4B/Vr1w91N7sawJcMw4ccJeH/9+3i+9fPo36o/EuMTI9qv7ysgmIfR9MPbiehXAGkAviCi+eaYFaUYyYQI9UyanKyJOKC9JiebY3O4dvjwPfNPmhQ488TqsEWwmEO418ApKRYB7LYrTFG9UnW83vl1rOu7Dml10vDEgifQJLsJ5m6d63siF1QTyE23eonZ0IrRZ+HynkkzM0+fKMLKXqRQz8b+x+nLTLF7Ug0zSvfaEa7SG2cIYouKMMW8rfO4wbgGDA+4/Yz2vP7Aevsaj3EgoRUHYDSkUN4zaXo6kJR06tE7Pd268dWhno39vce4OM1lBAAi654UgrXv73X7zkVWFjB7NtCtm/7jsCJ2EU6YJ8h3R0WYonNKZ7Sr1w5v/PgGPEs9aDaxGTJSMzAsfRiSK9twfYUzCaTuVi8x65Fbjb97pjJ1r2xnpm8mIrsqJpY99pycU++TkrRSA07wyKMgF6/gaAH3+6Ifxw+L52qjqnFWXhYXFRepNitqgUwsEQP4x51VjkxMS9O83rg4oLgYWLBAi9szn+qIDYQZ8WjfU0hW1qm0xT//PP1cnDyp77xYnf4YBbl451Q+B+NvGo81GWtw5QVXYuD8gWg6sSm+3PalatNiCgmtRCs+kfAPtdjJn3/6hvuc/nl8fGBbzMgmKW8fvnORkHB6xcZQ58XK2IXK7B2TaXRuI8y/bz7mbp2LJxY8gZveuwmdL+2MsR3GomGNhqrNi3pEyKMV1SLhu5H4UiIBzUMfNCiwLWbEo4Pto+y58K3rBPGMolw8IsKtDW5Fx0s7YvyK8Xhx6Ytokt0E/a7shxfSX0D1StVVmxi1SD1ywTp8YY5Dh4DXXtMENikpsLdttUcu2E7B0QI8t/g5TP5pMqpVrIYX019En9Q+SIgT/zFSgtUjlxi5YB2+mH21appX7vUGj0ubEY8OtQ+n5ITHCDWq1MDEWyZiVZ9VaF6zOfp/2R/NJjbDgh0LVJsWdYhHLliPEzxlfxsSEoCePbUyvOKx2wIz49Mtn2LwgsHYcXAHbql/C8Z2GIv6yfVVm+YqxCN3A3Z7jHa1F8hTnjQJ6NhRe7UD//j5iRNATk7UTRjhZIgIXS/rig2PbsDL7V7G0l1L0eiNRnh8/uM4dPyQavPcT6CcRKsXySMPgN1530baMzqcMCeH+VROiz1Fs3zHS3SqXSKttrpgO78d+Y0f/vRhJg/xOaPP4ewfs7m4pFi1WY4HkkfucKzO+y7rfZdtb8YMfd65GVOgzZ5d/nsr8D0V9OmjhVYATc6nTROvXAHnnXUeJt82GSt7r8TlNS5H3y/6okVOCyzauUi1aa5EhNwpWDk4JJD4+reXkABMnapPnM244XTrVv57q0hLA7KzgYcf1soFANqApSicxs0ttDi/BZY8sASzus/CkaIjaDujLW6feTu2/7VdtWmuQoTcKVg5ijBYfrWvvZ49tf/p8c7NuOH07q3FqDt00F579w5v+/Ji+3ri/j16ABUrWnfTlMyYsCAidLu8Gzb124TMGzPx9Y6v0eiNRnjq66fw94m/VZvnDgLFW6xeJEZuM+FMShGqFomZ83ZGgpmVDc0sG+g7L3rruAhB2ff3Pu45pyeTh/jcV87lySsnS/y8FFg5Z2e4iwi5AvSUns3M1MQoWCEnszpkjYiof6EpIuauXU/tS1URqkAdqS4tguUk8vfm87VTrmV4wM0nNuclO5eoNkk5IuSCPsoT67JCmZERviAb9Zpzc7WnBv+sl7i4M6scJiba99Tgf158NxjxyE3B6/XyB+s+4Atfu5DhAXeb2Y1//utn1WYpwxIhB/AKgM0A1gL4BEA1PduJkDucYB5zOCGYYPvS6zWXJ/gZGad7v/778oU4kpLUpHImJdlzA4mxiS//V/Q/Hr50OFd+qTInDU/iIQuH8N/H/1Ztlu1YJeQdACSU/v0ygJf1bOdqIbfiB+SmH6WeEIz/umXFWK9HXjaE4p/v7V/v3N8jD/dmYSZ2XkOVteYV8+vhX/n+j+9neMA1x9TkqT9N5RJviWqzbMPy0AqA2wG8q2dd1wq5FT8gFQOBAoUrrAiRBBNUPe3l5moev8/jTkoKbHNOTuDjiWahi4IJKYzyw68/cNqbaQwPuGVOS162e5lqk2zBDiH/HMB95fy/N4B8APkXXnihLQdtOlb8gOz8Ufp7sgkJmghaOcLTqKD6h1DCPTeReshlZ1ly4pNStN+odOL1evndte9y7VdrMzzgOz+6k3cd3KXaLEuJWMgBLASwPsDSxW+doaUxcgq1PxaP3Pp9BsN/gmZAm4ZNT4jECEbEUGXZgnCmhFOBU28yCig8UcgvLH6BK42oxBVHVORnv3mWC08UqjbLEizzyAE8CCAPQGW927hWyJndHSPPzdU8cf9sj4wMY2Jpte12ClbZuHykTwOCEn459AvfM/sehgd8wdgLeMbqGVEXPw8m5IbK2BJRJwCvAmjNzAV6t5MytgqZNAno3//0SR6AyGbMcUJ5WjMpW+qW/aaEc/uxxRB5e/Lw2FeP4cd9P6JVrVZ4vdPruLr21arNMoVgZWyNCvl2AEkA/iz96Htmzgi1nQi5Ynwz9xid6mzkSK0+S0mJNtx9+HBtIgmrMMtuvW0AzpkSTggLL3vxztp38J+F/8H+wv24p8k9GNV2FOr8s45q0wxhiZBHigh5lGCnRx6sLTvEXXAthUWFeHn5yxiTNwYEwtPXPo0nr30SlStUVm1aRMjEEoL5WFnoqyyBCn+ZUVJXiGrOSjwLw28cjs39NuPWBrfCs9SDBuMb4L1170GFE2sVIuSCMXzzclrtDZetupicDHg82mw/VtVwF6KGi6pdhJn/mollPZfhvCrn4d6P78W1U6/Fir0rVJtmChJaEdyDL4ySnAwMHKiJuNcLxMWd6riV8IoQAi978dbqt/DMomfwW+FvuL/p/RjZdiRq/aOWatNCIqEVwf34vP8//9Q8cJ+It2snIi7oJo7i0LNFT2ztvxVDrhuCDzd8iPrj62PEtyNw7OQx1eZFhAi54D78wyxJSVqIRURcCJOqSVWR2TYTm/ptQudLO+O5xc/hsgmXYeb6ma6Ln4uQC+7Dzk5WIeq5+OyLMevOWVj8wGKcXfFs3DX7Ltww/Qas3LdStWm6kRi5mUgqnCC4mhJvCaatnoahi4ai4GgBHmj+ADJvzMT5Vc9XbRoAySO3nmgb5SgIMczh44fx0rKXkPV9FpISkvDMdc9gUNogVEyoqNQu6ey0GjNmlxeE8pCJnW3jnxX/idHtR2Njv41oe3FbPLPoGTSc0BCzNs5yZPxchNwszJhdPlYRgQqNDH5SwqXVL8Wcu+Zg4f0LUTWxKrp/1B3pb6Vj1f5Vqk07DRFys5AOuMgQgdKHPPEppW29tvipz0/IvjkbGws2ouWklnjks0dwoPCAatMAiJCbi12jHKMJESh9yBOfchLiEpCRmoFtA7Zh0NWDMH3NdKSMS8Ho70bjRPEJpbaJkAtqEYHShzzxOYZqFathbMex2PDoBrSu2xpPL3wal79xOT7Z9Imy+LlkrQjqiSRtU1I9BYewYMcCDJo/CBsLNqJN3TbI6pSFpuc1taQtST8UogdJ9RQcRrG3GDn5OXh+yfM4dPwQHm7xMIbfOBznVjnX1HYsST8kouFEtJaIVhPRAiK6wMj+lCFZE+5C4uqCw0iIS0C/Vv2wbcA29L+yP6asmoKUcSkYmzsWRSVFlrdvNEb+CjM3ZebmAOYCeN64STYjWRPuQ+LqgkOpXqk6Xu/8Otb1XYdr61yLwV8PRqM3GuGzLZ9ZGj83JOTM/Lff2yoAnJcpHwrx7tyHdPwJDqdhjYaYd+88zLtnHhLiEtDlgy7o8E4H7D6025L2EozugIheAtADwGEAbcpZrzeA3gBw4YUXGm3WPHzenS/eKt6dO0hLEwEXHE/nlM5oV68dsvOzMW7FOFRNqmpJOyE7O4loIYCaAf41lJk/9VtvCICKzPxCqEYd19lpJANCsicEQdBBibcE8XHxhvZhedYKEV0IYB4zNw61ruOEPFIke0IQBBuxKmslxe9tFwCbjezPdUh8XRAEB2A0Rj6KiBoA8ALYDSDDuEkuQuLrgiA4AENCzszdzDLElfiyJyRGbi3SDyEI5WI4a8W1mCUOkj1hLdIPIQghiU0hF3FwD4H6IeRaCcJpxGb1Q+mkdA8yilMQQhKbHrl0UroHPf0QEkMXYpzYFHLppHQX5fVDSJhMEGJUyAHppIwWJIYuCDEaIxeiB4mhC0IMe+RCdCBhMkEQIReiAAmTCTGOhFYEQRBcjgi5IAiCyxEhFwRBcDki5IIgCC5HhFwQBMHliJALgiC4HBFyQRAEl2OKkBPRE0TERHSOGfsTBN3k5QEjR2qvghCjGB4QRER1AHQA8ItxcwQhDKRgliAAMMcjfw3AUwDYhH0Jgn6krrwgADAo5ETUBcBeZl6jY93eRJRPRPkFBQVGmhUEDSmYJQgAdIRWiGghgJoB/jUUwDPQwiohYeZJACYBQGpqqnjvgnGkYJYgANAh5MzcLtDnRNQEwMUA1hARANQG8BMRtWLm30y1UhCCIQWzBCHyzk5mXgfgXN97ItoFIJWZ/zDBLkEQBEEnkkcuCILgckyrR87Mdc3alyAIgqAf8cgFQRBcjgi5IAiCyxEhFwRBcDnEbH9KNxEVANgd4ebnAHBiZozYFR5iV3iIXfpxok2AOXZdxMw1yn6oRMiNQET5zJyq2o6yiF3hIXaFh9ilHyfaBFhrl4RWBEEQXI4IuSAIgstxo5BPUm1AEMSu8BC7wkPs0o8TbQIstMt1MXJBEAThdNzokQuCIAh+iJALgiC4HNcKORENIKLNRLSBiEartgcAiMhDRHuJaHXpcpNqm/xx2tyqRDSciNaWnqsFRHSBapsAgIheKf1urSWiT4iomgNs6l76XfcSkfLUOiLqRERbiGg7Ef1HtT0AQERTieh3Ilqv2hZ/iKgOES0moo2l1/Axs9twpZATURsAXQA0Y+ZGAMYoNsmf15i5eekyT7UxPhw6t+orzNyUmZsDmAvgecX2+PgaQGNmbgpgK4Ahiu0BgPUA7gDwrWpDiCgewAQAnQFcDuBuIrpcrVUAgOkAOqk2IgDFAJ5g5ssBXA2gn9nny5VCDqAvgFHMfAIAmPl3xfa4AcfNrcrMf/u9rQKH2MbMC5i5uPTt99AmTVEKM29i5i2q7SilFYDtzPwzMxcB+ACaY6UUZv4WwF+q7SgLM+9n5p9K/z4CYBOAWma24VYhrw/geiL6gYiWEtGVqg3yo3/pI/lUIjpbtTFAeHOr2g0RvUREewDcC+d45P70AvClaiMcRi0Ae/ze/wqThSlaIaK6AFoA+MHM/ZpWj9xsQswVmgCgOrTHlCsBfEhE9diGXMoQdmUDGA7NsxwOYCw0IbAcs+ZWNZvy7GLmT5l5KIChRDQEQH8ALzjBrtJ1hkJ7LH7XKTYJ7oWIzgIwG8DAMk+jhnGskAebKxQAiKgvgI9LhXsFEXmhFaQpUGmXP0Q0GVrc1xacOreq3vMFTSznwSYhD2UXET0I4BYAbe1wEPTY5CD2Aqjj97526WdCEIioAjQRf5eZPzZ7/24NrcwB0AYAiKg+gEQ4oNoZEZ3v9/Z2aB1USmHmdcx8LjPXLZ3F6VcAVzhhgmwiSvF72wXAZlW2+ENEnaD1J9zGzP9TbY8D+RFAChFdTESJAO4C8JlimxwLaR7UFACbmPlVS9pw48jO0i/PVADNARQBGMzMi5QaBYCI3oZmEwPYBaAPM+9XaVNZnDRJNhHNBtAAgBdaWeMMZlbu2RHRdgBJAP4s/eh7Zs5QaBKI6HYA4wDUAHAIwGpm7qjQnpsAZAGIBzCVmV9SZYsPInofQDq0p/MDAF5g5ilKjQJARNcBWAZgHbTvOgA8Y2ZWmyuFXBAEQTiFW0MrgiAIQiki5IIgCC5HhFwQBMHliJALgiC4HBFyQRAElyNCLgiC4HJEyAVBEFzO/wFbF5/b4O2/twAAAABJRU5ErkJggg==",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"model = DenseLayer(2, 2, \"sigmoid\")\n",
"model = SGD(x, y, model, \"bce\", learning_rate=0.3, epochs=50, batch_size=20)\n",
"\n",
"plt.plot(x[y == 0, 0], x[y == 0, 1], \"b.\")\n",
"plt.plot(x[y == 1, 0], x[y == 1, 1], \"r.\")\n",
"\n",
"x1_gen = np.linspace(-6, 2, 10)\n",
"x2_gen = -model.Wxy[0, 0] * x1_gen / model.Wxy[0, 1] - model.by[0, 0] / model.Wxy[0, 1]\n",
"\n",
"plt.plot(x1_gen, x2_gen, \"g-\")\n",
"\n",
"plt.show()\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Ypq84RCl0bnI"
},
"source": [
"## Test sur un problème de classification binaire plus complexe\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "6OPzEofrSrSF"
},
"source": [
"Testons maintenant un problème de classification plus complexe :\n"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {
"id": "_IQdphRV0hsB"
},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAXIAAAD4CAYAAADxeG0DAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAflklEQVR4nO2df4weR3nHv8+9ZxsEVJUuUaEkh5EaVbQYNeKU6hUIHUooUUWh1EUqqurgSD5FclQitaI9ohS3ETFVJGRE+OMujSNbiqCtTASiqUocciXgN5BzEgokQAMSJghKcJVChGzn7p7+sbe5vb39NbszuzO73490en3vvZ6d2X33O89+55kZUVUQQggJl6muK0AIIaQZFHJCCAkcCjkhhAQOhZwQQgKHQk4IIYEz3cVBL7vsMt27d28XhyaEkGA5e/bsz1X18vT7nQj53r17sbq62sWhCSEkWETkh1nv01ohhJDAoZATQkjgUMgJISRwKOSEEBI4FHJCCAkcCjkhhAQOhXyATCbA0aPRKyEkfDrJIyfdMZkA114LXLoE7N4NPPQQMB53XStCSBMYkQ+MlZVIxNfXo9eVla5rRAhpCoV8YMzPR5H4aBS9zs93XSNCSFNorQyM8TiyU1ZWIhGnrUJI+FDIB8h4TAEnpE/QWiGEkMChkBNCSOBQyAkhJHAo5IQQEjgUckJ6AmfsDhdmrRDSAzhjd9gwIiekB3DG7rChkJPBYGo9hGRVcMbusKG1QgaBqfUQmlXBGbvDhhE5CRLTaNnUegjRqhiPgcVFivgQaRyRi8iVAE4C+A0ACmBZVT/RtFxC8qgTLcfWQ/x/yqwH088T0iU2rJU1AH+lqo+LyKsAnBWRB1X1KQtlE7KDrGi5TMhNrQdaFSQkGgu5qv4EwE82//1LEXkawGsBUMiJE+pGy6aLhQ1hcbHJhJ1VH7A62CkiewFcDeBrGX9bALAAALOzszYPSyzRxU1d55iMlu0Q2oAuyceakIvIKwGcAnCLqv4i/XdVXQawDABzc3Na5xiMHtzRxU3d5JhDiJZdU8eiIn5iJWtFRHYhEvH7VPWzNspME9/0t90WvYaQ2xsSXWRphJgZ0ieYe94fGgu5iAiAewA8raofb16lbHjTu6WLm9r2MUOawOMDsUV1++20VULHhrXyFgB/AeCbIvLk5nsfVtUHLJT9EkwHc0sXvrPNY9LvrQctqn5gI2vlKwDEQl0K4QCXe7q4qW0dk34vGTJBTdFn9EDyCPWJrWgAn4P7pCpBCTkpZsg3vk9PbFWvQ5EdRKuImEAh7wm88f14YjO5DkV2EK0iYgIXzeoJzOrxA5PrUJS14yqLiJk9/YQReU/wzSMeqs1jch2K7CAXVhGf2voLhbwn+OYRD1Uw6izOlfcZ21YR7Zr+QiHvET54xEB7guFr1O/LdUjj21MbsQeFnFinDcFIRv3T08DBg8CBA34KqC/49NRG7EIhJ9ZpQzCSUf/6OrC0BJw4MSwbpw6+Pi2QZlDIiRNcC0Yc9V+4AKhGP331fX21kIg/UMhJkMRR/8mTwPHjUVTeR9+36cAxO4FhQCEnwRJH/QcO9FesmgwcDzl7aGhQyEnw9Nn3bTJwzHTD4UAhJ94zZHugycAx0w2HA4WceA3tgfpPHEw3HA4UcuI1ZfbAkKP1KvTZdiJbUMiJ1xTZA4zWCYng6ofE6xXxivaV5IqPhEQwIh84IUS1efYAB/MIiWBEPnB8j2qLnhZ83wXe5ycd0i8YkQ8cV1GtjUHIKk8Lvg7mhfCkQ/oDhbxlXGVZ1C3X5w0MQpjQknfeQ6g76Q8U8hZxFaU1LdfHDQwmE+DcuWiJWqA9D9ykQyw67/TvSZtQyFvEVZTmW/SXFLHp6UiQJ5N6a4SMRsChQ+2sNW7aIRadd07GIW3Cwc4WcbWhrqty6xKL2KFD0fKyd98dCWTVQb/0WuOzs8VCaGtQ0XTgt+y8j8fA4iJFnLiHEXmLuIrSbJZry8Mfj6NyYjE2eVIwsSVs2lXz88Du6XVc2gB2TwPz86PCz2edd840JV1AIW8ZV1kWNsq1IYpJIasqyGnxM+mYbNpKY0zwkC5iBW/BvH4VYxwFUFxY8rzH5+/ixShKv+suYGGhXl1c4WNH42OdQoNCTl6iqShmdQRlgpzXeVTtmKwOKq6sYLz+FYz1P4H1kfEJWFmJRHxjI/o5fBjYt88fcfIxJdLHOoUIPXLyEk299ryOoMgnbjohyeqkoIYnYH4++q8xGxvNJ1jZnFTk4+QvH+sUIlYichE5DuBdAH6mqm+0USZpn6Zee53o2EZEbc2uangCxuPITjl8GNhYV+wZrWF+5jsA9tWqju1o1ceUSB/rFCKiqs0LEXkbgBcAnKwi5HNzc7q6utr4uMQPkh4nYK6DffNIJ8vfxMrhf8X8xpcw3vN4bQU+ehS47bYoWh2NoqeOxcWGdfPwXPtYJ18RkbOqOpd+30pErqpfFpG9NsoiYZEVNZqKja/T7OsyPv8FjPUOYGMduGTutce4iFZ9PNc+1ik0WvPIRWRBRFZFZPW5555r67DEMY09zj6uLFXFa6/Qbt8XBSP+0FrWiqouA1gGImulreP6RB8fIRtFjT6lLNi8OGVeu0G747fjDjKvan38bpHqMP2wJXzSLJsYjQ+m1caXtQVMLk5VxSzyC0ranR5zKKtaX79bpDoU8pbwSbNWVoCZGeD8eXsBaGkZWWrjS8pCnj+UFmxbilnQ7vQhbrih/Hvjy3eLdIet9MNPA5gHcJmIPAvgI6p6j42y+4IPmpWcebixAUxNAXv2tBTBZanN4qIfK0ulL87MTLZg21LMgseY9CGA8u+ND98t0i22slbeb6OcPmOaouzC84xFYmMj+n1jo8UILk9tysL5rBORd3JsLcqeJ9g2FTOn3elDHDgQ/RQ1iysthoOzsQxVbf3nzW9+s5J8zpxRffnLVUej6PXMGbvlTk2pAtFrWflnzqjecYelOpgWlnUi8k6OzZNWVFZRGyydLKvnnHiDja8ogFXN0FR65B7iyvNMRm5VPHLrg2imCcN53nXWybG6elYqxAWiVMHkql5pLJ6sokMw6g4Xl2MZFHIPcel5mmhp54NoeSci/V68nVC80ImNkxafqKoC7fhkhZKZws4mH5f3NYXcA5os4+oSoy+e6R5pVVP4sk5EOlqOFW562v52QlUF2vGIY+edagVC6Wy6wul9neW3uP6hR76FKz/cFqV+7ZkzqjfdpLp791YjlpaKfWSbDb7jjqgsIHq9445m5aU5cyZqm0j02tqAws6iff6eqLq/FIQeubf4HmkVWjFxCHbhQrSnGxDlNt58c5QSkxWW2W5wG7l3Ittf83C4aIgvT2lFMA2yOyjkHRP0lz8W5VjERaLk9PX1/NxG2w2uMh2+TP2KZkmtrABra1Eb19Y67Wl9X1wqhM6mr1DIOyboL39SlKengYMHgauvBm65JV+oXTS4SSZJ2SypuvvVdYSLapiU6Xtn01co5B4QzJe/6qjsvn3lM1hsNzhLbcpsnMkEOHJkS8SBnU8SVToeT0b5XFTDVZldTozrIxTyAVLr5jDZXLPtnimvbkXRdFYkHr+mP1vWHk8GOlxUw3aZpuuTedA/BgGFfGDUvjk8EattxD3SuXPZdSuKppPrFUxNAdddB+zfX28lMU8GOlxUw3aZJl8jH79yvkIhHxi1bw5PxOolkj3SaBR59ED1aDrdniNH7M0Edak2BY9TroYfqpRZ9SnP5Gvk21fOZ6zs2WkK9+zsjkaPq20YllWPkd7Q8tAhYHa235uFeuo1mFaLHnl9nO7ZScKhUdTm2vtOK8KxY/lWR9YygaZ1C2aUeRNPvQbTapmc9tAuUVdQyAeItzdHUhEuXgQOH47yt7PCvDbsDFfhYN1ya3gNbUS0tEC6h0JO/CGpCHkTi7JSIF3gysZoUq5h59WWExP0XIieQCF3DD2+TaqciKQizMzsnFjUpkfsysZoWq5B55V+wDlypNmYrqVqEQdQyB3i6dhU+9Q5Efv27Qzzjh5tzyN25Re06EPEh4pT5U+fBh55xM33kAFLt1DIHdLV2JTtndAaU/VEpFMKb7xx+yBmm2asS7/ghhuiV5vL7WYwHkfjxXfeCXz/++629mPA4gFZSyK6/hnKMrZdLD3axk5o1iqVJrkOKhAtHWuy1ZrvtHwR6mztVwcuX9seyFnGdqrrjqTPxEHd7be3F6VkBb9F77dC1RMRR9zxcrGqOys7HgOLi92FfJNJZPFMJub/t+WLkDV51cX3ML5soxGzVrqC1opj2h4EynMfqrgSTq2XKiciFvyTJ4F7742WjfVJGZp6CDMzkaLGKZWO22Vz8moRzFrpHs7s7CF1PHLvfM62DP2qx4lXSjx9OgpxR6PoCWNxsfpx4kW6pqaAT30KWFiw0AAUtoGDkP2CMzsHRF7wWxQUb3vqv7COlZPPYjx+ndN6FtLGLNJ05J/Xe2WtlGgaUSd9DpFoxqqtdhT0wOnTSGHvJ/TICYDNx/DpdYzwInbrRcwfv6GeDxwCsfgtLUXiXOZZ2zCbXRnJBr573Ozbbote+3p5hwgjcgJg0+c8eB9Wlr6Lef0SxuuPebOWh3Vi8UtuUVc0cHDuXCTAQD2zOQ6Di9aOqYtBSqZpOiyj93CgkJOXGB+4CuMTN/V/0Yyk+GXlq8ckbYvp6WiFRdPcb9eDDwYjjSZp+FV3yaPQ+wGFfAAY3XAtTVaphCulqCp+yRAWiJbJNQ1h25gVVnE8wSS7pKza3g2ODxwKec+pfMOlP3jgQOt1LazPQw9F79sS9iriZyOEbTIbNdkxAFbaXnUMuazabc5aZuRfjhUhF5HrAXwCwAjAP6nqx2yUS5pT+Ybzba3rdH1OngROnDAT9qYKYCOErZtknbZ1VKOyWwp/y6rd1moJjPyr0VjIRWQE4FMA3gHgWQCPicjnVfWppmWT5lS+4ebnI8HY2Ihebd+ZpqKarjhQLuwunv1thLB1UimTHcPGRvRecqZrC2pWVO22JgH5Fl/4io2I/BoAz6jqDwBARD4D4D0AKOQeYHTDxVkctieJ1RHVdMWB7cINFN/hbSuAbWVLdgzpiNyTQeg2Zi1z04pq2BDy1wL4UeL3ZwH8fvpDIrIAYAEAZmdnLRyWVKXSDbeyEglFLBg2ha+uqKYrXiTs8Xrl8d+7UABTZSt6SsnqyGp2El17zE2Oz+n/1WhtsFNVlwEsA9EU/baOSyriUvhslV0m7Omo34UC2No5uMpTSrq9NdrQtcds4/htr1cUIjaE/McArkz8fsXmeyQkikKfNgcNTcuNyzp6dGsK/cWLkYc+O7t1PBthqUlydXqHo/Rnq+T3WYjGu/aYuz7+YMha29bkB1Fn8AMArwewG8A3APxu0f8ZynrkvaDThcwNWFraWsccUJ2e3qrz0pKdNpQtvJ08V9PTWwuBl302a831+G+7d6vu2VO77l1fvq6P3zeQsx5544hcVddE5GYA/4Eo/fC4qn67abnEE0IJqc6fj9ZBiTM81tai1wsXgHvusdMGk+Tqqalo6r9IdhZQ0VOKxYyVrj3mro8/FKx45Kr6AIAHbJRFPMOGv11ma9iwPWZmtjakSKIKPPHE9rVSytqQVx+T5OrRKDr2xsbOLKBk+VnL4KbLEWm0NnvXHnPXxx8CXI+clNNEaMt8ZRujYXEZFy5sXwgr/vdoFK2TkvTM89rVtD5xmefOAXffHUXVybXLq5bvYFYnCR+uR07q0ySkKrNmTKybvA4lLiMp4rt2bY9k02vH5Alq1foURe3x4Go6PdKkvRYyVkg1uk7PtAGFnLilzJqpat0URbJ5qxkC+XdonqBWqU/V1MEsG4YzXLyi6/RMW1DIiVvKfOWqo2FFkWxRGXF0fPRoNUHNKysZtplE1XHd4989Hv3rQ2RqSihj+aVkpbK4/mH6IcnkzJkoTS8rR61uHltZml/e8YrKqJrOWLXOVevhkKGmCYbWbrhKPyTh40UkVvaMWzeSLYvkq5STLuOJJ6qt214l3PPk2b43kakhHj8gGUEhHzie6Eg1JcmyKsqw4UmnF7A6fnxrAauiddurHLuo3S32sEO27vuQHkkhHzitRGJVBMnWIGMaGyFXsoxkWmHZCaty7Lx2p9vqYr9Pw6oSj8nyW1z/0CP3B+seYdrvNTlAmVdcNkW+ST1N/p+NE5Y8flZdkm2dmtq+5IDvRi5xBuiR9webT9xWI7GsiNkk5C97xrX1/D+ZRP/3xRejfHOTxxAbJ2x5Gbj55uic7NkTlZee4Zls69TU1nT9IRnYpDIU8sBw4Wlb8wizRLuJ+KZ7LFu9zsmTUX2Ard2GTMpqcsImE+Dw4a21YC5ezB8PiNuaXklxSAY2qQSFPDDyAlwvMk+yRLuu+Ob1WKGPTK2sbC2EBUQTmPKEOdnWffuiDoeQDCjkgZGlla1mnpjsatOkh3E5CnvgAHDvvVsnrCjzxDbz85GdcvFiZJncdVf1dsVT/k+cCHcKInEChTwwsrTy6NGWcoBNd7Vp0sO4zIcbj4GHH+7mEcZFPjwZPBTyAEm7C63lAJuKSdbn4/fLRMx1PlyXFk1L+fBe2G2kFSjkPaC1HGBTMUl/fmbGLEKvI7ZdL/9aRT3rLGVreJFt2m1Vm8ROozso5D2hlQDTtMdIf76JPWAqkOkNGaqKZROqqmeTqfsV62jLiam6TakXs4MHDIV8wNTSMNMeI/35qhF9OrI2FcgqW6TZVqCq6tl06n4Fmtptyf0xyqpB+757KOQDpZMoqmpEn67cDTeYC2Q6Ik8r2WQCHDkSZY/YmmgTH//ixejYzz+/c/ncquehaOp+hd63id2WfrCZ3lSJvA5hyOu0eEPWdE/XP5yi3z02Z7tbJ125m26qN80/bxp+PM0+3uV+aqr61Peyqf1LS6q7dqmKVCu7bOneussdNCDr9JetZuDBSryDAJyiT5J4HUWlK3fgAHD11cCpU8D+/WYDpEUWzMZGlMt93XVRdF4WtlZ5jDl/fvuGy0XRfpWle5O/t+RhZJ3+KsMhtFO6g0I+UFrLdKlDunLA1hT1Rx6JZjk2ScE4dy7yDIBIqaqIOFBNSJP2StxR2PLBW+p9bX43XGSzMENmJxTyAeN1FJWsXJ0ZT1l3ezICnp4GDh2qFm7GVBHS9BopRUvPmgpzi72vje+Gi3EYZshkQyGvQVcRwWAjEVPBy7vbkxEwAMzOmmfgHDtWbvFUVcE6wux177sdF04QM2SyoZAb0lVEEHQk0rQHMhW8vLvdRk6eLYsnpoIwh9qBu3CCvB7b6RAKuSFtRgR1Nm5vk9JJlJNJtGJfcmu0uj1QlUg0Pt5Pf5qdM9fUmujgIoTcgbtwgrwe2+kQCrkhbUUEWTt9+RSJlE6ixOYHLlzYyuBwKX6TCfD2t0eDjEC+B97EmuggHDTpO9KRuw+RvAsnKCB3qTUo5Ia0FRGkb+Dz5/2KREonUWLzA7GIi7gVv7hCMbEPbrIwVRkdhINV+46sjj+5F0VIkTwxp5GQi8j7ABwB8AYA16jqqo1K+U4bEUHeHg2+3IzlkygTH5ieBg4eNMsQqVuhOCIfjaI1x8vWWjHF8UWouylSuuM/dco/K464o2lE/i0AfwJgyUJdSALfvcCsVO/tdTVsgI0B0Ycf3r6LTtXd7j2hyaZI6Y5///5oPNYXK464pZGQq+rTACAidmpDtuFTBJ5F6STKqg2ou6xrUYUmk60ddQJRsiZjqVkd/759/gYCxC70yEn3VFEw0/SNth5pLI4oNh1LzepYKeDDoFTIReQ0gFdn/OlWVf1c1QOJyAKABQCYnZ2tXEEyAObnMRm9FSsbb8H86KsY21rW1bWSWc4N9N1OI/5SKuSqep2NA6nqMoBlAJibm1MbZZJ+MMEY18pDuATBblE8hBF2aJiPM0Ec5JXb7nt8SEEk7qG1QjpnZQW4tDbCugKX1nL00Ha4akPhKnQuXQppyJOJiBlN0w/fC+CTAC4H8G8i8qSqvtNKzchgqBxs2wpXbSlcSecymURvv/gisGtX+4kzPs4GJm5omrVyP4D7LdWFDJTWvWGbCpfRucRR+Ne/vjVH6dKlKDOyTSH10Y0ibqC1Qryg1QwLhwqXDPa7hoOnw4FCTnpLrj/tUOGSwf7UVDTBdGNja6edtmEK4jCgkJNeUmqDO1K4dLB/7Fjx3hKE2IBCTnpJVwN9tDNIF1DISS9pY6Avz7qhnZEP89rdQCEnvcR1ZMwcbXN4ztwx1XUFCDFhMon2Yp5Myj87HgOLi27EIsu6IcXwnLmDETkJBp8iOuZom8Nz5g4KuUPoB9rF1gCmjevCQU1zfFxloS9QyB3hU/TYF2xEdDavCwc1zfFtlYW+QI/cEfQD7RNHdLffXv/G5XUJj6xxEV7H7TAidwT9QDc0jeh4XcIiL/LmddwOhdwR9FD9pOi60HP1j7xxEd5f2xHV9vd4mJub09XV1daPS0ge9Fz9hNdlOyJyVlXn0u8zIicEXLvbVxh5V4NCTgjoufoMs4PKoZCTwVDkgXcV+dGXJzagkJNBUMVrbTvyo/9LbME8cjII2sw7rroeDHOhiS0YkZNB0JYHbhJl05cntqCQk0HQlgdukv3CjAxiCwp5z+Fg2hZteOCmUTYzMogNBi3kfRc5Dqa1D6Ns0gWDFfIhiBwnuXQDo2zSNoPNWhlCxkD8mD8acTCNkD4z2Ih8CBkDfMwnZBgMVsiHInJ8zCd9pu/jXFUZrJADFDlCQmYI41xVGaxH7gKTHd4JIc0YwjhXVRpF5CJyJ4A/AnAJwPcBHFTV5y3UKzgYHRDSLkMY56pK04j8QQBvVNU3AfgegMXmVQoTRgeEtIuNPVz7QqOIXFW/mPj1UQB/2qw64cLoYFhwkM0POM4VYXOw80YA/5z3RxFZALAAALOzsxYP6wdDyYIhtNGIf5QKuYicBvDqjD/dqqqf2/zMrQDWANyXV46qLgNYBqI9O2vV1nMYHQyDIc6Y5ROI35QKuapeV/R3EfkAgHcBuFa72MmZkJaZmQGmpgDVYdhofALxn0aDnSJyPYAPAXi3qv7KTpXcwNRAYoPJBLjlligan5oCjh3rv6hxIN9/mnrkdwHYA+BBEQGAR1X1psa1sgwjCmKLWNQ2NgAR4Pz5rmvkHg7k+0/TrJXfslURlwzR0yRuGKKocSDffwYxRX+INx9xw1BFjQP5fjMIIR/qzUfcYCpqzPggrhmEkAOMKEg3cHyGtAEXzSLEIcz4IG1AISfEIbZ2aWL6LCliMNYKIV1gY3yG9gwpg0JOiGOajs8wfZaUQWuFEM/hJtqkDEbkhHgO02dJGRRyEhxDzMtm+iwpgkJOgoIDf4TshB45CQrmZROyEwo5CQoO/BGyE1orJCg48EfITijkJDg48EfIdmitEEJI4FDICSEkcCjkhBASOBRyQggJHAo5IYQEDoWcEEICh0JOCCGBQyEnxCHc2Ye0AScEEeIILvBF2oIROSGO4AJfpC0o5IQ4ggt8kbagtUKII7jAF2kLCjkhDuECX6QNaK0QQkjgNBJyEbldRP5LRJ4UkS+KyG/aqhghhJBqNI3I71TVN6nq7wH4AoC/a14lQgghJjQSclX9ReLXVwDQZtUhhBBiSuPBThH5KIADAP4PwNsLPrcAYAEAZmdnmx6WEELIJqJaHESLyGkAr874062q+rnE5xYBvExVP1J20Lm5OV1dXTWtKyGEDBoROauqczveLxNygwPMAnhAVd9Y4bPPAfhh4q3LAPzcSkX8oW9tYnv8pm/tAfrXJhvteZ2qXp5+s5G1IiJXqep/b/76HgDfqfL/0hURkdWsXiZk+tYmtsdv+tYeoH9tctmeph75x0TktwFsIIqwb2peJUIIISY0EnJV3W+rIoQQQurhy8zO5a4r4IC+tYnt8Zu+tQfoX5uctcfaYCchhJBu8CUiJ4QQUhMKOSGEBI43Qt63BbhE5E4R+c5mm+4XkV/vuk5NEZH3ici3RWRDRIJNCxOR60XkuyLyjIj8bdf1aYKIHBeRn4nIt7quiw1E5EoReVhEntr8rn2w6zo1RUReJiJfF5FvbLbp760fwxePXER+LV67RUT+EsDvqGqw6Ywi8gcAvqSqayLyjwCgqn/TcbUaISJvQJRqugTgr1U1uOm5IjIC8D0A7wDwLIDHALxfVZ/qtGI1EZG3AXgBwMkqk/F8R0ReA+A1qvq4iLwKwFkAfxzq9QEAEREAr1DVF0RkF4CvAPigqj5q6xjeROR9W4BLVb+oqmubvz4K4Iou62MDVX1aVb/bdT0acg2AZ1T1B6p6CcBnEE1mCxJV/TKA/+26HrZQ1Z+o6uOb//4lgKcBvLbbWjVDI17Y/HXX5o9VffNGyIFoAS4R+RGAP0e/lsS9EcC/d10JAiAShR8lfn8WgQtFXxGRvQCuBvC1jqvSGBEZiciTAH4G4EFVtdqmVoVcRE6LyLcyft4DAKp6q6peCeA+ADe3Wbc6lLVn8zO3AlhD1CbvqdImQlwjIq8EcArALamn9SBR1fXNfRuuAHCNiFi1wVrds1NVr6v40fsAPACgdCXFLilrj4h8AMC7AFyrvgxGlGBwjULlxwCuTPx+xeZ7xBM2feRTAO5T1c92XR+bqOrzIvIwgOsBWBug9sZaEZGrEr9WXoDLV0TkegAfAvBuVf1V1/UhL/EYgKtE5PUishvAnwH4fMd1IptsDgzeA+BpVf141/WxgYhcHmeticjLEQ20W9U3n7JWTgHYtgCXqgYbKYnIMwD2ADi/+dajIWfhAICIvBfAJwFcDuB5AE+q6js7rVQNROQPARwDMAJwXFU/2m2N6iMinwYwj2iJ1P8B8BFVvafTSjVARN4K4BEA30SkBQDwYVV9oLtaNUNE3gTgBKLv2xSAf1HVf7B6DF+EnBBCSD28sVYIIYTUg0JOCCGBQyEnhJDAoZATQkjgUMgJISRwKOSEEBI4FHJCCAmc/wdczAUOF+WZVwAAAABJRU5ErkJggg==",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"x, y = datasets.make_gaussian_quantiles(\n",
" n_samples=250, n_features=2, n_classes=2, random_state=1\n",
")\n",
"\n",
"plt.plot(x[y == 0, 0], x[y == 0, 1], \"r.\")\n",
"plt.plot(x[y == 1, 0], x[y == 1, 1], \"b.\")\n",
"\n",
"plt.show()\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "8Ol3eqKGSyC5"
},
"source": [
"Le code ci-dessous vous permettra d'afficher la frontière de décision établie par votre modèle :\n"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"id": "lN8d7YK76MBm"
},
"outputs": [],
"source": [
"def print_decision_boundaries(model, x, y):\n",
" dx, dy = 0.1, 0.1\n",
" y_grid, x_grid = np.mgrid[slice(-4, 4 + dy, dy), slice(-4, 4 + dx, dx)]\n",
"\n",
" x_gen = np.concatenate(\n",
" (\n",
" np.expand_dims(np.reshape(y_grid, (-1)), 1),\n",
" np.expand_dims(np.reshape(x_grid, (-1)), 1),\n",
" ),\n",
" axis=1,\n",
" )\n",
" z_gen = model.forward(np.transpose(x_gen)).reshape(x_grid.shape)\n",
"\n",
" z_min, z_max = 0, 1\n",
"\n",
" c = plt.pcolor(x_grid, y_grid, z_gen, cmap=\"RdBu\", vmin=z_min, vmax=z_max)\n",
" plt.colorbar(c)\n",
" plt.plot(x[y == 0, 0], x[y == 0, 1], \"r.\")\n",
" plt.plot(x[y == 1, 0], x[y == 1, 1], \"b.\")\n",
" plt.show()\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "SRNifc8KS_MM"
},
"source": [
"Complétez le code ci-dessous :\n"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {
"id": "E9WV-Az70mR6"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 0 : Loss 0.8098\n",
"Epoch 1 : Loss 0.7164\n",
"Epoch 2 : Loss 0.6958\n",
"Epoch 3 : Loss 0.6941\n",
"Epoch 4 : Loss 0.6899\n",
"Epoch 5 : Loss 0.6902\n",
"Epoch 6 : Loss 0.6872\n",
"Epoch 7 : Loss 0.6860\n",
"Epoch 8 : Loss 0.6875\n",
"Epoch 9 : Loss 0.6857\n",
"Epoch 10 : Loss 0.6890\n",
"Epoch 11 : Loss 0.6890\n",
"Epoch 12 : Loss 0.6881\n",
"Epoch 13 : Loss 0.6902\n",
"Epoch 14 : Loss 0.6953\n",
"Epoch 15 : Loss 0.6916\n",
"Epoch 16 : Loss 0.6908\n",
"Epoch 17 : Loss 0.6911\n",
"Epoch 18 : Loss 0.6888\n",
"Epoch 19 : Loss 0.6923\n",
"Epoch 20 : Loss 0.6901\n",
"Epoch 21 : Loss 0.6914\n",
"Epoch 22 : Loss 0.6904\n",
"Epoch 23 : Loss 0.6928\n",
"Epoch 24 : Loss 0.6904\n",
"Epoch 25 : Loss 0.6899\n",
"Epoch 26 : Loss 0.6903\n",
"Epoch 27 : Loss 0.6852\n",
"Epoch 28 : Loss 0.6898\n",
"Epoch 29 : Loss 0.6921\n",
"Epoch 30 : Loss 0.6935\n",
"Epoch 31 : Loss 0.6887\n",
"Epoch 32 : Loss 0.6915\n",
"Epoch 33 : Loss 0.6900\n",
"Epoch 34 : Loss 0.6900\n",
"Epoch 35 : Loss 0.6859\n",
"Epoch 36 : Loss 0.6892\n",
"Epoch 37 : Loss 0.6903\n",
"Epoch 38 : Loss 0.6922\n",
"Epoch 39 : Loss 0.6876\n",
"Epoch 40 : Loss 0.6905\n",
"Epoch 41 : Loss 0.6924\n",
"Epoch 42 : Loss 0.6907\n",
"Epoch 43 : Loss 0.6938\n",
"Epoch 44 : Loss 0.6911\n",
"Epoch 45 : Loss 0.6914\n",
"Epoch 46 : Loss 0.6924\n",
"Epoch 47 : Loss 0.6920\n",
"Epoch 48 : Loss 0.6871\n",
"Epoch 49 : Loss 0.6920\n"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"model = DenseLayer(2, 1, \"sigmoid\")\n",
"model = SGD(x, y, model, \"bce\", learning_rate=0.3, epochs=50, batch_size=20)\n",
"\n",
"print_decision_boundaries(model, x, y)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "J9jMU_YcTAJl"
},
"source": [
"Cette fois-ci il n'est pas possible de faire résoudre un problème aussi \"complexe\" à notre simple perceptron monocouche. Nous allons pour cela devoir passer au perceptron multi-couches !\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "yiGyXLvum0uI"
},
"source": [
"---\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "HIEVrFXkDdMD"
},
"source": [
"# Perceptron multi-couches\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "6ZWNGM7vVlCb"
},
"source": [
"## Implémentation du perceptron multi-couches\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "1a6VuuWODu8G"
},
"source": [
"A partir du perceptron mono-couche créé précédemment, nous pouvons maintenant implémenter un perceptron multi-couches, qui est un véritable réseau de neurones dans la mesure où il met en jeu plusieurs couches de neurones successives. **Concrètement, le perceptron multi-couches est une composition de perceptron monocouches**, chacun prenant en entrée l'activation de sortie de la couche précédente. Prenons l'exemple ci-dessous :\n",
"\n",
"<img src=\"https://drive.google.com/uc?id=1ILboVqVVwy71lqAwM3ZGm6umCQegvmuV\" height=350>\n",
"\n",
"Ce perceptron multi-couches est la composition de deux perceptrons monocouches, le premier liant deux neurones d'entrée à deux neurones de sortie, et le second deux neurones d'entrée à un neurone de sortie.\n",
"\n",
"<img src=\"https://drive.google.com/uc?id=1hyrrsf8ZpqUcy2_T89HbQX7fpmqtbNwa\" height=350>\n",
"\n",
"Voici comment nous l'implémenterons : le perceptron multi-couches consiste simplement en une liste de perceptrons monocouches (_DenseLayer_). A l'initialisation, le perceptron multi-couches est une liste vide, dans laquelle il est possible d'ajouter des couches denses (fonction _add_layer()_).\n",
"\n",
"```python\n",
"model = MultiLayerPerceptron()\n",
"model.add_layer(DenseLayer(2, 2, 'relu'))\n",
"model.add_layer(DenseLayer(2, 1, 'sigmoid'))\n",
"```\n",
"\n",
"La fonction _forward()_ du perceptron multi-couches consiste en le calcul successif de la sortie des couches denses. Chaque couche dense effectue une prédiction sur la sortie de la couche dense précédente.\n",
"\n",
"La fonction _backward()_ implémente l'algorithme de rétro-propagation du gradient. Les gradients des paramètres de la dernière couche sont calculés en premier, et sont utilisés pour calculer les gradients de la couche précédente, comme illustré sur cette figure.\n",
"\n",
"<img src=\"https://drive.google.com/uc?id=1KVH0DWbAwT7R6-XmpqmpWob1jqftqC84\" height=350>\n"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"id": "RNhqq0KXm4Jd"
},
"outputs": [],
"source": [
"class MultiLayerPerceptron:\n",
" def __init__(self):\n",
" # Initialisation de la liste de couches du perceptron multi-couches à la liste vide\n",
" self.layers = []\n",
"\n",
" # Fonction permettant d'ajouter la couche passée en paramètre dans la liste de couches\n",
" # du perceptron multi-couches\n",
" def add_layer(self, layer):\n",
" self.layers.append(layer)\n",
"\n",
" # Fonction réalisant la prédiction du perceptron multi-couches :\n",
" # Elle consiste en la prédiction successive de chacune des couches de la liste de couches,\n",
" # chacune prenant en entrée la prédiction de la couche précédente\n",
" def forward(self, x_batch):\n",
" y = x_batch\n",
" for layer in self.layers:\n",
" y = layer.forward(y)\n",
"\n",
" return y\n",
"\n",
" # Fonction de calcul des gradients de la fonction objectif par rapport à chaque paramètre \n",
" # du perceptron multi-couches\n",
" # L'entrée dy_hat correspond au gradient de la fonction objectif par rapport à la prédiction\n",
" # finale du perceptron multi-couches (notée dJ/dŷ sur la figure précédente)\n",
" # Cette fonction doit implémenter la rétropropagation du gradient : on parcourt la liste des\n",
" # couches en sens inverse (fonction reversed) et le gradient de la fonction objectif par rapport \n",
" # à l'entrée d'une couche est utilisé pour calculer les gradients de la couche précédente\n",
" # \n",
" # Cette fonction retourne une liste de dictionnaires de gradients, de même dimension que le nombre\n",
" # de couches\n",
" def backward(self, dy_hat):\n",
" gradients = []\n",
" for layer in reversed(self.layers):\n",
" grad = layer.backward(dy_hat)\n",
" gradients.append(grad)\n",
" dy_hat = grad[\"dx\"]\n",
"\n",
" return gradients[::-1]\n",
"\n",
" # Fonction de mise à jour des paramètres en fonction des gradients établis dans la \n",
" # fonction backward et d'un taux d'apprentissage\n",
" def update_parameters(self, gradients, learning_rate):\n",
" # print(gradients)\n",
" for i, layer in enumerate(self.layers):\n",
" layer.update_parameters(gradients[i], learning_rate)\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "GyIW025tVcPR"
},
"source": [
"## Test sur le problème simple de classification binaire\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "JEg5-Z7mVEWd"
},
"source": [
"Vous pouvez maintenant tester votre perceptron multi-couches sur le problème précédent. Deux couches suffisent pour résoudre le problème !\n"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {
"id": "pijGm1ipwrAw"
},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAXIAAAD4CAYAAADxeG0DAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAflklEQVR4nO2df4weR3nHv8+9ZxsEVJUuUaEkh5EaVbQYNeKU6hUIHUooUUWh1EUqqurgSD5FclQitaI9ohS3ETFVJGRE+OMujSNbiqCtTASiqUocciXgN5BzEgokQAMSJghKcJVChGzn7p7+sbe5vb39NbszuzO73490en3vvZ6d2X33O89+55kZUVUQQggJl6muK0AIIaQZFHJCCAkcCjkhhAQOhZwQQgKHQk4IIYEz3cVBL7vsMt27d28XhyaEkGA5e/bsz1X18vT7nQj53r17sbq62sWhCSEkWETkh1nv01ohhJDAoZATQkjgUMgJISRwKOSEEBI4FHJCCAkcCjkhhAQOhXyATCbA0aPRKyEkfDrJIyfdMZkA114LXLoE7N4NPPQQMB53XStCSBMYkQ+MlZVIxNfXo9eVla5rRAhpCoV8YMzPR5H4aBS9zs93XSNCSFNorQyM8TiyU1ZWIhGnrUJI+FDIB8h4TAEnpE/QWiGEkMChkBNCSOBQyAkhJHAo5IQQEjgUckJ6AmfsDhdmrRDSAzhjd9gwIiekB3DG7rChkJPBYGo9hGRVcMbusKG1QgaBqfUQmlXBGbvDhhE5CRLTaNnUegjRqhiPgcVFivgQaRyRi8iVAE4C+A0ACmBZVT/RtFxC8qgTLcfWQ/x/yqwH088T0iU2rJU1AH+lqo+LyKsAnBWRB1X1KQtlE7KDrGi5TMhNrQdaFSQkGgu5qv4EwE82//1LEXkawGsBUMiJE+pGy6aLhQ1hcbHJhJ1VH7A62CkiewFcDeBrGX9bALAAALOzszYPSyzRxU1d55iMlu0Q2oAuyceakIvIKwGcAnCLqv4i/XdVXQawDABzc3Na5xiMHtzRxU3d5JhDiJZdU8eiIn5iJWtFRHYhEvH7VPWzNspME9/0t90WvYaQ2xsSXWRphJgZ0ieYe94fGgu5iAiAewA8raofb16lbHjTu6WLm9r2MUOawOMDsUV1++20VULHhrXyFgB/AeCbIvLk5nsfVtUHLJT9EkwHc0sXvrPNY9LvrQctqn5gI2vlKwDEQl0K4QCXe7q4qW0dk34vGTJBTdFn9EDyCPWJrWgAn4P7pCpBCTkpZsg3vk9PbFWvQ5EdRKuImEAh7wm88f14YjO5DkV2EK0iYgIXzeoJzOrxA5PrUJS14yqLiJk9/YQReU/wzSMeqs1jch2K7CAXVhGf2voLhbwn+OYRD1Uw6izOlfcZ21YR7Zr+QiHvET54xEB7guFr1O/LdUjj21MbsQeFnFinDcFIRv3T08DBg8CBA34KqC/49NRG7EIhJ9ZpQzCSUf/6OrC0BJw4MSwbpw6+Pi2QZlDIiRNcC0Yc9V+4AKhGP331fX21kIg/UMhJkMRR/8mTwPHjUVTeR9+36cAxO4FhQCEnwRJH/QcO9FesmgwcDzl7aGhQyEnw9Nn3bTJwzHTD4UAhJ94zZHugycAx0w2HA4WceA3tgfpPHEw3HA4UcuI1ZfbAkKP1KvTZdiJbUMiJ1xTZA4zWCYng6ofE6xXxivaV5IqPhEQwIh84IUS1efYAB/MIiWBEPnB8j2qLnhZ83wXe5ycd0i8YkQ8cV1GtjUHIKk8Lvg7mhfCkQ/oDhbxlXGVZ1C3X5w0MQpjQknfeQ6g76Q8U8hZxFaU1LdfHDQwmE+DcuWiJWqA9D9ykQyw67/TvSZtQyFvEVZTmW/SXFLHp6UiQJ5N6a4SMRsChQ+2sNW7aIRadd07GIW3Cwc4WcbWhrqty6xKL2KFD0fKyd98dCWTVQb/0WuOzs8VCaGtQ0XTgt+y8j8fA4iJFnLiHEXmLuIrSbJZry8Mfj6NyYjE2eVIwsSVs2lXz88Du6XVc2gB2TwPz86PCz2edd840JV1AIW8ZV1kWNsq1IYpJIasqyGnxM+mYbNpKY0zwkC5iBW/BvH4VYxwFUFxY8rzH5+/ixShKv+suYGGhXl1c4WNH42OdQoNCTl6iqShmdQRlgpzXeVTtmKwOKq6sYLz+FYz1P4H1kfEJWFmJRHxjI/o5fBjYt88fcfIxJdLHOoUIPXLyEk299ryOoMgnbjohyeqkoIYnYH4++q8xGxvNJ1jZnFTk4+QvH+sUIlYichE5DuBdAH6mqm+0USZpn6Zee53o2EZEbc2uangCxuPITjl8GNhYV+wZrWF+5jsA9tWqju1o1ceUSB/rFCKiqs0LEXkbgBcAnKwi5HNzc7q6utr4uMQPkh4nYK6DffNIJ8vfxMrhf8X8xpcw3vN4bQU+ehS47bYoWh2NoqeOxcWGdfPwXPtYJ18RkbOqOpd+30pErqpfFpG9NsoiYZEVNZqKja/T7OsyPv8FjPUOYGMduGTutce4iFZ9PNc+1ik0WvPIRWRBRFZFZPW5555r67DEMY09zj6uLFXFa6/Qbt8XBSP+0FrWiqouA1gGImulreP6RB8fIRtFjT6lLNi8OGVeu0G747fjDjKvan38bpHqMP2wJXzSLJsYjQ+m1caXtQVMLk5VxSzyC0ranR5zKKtaX79bpDoU8pbwSbNWVoCZGeD8eXsBaGkZWWrjS8pCnj+UFmxbilnQ7vQhbrih/Hvjy3eLdIet9MNPA5gHcJmIPAvgI6p6j42y+4IPmpWcebixAUxNAXv2tBTBZanN4qIfK0ulL87MTLZg21LMgseY9CGA8u+ND98t0i22slbeb6OcPmOaouzC84xFYmMj+n1jo8UILk9tysL5rBORd3JsLcqeJ9g2FTOn3elDHDgQ/RQ1iysthoOzsQxVbf3nzW9+s5J8zpxRffnLVUej6PXMGbvlTk2pAtFrWflnzqjecYelOpgWlnUi8k6OzZNWVFZRGyydLKvnnHiDja8ogFXN0FR65B7iyvNMRm5VPHLrg2imCcN53nXWybG6elYqxAWiVMHkql5pLJ6sokMw6g4Xl2MZFHIPcel5mmhp54NoeSci/V68nVC80ImNkxafqKoC7fhkhZKZws4mH5f3NYXcA5os4+oSoy+e6R5pVVP4sk5EOlqOFW562v52QlUF2vGIY+edagVC6Wy6wul9neW3uP6hR76FKz/cFqV+7ZkzqjfdpLp791YjlpaKfWSbDb7jjqgsIHq9445m5aU5cyZqm0j02tqAws6iff6eqLq/FIQeubf4HmkVWjFxCHbhQrSnGxDlNt58c5QSkxWW2W5wG7l3Ittf83C4aIgvT2lFMA2yOyjkHRP0lz8W5VjERaLk9PX1/NxG2w2uMh2+TP2KZkmtrABra1Eb19Y67Wl9X1wqhM6mr1DIOyboL39SlKengYMHgauvBm65JV+oXTS4SSZJ2SypuvvVdYSLapiU6Xtn01co5B4QzJe/6qjsvn3lM1hsNzhLbcpsnMkEOHJkS8SBnU8SVToeT0b5XFTDVZldTozrIxTyAVLr5jDZXLPtnimvbkXRdFYkHr+mP1vWHk8GOlxUw3aZpuuTedA/BgGFfGDUvjk8EattxD3SuXPZdSuKppPrFUxNAdddB+zfX28lMU8GOlxUw3aZJl8jH79yvkIhHxi1bw5PxOolkj3SaBR59ED1aDrdniNH7M0Edak2BY9TroYfqpRZ9SnP5Gvk21fOZ6zs2WkK9+zsjkaPq20YllWPkd7Q8tAhYHa235uFeuo1mFaLHnl9nO7ZScKhUdTm2vtOK8KxY/lWR9YygaZ1C2aUeRNPvQbTapmc9tAuUVdQyAeItzdHUhEuXgQOH47yt7PCvDbsDFfhYN1ya3gNbUS0tEC6h0JO/CGpCHkTi7JSIF3gysZoUq5h59WWExP0XIieQCF3DD2+TaqciKQizMzsnFjUpkfsysZoWq5B55V+wDlypNmYrqVqEQdQyB3i6dhU+9Q5Efv27Qzzjh5tzyN25Re06EPEh4pT5U+fBh55xM33kAFLt1DIHdLV2JTtndAaU/VEpFMKb7xx+yBmm2asS7/ghhuiV5vL7WYwHkfjxXfeCXz/++629mPA4gFZSyK6/hnKMrZdLD3axk5o1iqVJrkOKhAtHWuy1ZrvtHwR6mztVwcuX9seyFnGdqrrjqTPxEHd7be3F6VkBb9F77dC1RMRR9zxcrGqOys7HgOLi92FfJNJZPFMJub/t+WLkDV51cX3ML5soxGzVrqC1opj2h4EynMfqrgSTq2XKiciFvyTJ4F7742WjfVJGZp6CDMzkaLGKZWO22Vz8moRzFrpHs7s7CF1PHLvfM62DP2qx4lXSjx9OgpxR6PoCWNxsfpx4kW6pqaAT30KWFiw0AAUtoGDkP2CMzsHRF7wWxQUb3vqv7COlZPPYjx+ndN6FtLGLNJ05J/Xe2WtlGgaUSd9DpFoxqqtdhT0wOnTSGHvJ/TICYDNx/DpdYzwInbrRcwfv6GeDxwCsfgtLUXiXOZZ2zCbXRnJBr573Ozbbote+3p5hwgjcgJg0+c8eB9Wlr6Lef0SxuuPebOWh3Vi8UtuUVc0cHDuXCTAQD2zOQ6Di9aOqYtBSqZpOiyj93CgkJOXGB+4CuMTN/V/0Yyk+GXlq8ckbYvp6WiFRdPcb9eDDwYjjSZp+FV3yaPQ+wGFfAAY3XAtTVaphCulqCp+yRAWiJbJNQ1h25gVVnE8wSS7pKza3g2ODxwKec+pfMOlP3jgQOt1LazPQw9F79sS9iriZyOEbTIbNdkxAFbaXnUMuazabc5aZuRfjhUhF5HrAXwCwAjAP6nqx2yUS5pT+Ybzba3rdH1OngROnDAT9qYKYCOErZtknbZ1VKOyWwp/y6rd1moJjPyr0VjIRWQE4FMA3gHgWQCPicjnVfWppmWT5lS+4ebnI8HY2Ihebd+ZpqKarjhQLuwunv1thLB1UimTHcPGRvRecqZrC2pWVO22JgH5Fl/4io2I/BoAz6jqDwBARD4D4D0AKOQeYHTDxVkctieJ1RHVdMWB7cINFN/hbSuAbWVLdgzpiNyTQeg2Zi1z04pq2BDy1wL4UeL3ZwH8fvpDIrIAYAEAZmdnLRyWVKXSDbeyEglFLBg2ha+uqKYrXiTs8Xrl8d+7UABTZSt6SsnqyGp2El17zE2Oz+n/1WhtsFNVlwEsA9EU/baOSyriUvhslV0m7Omo34UC2No5uMpTSrq9NdrQtcds4/htr1cUIjaE/McArkz8fsXmeyQkikKfNgcNTcuNyzp6dGsK/cWLkYc+O7t1PBthqUlydXqHo/Rnq+T3WYjGu/aYuz7+YMha29bkB1Fn8AMArwewG8A3APxu0f8ZynrkvaDThcwNWFraWsccUJ2e3qrz0pKdNpQtvJ08V9PTWwuBl302a831+G+7d6vu2VO77l1fvq6P3zeQsx5544hcVddE5GYA/4Eo/fC4qn67abnEE0IJqc6fj9ZBiTM81tai1wsXgHvusdMGk+Tqqalo6r9IdhZQ0VOKxYyVrj3mro8/FKx45Kr6AIAHbJRFPMOGv11ma9iwPWZmtjakSKIKPPHE9rVSytqQVx+T5OrRKDr2xsbOLKBk+VnL4KbLEWm0NnvXHnPXxx8CXI+clNNEaMt8ZRujYXEZFy5sXwgr/vdoFK2TkvTM89rVtD5xmefOAXffHUXVybXLq5bvYFYnCR+uR07q0ySkKrNmTKybvA4lLiMp4rt2bY9k02vH5Alq1foURe3x4Go6PdKkvRYyVkg1uk7PtAGFnLilzJqpat0URbJ5qxkC+XdonqBWqU/V1MEsG4YzXLyi6/RMW1DIiVvKfOWqo2FFkWxRGXF0fPRoNUHNKysZtplE1XHd4989Hv3rQ2RqSihj+aVkpbK4/mH6IcnkzJkoTS8rR61uHltZml/e8YrKqJrOWLXOVevhkKGmCYbWbrhKPyTh40UkVvaMWzeSLYvkq5STLuOJJ6qt214l3PPk2b43kakhHj8gGUEhHzie6Eg1JcmyKsqw4UmnF7A6fnxrAauiddurHLuo3S32sEO27vuQHkkhHzitRGJVBMnWIGMaGyFXsoxkWmHZCaty7Lx2p9vqYr9Pw6oSj8nyW1z/0CP3B+seYdrvNTlAmVdcNkW+ST1N/p+NE5Y8flZdkm2dmtq+5IDvRi5xBuiR9webT9xWI7GsiNkk5C97xrX1/D+ZRP/3xRejfHOTxxAbJ2x5Gbj55uic7NkTlZee4Zls69TU1nT9IRnYpDIU8sBw4Wlb8wizRLuJ+KZ7LFu9zsmTUX2Ard2GTMpqcsImE+Dw4a21YC5ezB8PiNuaXklxSAY2qQSFPDDyAlwvMk+yRLuu+Ob1WKGPTK2sbC2EBUQTmPKEOdnWffuiDoeQDCjkgZGlla1mnpjsatOkh3E5CnvgAHDvvVsnrCjzxDbz85GdcvFiZJncdVf1dsVT/k+cCHcKInEChTwwsrTy6NGWcoBNd7Vp0sO4zIcbj4GHH+7mEcZFPjwZPBTyAEm7C63lAJuKSdbn4/fLRMx1PlyXFk1L+fBe2G2kFSjkPaC1HGBTMUl/fmbGLEKvI7ZdL/9aRT3rLGVreJFt2m1Vm8ROozso5D2hlQDTtMdIf76JPWAqkOkNGaqKZROqqmeTqfsV62jLiam6TakXs4MHDIV8wNTSMNMeI/35qhF9OrI2FcgqW6TZVqCq6tl06n4Fmtptyf0xyqpB+757KOQDpZMoqmpEn67cDTeYC2Q6Ik8r2WQCHDkSZY/YmmgTH//ixejYzz+/c/ncquehaOp+hd63id2WfrCZ3lSJvA5hyOu0eEPWdE/XP5yi3z02Z7tbJ125m26qN80/bxp+PM0+3uV+aqr61Peyqf1LS6q7dqmKVCu7bOneussdNCDr9JetZuDBSryDAJyiT5J4HUWlK3fgAHD11cCpU8D+/WYDpEUWzMZGlMt93XVRdF4WtlZ5jDl/fvuGy0XRfpWle5O/t+RhZJ3+KsMhtFO6g0I+UFrLdKlDunLA1hT1Rx6JZjk2ScE4dy7yDIBIqaqIOFBNSJP2StxR2PLBW+p9bX43XGSzMENmJxTyAeN1FJWsXJ0ZT1l3ezICnp4GDh2qFm7GVBHS9BopRUvPmgpzi72vje+Gi3EYZshkQyGvQVcRwWAjEVPBy7vbkxEwAMzOmmfgHDtWbvFUVcE6wux177sdF04QM2SyoZAb0lVEEHQk0rQHMhW8vLvdRk6eLYsnpoIwh9qBu3CCvB7b6RAKuSFtRgR1Nm5vk9JJlJNJtGJfcmu0uj1QlUg0Pt5Pf5qdM9fUmujgIoTcgbtwgrwe2+kQCrkhbUUEWTt9+RSJlE6ixOYHLlzYyuBwKX6TCfD2t0eDjEC+B97EmuggHDTpO9KRuw+RvAsnKCB3qTUo5Ia0FRGkb+Dz5/2KREonUWLzA7GIi7gVv7hCMbEPbrIwVRkdhINV+46sjj+5F0VIkTwxp5GQi8j7ABwB8AYA16jqqo1K+U4bEUHeHg2+3IzlkygTH5ieBg4eNMsQqVuhOCIfjaI1x8vWWjHF8UWouylSuuM/dco/K464o2lE/i0AfwJgyUJdSALfvcCsVO/tdTVsgI0B0Ycf3r6LTtXd7j2hyaZI6Y5///5oPNYXK464pZGQq+rTACAidmpDtuFTBJ5F6STKqg2ou6xrUYUmk60ddQJRsiZjqVkd/759/gYCxC70yEn3VFEw0/SNth5pLI4oNh1LzepYKeDDoFTIReQ0gFdn/OlWVf1c1QOJyAKABQCYnZ2tXEEyAObnMRm9FSsbb8H86KsY21rW1bWSWc4N9N1OI/5SKuSqep2NA6nqMoBlAJibm1MbZZJ+MMEY18pDuATBblE8hBF2aJiPM0Ec5JXb7nt8SEEk7qG1QjpnZQW4tDbCugKX1nL00Ha4akPhKnQuXQppyJOJiBlN0w/fC+CTAC4H8G8i8qSqvtNKzchgqBxs2wpXbSlcSecymURvv/gisGtX+4kzPs4GJm5omrVyP4D7LdWFDJTWvWGbCpfRucRR+Ne/vjVH6dKlKDOyTSH10Y0ibqC1Qryg1QwLhwqXDPa7hoOnw4FCTnpLrj/tUOGSwf7UVDTBdGNja6edtmEK4jCgkJNeUmqDO1K4dLB/7Fjx3hKE2IBCTnpJVwN9tDNIF1DISS9pY6Avz7qhnZEP89rdQCEnvcR1ZMwcbXN4ztwx1XUFCDFhMon2Yp5Myj87HgOLi27EIsu6IcXwnLmDETkJBp8iOuZom8Nz5g4KuUPoB9rF1gCmjevCQU1zfFxloS9QyB3hU/TYF2xEdDavCwc1zfFtlYW+QI/cEfQD7RNHdLffXv/G5XUJj6xxEV7H7TAidwT9QDc0jeh4XcIiL/LmddwOhdwR9FD9pOi60HP1j7xxEd5f2xHV9vd4mJub09XV1daPS0ge9Fz9hNdlOyJyVlXn0u8zIicEXLvbVxh5V4NCTgjoufoMs4PKoZCTwVDkgXcV+dGXJzagkJNBUMVrbTvyo/9LbME8cjII2sw7rroeDHOhiS0YkZNB0JYHbhJl05cntqCQk0HQlgdukv3CjAxiCwp5z+Fg2hZteOCmUTYzMogNBi3kfRc5Dqa1D6Ns0gWDFfIhiBwnuXQDo2zSNoPNWhlCxkD8mD8acTCNkD4z2Ih8CBkDfMwnZBgMVsiHInJ8zCd9pu/jXFUZrJADFDlCQmYI41xVGaxH7gKTHd4JIc0YwjhXVRpF5CJyJ4A/AnAJwPcBHFTV5y3UKzgYHRDSLkMY56pK04j8QQBvVNU3AfgegMXmVQoTRgeEtIuNPVz7QqOIXFW/mPj1UQB/2qw64cLoYFhwkM0POM4VYXOw80YA/5z3RxFZALAAALOzsxYP6wdDyYIhtNGIf5QKuYicBvDqjD/dqqqf2/zMrQDWANyXV46qLgNYBqI9O2vV1nMYHQyDIc6Y5ROI35QKuapeV/R3EfkAgHcBuFa72MmZkJaZmQGmpgDVYdhofALxn0aDnSJyPYAPAXi3qv7KTpXcwNRAYoPJBLjlligan5oCjh3rv6hxIN9/mnrkdwHYA+BBEQGAR1X1psa1sgwjCmKLWNQ2NgAR4Pz5rmvkHg7k+0/TrJXfslURlwzR0yRuGKKocSDffwYxRX+INx9xw1BFjQP5fjMIIR/qzUfcYCpqzPggrhmEkAOMKEg3cHyGtAEXzSLEIcz4IG1AISfEIbZ2aWL6LCliMNYKIV1gY3yG9gwpg0JOiGOajs8wfZaUQWuFEM/hJtqkDEbkhHgO02dJGRRyEhxDzMtm+iwpgkJOgoIDf4TshB45CQrmZROyEwo5CQoO/BGyE1orJCg48EfITijkJDg48EfIdmitEEJI4FDICSEkcCjkhBASOBRyQggJHAo5IYQEDoWcEEICh0JOCCGBQyEnxCHc2Ye0AScEEeIILvBF2oIROSGO4AJfpC0o5IQ4ggt8kbagtUKII7jAF2kLCjkhDuECX6QNaK0QQkjgNBJyEbldRP5LRJ4UkS+KyG/aqhghhJBqNI3I71TVN6nq7wH4AoC/a14lQgghJjQSclX9ReLXVwDQZtUhhBBiSuPBThH5KIADAP4PwNsLPrcAYAEAZmdnmx6WEELIJqJaHESLyGkAr874062q+rnE5xYBvExVP1J20Lm5OV1dXTWtKyGEDBoROauqczveLxNygwPMAnhAVd9Y4bPPAfhh4q3LAPzcSkX8oW9tYnv8pm/tAfrXJhvteZ2qXp5+s5G1IiJXqep/b/76HgDfqfL/0hURkdWsXiZk+tYmtsdv+tYeoH9tctmeph75x0TktwFsIIqwb2peJUIIISY0EnJV3W+rIoQQQurhy8zO5a4r4IC+tYnt8Zu+tQfoX5uctcfaYCchhJBu8CUiJ4QQUhMKOSGEBI43Qt63BbhE5E4R+c5mm+4XkV/vuk5NEZH3ici3RWRDRIJNCxOR60XkuyLyjIj8bdf1aYKIHBeRn4nIt7quiw1E5EoReVhEntr8rn2w6zo1RUReJiJfF5FvbLbp760fwxePXER+LV67RUT+EsDvqGqw6Ywi8gcAvqSqayLyjwCgqn/TcbUaISJvQJRqugTgr1U1uOm5IjIC8D0A7wDwLIDHALxfVZ/qtGI1EZG3AXgBwMkqk/F8R0ReA+A1qvq4iLwKwFkAfxzq9QEAEREAr1DVF0RkF4CvAPigqj5q6xjeROR9W4BLVb+oqmubvz4K4Iou62MDVX1aVb/bdT0acg2AZ1T1B6p6CcBnEE1mCxJV/TKA/+26HrZQ1Z+o6uOb//4lgKcBvLbbWjVDI17Y/HXX5o9VffNGyIFoAS4R+RGAP0e/lsS9EcC/d10JAiAShR8lfn8WgQtFXxGRvQCuBvC1jqvSGBEZiciTAH4G4EFVtdqmVoVcRE6LyLcyft4DAKp6q6peCeA+ADe3Wbc6lLVn8zO3AlhD1CbvqdImQlwjIq8EcArALamn9SBR1fXNfRuuAHCNiFi1wVrds1NVr6v40fsAPACgdCXFLilrj4h8AMC7AFyrvgxGlGBwjULlxwCuTPx+xeZ7xBM2feRTAO5T1c92XR+bqOrzIvIwgOsBWBug9sZaEZGrEr9WXoDLV0TkegAfAvBuVf1V1/UhL/EYgKtE5PUishvAnwH4fMd1IptsDgzeA+BpVf141/WxgYhcHmeticjLEQ20W9U3n7JWTgHYtgCXqgYbKYnIMwD2ADi/+dajIWfhAICIvBfAJwFcDuB5AE+q6js7rVQNROQPARwDMAJwXFU/2m2N6iMinwYwj2iJ1P8B8BFVvafTSjVARN4K4BEA30SkBQDwYVV9oLtaNUNE3gTgBKLv2xSAf1HVf7B6DF+EnBBCSD28sVYIIYTUg0JOCCGBQyEnhJDAoZATQkjgUMgJISRwKOSEEBI4FHJCCAmc/wdczAUOF+WZVwAAAABJRU5ErkJggg==",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"x, y = datasets.make_gaussian_quantiles(\n",
" n_samples=250, n_features=2, n_classes=2, random_state=1\n",
")\n",
"\n",
"plt.plot(x[y == 0, 0], x[y == 0, 1], \"r.\")\n",
"plt.plot(x[y == 1, 0], x[y == 1, 1], \"b.\")\n",
"\n",
"plt.show()\n"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {
"id": "h3He5gXmxQ1j"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 0 : Loss 0.6403\n",
"Epoch 1 : Loss 0.5871\n",
"Epoch 2 : Loss 0.5426\n",
"Epoch 3 : Loss 0.4999\n",
"Epoch 4 : Loss 0.4635\n",
"Epoch 5 : Loss 0.4315\n",
"Epoch 6 : Loss 0.3962\n",
"Epoch 7 : Loss 0.3760\n",
"Epoch 8 : Loss 0.3543\n",
"Epoch 9 : Loss 0.3248\n",
"Epoch 10 : Loss 0.3167\n",
"Epoch 11 : Loss 0.3017\n",
"Epoch 12 : Loss 0.2873\n",
"Epoch 13 : Loss 0.2752\n",
"Epoch 14 : Loss 0.2584\n",
"Epoch 15 : Loss 0.2557\n",
"Epoch 16 : Loss 0.2464\n",
"Epoch 17 : Loss 0.2313\n",
"Epoch 18 : Loss 0.2243\n",
"Epoch 19 : Loss 0.2278\n",
"Epoch 20 : Loss 0.2141\n",
"Epoch 21 : Loss 0.2088\n",
"Epoch 22 : Loss 0.2022\n",
"Epoch 23 : Loss 0.2044\n",
"Epoch 24 : Loss 0.1966\n",
"Epoch 25 : Loss 0.1851\n",
"Epoch 26 : Loss 0.1884\n",
"Epoch 27 : Loss 0.1830\n",
"Epoch 28 : Loss 0.1760\n",
"Epoch 29 : Loss 0.1794\n",
"Epoch 30 : Loss 0.1704\n",
"Epoch 31 : Loss 0.1716\n",
"Epoch 32 : Loss 0.1684\n",
"Epoch 33 : Loss 0.1631\n",
"Epoch 34 : Loss 0.1575\n",
"Epoch 35 : Loss 0.1578\n",
"Epoch 36 : Loss 0.1552\n",
"Epoch 37 : Loss 0.1564\n",
"Epoch 38 : Loss 0.1532\n",
"Epoch 39 : Loss 0.1495\n",
"Epoch 40 : Loss 0.1504\n",
"Epoch 41 : Loss 0.1449\n",
"Epoch 42 : Loss 0.1475\n",
"Epoch 43 : Loss 0.1397\n",
"Epoch 44 : Loss 0.1437\n",
"Epoch 45 : Loss 0.1367\n",
"Epoch 46 : Loss 0.1377\n",
"Epoch 47 : Loss 0.1336\n",
"Epoch 48 : Loss 0.1355\n",
"Epoch 49 : Loss 0.1329\n",
"Epoch 50 : Loss 0.1306\n",
"Epoch 51 : Loss 0.1305\n",
"Epoch 52 : Loss 0.1301\n",
"Epoch 53 : Loss 0.1281\n",
"Epoch 54 : Loss 0.1324\n",
"Epoch 55 : Loss 0.1229\n",
"Epoch 56 : Loss 0.1244\n",
"Epoch 57 : Loss 0.1213\n",
"Epoch 58 : Loss 0.1188\n",
"Epoch 59 : Loss 0.1223\n"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"model = MultiLayerPerceptron()\n",
"model.add_layer(DenseLayer(2, 10, \"relu\"))\n",
"model.add_layer(DenseLayer(10, 1, \"sigmoid\"))\n",
"\n",
"model = SGD(x, y, model, \"bce\", learning_rate=0.3, epochs=60, batch_size=20)\n",
"\n",
"print_decision_boundaries(model, x, y)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "SMTeraduVplm"
},
"source": [
"# Quelques exercices supplémentaires\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "46K0mq5bVvT1"
},
"source": [
"## Evanescence du gradient\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "pVBCGX9iVzdL"
},
"source": [
"Testez le réseau suivant sur le problème simple de classification binaire évoqué dans la partie précédente :\n",
"\n",
"```python\n",
"model.add_layer(DenseLayer(2, 10, 'sigmoid'))\n",
"model.add_layer(DenseLayer(10, 10, 'sigmoid'))\n",
"model.add_layer(DenseLayer(10, 10, 'sigmoid'))\n",
"model.add_layer(DenseLayer(10, 10, 'sigmoid'))\n",
"model.add_layer(DenseLayer(10, 1, 'sigmoid'))\n",
"```\n",
"\n",
"1. Qu'observez-vous ?\n",
"2. Comment résoudre ce problème ?\n"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 0 : Loss 0.7070\n",
"Epoch 1 : Loss 0.6948\n",
"Epoch 2 : Loss 0.6994\n",
"Epoch 3 : Loss 0.6982\n",
"Epoch 4 : Loss 0.6959\n",
"Epoch 5 : Loss 0.6980\n",
"Epoch 6 : Loss 0.6959\n",
"Epoch 7 : Loss 0.6919\n",
"Epoch 8 : Loss 0.7023\n",
"Epoch 9 : Loss 0.6971\n"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"model = MultiLayerPerceptron()\n",
"model.add_layer(DenseLayer(2, 10, 'sigmoid'))\n",
"model.add_layer(DenseLayer(10, 10, 'sigmoid'))\n",
"model.add_layer(DenseLayer(10, 10, 'sigmoid'))\n",
"model.add_layer(DenseLayer(10, 10, 'sigmoid'))\n",
"model.add_layer(DenseLayer(10, 1, 'sigmoid'))\n",
"\n",
"model = SGD(x, y, model, \"bce\", learning_rate=0.3, epochs=10, batch_size=20)\n",
"\n",
"print_decision_boundaries(model, x, y)\n"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 0 : Loss 0.6778\n",
"Epoch 1 : Loss 0.6748\n",
"Epoch 2 : Loss 0.6724\n",
"Epoch 3 : Loss 0.6701\n",
"Epoch 4 : Loss 0.6660\n",
"Epoch 5 : Loss 0.6633\n",
"Epoch 6 : Loss 0.6580\n",
"Epoch 7 : Loss 0.6547\n",
"Epoch 8 : Loss 0.6494\n",
"Epoch 9 : Loss 0.6421\n",
"Epoch 10 : Loss 0.6362\n",
"Epoch 11 : Loss 0.6279\n",
"Epoch 12 : Loss 0.6215\n",
"Epoch 13 : Loss 0.6149\n",
"Epoch 14 : Loss 0.6044\n",
"Epoch 15 : Loss 0.5944\n",
"Epoch 16 : Loss 0.5855\n",
"Epoch 17 : Loss 0.5786\n",
"Epoch 18 : Loss 0.5664\n",
"Epoch 19 : Loss 0.5563\n",
"Epoch 20 : Loss 0.5394\n",
"Epoch 21 : Loss 0.5330\n",
"Epoch 22 : Loss 0.5214\n",
"Epoch 23 : Loss 0.5041\n",
"Epoch 24 : Loss 0.4927\n",
"Epoch 25 : Loss 0.4778\n",
"Epoch 26 : Loss 0.4659\n",
"Epoch 27 : Loss 0.4547\n",
"Epoch 28 : Loss 0.4377\n",
"Epoch 29 : Loss 0.4234\n",
"Epoch 30 : Loss 0.4056\n",
"Epoch 31 : Loss 0.3976\n",
"Epoch 32 : Loss 0.3868\n",
"Epoch 33 : Loss 0.3725\n",
"Epoch 34 : Loss 0.3648\n",
"Epoch 35 : Loss 0.3478\n",
"Epoch 36 : Loss 0.3397\n",
"Epoch 37 : Loss 0.3312\n",
"Epoch 38 : Loss 0.3178\n",
"Epoch 39 : Loss 0.3181\n",
"Epoch 40 : Loss 0.3035\n",
"Epoch 41 : Loss 0.2940\n",
"Epoch 42 : Loss 0.2886\n",
"Epoch 43 : Loss 0.2820\n",
"Epoch 44 : Loss 0.2719\n",
"Epoch 45 : Loss 0.2672\n",
"Epoch 46 : Loss 0.2587\n",
"Epoch 47 : Loss 0.2549\n",
"Epoch 48 : Loss 0.2518\n",
"Epoch 49 : Loss 0.2478\n",
"Epoch 50 : Loss 0.2385\n",
"Epoch 51 : Loss 0.2306\n",
"Epoch 52 : Loss 0.2288\n",
"Epoch 53 : Loss 0.2221\n",
"Epoch 54 : Loss 0.2164\n",
"Epoch 55 : Loss 0.2198\n",
"Epoch 56 : Loss 0.2091\n",
"Epoch 57 : Loss 0.2040\n",
"Epoch 58 : Loss 0.2029\n",
"Epoch 59 : Loss 0.2026\n",
"Epoch 60 : Loss 0.1965\n",
"Epoch 61 : Loss 0.1904\n",
"Epoch 62 : Loss 0.1912\n",
"Epoch 63 : Loss 0.1886\n",
"Epoch 64 : Loss 0.1839\n",
"Epoch 65 : Loss 0.1799\n",
"Epoch 66 : Loss 0.1828\n",
"Epoch 67 : Loss 0.1728\n",
"Epoch 68 : Loss 0.1694\n",
"Epoch 69 : Loss 0.1756\n",
"Epoch 70 : Loss 0.1661\n",
"Epoch 71 : Loss 0.1675\n",
"Epoch 72 : Loss 0.1625\n",
"Epoch 73 : Loss 0.1611\n",
"Epoch 74 : Loss 0.1584\n",
"Epoch 75 : Loss 0.1535\n",
"Epoch 76 : Loss 0.1598\n",
"Epoch 77 : Loss 0.1520\n",
"Epoch 78 : Loss 0.1540\n",
"Epoch 79 : Loss 0.1506\n",
"Epoch 80 : Loss 0.1482\n",
"Epoch 81 : Loss 0.1495\n",
"Epoch 82 : Loss 0.1466\n",
"Epoch 83 : Loss 0.1386\n",
"Epoch 84 : Loss 0.1396\n",
"Epoch 85 : Loss 0.1403\n",
"Epoch 86 : Loss 0.1396\n",
"Epoch 87 : Loss 0.1361\n",
"Epoch 88 : Loss 0.1369\n",
"Epoch 89 : Loss 0.1330\n"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 432x288 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"model = MultiLayerPerceptron()\n",
"model.add_layer(DenseLayer(2, 10, 'relu'))\n",
"model.add_layer(DenseLayer(10, 10, 'relu'))\n",
"model.add_layer(DenseLayer(10, 10, 'relu'))\n",
"model.add_layer(DenseLayer(10, 10, 'relu'))\n",
"model.add_layer(DenseLayer(10, 1, 'sigmoid'))\n",
"\n",
"model = SGD(x, y, model, \"bce\", learning_rate=0.03, epochs=90, batch_size=20)\n",
"\n",
"print_decision_boundaries(model, x, y)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "YBChCCJREOuP"
},
"source": [
"## Application à un problème de classification d'image\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "C7efDmj6WNSg"
},
"source": [
"Le code ci-dessous vous permet de charger l'ensemble de données CIFAR-10 qui regroupe des imagettes de taille $32 \\times 32$ représentant 10 types d'objets différents.\n",
"\n",
"Des images de chat et de chien sont extraites de cet ensemble : à vous de mettre en place un perceptron multi-couches de classification binaire pour apprendre à reconnaître un chien d'un chat dans une image.\n"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {
"id": "ZFyeFRYfEN3A"
},
"outputs": [],
"source": [
"import tensorflow as tf\n",
"\n",
"# Récupération des données\n",
"(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()\n",
"\n",
"# La base de données CIFAR contient des images issues de 10 classes :\n",
"# 0\tairplane\n",
"# 1\tautomobile\n",
"# 2\tbird\n",
"# 3\tcat\n",
"# 4\tdeer\n",
"# 5\tdog\n",
"# 6\tfrog\n",
"# 7\thorse\n",
"# 8\tship\n",
"# 9\ttruck\n",
"\n",
"# Préparation des données pour la classification binaire :\n",
"\n",
"# Extraction des images des classes de chat et chien\n",
"indices_train = np.squeeze(y_train)\n",
"x_cat_train = x_train[indices_train == 3, :]\n",
"x_dog_train = x_train[indices_train == 5, :]\n",
"\n",
"indices_test = np.squeeze(y_test)\n",
"x_cat_test = x_test[indices_test == 3, :]\n",
"x_dog_test = x_test[indices_test == 5, :]\n",
"\n",
"# Création des données d'apprentissage et de test\n",
"# Les images sont redimensionnées en vecteurs de dimension 3072 (32*32*3)\n",
"# On assigne 0 à la classe chat et 1 à la classe chien\n",
"x_train = np.concatenate(\n",
" (\n",
" np.resize(x_cat_train[0:250], (250, 32 * 32 * 3)),\n",
" np.resize(x_dog_train[0:250], (250, 32 * 32 * 3)),\n",
" ),\n",
" axis=0,\n",
")\n",
"y_train = np.concatenate((np.zeros((250)), np.ones((250))), axis=0)\n",
"\n",
"x_test = np.concatenate(\n",
" (\n",
" np.resize(x_cat_test, (1000, 32 * 32 * 3)),\n",
" np.resize(x_dog_test, (1000, 32 * 32 * 3)),\n",
" ),\n",
" axis=0,\n",
")\n",
"y_test = np.concatenate((np.zeros((1000)), np.ones((1000))), axis=0)\n",
"\n",
"# Normalisation des entrées\n",
"x_train = x_train / 255\n",
"x_test = x_test / 255\n"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {
"id": "VBzhs000JbHT"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 0 : Loss 0.6907\n",
"Epoch 1 : Loss 0.6785\n",
"Epoch 2 : Loss 0.6762\n",
"Epoch 3 : Loss 0.6715\n",
"Epoch 4 : Loss 0.6657\n",
"Epoch 5 : Loss 0.6516\n",
"Epoch 6 : Loss 0.6528\n",
"Epoch 7 : Loss 0.6504\n",
"Epoch 8 : Loss 0.6356\n",
"Epoch 9 : Loss 0.6410\n",
"Epoch 10 : Loss 0.6463\n",
"Epoch 11 : Loss 0.6261\n",
"Epoch 12 : Loss 0.6174\n",
"Epoch 13 : Loss 0.6252\n",
"Epoch 14 : Loss 0.6196\n",
"Epoch 15 : Loss 0.6162\n",
"Epoch 16 : Loss 0.6057\n",
"Epoch 17 : Loss 0.5784\n",
"Epoch 18 : Loss 0.5908\n",
"Epoch 19 : Loss 0.5903\n",
"Epoch 20 : Loss 0.5652\n",
"Epoch 21 : Loss 0.5556\n",
"Epoch 22 : Loss 0.5439\n",
"Epoch 23 : Loss 0.5201\n",
"Epoch 24 : Loss 0.6409\n",
"Epoch 25 : Loss 0.5271\n",
"Epoch 26 : Loss 0.5146\n",
"Epoch 27 : Loss 0.5608\n",
"Epoch 28 : Loss 0.5149\n",
"Epoch 29 : Loss 0.4972\n",
"Epoch 30 : Loss 0.5159\n",
"Epoch 31 : Loss 0.4962\n",
"Epoch 32 : Loss 0.5198\n",
"Epoch 33 : Loss 0.5027\n",
"Epoch 34 : Loss 0.4672\n",
"Epoch 35 : Loss 0.5406\n",
"Epoch 36 : Loss 0.5124\n",
"Epoch 37 : Loss 0.4502\n",
"Epoch 38 : Loss 0.4163\n",
"Epoch 39 : Loss 0.4734\n",
"Epoch 40 : Loss 0.4098\n",
"Epoch 41 : Loss 0.4418\n",
"Epoch 42 : Loss 0.4128\n",
"Epoch 43 : Loss 0.4661\n",
"Epoch 44 : Loss 0.4381\n",
"Epoch 45 : Loss 0.4079\n",
"Epoch 46 : Loss 0.4724\n",
"Epoch 47 : Loss 0.4054\n",
"Epoch 48 : Loss 0.3555\n",
"Epoch 49 : Loss 0.3965\n"
]
}
],
"source": [
"model = MultiLayerPerceptron()\n",
"model.add_layer(DenseLayer(3072, 100, \"relu\"))\n",
"model.add_layer(DenseLayer(100, 100, \"relu\"))\n",
"model.add_layer(DenseLayer(100, 100, \"relu\"))\n",
"model.add_layer(DenseLayer(100, 100, \"relu\"))\n",
"model.add_layer(DenseLayer(100, 1, \"sigmoid\"))\n",
"\n",
"model = SGD(x_train, y_train, model, \"bce\", learning_rate=0.03, epochs=50, batch_size=20)\n"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {
"id": "hPUcXM60L0-b"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Précision de 57.4 %\n"
]
}
],
"source": [
"# Prédiction du modèle sur les données de test\n",
"y_pred_test = model.forward(np.transpose(x_test))\n",
"\n",
"# Calcul de la précision : un écart inférieur à 0.5 entre prédiction et label\n",
"# est considéré comme bonne prédiction\n",
"prediction_eval = np.where(np.abs(y_pred_test - y_test) < 0.5, 1, 0)\n",
"overall_test_precision = 100 * np.sum(prediction_eval) / y_test.shape[0]\n",
"print(f\"Précision de {overall_test_precision:2.1f} %\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "A1jASzh3PSKa"
},
"source": [
"Si vous obtenez une précision supérieure à 50%, votre réseau est meilleur qu'une prédiction aléatoire, ce qui est déjà bien ! Notez qu'ici nous avons circonscrit l'ensemble d'apprentissage à 500 échantillons (250 de chaque classe) car les calculs de produit matriciel sont longs. C'est tout l'intérêt de porter les calculs sur GPU ou TPU, des dispositifs matériels spécialement conçus et optimisés pour paralléliser ces calculs.\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "YV4WZTfL0KB9"
},
"source": [
"## Utilisation de la librairie Keras\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "XFR3jwelW1jh"
},
"source": [
"L'utilisation d'une librairie comme Keras permet d'abstraire toutes les difficultés présentées dans ce TP : voici par exemple comment résoudre grâce à Keras le premier problème de régression linéaire présenté dans ce TP.\n"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {
"id": "ew3_k9uK0P9g"
},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAXkAAAD4CAYAAAAJmJb0AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAArt0lEQVR4nO2deZRU9bXvv7uqBzAS9TYaom2LSSRGaGRoSHqhpglEUFGukmh8GBSRNkSMXIwDMbmy4oBXXUpQ4qN9gUfHvKgLjegLPgikm4uLSkjjRBQHVETQRGiHgNgM3fv98avTdbr6nKpTVaemU9/PWr2q64z79PD97dq//dtbVBWEEEKCSSjfBhBCCMkeFHlCCAkwFHlCCAkwFHlCCAkwFHlCCAkwZfk2wE7//v114MCB+TaDEEKKis2bN+9R1WOd9hWUyA8cOBBtbW35NoMQQooKEXnXbR/DNYQQEmAo8oQQEmAo8oQQEmAKKibvxKFDh7Bz5050dHTk2xRCetCnTx9UV1ejvLw836YQ4krBi/zOnTvRr18/DBw4ECKSb3MIAQCoKtrb27Fz506cfPLJ+TaHEFcKPlzT0dGBqqoqCjwpKEQEVVVV/IRJCp6CF3kAFHhSkPDvsjSJRIAFC8xrMVDw4RpCCCkUIhFg3Djg4EGgogJYtw6or8+3VYkpCk8+34TDYQwbNqz766677sq5DfPnz8e9997ba/v27dsxZMgQX657xRVXoLW1Ne1rZYuFCxdi//793e/PPfdcfPLJJ/kziJQsra1G4Ds7zWsB/rv0gp68B/r27YsXX3wx32YUPYcPH0ZZWep/cgsXLsRll12GI444AgCwatUqv00jxBMNDcaDtzz5hoZ8W5ScQHryuYqZDRw4ELfeeitGjBiB2tpavPbaawCA9evXd3v9w4cPx969ewEA99xzD0aNGoWhQ4fi1ltvBWA88VNPPRVXXHEFBg0ahKlTp2Lt2rUYM2YMTjnlFGzatKn7fi+99BLq6+txyimn4OGHH+5lT2dnJ2644YbueyxZssTR7jvuuAODBg3CGWecgddff717+1FHHYWKigoAwC9/+UuMGjUKQ4YMQWNjI6wOYg0NDbjuuuswbNgwDBkypNu++fPn44c//GEv+1pbW3HmmWfiggsuwGmnneZqY2trKxoaGvC9730Pp556KqZOnQpVxaJFi/D+++9j7NixGDt2bPfPfc+ePfjss89w3nnn4fTTT8eQIUPw2GOPAQBuvvlmnHbaaRg6dCh++tOfAgCeeeYZfPOb38Tw4cMxfvx4/POf/wQA7N69G9/97ncxePBgXHXVVTjppJOwZ88eAMAjjzyC0aNHY9iwYbj66qvR2dmZwl8HCSL19SZEc9ttxRGqAWBSwQrla+TIkRrPq6++2mtbIjZuVO3bVzUcNq8bN6Z0uiOhUEhPP/307q9HH31UVVVPOukkXbRokaqqLl68WGfMmKGqqpMmTdLnnntOVVX37t2rhw4d0tWrV+vMmTO1q6tLOzs79bzzztP169frO++8o+FwWF9++WXt7OzUESNG6PTp07Wrq0ufeuopnTx5sqqq3nrrrTp06FDdv3+/7t69W6urq3XXrl36zjvv6ODBg1VVdcmSJXrbbbepqmpHR4eOHDlS33777R7P0tbWpkOGDNHPPvtMP/30U/3qV7+q99xzT69nbm9v7/7+sssu06efflpVVb/97W/rVVddpaqq69ev7763m30tLS16xBFHdNvhZmNLS4t+8Ytf1Pfee087Ozv1W9/6lm7YsKH757x79+5ue6z3K1as6LZFVfWTTz7RPXv26KBBg7Srq0tVVT/++GNVVf3oo4+6tz388MM6d+5cVVW95ppr9M4771RV1WeffVYB6O7du/XVV1/VSZMm6cGDB1VVddasWbp8+fJeP6dU/z4JyQYA2tRFVwMXrnGKmWU62iYK11x00UUAgJEjR+LJJ58EAIwZMwZz587F1KlTcdFFF6G6uhpr1qzBmjVrMHz4cADAvn378Oabb6KmpgYnn3wyamtrAQCDBw/GuHHjICKora3F9u3bu+81efJk9O3bF3379sXYsWOxadMmDBs2rHv/mjVr8PLLL2PFihUAgE8//RRvvvlmjzzuDRs24MILL+wOfVxwwQWOz9XS0oK7774b+/fvx0cffYTBgwfj/PPPBwBceumlAICzzjoL//rXv7rj4072HX300Rg9enS3DW42VlRUYPTo0aiurgYADBs2DNu3b8cZZ5zh+nupra3F9ddfj5tuugmTJk3CmWeeicOHD6NPnz6YMWMGJk2ahEmTJgEw6y0uueQSfPDBBzh48GC3Pc899xz+8Ic/AAAmTpyIY445BgCwbt06bN68GaNGjQIAfP755zjuuONcbSGkUAmcyOc6ZlZZWQnATM4ePnwYgAkXnHfeeVi1ahXGjBmD1atXQ1Uxb948XH311T3O3759e/c1ACAUCnW/D4VC3dcEeqfsxb9XVTzwwAOYMGFCRs/U0dGBH//4x2hra8OJJ56I+fPn98gHd7PDbfsXvvCFpDa2trb2+DnYf55uDBo0CM8//zxWrVqFn//85xg3bhz+8z//E5s2bcK6deuwYsUKPPjgg/jzn/+Ma6+9FnPnzsUFF1yA1tZWzJ8/P+G1VRWXX345FixYkPA4QgqdwMXkCyFm9tZbb6G2thY33XQTRo0ahddeew0TJkzA0qVLsW/fPgDArl278OGHH6Z03ZUrV6KjowPt7e1obW3t9jItJkyYgIceegiHDh0CALzxxhv47LPPehxz1lln4amnnsLnn3+OvXv34plnnul1H0vQ+/fvj3379nV73RZW7Pu5557DUUcdhaOOOsqTfV5tjKdfv37d8xp23n//fRxxxBG47LLLcMMNN+D555/Hvn378Omnn+Lcc8/F/fffj5deegmA+cRwwgknAACWL1/efY0xY8bg8ccfB2A+ZXz88ccAgHHjxmHFihXdv6OPPvoI777rWs2VkIIlcJ48YITdT3H//PPPe4RFJk6cmDCNcuHChWhpaUEoFMLgwYNxzjnnoLKyElu3bkV91LAjjzwSjzzyCMLhsGc7hg4dirFjx2LPnj34xS9+geOPP75HOOeqq67C9u3bMWLECKgqjj32WDz11FM9rjFixAhccsklOP3003Hcccc5CvHRRx+NmTNnYsiQIRgwYECvY/r06YPhw4fj0KFDWLp0aUL73njjjR7nerExnsbGRkycOBHHH388Wlpaurdv2bIFN9xwA0KhEMrLy/HQQw9h7969mDx5Mjo6OqCquO+++wCYieHvf//7OOaYY/Cd73wH77zzDgDg1ltvxaWXXorf/va3qK+vx4ABA9CvXz/0798ft99+O84++2x0dXWhvLwcixcvxkknnZTQVkIKDdFo1kRGFxE5GsD/AjAEgAK4EsDrAB4DMBDAdgAXq+rHia5TV1en8U1Dtm7dim984xsZ20j8oaGhAffeey/q6up6bJ8/fz6OPPLI7myWYuHAgQMIh8MoKytDJBLBrFmzUkqX5d8nKQREZLOq1jnt88uT/xWA/6eq3xORCgBHAPgZgHWqepeI3AzgZgA3+XQ/Qnxhx44duPjii9HV1YWKigrH1FRC7EQiJqGjoaE4Uigz9uRF5CgALwL4itouJiKvA2hQ1Q9E5MsAWlX164muRU+eFBv8+ywtslXWINOBI9ue/MkAdgNYJiKnA9gM4DoAX1LVD6LH/APAl1yMawTQCAA1NTWON1BVFoMiBYcfoU5SXGQjRTvb9XD8yK4pAzACwEOqOhzAZzChmW6iHr7jf4SqNqlqnarWHXts72bjffr0QXt7O/+hSEGh0Xryffr0ybcpJIdYKdrhsH8p2tmuh+OHJ78TwE5V/Wv0/QoYkf+niHzZFq5JLV8wSnV1NXbu3Indu3f7YCoh/mF1hiKlg5Wi7WdMPttrezIWeVX9h4i8JyJfV9XXAYwD8Gr063IAd0VfV6Zz/fLycnbeIYQUDH6naGdj4LDjV3bNtQB+F82seRvAdJhQ0OMiMgPAuwAu9ulehJA0KbbMkGySr5+F0339Hjjs+CLyqvoiAKeZ3XF+XJ8QkjnF2PAiW+TrZ5GP+waurAEhxJlibHiRLfL1s8jHfSnyhJQI2cgMKVYaGoCyMkDEvObqZ5GP30Ega9cQQnqT7Qm+YsCKh1dVAVZWdi6zs/PxO6DIE1JCZHOCr9Cxx8NDIRMyUTWvfixq8kqufwcUeUJISWCPh6saoRcJfuiKIk8IKQniFx0tXAi0twc/dEWRJ4SUBKU6J0GRJ4SUDH7Ew4ttQRlFnhBCXIgX9GJcUEaRJ4TkjWx4xX5d00nQs1FqONtQ5AkheSEbXrGf13QS9GxXjMwGXPFKCMkL2Vji7+c1nVanWpO3t91WHKEagJ48ISRPZMMr9vOabtk4xbagLOMer37i1OOVEFJ4+Bn3LtSYfDGRqMcrRZ4QkhLFmGESdBKJPGPyhJCUSCXuHYkACxaYV5IfGJMnhKSE17g3Pf7CgCJPCEkJr+UBijGnPIhQ5AkhKeMlwySdTJdSnDTNNhR5QkhWSLUgWK7DO6UyoFDkCSFZI5Wc8lyGd0ppvsC37BoRCYvICyLyf6PvTxaRv4rINhF5TEQq/LoXISR45LL/aSk1NfczhfI6AFtt7/8LwP2q+jUAHwOY4eO9CCEBw2vJAD/SMkupqbkvi6FEpBrAcgB3AJgL4HwAuwEMUNXDIlIPYL6qTkh0HS6GIqSwyXcc288wS76fxU8SLYbyKya/EMCNAPpF31cB+ERVD0ff7wRwgk/3IoRkQLriVghxbD/j9sVWgyZdMhZ5EZkE4ENV3SwiDWmc3wigEQBqamoyNYeQwJCtui7pCnWuJ0bjm3W0tgJVVcVX6jff+OHJjwFwgYicC6APgC8C+BWAo0WkLOrNVwPY5XSyqjYBaAJMuMYHewgperLlNWci1LmqpR7/7AsXAnPmlF4Dbr/IeOJVVeeparWqDgTwAwB/VtWpAFoAfC962OUAVmZ6L0JKhWxlf2Qy4VhfbwR23Djzmi2BjX/2J57o+b69HZg3jwLvlWzmyd8E4FERuR3ACwB+k8V7ERIosuU1p7pAyU4kEvOoN2wAamuzI7Txzz5lirnfgQOAiAnZeLE1KJOqmeKryKtqK4DW6PdvAxjt5/UJKRUyEWMv1wZinw4KLSbv9OxvvQXce6+595w5iQeYQpggLiS44pWQAiVb2R/pimAu+5vanz0SAe6/H+jqMu8PHEg8wLAwWk9YT56QgJFssVC68f589TdtbTW2WoRCiQeYUlro5AV68oQECDcv3R6jzsQjz0dueUMDUFlpPPhwGHjwwcQ2ZDPUVYxQ5AkJEG5eerzwF5MIpiPapbLQyQsUeUICRLyXXlUFzJ9vvOCurpjwF1sIg6KdPhR5QgKE3eutqjKZKJbAh0Ix4Q9a9glTJt2hyBMSMCyvd8ECI+SWwI8fb7z6oGSf2Esd2FfEBmHQ8hOKPCFFQqreanzoZv782HnFXv/FPsEcCpkByx6OosjHoMgTUgSkk9vuNmEZhOwT+6cRVSP0IsU7aGUTijwhRUC6IRa3Cct0JjILKe4d/ymFRcvcocgTUgQ45banI7q5qCUfiQDNzeb7adNyV/qAOEORJ6QIiBc1IPXwTS5qyUcixr6DB837ZcuAlpbsCT3FPTkUeUKKBLuoWZkzXsI3lve+Y0fq51hestdVss3NMYEHOBFaCFDkCSlwnEIsXkXX7r2XlZmyAID3c+we/7p1sTCM23nLlvXcxonQ/EORJ6SAcRNcrzFpe5gFAGbOBGpqvJ8T74kvX262LV/eO9zT2gocjnZ1FgFGjcpucxHiDYo8IQVMIsH1EpO2PP4DB0ya4fDhQGOjt3PiPyUki8s7ZbxQ4PMPRZ6QAsZLWMYtY8bafu21wH33eWu4Abh/SvCS4cOMl8JDVAund3ZdXZ22tbXl2wxC8o5dPIGe39vTEwH30sJOK0Lt5Q3SEeGmJtNzdcoUM1gErQZOsSIim1W1znGnqhbM18iRI5WQUmfJEtWyMtVQSLVvX9WNG832jRtVKytVzRpP1YoK1R/9SDUcNu/DYdU77zTH3nlnbHsoFLue9d5+Xa9s3GjOC4fNq/3eoZDq2Wenfk3iDwDa1EVX2RmKkAIiEgFmzzYTmF1dsVZ3kUisZLDFoUPm1akLkr07UmUlsHix8eBDoZ41XpJ1kbLT3Ax0dMRi8ta9rWuuXWs8ey/XIrmDMXlCCginVndWaWC7wAOxdEinJf1u8fGWFvOaaslhKz3Siu6GwyZcNG2aGXzWrmWBsEIlY5EXkRMBNAP4EgAF0KSqvxKRfwPwGICBALYDuFhVP870foQEGadWd+3tPUsG19UBxx8PPPss8PDD7gId3wx7zhwzgIRCsYEhUbaMfV4gPj3yyitjx86fD2zYUNxVLYOMH578YQDXq+rzItIPwGYR+ROAKwCsU9W7RORmADcDuMmH+xESWJw88Eikd2piayvwzDPeC5ZZ6Y9dXUakX3jBbHdbHBWfn79wYU8brElfN5tJ4ZCxyKvqBwA+iH6/V0S2AjgBwGQADdHDlgNoBUWekKTE57+7iWh8m78FC9xF1p7+GA6b0Mvhw2YV7MyZvQuJxefEt7cnFnLWkSlcfI3Ji8hAAMMB/BXAl6IDAAD8AyacQwhJg0TC76Uzkv34HTtMmMeK/dfU9D7eKSeeQl6c+JZdIyJHAngCwBxV/Zd9XzTFxzEhX0QaRaRNRNp2797tlzmE5JRUslT8or4emDfPObae6Php05wzcuKPXbcOuO025r8XO7548iJSDiPwv1PVJ6Ob/ykiX1bVD0TkywA+dDpXVZsANAFmMZQf9hCSSzIp4esHdq+7rMx46pGIuw1eY+j03INBxp68iAiA3wDYqqr32XY9DeDy6PeXA1iZ6b0IKUTi49fNzal79al8Eog/1hLtmTNNiuPDDyfPV7e8eop48PHDkx8D4IcAtojIi9FtPwNwF4DHRWQGgHcBXOzDvQgpONwmNTNt5uFUkyZRVUorxz7VFoF2O5ghEzz8yK55DoC47B6X6fUJKXTcJjW9Cq1TdUfAWcwTVYL0WmPeCT9CThwkChOueCXEByxvOhKJ1Vz3WjXSSZxbW82CKHtpA+vYcNhsD4d7Xj+TfPV0G4Xbn4nFygoTijwhPuImtJawO6U7AsDl0dkrK199yxYj5IB5raqK3UOk52v8/dMR10w+BQCpDRL0+HMLRZ4Qn4kXWruXK2JE26rz0tzc0/O3VpK2t8cKf4VC5j0QKy+gal6bmxMLZryguglspqtW02lHSI8/N1DkCfEJNwG1e7mhkAmziBiRA5w9YKuGTbxopjLJawmq1RVq7lzggQfcBdbrpwCn50ynHSGLmeUGijwhSfASXkjkoTq1xbOqRgLOMXw30fQyyWvZu2NHLK7f1QXce6+5RibVIhM9ZyrtCFnMLHdQ5AlJgNfwQrJerIni9E6lgr0MLMOHO7fjs+y1PjHYCYVinyLSEdhMPXEWM8s9FHkSGFKZ0Et2rN0b9iJqDQ1mtWlXl3mNF9BEcfr4wSOVfddeC7z4omnHV19vFklZ9gLA+ecDf/yjeV9Z6TygpIIfnjhX0uYWijwJBHbxKysDpk/vXVnR6dhEsWzLGy6L/pckEzWroYaXtsmJPGKv+w4cAO6/3wwsGzaYnqvxInzjjebLL8+ZnnjxQZEngcAufp2dwJIlJtbtFF5JFnKw7wdMuYCamuQTip2dRuA7OxM34HDLjbdIVIvGvk8k1qDbeo5589xj+U52pAM98SLDrflrPr7YyJuki9VkWiTW6Nre2NrpWKshdXzz6WT7E93f6Ry3fRs3Gvucrr9xo2mUXVHhft6SJanZmc5zkeIACRp505MngcAKIzQ3A0uXmrRCkZ6LiICek51WdyS3a3nJqLEf43aO2ycHewjGuq/dBrdaNPZza2u9e+ZMXyxR3NQ/H1/05IkfLFmiWl6uGgr19oAtT7aiQrWyMn2vNpnnbvfQlyxRLStztqey0nz6qKz07xNFok8H9OSDCejJk1Kivb3nqlLLY7V7slbJANXUvdpIxDSvtnLQ43PU43ujzpkT6606YULsOs3N5hqAeW1uzmwVarIJZU6aliYUeRI43CY141eLisRWi3pNBbSvIrVKDtjPjw+JPPFErIE2AKxcCaxeHatZk4xUJjm9hGM4aVp6UORJ4PCyWtQuyql4tZaQWgI/frzx6t1Wt06ZAqxfH8vUUY1VlZw2zcwfHDoElJfH6tYA6WXBcDUpcULUS1Jvjqirq9O2trZ8m0GIK01NwOzZscVFTima8QI9a5ZJ6bT+1crLjfC7FQzLpIgXKzyWJiKyWVXrnPbRkyfEI01NwDXXGIEPh0283UlI40Mi06aZnH2rUNiDDyau95JJFgzDMSQeijwJDJl4sU1NJn4+ZQrQ2Oh87dmzTQwfMOEaq/xvIluqqsxxVjkB632iRtsMuxA/ociTQJBJiOOmm4C77zbfr1ljXuOF3spZtxDpuRLVyRb75KxVNya+YYjbJwFmwRC/COXbAJI9IhFTsCoSybcl6ePlGewpjfF9UpNdKxKJleC1eOKJ3uda9d2tevChkCnzO25cb9uam4GOjp6dneyZNvE2BuH3RAoXevIBJQgdeLw8Q7KURusYayVsZ2fsWlu2APfcExNjiylTetvipY67da+lS3sWKbNsmjLFFBJzKw1sbwdY7L87Ujhk3ZMXkYki8rqIbBORm7N9P2JwmrwrNrw8g1NKoyWUs2YBF14IjB1rslvs17r7buDqq4Ft22LXCoVMxcba2p6eteVpA6YA2LRppnCYiHmtqoodbw/riAD//u/A7bcbmxobzettt8WE2+kZg/C7I4VDVj15EQkDWAzguwB2AvibiDytqq9m874kGJN3Xp4h/pj582PbDx7sfbzVMOP993tu/9rXjLcPOK9Yjfe0LU+9sxP4yU9Mrns4DPzHf/Qu9ZuoxZ7TM27ZYgYc1eL93ZHCIdvhmtEAtqnq2wAgIo8CmAyAIp9lgjB55+UZnI5ZsMCIrh1L3M85BxgwAPjiF4FNm2L7L7qod9ON+Dh6R4cZCGpqepYVtr7v6gLuuw9YvDh5pyf7+/gFWnPmxPrBuqVpEuKVbIv8CQDes73fCeCbWb4niRKEnOlkz+CUNtnQYBYcWZ58eTkwY4Zpl2f3yqdOBX7/eyPQDzxgQitOK1btteKXLQMWLepZHsESeiCWWjlvXk8bk306sI63Bhmr1k2iNE1CvJD3iVcRaQTQCAA1NTV5toYUE24Ts1as2wq/WB2i4r303buNkCZruvHCC7EVq4cPG+G1H7Nli1kk1dVlMnDiwytu9WycJm6DEGYjhUW2RX4XgBNt76uj27pR1SYATYApa5Ble0iB4Mfy+0QrQ50+ATh56fHZLk7nWitW7cfZj6mv713X3f58Xu9rXavYw2yksMhq7RoRKQPwBoBxMOL+NwD/Q1VfcTqetWtKg3TTO61USCBWzCvV6ySKjSdq6G2tVE235C+Q2n0JSYW81a5R1cMiMhvAagBhAEvdBJ6UDunUZolEembMLFsGtLSk7vXGe+mJYv6JBqNEIu30fPPmeb+vGxwYSDpkPSavqqsArMr2fUjxkE7cubW1Z8aMm3i6kY5AWitX4xuLJPskko24ehAWt5H8kPeJV1J61NebDBOrIJgXsYrPmEmn0UeqYZ1ly3quXLX6xSb7JJKNuHomlSlJaUORJzknEomlEG7YYCYtkwmWlTFz991mIdOMGd4bbNsF8sABs2DK3ujDidbWWMVJwJx7zTXmey+eut/pq8y6IelCkSc5xy0M4oXVq805W7Y4Dw5OXrslkFZ9m7VrzeCSyKO3zrHsBIzoz55tGn7EL2BasCD9blNeYNYNSReKPMkp8QW8ysq8e6VeQhZuk57r1hnvfe3a3s23nbBEtbk5VowMMK/2uQD7oFJWFlsFm424eRAWt5Hcw1LDJKfEF/CaPj31HqbhsHm1FwZzO8Y+gHzlKyau77TPifp64KGHgF//2pxn1YW3nxc/qBw61LMEAiH5hp48ySnxsWV78+pk2EMWVVXuDTguv9y8Witd7d52OAzMnBnb54XaWjMHYL+m0/OUlRmBP3w4VgIhlfsQkg0o8sQXEqUoxu/LJLZshSziSxRY5XjHju09gNi9bcAUGEulMbY9xm8flKznslr7NTQY791eAoFZMCTfUORJxiRbNORWXyYTnLJNmpvN5CpgXpubzX0yyUxxmwdI9Mz2EghWSImTpSRfUORJxiSaEM1WfrfTJwKrT6uXY73iNkDEP1dzc+/SwYlCSoTkCoo8yZhEnnI287vtnwgiEWCVbV11ONwztGIfdOzvvdzDaYCIj8XHtxacN885pESRJ7mGIh9QclnnJJGnnKv87vjFS/FkUhbAKbxkfy63nq9cwEQKAYp8AMlHnZNEcfZkRcDi676nSiRihFYktk01+2Ej67kikd6liK39XMBE8g1FPoAUQ50TS9x/85tY4bGlS3va6uXTiH1As/qiqvZeZJXtsFGiTzKF9rMnpQVFPoAUUpjASagtYbaXDACM2Hut9GhhH9BUjTdvvdpxE2K/wloUc1KoUOQDSKGECdyE2hLm+H415eXO2SvW6lGn57APaFYrP7cc9XghZvleUgpQ5ANKIXiWbmGj+MyUc84BBgzoGZNvaIitIFU1oRynmH2iVbDJPsEUQ1iLkEyhyJNu0g1duJ3nFjaKF+b4tnrW9c45B1i5Mlb0y02E7QNafK/VRDjZx+5LJGhQ5EuIZKUH0u276nZesglJwLkXqr3OTEWFCb14nVtI5RNMvH1O9lDoSbFDkS8Rkol4uqELL12S3K7jdC7Qs87MzJmm1kwmnnWiwc1uHxcvkSBCkS8Rkolxuhk5mWTyuJ0bX6UyE6FN5RNKIWUlEeIXFPkSIZmA1den3nfVOi/dTB7rXHvdda/X8xo7T6X1X6FkJRHiJ6LxeWypnCxyD4DzARwE8BaA6ar6SXTfPAAzAHQC+Imqrk52vbq6Om1ra0vbHpKYbMTkM7UDSK/JttdzrGOt1n9W4w/G20mQEJHNqlrntC/TzlB/AjBEVYcCeAPAvOgNTwPwAwCDAUwE8GsRCWd4L5Ih9fWxtnXxOOWlZ4OmJuCss4Cf/9yIb3Ozc1w+EW6xfCcs73z8eCPw9tZ/hJQCGYm8qq5RVass1F8AVEe/nwzgUVU9oKrvANgGYHQm9yL+Eon0bJ3X0GCyWYBYVyN7Wz2/7jl7tsmW6eqK1X53a9fnRqIWf07U15sQTWVlavchJAj4GZO/EsBj0e9PgBF9i53RbcQnMsnndgt3XHml/12N7Ha2tsayZgDjWU+bZr6snPnmZvOVaMI1nfkDxttJqZJU5EVkLYABDrtuUdWV0WNuAXAYwO9SNUBEGgE0AkBNTU2qp5ckmcbP3TJtpk1zrqbodH8vYhlv58KFxps+cMB41A8+2PP8sWNj3n18sbL461orWzdsMAugvAo9xZ2UGklFXlXHJ9ovIlcAmARgnMZmcXcBONF2WHV0m9P1mwA0AWbiNbnJJFk6ZDIR9rIS1e3cVAaYeDvb292vbx1rYS9WlurzE0JiZBSuEZGJAG4E8G1V3W/b9TSA/yMi9wE4HsApADZlci8SI1E6pBcRzqQ0biKBjR9cnOx0u751rOXJ24uVeXl+liMgxJlMY/IPAqgE8CcxtV3/oqo/UtVXRORxAK/ChHGuUdXOBNchKZBIpL16uemGLtwGGLfBxcsnAyuTZ9Ei4IUXzPfJYvIsR0CINzISeVX9WoJ9dwC4I5PrE3eSecTZWrXpJtxug0uiwSQS6RmHr6joWU9+wQL3wYHlCAjxBle8BoxcZJE4CXdVlannHgp5H1zc4vBAap45yxEQ4g5FPoBkmkWSanzbynbp6jJZMwsXejuvqsoMClZaZShktqU6seo2sDFOTwhFnkSxBDG+8YaX+LYlyl1dxptvb/d2vzlzTE5+KLokT9VsW7gwdc88fmBj1ydCDBR50qsZdmdnz+X/6TTfSHSv1lZgx46eAwNgRD5ZqqVXmGZJiIEiXwIkC1vYBdHyrEW8edHWtRcu7N3hyelYe0OQsuhfX1lZrPtTslRLrzBOT4iBIh9wvIQtrH6qXV0mP33RouSCbV177NjYtVtavOfYAz0bglj7/Yqfs4wBIQaKfIHh92Sh17CFtVZZ1XuZgObmWPrjgQPmfSpZMPG58H4LMcsYEEKRLyiyMVnoJWxhFQ5L1jA7U+hdE5J7KPIFRDYmC70Ia1VV7PuyMu/x62nTTCGxQ4dMmGfaNG/2UNwJyR0U+QIiW5OFyVad/uQnsTi5vRSwl+u2ttIzJ6SQKRmRL4aFMfkIZ8SvOk01XEPPnJDCpiREvlAWxngZaHK9WjWV6o/FTDEM8oRkg5IQ+UJYGJOLgSade9TXm9RHqxJkouqPxUqhDPKE5IOSEPlCWBiTi4Em3XsEPeRSCIM8IfmiJES+EFL3cjHQFMJgVojw50JKGYl17Ms/dXV12tbWlm8zskYu4sKMPTvDnwsJMiKyWVXrHPdR5EsPCh4hwSKRyJdEuIYYrFZ7S5fGioFxEpKQYEORDwBePHMrw6SjI1anhpOQhAQfinyR4zU90MowsQTeaynhTG1jWIiQ/EKRL3K8pgfaM0zKyoDp07ObE8/cdEIKg5AfFxGR60VERaR/9L2IyCIR2SYiL4vICD/uQ3pjiXc4nNgzt9JIZ87MvsADzoMPIST3ZOzJi8iJAM4GsMO2+RwAp0S/vgngoegr8ZlU1wAsX25Ed/ny7HrXzE0npDDwI1xzP4AbAay0bZsMoFlNfuZfRORoEfmyqn7gw/1IHF5XrOZy5WchLEAjhGQo8iIyGcAuVX1JrG7MhhMAvGd7vzO6jSKfR3LtXQe9XAIhxUBSkReRtQAGOOy6BcDPYEI1aSMijQAaAaCmpiaTS5EkuHnXzIIhJLgkFXlVHe+0XURqAZwMwPLiqwE8LyKjAewCcKLt8OroNqfrNwFoAsyK11SMJ6nhJOapZsFwQCCkuEg7XKOqWwAcZ70Xke0A6lR1j4g8DWC2iDwKM+H6adDj8YUufm5inkqcnmmRhBQf2cqTXwXgXADbAOwHMD1L9ykIikH83MQ8lTg9S/YSUnz4JvKqOtD2vQK4xq9rFzrFIH5uYp5KFgzTIgkpPrji1QfyLX5e2wq6ibnXLBimRRJSfLDUsE9kGpO3KkQCqa1GzVWoqNDnHAgpZVhqOAdkkhMeiRjxPHjQvF+2zPRdLZQFTsUw50AIccaX2jVBJhIBFiwwr9mitRU4dCj2PpVaL15r12RqH+vQEFKc0JNPQK482IYGoLw85smnIta5iJPne86BEJI+FPkE5CprxspXTycmb52fzfAJJ1wJKV4o8gnIpQdb6HVeCt0+QogzFPkE0IMlhBQ7FPkkpOPBMt2QEFIoUOR9humGhJBCgimUPsN0Q0JIIUGR95lc5K27kYucfkJIccFwjc/ka7KWYSJCiBMU+SyQj3TDYqiESQjJPQzXBIR8hokIIYULPfkUyEZqpF/XZE4/IcQJirxHshHz9vuaXJVKCImH4RqPZCM1kumWhJBsQ5H3SDZi3oyjE0KyDcM1HslGzJtxdEJItmH7P0IIKXIStf/LOFwjIteKyGsi8oqI3G3bPk9EtonI6yIyIdP7EEIISZ2MwjUiMhbAZACnq+oBETkuuv00AD8AMBjA8QDWisggVe3M1GBCCCHeydSTnwXgLlU9AACq+mF0+2QAj6rqAVV9B8A2AKMzvBchhJAUyVTkBwE4U0T+KiLrRWRUdPsJAN6zHbczuo0QQkgOSRquEZG1AAY47Lolev6/AfgWgFEAHheRr6RigIg0AmgEgJqamlROJYQQkoSkIq+q4932icgsAE+qSdHZJCJdAPoD2AXgRNuh1dFtTtdvAtAEmOwa76YTQghJRqbhmqcAjAUAERkEoALAHgBPA/iBiFSKyMkATgGwKcN7EUIISZFMF0MtBbBURP4O4CCAy6Ne/Ssi8jiAVwEcBnANM2sIIST3ZCTyqnoQwGUu++4AcEcm1/cKG2cTQogzRV/WgB2RCCHEnaIvUMZKjoQQ4k7RizwrORJCiDtFH65hJUdCCHGn6EUeYEckQghxo+jDNYQQQtyhyBNCSIChyBNCSIChyBNCSIChyBNCSIChyBNCSIApqEbeIrIbwLv5tsMD/WGqbZYSpfjMQGk+N5+5+DhJVY912lFQIl8siEibW2f0oFKKzwyU5nPzmYMFwzWEEBJgKPKEEBJgKPLp0ZRvA/JAKT4zUJrPzWcOEIzJE0JIgKEnTwghAYYiTwghAYYinyYico+IvCYiL4vIH0Tk6HzblG1E5Psi8oqIdIlIINPNLERkooi8LiLbROTmfNuTC0RkqYh8KCJ/z7ctuUJEThSRFhF5Nfq3fV2+bfIbinz6/AnAEFUdCuANAPPybE8u+DuAiwD8d74NySYiEgawGMA5AE4DcKmInJZfq3LC/wYwMd9G5JjDAK5X1dMAfAvANUH7XVPk00RV16jq4ejbvwCozqc9uUBVt6rq6/m2IweMBrBNVd9W1YMAHgUwOc82ZR1V/W8AH+Xbjlyiqh+o6vPR7/cC2ArghPxa5S8UeX+4EsCz+TaC+MYJAN6zvd+JgP3jk96IyEAAwwH8Nc+m+Eog2v9lCxFZC2CAw65bVHVl9JhbYD7y/S6XtmULL89MSNAQkSMBPAFgjqr+K9/2+AlFPgGqOj7RfhG5AsAkAOM0IAsOkj1zibALwIm299XRbSSAiEg5jMD/TlWfzLc9fsNwTZqIyEQANwK4QFX359se4it/A3CKiJwsIhUAfgDg6TzbRLKAiAiA3wDYqqr35duebECRT58HAfQD8CcReVFE/me+Dco2InKhiOwEUA/gjyKyOt82ZYPohPpsAKthJuIeV9VX8mtV9hGR3wOIAPi6iOwUkRn5tikHjAHwQwDfif4fvygi5+bbKD9hWQNCCAkw9OQJISTAUOQJISTAUOQJISTAUOQJISTAUOQJISTAUOQJISTAUOQJISTA/H+8kC770GoivgAAAABJRU5ErkJggg==",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"x, y = datasets.make_regression(\n",
" n_samples=250, n_features=1, n_targets=1, random_state=1, noise=10\n",
")\n",
"\n",
"plt.plot(x, y, \"b.\", label=\"Ensemble d'apprentissage\")\n",
"\n",
"plt.legend()\n",
"plt.show()\n"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {
"id": "jBQYiUU-XX9a"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model: \"sequential_2\"\n",
"_________________________________________________________________\n",
" Layer (type) Output Shape Param # \n",
"=================================================================\n",
" dense_2 (Dense) (None, 1) 2 \n",
" \n",
"=================================================================\n",
"Total params: 2\n",
"Trainable params: 2\n",
"Non-trainable params: 0\n",
"_________________________________________________________________\n"
]
}
],
"source": [
"from tensorflow.keras.models import Sequential\n",
"from tensorflow.keras.layers import Dense\n",
"\n",
"model = Sequential()\n",
"model.add(\n",
" Dense(1, activation=\"linear\", input_dim=1)\n",
") # input_dim indique la dimension de la couche d'entrée, ici 1\n",
"\n",
"model.summary() # affiche un résumé du modèle\n"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {
"id": "S0Vqoo26Xfe3"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1/10\n",
"10/10 [==============================] - 0s 19ms/step - loss: 245.9282 - mae: 11.5425 - val_loss: 117.3151 - val_mae: 8.8674\n",
"Epoch 2/10\n",
"10/10 [==============================] - 0s 9ms/step - loss: 84.9707 - mae: 7.2142 - val_loss: 129.4701 - val_mae: 9.4206\n",
"Epoch 3/10\n",
"10/10 [==============================] - 0s 7ms/step - loss: 83.3558 - mae: 7.2297 - val_loss: 128.8718 - val_mae: 9.3796\n",
"Epoch 4/10\n",
"10/10 [==============================] - 0s 8ms/step - loss: 82.9053 - mae: 7.2037 - val_loss: 131.2379 - val_mae: 9.4093\n",
"Epoch 5/10\n",
"10/10 [==============================] - 0s 9ms/step - loss: 83.3645 - mae: 7.1756 - val_loss: 136.7746 - val_mae: 9.5448\n",
"Epoch 6/10\n",
"10/10 [==============================] - 0s 9ms/step - loss: 83.7992 - mae: 7.1879 - val_loss: 132.7072 - val_mae: 9.4856\n",
"Epoch 7/10\n",
"10/10 [==============================] - 0s 6ms/step - loss: 83.8195 - mae: 7.1865 - val_loss: 130.4464 - val_mae: 9.4139\n",
"Epoch 8/10\n",
"10/10 [==============================] - 0s 7ms/step - loss: 85.3769 - mae: 7.3006 - val_loss: 127.4360 - val_mae: 9.3335\n",
"Epoch 9/10\n",
"10/10 [==============================] - 0s 5ms/step - loss: 83.1083 - mae: 7.1654 - val_loss: 130.0450 - val_mae: 9.4079\n",
"Epoch 10/10\n",
"10/10 [==============================] - 0s 4ms/step - loss: 84.1076 - mae: 7.2231 - val_loss: 131.9810 - val_mae: 9.4652\n"
]
}
],
"source": [
"from tensorflow.keras import optimizers\n",
"\n",
"sgd = optimizers.SGD(\n",
" learning_rate=0.1\n",
") # On choisit la descente de gradient stochastique, avec un taux d'apprentssage de 0.1\n",
"\n",
"# On définit ici, pour le modèle introduit plus tôt, l'optimiseur choisi, la fonction de perte (ici\n",
"# l'erreur quadratique moyenne pour un problème de régression) et les métriques que l'on veut observer pendant\n",
"# l'entraînement. L'erreur absolue moyenne (MAE) est un indicateur plus simple à interpréter que la MSE.\n",
"model.compile(optimizer=sgd, loss=\"mean_squared_error\", metrics=[\"mae\"])\n",
"\n",
"# Entraînement du modèle avec des mini-batchs de taille 20, sur 10 epochs.\n",
"# Le paramètre validation_split signifie qu'on tire aléatoirement une partie des données\n",
"# (ici 20%) pour servir d'ensemble de validation\n",
"history = model.fit(x, y, validation_split=0.2, epochs=10, batch_size=20)\n"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {
"id": "46LiNDvGYQdK"
},
"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": [
"plt.plot(x, y, \"b.\", label=\"Ensemble d'apprentissage\")\n",
"\n",
"x_gen = np.expand_dims(np.linspace(-3, 3, 10), 1)\n",
"y_gen = model.predict(x_gen)\n",
"\n",
"plt.plot(x_gen, y_gen, \"g-\", label=\"Prédiction du modèle\")\n",
"plt.legend()\n",
"plt.show()\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "kHu5v6lUYqTm"
},
"source": [
"S'il vous reste du temps, reprenez les différents problèmes définis précédemment et utilisez la librairie Keras pour les résoudre.\n"
]
}
],
"metadata": {
"colab": {
"collapsed_sections": [],
"name": "TP Réseaux de Neurones avec Numpy - Sujet.ipynb",
"provenance": []
},
"coursera": {
"course_slug": "nlp-sequence-models",
"graded_item_id": "xxuVc",
"launcher_item_id": "X20PE"
},
"kernelspec": {
"display_name": "Python 3",
"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.2"
},
"toc": {
"nav_menu": {},
"number_sections": true,
"sideBar": true,
"skip_h1_title": false,
"toc_cell": true,
"toc_position": {},
"toc_section_display": "block",
"toc_window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 0
}