Blame
|
1 | # 6. Réseaux de neurones multi-couches |
||||||
|
2 | |||||||
|
3 | Une seule unité linéaire ne trace qu'une frontière droite. Empiler de nombreuses unités simples avec une non-linéarité entre elles donne un réseau de neurones multi-couches, qui ajuste des frontières courbes et apprend ses propres caractéristiques. Ce module construit ce modèle en douceur : prendre la régression logistique du module précédent, la dessiner comme un graphe, et la rendre profonde, une étape à la fois. La recette est celle de chaque module : un modèle (des couches, exécutées par la propagation avant), une fonction de perte adaptée à la tâche, et la descente de gradient, désormais propulsée par la rétropropagation. L'histoire continue ensuite dans le cours de [Deep Learning](/fr/Deep%20Learning), qui reprend exactement ici : pourquoi les gradients disparaissent dans les piles profondes, les activations qui les raniment, les bonnes pratiques qui stabilisent l'entraînement, et les améliorations de la descente de gradient. |
||||||
|
4 | |||||||
|
5 | ## 6.1 Linéaire contre non linéaire |
||||||
|
6 | |||||||
|
7 | Les classifieurs linéaires du [module de classification linéaire](/fr/Machine%20Learning/05%20Linear%20classification) séparent les classes par une seule frontière droite, si bien qu'un problème comme XOR, non linéairement séparable, est hors de portée. Courber la frontière demande quelque chose de non linéaire, et toute la question est de savoir d'où vient la non-linéarité. [Régression linéaire](/fr/Machine%20Learning/04%20Linear%20regression) y a déjà répondu une première fois, avec des fonctions de base $\phi$ fixées à la main avant l'entraînement. Les réseaux y répondent autrement : ils apprennent eux-mêmes les caractéristiques. La section suivante construit cette machine à partir d'un modèle déjà connu. |
||||||
| 8 | ||||||||
| 9 | ## 6.2 Rendre la régression logistique profonde |
|||||||
| 10 | ||||||||
| 11 | ### 6.2.1 La régression logistique comme réseau |
|||||||
| 12 | ||||||||
| 13 | [Classification linéaire](/fr/Machine%20Learning/05%20Linear%20classification) s'est terminée sur la régression logistique : un produit scalaire avec les poids $w$ et une sigmoïde qui écrase le score en probabilité, |
|||||||
| 14 | ||||||||
| 15 | $$\boxed{ \hat{y} = \sigma(w^T x) }$$ |
|||||||
| 16 | ||||||||
| 17 | avec la convention habituelle du cours : $x$ est augmenté d'une constante $x_0 = 1$, si bien que le poids $w_0$ est le biais. Dessiné comme un graphe, c'est déjà un réseau, le plus petit possible. La couche d'entrée contient $x$, constante comprise, et ne calcule rien. Un seul neurone de sortie fait tout le travail : multiplier par les poids, appliquer l'activation. Chaque neurone de ce module est exactement cette unité. |
|||||||
| 18 | ||||||||
| 19 |  |
|||||||
| 20 | ||||||||
| 21 | *Chaque arête porte un poids et le neurone applique $\sigma$ à la somme pondérée. Le neurone fixé à $1$ porte le biais : son poids est $w_0$.* |
|||||||
| 22 | ||||||||
| 23 | *Remarque :* le biais reste replié dans les poids tout au long de ce module, dessiné comme un neurone constant. Le cours de [Deep Learning](/fr/Deep%20Learning) garde au contraire un vecteur de biais explicite $b^{[l]}$, et signale ce changement de convention au moment de l'introduire. |
|||||||
| 24 | ||||||||
| 25 | ### 6.2.2 Insérer une couche cachée |
|||||||
| 26 | ||||||||
| 27 | Rien n'oblige le neurone de sortie à lire l'entrée brute. Insérons quelques neurones entre l'entrée et la sortie, disons trois. Chacun est la même unité à produit scalaire que toujours, avec ses propres poids $w_i$ et une activation non linéaire $g$ : |
|||||||
| 28 | ||||||||
| 29 | $$a_i = g(w_i^T x), \qquad i = 1, 2, 3$$ |
|||||||
|
30 | |||||||
|
31 | Empilons les trois vecteurs de poids $w_i^T$ comme lignes d'une matrice $W^{[1]}$, et toute la couche tient en une ligne, $a = g(W^{[1]} x)$. L'exposant entre crochets $[1]$ est nouveau, et il existe pour une raison prosaïque : le modèle a maintenant deux jeux de poids, chacun a donc besoin d'un nom. $[l]$ dit simplement à quelle couche un symbole appartient. |
||||||
|
32 | |||||||
|
33 | Le neurone de sortie n'a pas changé du tout. C'est toujours la régression logistique de la section 6.2.1, il lit simplement les trois valeurs apprises $a$, augmentées d'une constante $a_0 = 1$ (chaque couche reçoit un neurone de biais, exactement comme l'entrée), au lieu de l'entrée brute : |
||||||
|
34 | |||||||
|
35 | $$\boxed{ \hat{y} = \sigma\!\left(w^{[2]T} a\right) = \sigma\!\left(w^{[2]T}\, g(W^{[1]} x)\right) }$$ |
||||||
|
36 | |||||||
|
37 |  |
||||||
|
38 | |||||||
|
39 | *Le neurone de sortie orange est identique dans les deux dessins. Rendre le modèle profond a changé ce qu'il lit : trois caractéristiques apprises $a$ au lieu du $x$ brut. Chaque couche porte son propre neurone constant $1$, dont les poids sortants sont les biais.* |
||||||
|
40 | |||||||
|
41 | Deux faits sur cette insertion portent toute l'histoire. |
||||||
| 42 | ||||||||
| 43 | **L'activation cachée doit être non linéaire.** Si $g$ était l'identité, les deux couches se réduiraient à une seule application linéaire, |
|||||||
| 44 | ||||||||
| 45 | $$\boxed{ W^{[2]}\!\left(W^{[1]} x\right) = W' x }$$ |
|||||||
| 46 | ||||||||
| 47 | et la profondeur n'apporterait rien. C'est la non-linéarité qui rend l'empilement utile, et c'est elle qui met désormais XOR à portée. |
|||||||
| 48 | ||||||||
| 49 | **La couche cachée apprend les caractéristiques.** Le neurone de sortie reste un classifieur linéaire, le travail de la couche cachée est donc de déplacer les données là où les classes deviennent linéairement séparables. Elle joue exactement le rôle des fonctions de base $\phi$ de [Régression linéaire](/fr/Machine%20Learning/04%20Linear%20regression), avec une amélioration : $\phi$ était fixée à la main avant l'entraînement, tandis que $a$ est apprise des données, de bout en bout. |
|||||||
| 50 | ||||||||
| 51 | ### 6.2.3 Comment faire une prédiction ? |
|||||||
| 52 | ||||||||
| 53 | Une couche cachée a fonctionné, alors répétons le geste : le vecteur $a^{[1]}$ peut alimenter une deuxième couche cachée, dont la sortie $a^{[2]}$ peut en alimenter une troisième, jusqu'à une couche de sortie qui produit $\hat{y}$. La couche $l$ possède sa matrice de poids $W^{[l]}$ (une ligne par neurone, la couche de sortie ci-dessus avait donc l'unique ligne $w^{[2]T}$) et son activation $g^{[l]}$. La largeur et la profondeur sont les boutons de capacité : plus d'unités et plus de couches donnent plus de paramètres et des frontières plus expressives, et, comme [Concepts généraux](/fr/Machine%20Learning/02%20General%20concepts) l'a prévenu, plus de place pour surapprendre. |
|||||||
|
54 | |||||||
|
55 |  |
||||||
|
56 | |||||||
|
57 | *Chaque arête porte un poids de $W^{[l]}$. Les neurones de biais constants ne sont pas dessinés.* |
||||||
| 58 | ||||||||
| 59 | Calculer la prédiction en lisant le réseau de gauche à droite s'appelle la propagation avant, et la formule générale ne fait que redire ce que les deux dernières sections ont construit, une fois par couche : |
|||||||
| 60 | ||||||||
| 61 | $$\boxed{ z^{[l]} = W^{[l]} a^{[l-1]}, \quad a^{[l]} = g^{[l]}\!\left(z^{[l]}\right), \quad a^{[0]} = x, \quad \hat{y} = a^{[L]} }$$ |
|||||||
| 62 | ||||||||
| 63 | avec une convention à retenir : chaque $a^{[l]}$, comme l'entrée, se lit avec son neurone de biais $a^{[l]}_0 = 1$ ajouté en tête. Sous forme vectorisée, tout le mini-lot circule d'un coup, une opération matricielle par couche avec les exemples en colonnes, ce qui est à la fois plus clair et bien plus rapide : |
|||||||
| 64 | ||||||||
| 65 | $$\boxed{ Z^{[l]} = W^{[l]} A^{[l-1]} }$$ |
|||||||
| 66 | ||||||||
| 67 | La propagation avant est la première moitié de chaque pas d'entraînement. La seconde moitié, la rétropropagation, parcourt le même câblage en sens inverse (section 6.4). |
|||||||
| 68 | ||||||||
| 69 | ### 6.2.4 La formule sur le graphe |
|||||||
|
70 | |||||||
|
71 | Chaque symbole de la formule de propagation avant vit quelque part sur le dessin du réseau. La figure ci-dessous les place un à un sur le plus petit réseau intéressant, deux entrées, une couche cachée de deux unités et une sortie : |
||||||
|
72 | |||||||
|
73 |  |
||||||
|
74 | |||||||
|
75 | *À gauche : l'exposant $[l]$ nomme la couche, chaque arête porte un poids $w^{[l]}_{ij}$, et les neurones fixés à $1$ portent les biais $w^{[l]}_{i0}$. À droite : à l'intérieur d'une unité, la somme pondérée donne $z^{[l]}_i$, puis l'activation $g$ la transforme en $a^{[l]}_i$.* |
||||||
| 76 | ||||||||
| 77 | | Symbole | Nom | Où il vit sur le graphe | |
|||||||
| 78 | | --- | --- | --- | |
|||||||
| 79 | | $l$, $L$ | indice de couche, nombre de couches | la colonne d'unités ($l = 0$ est l'entrée, ici $L = 2$) | |
|||||||
| 80 | | $x = a^{[0]}$ | l'entrée | la colonne la plus à gauche | |
|||||||
| 81 | | $w^{[l]}_{ij}$ | un poids | le nombre porté par une arête : vers l'unité $i$ de la couche $l$, depuis l'unité $j$ de la couche $l-1$ | |
|||||||
| 82 | | $W^{[l]}$ | la matrice de poids de la couche $l$ | toutes les arêtes qui arrivent dans la couche $l$, une ligne par unité | |
|||||||
| 83 | | $x_0$, $a^{[l]}_0$ | le neurone de biais | une unité fixée à $1$ dans chaque couche, dont le poids sortant $w^{[l]}_{i0}$ est le biais de l'unité $i$ | |
|||||||
| 84 | | $z^{[l]}_i$ | la pré-activation | la somme pondérée que l'unité calcule avant d'appliquer $g$ | |
|||||||
| 85 | | $g^{[l]}$ | la fonction d'activation | appliquée à l'intérieur de chaque unité de la couche $l$ | |
|||||||
| 86 | | $a^{[l]}_i$ | l'activation | la valeur que l'unité envoie sur ses arêtes sortantes | |
|||||||
| 87 | | $\hat{y} = a^{[L]}$ | la prédiction | ce qui sort de la dernière couche | |
|||||||
| 88 | ||||||||
| 89 | Faisons maintenant tourner ce réseau exact avec des nombres. Prenons $x = (1, 2)$, augmenté en $(1, 1, 2)$ par le neurone de biais $x_0 = 1$, la sigmoïde du module précédent comme activation partout, avec |
|||||||
| 90 | ||||||||
| 91 | $$W^{[1]} = \begin{pmatrix} 0 & 2 & -1 \\ -1 & 1 & 1 \end{pmatrix}, \qquad W^{[2]} = \begin{pmatrix} 0 & 1 & 1 \end{pmatrix}$$ |
|||||||
| 92 | ||||||||
| 93 | La ligne $i$ de $W^{[1]}$ rassemble les poids des arêtes qui arrivent dans l'unité cachée $i$, biais en tête. Couche 1, unité par unité : |
|||||||
| 94 | ||||||||
| 95 | $$z^{[1]}_1 = \underbrace{0}_{w^{[1]}_{10}} \cdot \underbrace{1}_{x_0} + \underbrace{2}_{w^{[1]}_{11}} \cdot \underbrace{1}_{x_1} + \underbrace{(-1)}_{w^{[1]}_{12}} \cdot \underbrace{2}_{x_2} = 0, \qquad a^{[1]}_1 = \sigma(0) = 0{,}5$$ |
|||||||
| 96 | ||||||||
| 97 | $$z^{[1]}_2 = -1 \cdot 1 + 1 \cdot 1 + 1 \cdot 2 = 2, \qquad a^{[1]}_2 = \sigma(2) \approx 0{,}88$$ |
|||||||
| 98 | ||||||||
| 99 | L'unité cachée 1 tombe exactement sur zéro, le point milieu de la sigmoïde, elle sort donc $0{,}5$, tandis que l'unité 2 se place haut sur la courbe. La couche de sortie répète les deux mêmes étapes, en lisant cette fois $a^{[1]} = (0{,}5,\ 0{,}88)$, augmenté en $(1,\ 0{,}5,\ 0{,}88)$ par son propre neurone de biais, au lieu de $x$ : |
|||||||
| 100 | ||||||||
| 101 | $$z^{[2]} = 0 \cdot 1 + 1 \cdot 0{,}5 + 1 \cdot 0{,}88 = 1{,}38, \qquad \hat{y} = a^{[2]} = \sigma(1{,}38) \approx 0{,}80$$ |
|||||||
| 102 | ||||||||
| 103 | Le réseau prédit la classe 1 avec une probabilité d'environ $0{,}80$. C'est tout ce que fait la propagation avant : multiplier par les poids des arêtes, neurone de biais compris, appliquer l'activation, à chaque unité de chaque couche. |
|||||||
| 104 | ||||||||
| 105 | ## 6.3 La fonction de perte |
|||||||
| 106 | ||||||||
| 107 | Le corps du réseau ignore la tâche. La tâche vit dans la dernière couche : son activation met en forme $\hat{y}$, et la perte compare $\hat{y}$ à l'étiquette, en réutilisant les pertes de [Concepts généraux](/fr/Machine%20Learning/02%20General%20concepts) et de [Classification linéaire](/fr/Machine%20Learning/05%20Linear%20classification) : |
|||||||
| 108 | ||||||||
| 109 | | Tâche | Activation de sortie | Fonction de perte | |
|||||||
| 110 | | --- | --- | --- | |
|||||||
| 111 | | régression | identité | erreur quadratique | |
|||||||
| 112 | | classification binaire | sigmoïde | entropie croisée binaire | |
|||||||
| 113 | | classification multiclasse | softmax | entropie croisée catégorielle | |
|||||||
|
114 | |||||||
| 115 | $$\boxed{ \hat{y} = \frac{1}{1 + e^{-z}} \quad\text{(binaire)} \qquad \hat{y}_c = \frac{e^{z_c}}{\sum_{j} e^{z_j}} \quad\text{(multiclasse)} }$$ |
|||||||
| 116 | ||||||||
|
117 | *Remarque :* ce sont exactement les têtes de neurone de [Classification linéaire](/fr/Machine%20Learning/05%20Linear%20classification). Un réseau est cette même tête posée sur des caractéristiques apprises plutôt que sur les entrées brutes. |
||||||
| 118 | ||||||||
| 119 | ## 6.4 Comment optimiser les paramètres ? |
|||||||
| 120 | ||||||||
| 121 | Rien de nouveau ici non plus : entraîner un réseau suit les mêmes étapes que chaque modèle de ce cours, alors parcourons-les dans l'ordre. |
|||||||
| 122 | ||||||||
| 123 | **Étape 0 : poser l'objectif.** Chercher les poids qui minimisent la perte plus un régulariseur qui les garde petits, la recette du maximum a posteriori de [Régression linéaire](/fr/Machine%20Learning/04%20Linear%20regression) : |
|||||||
| 124 | ||||||||
| 125 | $$\boxed{ W^\star = \arg\min_W \; L(W) + \lambda\, R(W), \qquad R(W) = \lVert W \rVert_1 \;\text{ ou }\; \lVert W \rVert_2^2 }$$ |
|||||||
| 126 | ||||||||
| 127 | **Étape 1 : choisir la perte.** C'est la section 6.3, et son tableau porte l'avertissement qui va avec : la perte et l'activation de sortie se choisissent en paire. L'entropie croisée appelle une softmax (ou une sigmoïde), l'erreur quadratique une sortie identité. |
|||||||
| 128 | ||||||||
| 129 | **Étape 2 : descendre le gradient.** Mettre à jour chaque poids d'un petit pas contre son gradient, avec le taux d'apprentissage $\alpha$, exactement la descente de gradient de [Classification linéaire](/fr/Machine%20Learning/05%20Linear%20classification) : |
|||||||
| 130 | ||||||||
| 131 | $$\boxed{ w^{[l]}_{ij} \leftarrow w^{[l]}_{ij} - \alpha\, \frac{\partial \left(L + \lambda R\right)}{\partial w^{[l]}_{ij}} }$$ |
|||||||
| 132 | ||||||||
| 133 | **Étape 3 : obtenir le gradient par rétropropagation.** La pièce vraiment nouvelle est le calcul de ce gradient pour chaque poids d'une pile de couches. La rétropropagation y parvient avec la règle de dérivation en chaîne, en une passe avant et une passe arrière : la propagation avant met en cache chaque $z^{[l]}$ et $a^{[l]}$, puis la passe arrière propage le gradient de la perte couche par couche, de la sortie jusqu'à la première couche, en réutilisant le cache. Avec l'erreur de couche $\delta^{[l]} = \partial L / \partial z^{[l]}$, |
|||||||
| 134 | ||||||||
| 135 | $$\boxed{ \delta^{[l]} = \left((W^{[l+1]})^T \delta^{[l+1]}\right) \odot g'^{[l]}\!\left(z^{[l]}\right), \qquad \frac{\partial L}{\partial W^{[l]}} = \delta^{[l]} (a^{[l-1]})^T }$$ |
|||||||
| 136 | ||||||||
| 137 | Les neurones de biais s'intègrent gratuitement : constants, ils ne reçoivent aucune erreur (leur ligne de $(W^{[l+1]})^T \delta^{[l+1]}$ est simplement abandonnée), et comme $a^{[l-1]}$ contient la constante $1$, le même produit extérieur livre les gradients des biais avec le reste. |
|||||||
|
138 | |||||||
|
139 |  |
||||||
| 140 | ||||||||
|
141 | *La propagation avant calcule et met en cache les activations, la rétropropagation renvoie le gradient de la perte par les mêmes arêtes.* |
||||||
| 142 | ||||||||
| 143 | Un point pratique complète la recette : le gradient de l'étape 2 se calcule sur un mini-lot. [Classification linéaire](/fr/Machine%20Learning/05%20Linear%20classification) offrait deux extrêmes, le lot complet ou un seul exemple par pas. Les réseaux s'entraînent entre les deux, un petit lot par pas : un gradient assez précis pour progresser, un pas assez bon marché pour en faire des milliers, et la propagation avant vectorisée de la section 6.2.3 traite tout le mini-lot en un produit matriciel par couche. |
|||||||
|
144 | |||||||
| 145 | <details class="proof"> |
|||||||
| 146 | <summary>Exemple complet : un pas de descente de gradient sur le petit réseau</summary> |
|||||||
| 147 | ||||||||
| 148 | Reprenons le réseau de la section 6.2.4 exactement où la propagation avant l'a laissé : $\bar{x} = (1, 1, 2)$, $a^{[1]} = (0{,}5,\ 0{,}88)$, $\hat{y} = 0{,}80$, et donnons une étiquette à l'exemple : la vraie classe est $y = 0$. Prenons l'entropie croisée binaire de la section 6.3 sans régularisation ($\lambda = 0$), la perte vaut donc |
|||||||
| 149 | ||||||||
| 150 | $$L = -\ln(1 - \hat{y}) = -\ln(0{,}20) \approx 1{,}61$$ |
|||||||
| 151 | ||||||||
| 152 | Le réseau se trompe avec assurance, et le gradient va le lui dire. |
|||||||
| 153 | ||||||||
| 154 | **En arrière à travers la couche de sortie.** Pour une sortie sigmoïde entraînée avec l'entropie croisée, l'erreur de sortie se réduit au familier $\hat{y} - y$ de [Classification linéaire](/fr/Machine%20Learning/05%20Linear%20classification) : |
|||||||
| 155 | ||||||||
| 156 | $$\delta^{[2]} = \hat{y} - y = 0{,}80$$ |
|||||||
| 157 | ||||||||
| 158 | Chaque poids de $W^{[2]}$ reçoit $\delta^{[2]}$ fois l'activation qu'il lit (la formule du produit extérieur, neurone de biais compris) : |
|||||||
| 159 | ||||||||
| 160 | $$\frac{\partial L}{\partial W^{[2]}} = \delta^{[2]} \left(\bar{a}^{[1]}\right)^T = 0{,}80 \cdot (1,\ 0{,}5,\ 0{,}88) = (0{,}80,\ 0{,}40,\ 0{,}70)$$ |
|||||||
| 161 | ||||||||
| 162 | **En arrière à travers la couche cachée.** Chaque unité cachée prend sa part de l'erreur à travers son poids sortant, fois sa propre pente $\sigma'(z) = \sigma(z)(1 - \sigma(z))$ : |
|||||||
| 163 | ||||||||
| 164 | $$\delta^{[1]}_1 = w^{[2]}_{11}\, \delta^{[2]}\, \sigma'(0) = 1 \cdot 0{,}80 \cdot 0{,}25 = 0{,}20, \qquad \delta^{[1]}_2 = 1 \cdot 0{,}80 \cdot 0{,}10 = 0{,}08$$ |
|||||||
| 165 | ||||||||
|
166 | (le neurone de biais constant ne prend aucune erreur, et notez la petite pente $0{,}10$ de l'unité 2 : le cours de [Deep Learning](/fr/Deep%20Learning) en fera toute une histoire). Puis le même produit extérieur contre $\bar{x} = (1, 1, 2)$ : |
||||||
|
167 | |||||||
| 168 | $$\frac{\partial L}{\partial W^{[1]}} = \delta^{[1]}\, \bar{x}^T = \begin{pmatrix} 0{,}20 & 0{,}20 & 0{,}40 \\ 0{,}08 & 0{,}08 & 0{,}16 \end{pmatrix}$$ |
|||||||
| 169 | ||||||||
| 170 | **La mise à jour.** L'étape 2 avec un $\alpha = 1$ volontairement grand, pour rendre le mouvement visible : |
|||||||
| 171 | ||||||||
| 172 | $$W^{[2]} \leftarrow (0,\ 1,\ 1) - (0{,}80,\ 0{,}40,\ 0{,}70) = (-0{,}80,\ 0{,}60,\ 0{,}30)$$ |
|||||||
| 173 | ||||||||
| 174 | $$W^{[1]} \leftarrow \begin{pmatrix} 0 & 2 & -1 \\ -1 & 1 & 1 \end{pmatrix} - \begin{pmatrix} 0{,}20 & 0{,}20 & 0{,}40 \\ 0{,}08 & 0{,}08 & 0{,}16 \end{pmatrix} = \begin{pmatrix} -0{,}20 & 1{,}80 & -1{,}40 \\ -1{,}08 & 0{,}92 & 0{,}84 \end{pmatrix}$$ |
|||||||
| 175 | ||||||||
| 176 | **Est-ce que ça a aidé ?** Relançons la propagation avant avec les nouveaux poids : $z^{[1]} = (-1{,}20,\ 1{,}52)$, $a^{[1]} = (0{,}23,\ 0{,}82)$, $z^{[2]} = -0{,}42$, et |
|||||||
| 177 | ||||||||
| 178 | $$\hat{y} = \sigma(-0{,}42) \approx 0{,}40, \qquad L = -\ln(1 - 0{,}40) \approx 0{,}51$$ |
|||||||
| 179 | ||||||||
| 180 | Un seul pas, et la prédiction de la classe 1 est passée de $0{,}80$ à $0{,}40$, la perte de $1{,}61$ à $0{,}51$. L'entraînement, c'est cette boucle, répétée sur les mini-lots jusqu'à ce que la perte se stabilise. |
|||||||
| 181 | ||||||||
| 182 | </details> |
|||||||
| 183 | ||||||||
|
184 | *Ce module est la porte d'entrée du cours de [Deep Learning](/fr/Deep%20Learning), qui reprend l'histoire exactement ici : les fonctions d'activation, les optimiseurs, l'initialisation, la normalisation, la régularisation et les architectures bâties dessus. Le module suivant revient aux modèles linéaires sous un nouvel angle, le classifieur à marge maximale.* |
||||||
|
185 | |||||||
| 186 | --- |
|||||||
|
187 | Suivant : [Machines à vecteurs de support](/fr/Machine%20Learning/07%20Support%20Vector%20Machines) · [Vue d'ensemble du cours](/fr/Machine%20Learning) |
||||||
