Utilisation Avancée de Keras
Fonctions d'Activation (ReLU, sigmoid, tanh, etc.) : Rôle et Choix
Les fonctions d'activation sont un élément essentiel des réseaux de neurones. Elles sont appliquées à la sortie de chaque neurone (ou, plus précisément, à la somme pondérée des entrées du neurone plus le biais) et introduisent des non-linéarités dans le modèle.
Pourquoi les Fonctions d'Activation sont-elles Nécessaires ?
Sans fonctions d'activation, un réseau de neurones, quelle que soit sa profondeur (nombre de couches), serait équivalent à une simple régression linéaire. Les non-linéarités introduites par les fonctions d'activation permettent au réseau d'apprendre des relations complexes entre les entrées et les sorties.
En d'autres termes : Sans non-linéarités, empiler des couches reviendrait à faire une seule grande transformation linéaire. Les fonctions d'activation permettent au réseau d'apprendre des fonctions beaucoup plus riches et plus variées. Par exemple, un réseau sans activation ne pourrait pas apprendre à reconnaître des motifs complexes comme des visages ou des formes géométriques.
Fonctions d'Activation Courantes
Voici quelques-unes des fonctions d'activation les plus utilisées, avec leurs caractéristiques et leurs cas d'usage typiques :
1. Sigmoïde (Sigmoid)
- Formule :
- Plage de sortie : (0, 1)
- Interprétation : Peut être interprétée comme une probabilité (sortie entre 0 et 1).
- Utilisation typique : Couche de sortie pour la classification binaire (deux classes).
- Avantages :
- Sortie bornée entre 0 et 1.
- Inconvénients :
- Problème du gradient qui s'évanouit (vanishing gradient) : Pour des valeurs d'entrée très grandes ou très petites, la dérivée de la sigmoïde est proche de 0. Cela peut ralentir ou bloquer l'apprentissage (la descente de gradient devient inefficace).
- Non centrée autour de 0 : Cela peut aussi ralentir l'apprentissage.

Exemple d'utilisation :
# Classification binaire avec sigmoïde
model = tf.keras.Sequential([
tf.keras.layers.Dense(64, activation='relu', input_shape=(784,)),
tf.keras.layers.Dense(1, activation='sigmoid') # Couche de sortie
])
model.compile(optimizer='adam', loss='binary_crossentropy')
2. Tangente Hyperbolique (tanh)
- Formule :
- Plage de sortie : (-1, 1)
- Utilisation typique : Couches cachées.
- Avantages :
- Centrée autour de 0 (contrairement à la sigmoïde), ce qui peut accélérer l'apprentissage.
- Inconvénients :
- Souffre aussi du problème du gradient qui s'évanouit, bien que de manière moins prononcée que la sigmoïde.

Exemple d'utilisation :
# Réseau avec tanh dans les couches cachées
model = tf.keras.Sequential([
tf.keras.layers.Dense(64, activation='tanh', input_shape=(784,)),
tf.keras.layers.Dense(10, activation='softmax') # Couche de sortie
])
3. ReLU (Rectified Linear Unit)
- Formule :
- Plage de sortie : [0, +∞)
- Utilisation typique : Couches cachées (c'est souvent le choix par défaut).
- Avantages :
- Simplicité : Très facile et rapide à calculer (comparée à la sigmoïde et à la tanh).
- Moins de problèmes de gradient qui s'évanouit : La dérivée est 1 pour les valeurs positives, ce qui facilite l'apprentissage.
- Inconvénients :
- "Neurones mourants" (dying ReLU) : Si un neurone se retrouve avec une sortie toujours négative, son gradient sera toujours 0, et il ne sera plus jamais mis à jour. Cela peut arriver si le taux d'apprentissage est trop élevé.
- Non bornée supérieurement : Cela peut parfois poser des problèmes de stabilité numérique.

Exemple d'utilisation :
# Réseau avec ReLU (choix par défaut)
model = tf.keras.Sequential([
tf.keras.layers.Dense(64, activation='relu', input_shape=(784,)),
tf.keras.layers.Dense(10, activation='softmax')
])
4. Leaky ReLU
- Formule : où est une constante (souvent 0.01)
- Plage de sortie : (-∞, +∞)
- Utilisation typique : Couches cachées (alternative à ReLU).
- Avantages :
- Résout le problème des "neurones mourants" de ReLU, car la dérivée n'est jamais nulle.
- Inconvénients :
- Le choix de la valeur de α peut être délicat.

Exemple d'utilisation :
# Réseau avec Leaky ReLU
model = tf.keras.Sequential([
tf.keras.layers.Dense(64, activation=tf.keras.layers.LeakyReLU(alpha=0.01), input_shape=(784,)),
tf.keras.layers.Dense(10, activation='softmax')
])
5. Softmax
- Formule : (où est un vecteur de taille )
- Plage de sortie : (0, 1) pour chaque élément du vecteur de sortie, et la somme des éléments vaut 1.
- Interprétation : Peut être interprétée comme une distribution de probabilité sur plusieurs classes.
- Utilisation typique : Couche de sortie pour la classification multi-classe (plus de deux classes).
- Avantages :
- Produit une distribution de probabilité sur les classes.
- Inconvénients :
- N'est pas adaptée pour les couches cachées.

Exemple d'utilisation :
# Classification multi-classe avec softmax
model = tf.keras.Sequential([
tf.keras.layers.Dense(64, activation='relu', input_shape=(784,)),
tf.keras.layers.Dense(10, activation='softmax') # 10 classes
])
model.compile(optimizer='adam', loss='categorical_crossentropy')
Autres
Il existe de nombreuses fonctions d'activations, en voici quelques-unes :
- ELU (Exponential Linear Unit).
- SELU (Scaled Exponential Linear Unit).
- Swish.
- GELU (Gaussian Error Linear Unit).
Problème du Gradient qui s'Évanouit (Vanishing Gradient)
Le problème du gradient qui s'évanouit (vanishing gradient problem) est un phénomène qui peut se produire lors de l'entraînement de réseaux de neurones profonds (avec de nombreuses couches), en particulier lorsque des fonctions d'activation comme la sigmoïde ou la tangente hyperbolique (tanh) sont utilisées.
Qu'est-ce que le Gradient ?
Rappelons que le gradient de la fonction de perte par rapport aux paramètres du modèle (poids et biais) indique la direction dans laquelle il faut modifier ces paramètres pour faire diminuer la perte. La descente de gradient utilise ce gradient pour mettre à jour les paramètres.
Le Problème
Avec les fonctions sigmoïde et tanh, le gradient peut devenir extrêmement petit (proche de zéro) lorsque l'entrée de la fonction d'activation est très grande (en valeur absolue) ou très petite.
Pourquoi ?
- Sigmoïde : La dérivée de la sigmoïde est maximale en 0 (où elle vaut 0.25), et elle tend vers 0 lorsque l'entrée tend vers +∞ ou -∞.
- tanh : La dérivée de la tanh est maximale en 0 (où elle vaut 1), et elle tend vers 0 lorsque l'entrée tend vers +∞ ou -∞.
Lorsque le gradient est proche de zéro, les mises à jour des paramètres deviennent minuscules, et l'apprentissage ralentit considérablement, voire s'arrête complètement. Ce problème est particulièrement prononcé dans les premières couches d'un réseau profond, car le gradient est rétropropagé (calculé de la couche de sortie vers la couche d'entrée), et il est multiplié par les dérivées des fonctions d'activation à chaque couche. Si ces dérivées sont petites, le gradient devient de plus en plus petit au fur et à mesure qu'il traverse le réseau.
Conséquences
- Apprentissage lent ou impossible : Les premières couches du réseau apprennent très lentement, voire pas du tout.
- Difficulté à entraîner des réseaux profonds : Le problème s'aggrave avec la profondeur du réseau.
Solutions et Atténuations
Plusieurs techniques permettent d'atténuer ou de résoudre le problème du gradient qui s'évanouit :
-
Utiliser des fonctions d'activation qui ne saturent pas (ou moins) :
- ReLU et ses variantes (Leaky ReLU, ELU, etc.) sont beaucoup moins sensibles au problème, car leur dérivée est constante (1) pour les valeurs positives.
- C'est la principale raison pour laquelle ReLU est devenu si populaire pour les couches cachées.
-
Initialisation des poids :
- Une initialisation appropriée des poids peut aider à éviter que les activations ne soient trop grandes ou trop petites au début de l'entraînement. Nous y reviendrons.
-
Batch Normalization :
- Cette technique (que nous verrons plus tard) normalise les activations de chaque couche, ce qui aide à maintenir les gradients dans une plage raisonnable.
-
Architectures spécifiques :
- Certaines architectures, comme les réseaux résiduels (ResNets), utilisent des connexions "raccourcis" (skip connections) qui facilitent la propagation du gradient.
-
Optimiseurs adaptatifs :
- Des optimiseurs comme Adam, RMSprop adaptent le taux d'apprentissage, ce qui peut aider.
Le problème du gradient qui s'évanouit a été l'un des principaux obstacles au développement des réseaux de neurones profonds. Les techniques mentionnées ci-dessus ont permis de surmonter ce problème et ont rendu possible l'entraînement de réseaux beaucoup plus profonds et plus performants.
Visualisation
Voici un graphique montrant les dérivées des fonctions d'activation :

Vous pouvez constater que les dérivées de la sigmoïde et de la tangente hyperbolique tendent vers 0 lorsque x s'éloigne de 0, alors que la dérivée de ReLU reste constante (1) pour les valeurs positives de x.
Comment Choisir la Bonne Fonction d'Activation ?
Choisir la bonne fonction d'activation est crucial pour la performance de votre réseau de neurones. Voici quelques astuces et heuristiques pour vous guider :
1. Type de Problème et Couche de Sortie
Le choix de la fonction d'activation pour la couche de sortie est généralement dicté par le type de problème que vous essayez de résoudre :
- Classification binaire (deux classes) :
- Sigmoïde : Produit une probabilité (entre 0 et 1).
- Utilisez
binary_crossentropycomme fonction de perte.
- Classification multi-classe (plus de deux classes) :
- Softmax : Produit une distribution de probabilité sur les classes.
- Utilisez
categorical_crossentropy(si vos étiquettes sont en one-hot encoding) ousparse_categorical_crossentropy(si vos étiquettes sont des entiers).
- Régression (prédiction d'une valeur continue) :
- Aucune fonction d'activation (identité/linéaire) : Si la sortie peut prendre n'importe quelle valeur réelle.
- ReLU : Si la sortie doit être positive (par exemple, un prix, une distance).
- Sigmoïde (ou tanh) : Si la sortie doit être bornée (par exemple, entre 0 et 1, ou entre -1 et 1). Moins courant.
- Problèmes plus spécifiques :
- Par exemple, la détection d'objets ou la segmentation d'images.
2. Couches Cachées
Pour les couches cachées, le choix est moins strict, mais voici quelques recommandations :
- ReLU : C'est généralement le meilleur choix par défaut. Simple, rapide à calculer, et souvent plus performant que sigmoïde/tanh.
- Leaky ReLU (et autres variantes de ReLU : ELU, SELU) : À essayer si vous rencontrez des problèmes de "neurones mourants" avec ReLU.
- tanh : Historiquement populaire, mais généralement moins performant que ReLU et ses variantes dans les réseaux modernes. Peut être utile dans certains cas (par exemple, si vous avez besoin que les sorties des couches cachées soient centrées autour de 0).
- Swish et GELU : À tester, notamment dans les architectures modernes comme les transformers.
3. Profondeur du Réseau
- Réseaux peu profonds (1-2 couches cachées) : La différence de performance entre les fonctions d'activation est souvent moins marquée. Vous pouvez essayer différentes options (ReLU, tanh, etc.).
- Réseaux profonds : ReLU et ses variantes sont généralement préférables pour éviter le problème du gradient qui s'évanouit.
4. Expérimentation
Le choix de la fonction d'activation est un hyperparamètre. Il n'y a pas de règle absolue. La meilleure approche est souvent d'expérimenter :
- Commencez avec ReLU pour les couches cachées.
- Essayez d'autres options si vous n'êtes pas satisfait des résultats.
- Utilisez la validation croisée pour comparer objectivement les performances des différentes fonctions d'activation.
Comment Détecter un Mauvais Choix de Fonction d'Activation ?
Voici quelques signes qui peuvent indiquer que vous n'avez pas choisi la bonne fonction d'activation :
-
Apprentissage très lent ou bloqué :
- Cause possible : Gradient qui s'évanouit (avec sigmoïde/tanh).
- Solution : Essayez ReLU ou ses variantes.
-
"Neurones mourants" (avec ReLU) :
- Symptômes :
- Beaucoup de neurones ont une sortie constamment nulle (quelle que soit l'entrée).
- Les poids de ces neurones ne sont plus mis à jour.
- Causes possibles :
- Taux d'apprentissage trop élevé.
- Initialisation des poids inappropriée.
- Biais trop négatifs.
- Solutions :
- Utilisez Leaky ReLU (ou une autre variante de ReLU).
- Diminuez le taux d'apprentissage.
- Essayez une autre initialisation des poids.
- Utilisez Batch Normalization.
- Symptômes :
-
Instabilité numérique (valeurs très grandes ou NaN) :
- Cause possible : Fonction d'activation non bornée (ReLU) combinée avec des poids élevés ou un taux d'apprentissage trop élevé.
- Solutions :
- Diminuez le taux d'apprentissage.
- Utilisez la régularisation L1 ou L2 (pour réduire les poids).
- Utilisez Batch Normalization.
- Utilisez le gradient clipping.
-
Mauvaise performance (faible exactitude, perte élevée) :
- Cela peut avoir de nombreuses causes, mais une fonction d'activation inappropriée peut en être une.
- Solution : Expérimentez avec différentes fonctions d'activation, en gardant à l'esprit les recommandations ci-dessus.
-
Sorties non bornées pour un problème borné
- Si votre modèle de régression prédit des valeurs négatives alors que la sortie réelle est toujours positive.
L'analyse des courbes de perte et d'exactitude, ainsi que l'observation des activations et des gradients, peuvent vous aider à diagnostiquer les problèmes liés aux fonctions d'activation.
Initialisation des Poids
L'initialisation des poids est une étape souvent négligée, mais cruciale, dans la construction d'un réseau de neurones. Une mauvaise initialisation peut entraîner un apprentissage lent, voire impossible, ou conduire à de mauvaises performances.
Pourquoi est-ce important ?
- Briser la symétrie : Si tous les poids sont initialisés à la même valeur (par exemple, à zéro), tous les neurones d'une même couche apprendront la même chose. Le réseau ne pourra pas apprendre de représentations intéressantes. Il faut donc introduire de l'asymétrie.
- Éviter les gradients trop faibles ou trop forts :
- Si les poids sont initialisés avec des valeurs trop petites, les activations (sorties des neurones) deviendront de plus en plus petites au fur et à mesure qu'elles traversent les couches, ce qui peut conduire au problème du gradient qui s'évanouit.
- Si les poids sont initialisés avec des valeurs trop grandes, les activations peuvent devenir très grandes ("exploser"), ce qui peut rendre l'entraînement instable (divergence).
- Accélérer l'apprentissage : Une bonne initialisation permet au réseau de converger plus rapidement.
- Éviter les problèmes de convergence : Une mauvaise initialisation peut empêcher le réseau de converger vers une solution optimale.
- Atteindre de meilleures performances : Une initialisation adaptée peut améliorer la qualité finale du modèle.
Initialisations Courantes
Keras offre plusieurs initialiseurs de poids (dans le module tf.keras.initializers). Voici quelques-uns des plus courants :
-
Zeros: Initialise tous les poids à zéro.- À éviter pour les poids (sauf cas très spécifiques). Cela ne brise pas la symétrie.
- Peut être utilisé pour les biais.
-
Ones: Initialise tous les poids à un.- À éviter pour les mêmes raisons que
Zeros.
- À éviter pour les mêmes raisons que
-
Constant(value): Initialise tous les poids à une valeur constante donnée.- Rarement utilisé pour les poids, sauf cas très spécifiques.
-
RandomNormal(mean=0.0, stddev=0.05): Initialise les poids avec des valeurs aléatoires tirées d'une distribution normale.mean: La moyenne de la distribution (généralement 0).stddev: L'écart-type de la distribution. C'est ce paramètre qui contrôle l'amplitude des poids. Un écart-type trop petit ou trop grand peut poser problème.- Peut être utilisé, mais il existe de meilleures options.
-
RandomUniform(minval=-0.05, maxval=0.05): Initialise les poids avec des valeurs aléatoires tirées d'une distribution uniforme.minval: Borne inférieure de l'intervalle.maxval: Borne supérieure de l'intervalle.
- Peut être utilisé, mais il existe de meilleures options.
-
GlorotNormal(ouXavierNormal) : Initialise les poids avec des valeurs aléatoires tirées d'une distribution normale tronquée. L'écart-type dépend du nombre d'entrées et de sorties de la couche :- C'est l'un des initialiseurs les plus couramment utilisés, et souvent un bon choix par défaut.
- Conçu pour fonctionner particulièrement bien avec les fonctions d'activation de type tanh et sigmoïde
-
GlorotUniform(ouXavierUniform) : Similaire àGlorotNormal, mais utilise une distribution uniforme :- C'est l'un des initialiseurs les plus couramment utilisés, et souvent un bon choix par défaut.
- Conçu pour fonctionner particulièrement bien avec les fonctions d'activation de type tanh et sigmoïde
-
HeNormal: Initialise les poids avec des valeurs aléatoires tirées d'une distribution normale tronquée. L'écart-type dépend du nombre d'entrées de la couche :- Spécialement conçu pour les fonctions d'activation de type ReLU.
-
HeUniform: Similaire àHeNormal, mais utilise une distribution uniforme.- Spécialement conçu pour les fonctions d'activation de type ReLU.
-
LecunNormal:- Conçu pour fonctionner avec la fonction d'activation SELU.
-
LecunUniform:- Conçu pour fonctionner avec la fonction d'activation SELU.
Comment Utiliser les Initialiseurs en Keras
Vous pouvez spécifier l'initialiseur des poids et du biais lors de la création d'une couche :
import tensorflow as tf
model = tf.keras.Sequential([
tf.keras.layers.Dense(units=64, activation='relu', input_shape=(784,),
kernel_initializer='glorot_normal', # Initialiseur des poids
bias_initializer='zeros') # Initialiseur du biais
])
Vous pouvez aussi utiliser des instances d'initialiseurs pour plus de contrôle :
initializer = tf.keras.initializers.HeNormal()
model.add(tf.keras.layers.Dense(units=64, activation='relu', kernel_initializer=initializer))
Conseils Pratiques
- Biais : L'initialisation des biais à zéro (
'zeros'outf.keras.initializers.Zeros()) est courante et généralement acceptable. - Couches cachées :
- ReLU : Utilisez
HeNormalouHeUniform. - tanh : Utilisez
GlorotNormalouGlorotUniform. - Sigmoïde :
GlorotNormalouGlorotUniformfonctionnent généralement mieux que des initialiseurs conçus pour ReLU.
- ReLU : Utilisez
- SELU : Utilisez
LecunNormalouLecunUniformpour une meilleure stabilité. - Expérimentez : Si vous n'êtes pas sûr, essayez différentes initialisations et comparez les résultats.
N'initialisez jamais tous les poids à la même valeur (sauf zéro pour les biais, et encore) ! Cela empêcherait le réseau d'apprendre.
Optimiseurs Keras (optimizer)
L'optimiseur est un élément crucial de l'entraînement d'un réseau de neurones. C'est l'algorithme qui est responsable de la mise à jour des poids du modèle (et des biais) en fonction du gradient de la fonction de perte. Keras offre une variété d'optimiseurs, chacun avec ses propres caractéristiques et avantages.
Rappel : Descente de Gradient
L'idée de base de la plupart des optimiseurs est la descente de gradient. On calcule le gradient de la fonction de perte par rapport aux paramètres du modèle, et on modifie les paramètres dans la direction opposée au gradient (pour faire diminuer la perte).
La formule de mise à jour la plus simple (descente de gradient stochastique, SGD) est :
où :
- représente l'ensemble des paramètres du modèle (poids et biais).
- (eta) est le taux d'apprentissage (learning rate).
- est le gradient de la fonction de perte par rapport aux paramètres .
Optimiseurs Courants dans Keras
Voici quelques-uns des optimiseurs les plus couramment utilisés dans Keras, disponibles dans le module tf.keras.optimizers :
1. SGD (Stochastic Gradient Descent)
- Principe : C'est la descente de gradient stochastique "de base". Elle met à jour les paramètres en utilisant le gradient calculé sur un mini-batch de données (d'où le terme "stochastique").
- Paramètres :
learning_rate: Le taux d'apprentissage (par défaut, 0.01).momentum: Un terme d'inertie qui permet d'accélérer l'apprentissage dans les directions où le gradient est constant, et d'atténuer les oscillations (par défaut, 0.0).nesterov: Booléen, indique si l'on utilise le "momentum de Nesterov" (une variante du momentum qui donne souvent de meilleurs résultats).
- Avantages :
- Simple à comprendre et à implémenter.
- Inconvénients :
- Peut être lent à converger, en particulier pour les problèmes complexes.
- Sensible au choix du taux d'apprentissage.
- Peut osciller autour du minimum.
2. Adam (Adaptive Moment Estimation)
-
Principe : Adam est un optimiseur adaptatif qui combine les idées du momentum et de RMSprop. Il maintient :
- Une estimation du premier moment (la moyenne) du gradient.
- Une estimation du second moment (la variance non centrée) du gradient.
Il utilise ces estimations pour adapter le taux d'apprentissage pour chaque paramètre du modèle.
-
Paramètres :
learning_rate: Le taux d'apprentissage initial (par défaut, 0.001).beta_1: Le coefficient de décroissance exponentielle pour l'estimation du premier moment (par défaut, 0.9).beta_2: Le coefficient de décroissance exponentielle pour l'estimation du second moment (par défaut, 0.999).epsilon: Une petite constante pour éviter la division par zéro (par défaut, 1e-7).
-
Avantages :
- Converge généralement plus vite que SGD.
- Moins sensible au choix du taux d'apprentissage (dans une certaine mesure).
- Fonctionne bien dans de nombreuses situations (c'est souvent un bon choix par défaut).
-
Inconvénients :
- Peut parfois converger vers un minimum local moins bon que SGD (avec un bon réglage du taux d'apprentissage).
- Plus de paramètres à régler que SGD.
3. RMSprop (Root Mean Square Propagation)
- Principe : RMSprop est un autre optimiseur adaptatif. Il divise le taux d'apprentissage par une moyenne mobile des carrés des gradients récents. Cela permet d'adapter le taux d'apprentissage pour chaque paramètre, en donnant moins de poids aux gradients des paramètres qui varient beaucoup.
- Paramètres :
learning_rate: Le taux d'apprentissage initial (par défaut, 0.001).rho: Le coefficient de décroissance pour la moyenne mobile des carrés des gradients (par défaut, 0.9).epsilon: Une petite constante pour éviter la division par zéro (par défaut, 1e-7).
- Avantages :
- Similaire à Adam en termes de performance, mais avec moins de paramètres.
- Inconvénients :
- Peut être moins performant qu'Adam dans certains cas.
4. Adagrad (Adaptive Gradient Algorithm)
- Principe : Adagrad adapte le taux d'apprentissage pour chaque paramètre en divisant le taux d'apprentissage par la racine carrée de la somme des carrés des gradients passés. Cela a pour effet de réduire le taux d'apprentissage plus rapidement pour les paramètres qui ont déjà beaucoup varié.
- Paramètres :
learning_rate: Le taux d'apprentissage.initial_accumulator_value: Valeur initiale.epsilon: Une petite constante pour éviter la division par zéro.
- Avantages :
- Adapté aux problèmes où les gradients sont épars (beaucoup de gradients nuls).
- Inconvénients :
- Le taux d'apprentissage peut devenir trop petit au fil du temps, ce qui peut bloquer l'apprentissage.
5. Adadelta
- Principe: Adadelta est une extension d'Adagrad qui cherche à réduire son taux d'apprentissage décroissant de manière monotone.
- Paramètres:
learning_rate: Le taux d'apprentissage initial (par défaut, 0.001).rho: Le coefficient de décroissance pour la moyenne mobile des carrés des gradients (par défaut, 0.95).epsilon: Une petite constante pour éviter la division par zéro (par défaut, 1e-7).
- Avantages:
- Le taux d'apprentissage ne décroit pas indéfiniment.
Autres Optimiseurs
Il existe d'autres optimiseurs dans Keras (Adadelta, Adamax, Nadam, Ftrl), mais ils sont moins couramment utilisés.
Comment Choisir le Bon Optimiseur ?
- Adam est souvent un bon choix par défaut. Il fonctionne bien dans de nombreuses situations et ne nécessite pas trop de réglage des hyperparamètres.
- SGD avec momentum peut donner de très bons résultats, mais il faut souvent ajuster soigneusement le taux d'apprentissage et le momentum.
- RMSprop est une alternative à Adam.
- Adagrad peut être utile pour les problèmes avec des gradients épars (par exemple, en traitement du langage naturel).
En pratique :
- Commencez avec Adam.
- Si vous n'êtes pas satisfait des résultats, essayez SGD avec momentum (en ajustant soigneusement le taux d'apprentissage).
- Si vous avez des connaissances spécifiques sur votre problème (par exemple, gradients épars), vous pouvez essayer d'autres optimiseurs.
- Utilisez la validation croisée pour comparer objectivement les performances des différents optimiseurs.
Le choix de l'optimiseur est un hyperparamètre, et il n'y a pas de solution unique. L'expérimentation est souvent nécessaire. Cependant, Adam est un point de départ solide dans la plupart des cas.
Mini-Batch, Batch, et Descente de Gradient Stochastique
Lorsque l'on parle de descente de gradient, il est important de distinguer trois variantes, en fonction de la quantité de données utilisée pour calculer le gradient à chaque étape :
-
Descente de Gradient par Batch (Batch Gradient Descent) :
- Le gradient est calculé en utilisant l'ensemble des données d'entraînement.
- Les mises à jour des paramètres sont effectuées une seule fois par époque (une passe complète sur les données).
- Avantages :
- Le gradient est précis (pas de bruit).
- Convergence garantie vers un minimum local (pour les fonctions convexes).
- Inconvénients :
- Très lent pour les grands jeux de données (car il faut calculer le gradient sur toutes les données avant de faire une seule mise à jour).
- Peut nécessiter beaucoup de mémoire.
-
Descente de Gradient Stochastique (Stochastic Gradient Descent, SGD) :
- Le gradient est calculé en utilisant un seul exemple d'entraînement à la fois.
- Les paramètres sont mis à jour après chaque exemple.
- Avantages :
- Très rapide (beaucoup de mises à jour par époque).
- Peu gourmand en mémoire.
- Peut "échapper" aux minima locaux (grâce au bruit introduit par l'utilisation d'un seul exemple).
- Inconvénients :
- Le gradient est très bruité (grande variance).
- La convergence peut être oscillatoire.
- Nécessite souvent un taux d'apprentissage plus petit que la descente de gradient par batch.
-
Descente de Gradient par Mini-Batch (Mini-Batch Gradient Descent) :
- C'est un compromis entre la descente de gradient par batch et la descente de gradient stochastique.
- Le gradient est calculé en utilisant un petit sous-ensemble (mini-batch) des données d'entraînement (par exemple, 32, 64, 128 exemples).
- Les paramètres sont mis à jour après chaque mini-batch.
- Avantages :
- Plus rapide que la descente de gradient par batch (plus de mises à jour par époque).
- Moins bruité que la descente de gradient stochastique (le gradient est moyenné sur plusieurs exemples).
- Permet de tirer parti de l'optimisation vectorielle (GPU).
- Inconvénients :
- Introduit un nouvel hyperparamètre : la taille du mini-batch (
batch_size).
- Introduit un nouvel hyperparamètre : la taille du mini-batch (
batch_size en Keras
Dans Keras, la taille du mini-batch est spécifiée lors de l'appel à la méthode fit() :
model.fit(x_train, y_train, epochs=10, batch_size=32)
Dans cet exemple, le modèle sera entraîné avec des mini-batchs de 32 exemples.
Comment Choisir la Taille du Mini-Batch (batch_size) ?
Il n'y a pas de règle absolue, mais voici quelques conseils :
- Puissances de 2 : On utilise souvent des tailles de mini-batch qui sont des puissances de 2 (32, 64, 128, 256, 512, ...). Cela peut optimiser l'utilisation de la mémoire et des calculs sur GPU.
- Valeurs courantes : 32, 64 et 128 sont des valeurs très courantes.
- Compromis vitesse/stabilité :
- Petits mini-batchs (par exemple, 1, 8, 16) : Plus de bruit, mais potentiellement plus rapide pour échapper aux minima locaux. Moins bonne utilisation du parallélisme matériel.
- Grands mini-batchs (par exemple, 512, 1024, ...) : Moins de bruit, convergence plus stable, meilleure utilisation du parallélisme matériel, mais mises à jour moins fréquentes et risque de converger vers des minima locaux moins bons.
- Contraintes mémoires : Si le
batch_sizeest trop grand, on peut rencontrer des problèmes de mémoire (OOM, Out of Memory). - Si le batch_size est trop grand, on peut rencontrer des problèmes de mémoire
- Expérimentation : La meilleure façon de choisir la taille du mini-batch est souvent d'essayer différentes valeurs et de comparer les performances (sur un ensemble de validation).
Terminologie
- Itération : Une mise à jour des paramètres (après le passage d'un mini-batch).
- Époque (epoch) : Un passage complet sur toutes les données d'entraînement. Si vous avez 1000 exemples et un
batch_sizede 100, il y aura 10 itérations par époque.
La descente de gradient par mini-batch est la variante la plus couramment utilisée en pratique. Elle combine les avantages de la descente de gradient par batch (stabilité) et de la descente de gradient stochastique (vitesse), tout en permettant une utilisation efficace du matériel (GPU). Le choix de la taille du mini-batch est un hyperparamètre important.
Fonctions de Perte (Loss Functions) dans Keras
La fonction de perte (ou fonction de coût, loss function en anglais) est un élément fondamental de l'entraînement d'un modèle de Machine Learning. Elle quantifie la différence entre les prédictions du modèle et les vraies valeurs (les étiquettes ou cibles). L'objectif de l'entraînement est de minimiser cette fonction de perte.
Keras offre une variété de fonctions de perte pré-définies, adaptées à différents types de problèmes. Le choix de la fonction de perte dépend crucialement de la nature de la tâche que vous essayez de résoudre.
Types de Problèmes et Fonctions de Perte Associées
On peut classer les problèmes de Machine Learning supervisé en quelques grandes catégories, chacune associée à des fonctions de perte typiques :
- Régression : Prédire une ou plusieurs valeurs continues.
- Classification binaire : Prédire une classe parmi deux possibles (0 ou 1).
- Classification multiclasse : Prédire une classe parmi plus de deux possibles.
- Classification multi-label : Chaque instance peut appartenir à plusieurs classes (par exemple, une image peut contenir à la fois un chat et un chien).
Fonctions de Perte Courantes dans Keras
Voici quelques-unes des fonctions de perte les plus courantes dans Keras (module tf.keras.losses), avec leurs caractéristiques et leurs cas d'utilisation :
1. Pour la Régression
-
mean_squared_error(MSE) :- Formule :
- Description : Calcule la moyenne des carrés des différences entre les prédictions () et les vraies valeurs ().
- Avantages :
- Différentiable (nécessaire pour la descente de gradient).
- Pénalise fortement les grandes erreurs (à cause du carré).
- Inconvénients :
- Sensible aux valeurs aberrantes (outliers).
- Quand l'utiliser ? : Problème de régression standard.
-
mean_absolute_error(MAE) :- Formule :
- Description : Calcule la moyenne des valeurs absolues des différences entre les prédictions et les vraies valeurs.
- Avantages :
- Moins sensible aux valeurs aberrantes que la MSE.
- Inconvénients :
- La dérivée n'est pas continue en 0 (mais cela pose rarement problème en pratique avec les optimiseurs modernes).
- Quand l'utiliser ? : Régression, en particulier si vous avez des valeurs aberrantes dans vos données.
-
mean_squared_logarithmic_error(MSLE) :- Formule:
- Quand l'utiliser ? : Utile lorsque la cible a une distribution exponentielle, ou lorsque vous vous souciez davantage des erreurs relatives que des erreurs absolues.
-
Huber Loss :
- Formule : Combine les avantages de la MSE et du MAE.
- Quand l'utiliser ? : Utile lorsque les données peuvent contenir des valeurs aberrantes.
- Formule: Combine les avantages de la MSE et du MAE
- Quand l'utiliser ?: Utile lorsque les données peuvent contenir des valeurs aberrantes.
2. Pour la Classification Binaire
binary_crossentropy:- Formule :
- Description : C'est l'entropie croisée binaire. Elle mesure la différence entre la distribution de probabilité prédite par le modèle (généralement obtenue avec une fonction d'activation sigmoïde) et la vraie distribution (0 ou 1).
- Avantages :
- Fonctionne bien avec la sigmoïde.
- Interprétation probabiliste.
- Inconvénients :
- Nécessite que les prédictions soient des probabilités (entre 0 et 1).
- Quand l'utiliser ? : Classification binaire (deux classes). Utilisez une sigmoïde comme fonction d'activation dans la couche de sortie.
3. Pour la Classification Multiclasse
categorical_crossentropy:- Description : C'est l'entropie croisée catégorielle. Elle généralise l'entropie croisée binaire au cas multiclasse.
- Prérequis : Les étiquettes doivent être en format one-hot encoding (par exemple,
[0, 1, 0]pour la classe 1). - Utilisation typique : Classification multiclasse, avec une fonction d'activation softmax dans la couche de sortie.
sparse_categorical_crossentropy:- Description : Identique à
categorical_crossentropydu point de vue mathématique, mais plus efficace en termes de calcul et de mémoire lorsque les étiquettes sont des entiers (par exemple, 0, 1, 2) plutôt que des vecteurs one-hot. - Prérequis : Les étiquettes doivent être des entiers.
- Utilisation typique : Classification multiclasse, avec une fonction d'activation softmax dans la couche de sortie.
- Description : Identique à
4. Pour la Classification Multi-label
binary_crossentropy: Même si on est dans un cas multi-label, on peut utiliserbinary_crossentropy. Chaque classe est traitée indépendamment comme un problème de classification binaire.
Comment Utiliser les Fonctions de Perte en Keras
Vous spécifiez la fonction de perte lors de la compilation du modèle :
model.compile(optimizer='adam',
loss='mean_squared_error', # Pour la régression
metrics=['mae'])
model.compile(optimizer='sgd',
loss='binary_crossentropy', # Pour la classification binaire
metrics=['accuracy'])
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy', # Pour la classification multiclasse (one-hot)
metrics=['accuracy'])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy', # Pour la classification multiclasse (entiers)
metrics=['accuracy'])
Vous pouvez aussi utiliser des instances de classes de perte :
loss_fn = tf.keras.losses.BinaryCrossentropy()
model.compile(optimizer='adam', loss=loss_fn, metrics=['accuracy'])
Choisir la Bonne Fonction de Perte : Résumé
| Type de Problème | Fonction de Perte | Fonction d'Activation (Couche de Sortie) | Format des Étiquettes |
|---|---|---|---|
| Régression | mean_squared_error (MSE) | Aucune (linéaire) | Nombres réels |
| Régression | mean_absolute_error (MAE) | Aucune (linéaire) | Nombres réels |
| Classification binaire | binary_crossentropy | Sigmoïde | 0 ou 1 |
| Classification multiple label | binary_crossentropy | Sigmoïde | 0 ou 1 |
| Classification multiclasse | categorical_crossentropy | Softmax | One-hot encoding |
| Classification multiclasse | sparse_categorical_crossentropy | Softmax | Entiers |
Le choix de la fonction de perte est essentiel. Il doit être cohérent avec le type de problème que vous essayez de résoudre et avec la représentation de vos étiquettes. Une fonction de perte mal choisie rendra l'entraînement impossible ou produira des résultats non interprétables.
Métriques d'Évaluation (metrics) dans Keras
Les métriques d'évaluation sont utilisées pour juger de la performance d'un modèle de Machine Learning. Contrairement aux fonctions de perte, les métriques ne sont pas utilisées pour optimiser le modèle (c'est-à-dire qu'elles n'influencent pas directement la mise à jour des poids). Elles servent uniquement à mesurer la qualité des prédictions du modèle, de manière interprétable par un humain.
Différence entre Métriques et Fonctions de Perte
- Fonction de perte :
- Utilisée pendant l'entraînement.
- Doit être différentiable (pour la descente de gradient).
- Peut ne pas être facilement interprétable (par exemple, l'entropie croisée).
- Minimisée par l'optimiseur.
- Métrique :
- Utilisée pendant l'entraînement et l'évaluation (sur les données de validation/test).
- N'a pas besoin d'être différentiable.
- Doit être facilement interprétable (par exemple, l'exactitude).
- N'est pas optimisée directement (mais on cherche généralement à l'améliorer).
Il est courant d'utiliser la même fonction à la fois comme perte et comme métrique (par exemple, utiliser la MSE comme perte et comme métrique pour un problème de régression). Cependant, ce n'est pas toujours possible ou souhaitable.
Métriques Courantes dans Keras
Keras offre une variété de métriques pré-définies (dans le module tf.keras.metrics), adaptées à différents types de problèmes.
1. Pour la Régression
mean_squared_error(MSE) : Moyenne des carrés des erreurs.mean_absolute_error(MAE) : Moyenne des valeurs absolues des erreurs.mean_absolute_percentage_error(MAPE) : Moyenne des erreurs relatives en pourcentage.root_mean_squared_error(RMSE): Racine carrée de la moyenne des carrés des erreurs.mean_squared_logarithmic_error(MSLE) :cosine_similarity: Mesure la similarité cosinus entre les prédictions et les vraies valeurs.
2. Pour la Classification Binaire
binary_accuracy: Proportion de prédictions correctes (en comparant la sortie du modèle à un seuil, généralement 0.5).accuracy: Identique àbinary_accuracydans le cas binaire (mais peut aussi être utilisé pour la classification multiclasse).Precision: Proportion de vrais positifs parmi les exemples prédits comme positifs (TP / (TP + FP)). Mesure la capacité du modèle à ne pas classer comme positif un exemple qui est négatif.Recall: Proportion de vrais positifs parmi les exemples positifs réels (TP / (TP + FN)). Mesure la capacité du modèle à trouver tous les exemples positifs.AUC(Area Under the ROC Curve) : Aire sous la courbe ROC (Receiver Operating Characteristic). Mesure la capacité du modèle à distinguer les classes. Une valeur de 1 est parfaite, une valeur de 0.5 est équivalente à un classifieur aléatoire.F1Score: Moyenne harmonique de la précision et du rappel.BinaryCrossentropy: Peut être utilisée comme métrique pour évaluer la perte d'entropie croisée.Hinge: Utilisée pour les SVM (Support Vector Machines).SquaredHinge: Variante de la perte Hinge.
3. Pour la Classification Multiclasse
categorical_accuracy: Proportion de prédictions correctes (quand les étiquettes sont en one-hot encoding).sparse_categorical_accuracy: Proportion de prédictions correctes (quand les étiquettes sont des entiers).top_k_categorical_accuracy: Vérifie si la vraie classe est parmi les k classes les plus probables prédites par le modèle (utile si vous vous intéressez aux k meilleures prédictions, pas seulement à la meilleure).sparse_top_k_categorical_accuracy: Même chose, mais pour des étiquettes entières.CategoricalCrossentropy: Peut être utilisée comme métrique pour évaluer la perte d'entropie croisée catégorielle.SparseCategoricalCrossentropy: Variante pour les étiquettes entières.KLDivergence: Mesure la divergence de Kullback-Leibler entre les distributions prédites et réelles.
Comment Utiliser les Métriques en Keras
Vous spécifiez les métriques lors de la compilation du modèle, sous forme de liste :
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy', 'Precision', 'Recall']) # Plusieurs métriques
Vous pouvez utiliser les noms des métriques (sous forme de chaînes de caractères) ou des instances de classes de métriques :
model.compile(optimizer='adam',
loss='mse',
metrics=[tf.keras.metrics.MeanAbsoluteError(),
tf.keras.metrics.RootMeanSquaredError()])
Métriques Personnalisées
Si les métriques pré-définies ne suffisent pas, vous pouvez définir vos propres métriques personnalisées. Cela dépasse le cadre de cette introduction, mais sachez que c'est possible.
Interprétation des Métriques
- Exactitude (accuracy) : C'est la métrique la plus intuitive pour la classification. Elle représente le pourcentage de prédictions correctes. Cependant, elle peut être trompeuse si les classes sont déséquilibrées (par exemple, si 90% des exemples appartiennent à la classe A et 10% à la classe B, un modèle qui prédit toujours A aura une exactitude de 90%, même s'il ne fait rien d'intelligent).
- Précision et rappel : Utiles pour les problèmes où les faux positifs et les faux négatifs ont des coûts différents.
- AUC : Bonne métrique pour la classification binaire, car elle prend en compte le compromis entre les vrais positifs et les faux positifs à différents seuils.
- MSE, MAE, RMSE : Pour la régression, des valeurs plus faibles sont meilleures. L'interprétation dépend de l'échelle de la variable cible.
Le choix des métriques dépend du problème spécifique que vous essayez de résoudre et de ce qui est important pour vous (par exemple, minimiser les faux positifs, maximiser le rappel, etc.). Il est souvent utile d'utiliser plusieurs métriques pour avoir une vue complète de la performance du modèle.