Skip to main content

Introduction à Keras

Jusqu'à présent, nous avons utilisé TensorFlow "de base", en manipulant directement les tenseurs, les variables et les opérations. Bien que cela soit instructif pour comprendre les concepts fondamentaux, cela peut devenir fastidieux pour construire des modèles plus complexes.

C'est là qu'intervient Keras.

Qu'est-ce que Keras ?

Keras est une API de haut niveau pour construire et entraîner des modèles de Deep Learning. Elle a été conçue pour être :

  • Simple : Facile à apprendre et à utiliser, avec une API intuitive et cohérente.
  • Modulaire : Les modèles sont construits en assemblant des blocs de construction (couches, fonctions d'activation, optimiseurs, etc.).
  • Extensible : Vous pouvez facilement définir vos propres blocs de construction si nécessaire.
  • Flexible: Keras peut fonctionner avec différents backends.

Keras est aujourd'hui l'API de haut niveau officielle de TensorFlow. Elle est intégrée à TensorFlow (dans le module tf.keras), ce qui signifie que vous pouvez utiliser Keras tout en ayant accès aux fonctionnalités de bas niveau de TensorFlow si besoin.

Pourquoi Utiliser Keras ?

  • Productivité : Vous pouvez construire et entraîner des modèles beaucoup plus rapidement qu'avec TensorFlow de base.
  • Facilité d'apprentissage : L'API Keras est plus intuitive et plus facile à maîtriser que l'API de bas niveau de TensorFlow.
  • Bonnes pratiques : Keras encourage les bonnes pratiques de développement de modèles de Deep Learning (modularité, réutilisation de code, etc.).
  • Large communauté : Keras est très populaire, ce qui signifie que vous trouverez facilement de l'aide, des tutoriels et des exemples en ligne.

Ce que Vous Allez Apprendre

Dans cette introduction à Keras, nous allons :

  • Découvrir l'API séquentielle de Keras pour construire des modèles simples.
  • Comprendre les concepts de couches (layers), de fonctions d'activation (activations), d'optimiseurs (optimizers) et de fonctions de perte (losses) dans Keras.
  • Compiler et entraîner un modèle Keras.
  • Faire le lien entre Keras et ce que nous avons vu avec TensorFlow de base (le Perceptron, la régression linéaire).
info

Keras est l'outil que nous utiliserons principalement dans la suite de ce cours. Il vous permettra de construire rapidement des modèles de Deep Learning performants, sans vous perdre dans les détails de bas niveau de TensorFlow.

L'API Séquentielle : Création d'un Modèle Simple

Keras offre plusieurs façons de construire des modèles, mais la plus simple est l'API séquentielle (tf.keras.Sequential).

Qu'est-ce que l'API Séquentielle ?

L'API séquentielle permet de construire des modèles en empilant des couches (layers) les unes après les autres, comme des briques LEGO. Chaque couche reçoit les sorties de la couche précédente et produit des sorties pour la couche suivante.

Caractéristiques :

  • Simplicité : C'est l'approche la plus facile pour construire des modèles simples, où les données circulent de manière linéaire, d'une couche à l'autre.
  • Linéarité : Les couches sont connectées séquentiellement. Il n'y a pas de branches, de sauts ou de connexions complexes.
  • Une entrée, une sortie : Un modèle séquentiel a une seule entrée et une seule sortie.

Création d'un Modèle Séquentiel

Il existe deux manières principales de créer un modèle séquentiel :

  1. En passant une liste de couches au constructeur Sequential :

    import tensorflow as tf

    model = tf.keras.Sequential([
    tf.keras.layers.Dense(units=64, activation='relu', input_shape=(784,)),
    tf.keras.layers.Dense(units=10, activation='softmax')
    ])
  2. En ajoutant les couches une par une avec la méthode add() :

    import tensorflow as tf

    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Dense(units=64, activation='relu', input_shape=(784,)))
    model.add(tf.keras.layers.Dense(units=10, activation='softmax'))

Ces deux codes créent exactement le même modèle.

Régression Linéaire Simple avec Keras

Dans ce notebook, nous allons implémenter une régression linéaire simple en utilisant l'API séquentielle de Keras. Nous allons reprendre le problème que nous avons déjà résolu avec TensorFlow "de base", mais vous verrez que Keras rend le code beaucoup plus concis et plus facile à lire.

Problème : Trouver la relation linéaire y=wx+by = w \cdot x + b entre une variable d'entrée xx et une variable de sortie yy.

1. Importation des Librairies

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

2. Définition des Données

# Données d'entrée et de sortie (synthétiques)
x_train = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], dtype=np.float32)
y_train = np.array([2.0, 3.0, 4.0, 5.0, 6.0, 7.0], dtype=np.float32) # Relation linéaire simple : y = x + 1

Nous créons des données synthétiques où la relation entre x et y est parfaitement linéaire (y = x + 1). Cela nous permettra de vérifier facilement si notre modèle apprend correctement.

3. Création du Modèle

# Création d'un modèle séquentiel
model = tf.keras.Sequential([
tf.keras.layers.Dense(units=1, input_shape=[1])
])
  • tf.keras.Sequential(...) : Crée un modèle séquentiel, qui est une pile linéaire de couches.
  • tf.keras.layers.Dense(units=1, input_shape=[1]) : Ajoute une couche dense (entièrement connectée) au modèle.
    • units=1 : Il y a un seul neurone dans cette couche (ce qui correspond à notre régression linéaire simple).
    • input_shape=[1] : L'entrée de cette couche est un scalaire (une seule valeur, la variable xx ).

Cette seule ligne de code définit l'architecture de notre modèle. La couche Dense contient implicitement les variables pour le poids ( ww ) et le biais ( bb ). Keras les initialisera automatiquement.

4. Compilation du Modèle

# Compilation du modèle
model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=0.01),
loss='mean_squared_error',
metrics=['mean_absolute_error'])

Avant d'entraîner le modèle, nous devons le compiler. Cela configure le processus d'apprentissage :

  • optimizer=tf.keras.optimizers.SGD(learning_rate=0.01) : Nous utilisons la descente de gradient stochastique (SGD) comme optimiseur, avec un taux d'apprentissage de 0.01.
  • loss='mean_squared_error' : Nous utilisons l'erreur quadratique moyenne (MSE) comme fonction de perte.
  • metrics=['mean_absolute_error'] : Nous ajoutons l'erreur absolue moyenne (MAE) comme métrique pour évaluer la performance du modèle.

5. Entraînement du Modèle

# Entraînement du modèle
history = model.fit(x_train, y_train, epochs=500, verbose=0) # verbose=0 pour ne pas afficher les détails de l'entraînement

print("Entraînement terminé.")
  • model.fit(x_train, y_train, epochs=500, verbose=0) : Entraîne le modèle.
    • x_train : Données d'entrée.
    • y_train : Données de sortie (labels).
    • epochs=500 : Nombre d'itérations (époques) d'entraînement. Une époque correspond à un passage complet sur toutes les données d'entraînement.
    • verbose=0 : Ici, on entraine le modèle sans afficher les détails de l'avancement de l'entrainement.
  • history : Cette variable (un objet History) contient des informations sur l'entraînement (la perte et les métriques à chaque époque).

6. Visualisation de la Courbe de Perte

# Visualisation de la courbe de perte
plt.plot(history.history['loss'])
plt.xlabel('Epoch')
plt.ylabel('Loss (MSE)')
plt.title('Courbe de Perte')
plt.show()

plt.plot(history.history['mean_absolute_error'])
plt.xlabel('Epoch')
plt.ylabel('MAE')
plt.title('Courbe MAE')
plt.show()

CourbePerte

courbeMae

Nous traçons la courbe de perte (MSE) et la courbe de l'erreur absolue moyenne (MAE) en fonction du nombre d'époques. Cela nous permet de visualiser comment le modèle apprend et de vérifier qu'il converge.

7. Prédiction avec le Modèle Entraîné

# --- Prédiction et Droite de Régression ---
# Calcul des prédictions pour TOUS les x d'entraînement

y_pred_train = model.predict(x_train)
  • model.predict(x_train) : Utilise le modèle entraîné pour faire des prédictions sur données d'entrainement (x_train) afin de voir la droite de régression.

8. Visualisation des Prédictions

# Visualisation des prédictions
plt.plot(x_train, y_train, 'ro', label='Données originales')
plt.plot(x_train, y_pred_train, color='blue', label='Droite de régression')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Régression Linéaire avec Keras')
plt.legend()
plt.show()

visionIntro

Nous visualisons les données d'entraînement et les prédictions du modèle sur un même graphique. Si le modèle a bien appris, la droite de prédiction (régression) devrait être proche des points d'entraînement.

9. Affichage des paramètres du modèle

# Affichage des paramètres du modèle
print(f"Poids (w) : {model.layers[0].get_weights()[0][0][0]:.2f}")
print(f"Biais (b) : {model.layers[0].get_weights()[1][0]:.2f}")
Poids (w) : 1.04
Biais (b) : 0.83

Nous pouvons accéder aux poids (w) et au biais (b) appris par le modèle. Puisque notre modèle a une seule couche dense, nous pouvons y accéder avec model.layers[0]

Ce code, beaucoup plus court que notre implémentation TensorFlow de base.

Résumé

  • API séquentielle : Pile linéaire de couches.
  • tf.keras.Sequential() : Crée un modèle séquentiel.
  • tf.keras.layers.Dense() : Couche entièrement connectée (neurones).
  • model.compile() : Configure le processus d'apprentissage.
    • optimizer : Algorithme de mise à jour des paramètres (ex : SGD).
    • loss : Fonction de coût (ex : MSE).
    • metrics : Fonctions d'évaluation supplémentaires (ex : MAE).
info

Keras rend la création et la configuration de modèles beaucoup plus simples et plus rapides. Vous pouvez vous concentrer sur l'architecture du modèle et les hyperparamètres, plutôt que sur les détails d'implémentation de bas niveau.

Compilation (Optimiseur, Perte, Métriques)

Méthode compile()

La méthode compile() prend trois arguments principaux :

  • optimizer : L'algorithme d'optimisation qui sera utilisé pour ajuster les paramètres du modèle (poids et biais).
  • loss : La fonction de perte (ou fonction de coût) qui sera utilisée pour mesurer l'erreur du modèle.
  • metrics : Une liste de métriques qui seront utilisées pour évaluer la performance du modèle pendant l'entraînement et les tests.
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])

Optimiseurs (optimizer)

L'optimiseur est l'algorithme qui met à jour les paramètres du modèle (poids et biais) en fonction des gradients de la fonction de perte. Keras offre plusieurs optimiseurs :

  • SGD (Stochastic Gradient Descent) : La descente de gradient stochastique, l'algorithme de base que nous avons déjà vu.
  • Adam (Adaptive Moment Estimation) : Une variante plus sophistiquée de la descente de gradient, qui adapte automatiquement le taux d'apprentissage pour chaque paramètre. C'est souvent un bon choix par défaut.
  • RMSprop : Une autre variante de la descente de gradient avec adaptation du taux d'apprentissage.
  • Adagrad, Adadelta, Adamax, Nadam : D'autres variantes.

Vous pouvez spécifier l'optimiseur par son nom (sous forme de chaîne de caractères) ou en créant une instance de la classe correspondante :

# Par nom
model.compile(optimizer='adam', ...)

# Par instance
optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
model.compile(optimizer=optimizer, ...)

Fonctions de Perte (loss)

La fonction de perte mesure l'erreur entre les prédictions du modèle et les vraies valeurs. Keras offre de nombreuses fonctions de perte, adaptées à différents types de problèmes :

  • Régression :
    • mean_squared_error (MSE) : Erreur quadratique moyenne.
    • mean_absolute_error (MAE) : Erreur absolue moyenne.
    • mean_absolute_percentage_error (MAPE) : Erreur absolue moyenne en pourcentage.
    • mean_squared_logarithmic_error (MSLE) : Erreur logarithmique quadratique moyenne.
  • Classification binaire (deux classes) :
    • binary_crossentropy : Entropie croisée binaire.
  • Classification multi-classe (plus de deux classes) :
    • categorical_crossentropy : Entropie croisée catégorielle (quand les étiquettes sont encodées en one-hot).
    • sparse_categorical_crossentropy : Entropie croisée catégorielle (quand les étiquettes sont des entiers).
    • KLDivergence: La divergence de Kullback-Leibler

Vous pouvez spécifier la fonction de perte par son nom (sous forme de chaîne de caractères) ou en utilisant une fonction :

# Par nom
model.compile(loss='categorical_crossentropy', ...)

# Par fonction
model.compile(loss=tf.keras.losses.categorical_crossentropy, ...)

Métriques (metrics)

Les métriques sont utilisées pour évaluer la performance du modèle. Elles sont similaires aux fonctions de perte, mais elles ne sont pas utilisées pour l'entraînement (elles n'influencent pas les mises à jour des paramètres).

Keras offre de nombreuses métriques :

  • accuracy : Taux de bonnes prédictions (pour la classification).
  • binary_accuracy : Taux de bonnes prédictions pour la classification binaire.
  • categorical_accuracy : Taux de bonnes prédictions pour la classification multi-classe.
  • precision : Proportion de vrais positifs parmi les exemples prédits comme positifs.
  • recall : Proportion de vrais positifs parmi les exemples positifs réels.
  • AUC (Area Under the ROC Curve) : Aire sous la courbe ROC (pour la classification binaire).
  • mse, mae : Vous pouvez aussi utiliser des fonctions de perte comme métriques.

Vous spécifiez les métriques sous forme de liste :

model.compile(..., metrics=['accuracy', 'mse'])

Comprendre la Frontière de Décision de la Régression Logistique

Avant de passer aux exercices, il est important de bien comprendre comment visualiser la frontière de décision d'un modèle de régression logistique, en particulier lorsque nous avons deux variables d'entrée (ce qui permet une représentation graphique en 2D).

Régression Logistique et Probabilité

Notre modèle de régression logistique calcule une probabilité, pp, que l'entrée appartienne à la classe 1. Cette probabilité est obtenue en appliquant la fonction sigmoïde à une combinaison linéaire des entrées et des paramètres :

p=σ(w0x0+w1x1+b)p = \sigma(w_0 \cdot x_0 + w_1 \cdot x_1 + b)

où :

  • pp est la probabilité d'appartenir à la classe 1.
  • σ\sigma est la fonction sigmoïde : σ(z)=11+ez\sigma(z) = \frac{1}{1 + e^{-z}}
  • x0x_0 et x1x_1 sont les deux caractéristiques d'entrée.
  • w0w_0 et w1w_1 sont les poids associés à ces caractéristiques.
  • bb est le biais.

Seuil de Décision et Frontière

Pour faire une prédiction, on compare cette probabilité pp à un seuil, généralement 0.5 :

  • Si p0.5p \ge 0.5, on prédit la classe 1.
  • Si p<0.5p < 0.5, on prédit la classe 0.

La frontière de décision est l'ensemble des points où la probabilité prédite est exactement 0.5 : p=0.5p = 0.5. La fonction sigmoïde vaut 0.5 quand son argument est égal à 0 (σ(z)=0.5\sigma(z) = 0.5 quand z=0z = 0). Donc, la frontière de décision est définie par l'équation :

w0x0+w1x1+b=0w_0 \cdot x_0 + w_1 \cdot x_1 + b = 0

Équation de la Droite

L'équation w0x0+w1x1+b=0w_0 \cdot x_0 + w_1 \cdot x_1 + b = 0 est l'équation d'une droite dans le plan (x0,x1)(x_0, x_1). Pour la tracer, on l'exprime généralement sous la forme x1=mx0+px_1 = m \cdot x_0 + p (ou, avec des notations plus courantes, y=mx+py = mx + p, où yy correspond à x1x_1 et xx correspond à x0x_0).

En réarrangeant l'équation, on obtient :

w1x1=w0x0bw_1 \cdot x_1 = -w_0 \cdot x_0 - b

x1=w0w1x0bw1x_1 = \frac{-w_0}{w_1} \cdot x_0 - \frac{b}{w_1}

C'est l'équation d'une droite de pente w0w1\frac{-w_0}{w_1} et d'ordonnée à l'origine bw1-\frac{b}{w_1}.

info

Comprendre cette dérivation vous aidera à interpréter les visualisations de la frontière de décision et à comprendre comment la régression logistique sépare les classes.

Exercices : Portes Logiques avec Keras

Dans ces exercices, vous allez implémenter les portes logiques ET, OU et XOR en utilisant l'API séquentielle de Keras.

info

Pour chaque porte logique :

  1. Définissez les données d'entrée (X) et de sortie (Y).
  2. Créez un modèle Keras séquentiel avec une seule couche dense (Dense).
    • Utilisez la fonction d'activation 'sigmoid' pour la couche de sortie.
  3. Compilez le modèle.
    • Utilisez l'optimiseur SGD avec un taux d'apprentissage de 0.1 à 0.5.
    • Utilisez la fonction de perte binary_crossentropy.
    • Ajoutez l'exactitude ('accuracy') comme métrique.
  4. Entraînez le modèle pendant un nombre suffisant d'époques (par exemple, 500 ou 1000).
  5. Affichez la courbe de perte et la courbe d'exactitude et analysez et interprétez les résultats en fonction du nombre d'époques, du taux d'appentissage, etc.
  6. Testez le modèle sur toutes les combinaisons d'entrées possibles (0 et 1) et affichez les prédictions.
  7. Analysez les résultats. Le modèle a-t-il réussi à apprendre la porte logique ? Si oui, comment le voyez-vous ? Si non, pourquoi ?

Exercice 1 : Porte Logique ET

Implémentez la porte logique ET avec Keras.

x1x2y (ET)
000
010
100
111
Solution Exercice 1 (Porte ET)
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

# 1. Données
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]], dtype=np.float32)
Y = np.array([0, 0, 0, 1], dtype=np.float32)

# 2. Modèle
model = tf.keras.Sequential([
tf.keras.layers.Dense(units=1, input_shape=(2,), activation='sigmoid')
])

# 3. Compilation
model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=0.1),
loss='binary_crossentropy',
metrics=['accuracy'])

# 4. Entraînement
history = model.fit(X, Y, epochs=1000, verbose=0)

# 5. Courbes
plt.plot(history.history['loss'])
plt.title('Courbe de perte (ET)')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.show()

plt.plot(history.history['accuracy'])
plt.title('Courbe d\'exactitude (ET)')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.show()

# 6. Tests
predictions = model.predict(X)
print(f"Prédictions (ET) :\n{predictions}")

# 7. Visualisation des prédictions
plt.scatter(X[:, 0], X[:, 1], c=Y, cmap='viridis', marker='o', label='Données originales')
w0 = model.get_weights()[0][0]
w1 = model.get_weights()[0][1]
biais = model.get_weights()[1]
x = np.linspace(0, 1.1, 2)
y = (-w0 / w1) * x + (-biais / w1)
plt.plot(x, y, label='Droite de régression', c='orange')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Porte ET')
plt.legend()
plt.show()

# Interprétation:
# Le modèle doit afficher des valeurs proches de 0 pour les trois premières entrées, et une valeur proche de 1 pour la dernière entrée.

Exercice 2 : Porte Logique OU

Implémentez la porte logique OU avec Keras.

x1x2y (OU)
000
011
101
111
Solution Exercice 2 (Porte OU)
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

# 1. Données
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]], dtype=np.float32)
Y = np.array([0, 1, 1, 1], dtype=np.float32)

# 2. Modèle
model = tf.keras.Sequential([
tf.keras.layers.Dense(units=1, input_shape=(2,), activation='sigmoid')
])

# 3. Compilation
model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=0.1),
loss='binary_crossentropy',
metrics=['accuracy'])

# 4. Entraînement
history = model.fit(X, Y, epochs=1000, verbose=0)

# 5. Courbes
plt.plot(history.history['loss'])
plt.title('Courbe de perte (OU)')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.show()

plt.plot(history.history['accuracy'])
plt.title('Courbe d\'exactitude (OU)')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.show()

# 6. Tests
predictions = model.predict(X)
print(f"Prédictions (OU) :\n{predictions}")

# 7. Visualisation des prédictions
plt.scatter(X[:, 0], X[:, 1], c=Y, cmap='viridis', marker='o', label='Données originales')
w0 = model.get_weights()[0][0]
w1 = model.get_weights()[0][1]
biais = model.get_weights()[1]
x = np.linspace(0, 1.1, 2)
y = (-w0 / w1) * x + (-biais / w1)
plt.plot(x, y, label='Droite de régression', c='orange')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Porte OR')
plt.legend()
plt.show()

# Interprétation:
# Le modèle doit afficher des valeurs proches de 0 pour la première entrée, et des valeurs proches de 1 pour les trois autres entrées.

Exercice 3 : Porte Logique XOR

Implémentez la porte logique XOR avec Keras.

x1x2y (XOR)
000
011
101
110
Solution Exercice 3 (Porte XOR)
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

# 1. Données
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]], dtype=np.float32)
Y = np.array([0, 1, 1, 0], dtype=np.float32)

# 2. Modèle
model = tf.keras.Sequential([
tf.keras.layers.Dense(units=1, input_shape=(2,), activation='sigmoid')
])

# 3. Compilation
model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=0.1),
loss='binary_crossentropy',
metrics=['accuracy'])

# 4. Entraînement
history = model.fit(X, Y, epochs=1000, verbose=0)

# 5. Courbes
plt.plot(history.history['loss'])
plt.title('Courbe de perte (XOR)')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.show()

plt.plot(history.history['accuracy'])
plt.title('Courbe d\'exactitude (XOR)')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.show()

# 6. Tests
predictions = model.predict(X)
print(f"Prédictions (XOR) :\n{predictions}")

# 7. Visualisation des prédictions
plt.scatter(X[:, 0], X[:, 1], c=Y, cmap='viridis', marker='o', label='Données originales')
w0 = model.get_weights()[0][0]
w1 = model.get_weights()[0][1]
biais = model.get_weights()[1]
x = np.linspace(0, 1.1, 2)
y = (-w0 / w1) * x + (-biais / w1)
plt.plot(x, y, label='Droite de régression', c='orange')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Porte XOR')
plt.legend()
plt.show()

# Interprétation:
# Le modèle aura du mal à apprendre la porte XOR. Les prédictions ne correspondront pas aux valeurs attendues.
# L'exactitude ne dépassera pas 0.5 (50%), ce qui équivaut à des prédictions aléatoires.
# Cela démontre la limitation des modèles linéaires (comme une seule couche Dense) : ils ne peuvent pas résoudre des problèmes non linéairement séparables.
danger

Observez attentivement les résultats de la porte XOR. Que remarquez-vous ?
Pourquoi le modèle ne parvient-il pas à apprendre correctement la porte XOR, alors qu'il réussit pour ET et OU ?

Exercice : Prédiction de Succès d'une Campagne Marketing

Imaginons que vous travaillez dans une entreprise qui lance une nouvelle campagne marketing. Vous souhaitez prédire si une personne contactée sera intéressée par l'offre (classe 1) ou non intéressée (classe 0) en fonction de deux caractéristiques :

  • Caractéristique 1 (X[:, 0]) : L'âge de la personne (normalisé).
  • Caractéristique 2 (X[:, 1]) : Le revenu annuel de la personne (normalisé).

Vous allez créer un modèle de régression logistique avec Keras pour faire cette prédiction.

Consignes

  1. Génération des données :

    • Créez un tableau NumPy X de forme (100, 2) contenant des nombres aléatoires tirés d'une distribution normale (par exemple, np.random.randn(100, 2)). Ces données représentent l'âge et le revenu normalisés de 100 personnes.
    • Créez un tableau Y de forme (100,) contenant des 0 et des 1 (0 pour non intéressé, 1 pour intéressé). Pour cela :
      • Définissez une "frontière de décision" linéaire, par exemple y_temp = -0.5 * X[:, 0] + X[:, 1]. (Vous pouvez modifier les coefficients pour changer la séparation entre les classes).
      • Assignez la valeur 1 à Y si y_temp est supérieur à 0.2, et 0 sinon. (Vous pouvez modifier le seuil de 0.2 pour ajuster la proportion de 0 et de 1).
  2. Création du modèle :

    • Créez un modèle Keras séquentiel avec une seule couche Dense.
    • Utilisez l'activation sigmoid pour la couche de sortie.
    • L'entrée doit avoir la forme (2,).
  3. Compilation du modèle :

    • Utilisez l'optimiseur SGD avec un taux d'apprentissage de 0.1.
    • Utilisez la fonction de perte binary_crossentropy.
    • Ajoutez l'exactitude ('accuracy') comme métrique.
  4. Entraînement du modèle :

    • Entraînez le modèle sur les données X et Y pendant 200 époques.
  5. Visualisation :

    • Tracez la courbe de perte.
    • Tracez la courbe d'exactitude.
    • Affichez les points de données (personnes), colorés en fonction de leur classe réelle (intéressée ou non).
    • Affichez la frontière de décision apprise par le modèle.
  6. Prédiction et Visualisation d'un Nouveau Point :

    • Choisissez manuellement les caractéristiques d'une nouvelle personne (par exemple, nouvelle_personne = np.array([[0.8, -0.2]]) - une personne relativement âgée et avec un revenu faible).
    • Utilisez model.predict() pour obtenir la prédiction du modèle pour cette personne.
    • Interprétez le résultat.
    • Affichez ce nouveau point sur le graphique, en rouge, avec les autres points et la frontière de décision.
  7. Calcul de l'Exactitude (Accuracy) :

    • Utilisez la méthode model.evaluate() sur les données d'entraînement (X, Y) pour obtenir la perte et l'exactitude du modèle.
    • Affichez l'exactitude (accuracy) du modèle. L'exactitude est la proportion de prédictions correctes.
Solution
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

# 1. Génération des données
X = np.random.randn(100, 2)
y_temp = -0.5 * X[:, 0] + X[:, 1] # Frontière de décision linéaire
Y = (y_temp > 0.2).astype(np.float32)

# 2. Création du modèle
model = tf.keras.Sequential([
tf.keras.layers.Dense(units=1, input_shape=(2,), activation='sigmoid')
])

# 3. Compilation
model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=0.1),
loss='binary_crossentropy',
metrics=['accuracy'])

# 4. Entraînement
history = model.fit(X, Y, epochs=200, verbose=0)

# 5. Visualisation
# Courbes de perte et d'exactitude
plt.plot(history.history['loss'])
plt.title('Courbe de perte')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.show()

plt.plot(history.history['accuracy'])
plt.title('Courbe d\'exactitude')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.show()

# Affichage des données et de la frontière de décision
plt.scatter(X[:, 0], X[:, 1], c=Y, cmap='viridis', marker='o', label='Données originales')
w0 = model.get_weights()[0][0]
w1 = model.get_weights()[0][1]
biais = model.get_weights()[1]
x_boundary = np.linspace(-3, 3, 100)
y_boundary = (-w0 / w1) * x_boundary + (-biais / w1)
plt.plot(x_boundary, y_boundary, label='Frontière de décision', c='green')

# 6. Prédiction et visualisation d'un nouveau point
nouvelle_personne = np.array([[0.8, -0.2]])
prediction = model.predict(nouvelle_personne)
print(f"Prédiction pour la nouvelle personne : {prediction}")

plt.scatter(nouvelle_personne[:, 0], nouvelle_personne[:, 1], c='red', marker='x', s=100, label='Nouvelle personne') # s = size

if prediction > 0.5:
print("Le modèle prédit que cette personne est INTÉRESSÉE (classe 1).")
else:
print("Le modèle prédit que cette personne est NON INTÉRESSÉE (classe 0).")


plt.xlabel('Âge normalisé')
plt.ylabel('Revenu normalisé')
plt.title('Prédiction de Succès d\'une Campagne Marketing')
plt.legend()
plt.show()

# 7. Calcul de l'exactitude (accuracy)
loss, accuracy = model.evaluate(X, Y, verbose=0)
print(f"Exactitude (accuracy) sur les données d'entraînement : {accuracy * 100:.2f}%")
info

La frontière de décision sépare l'espace des caractéristiques en deux régions : la région où le modèle prédit "intéressé" et la région où il prédit "non intéressé". La position du nouveau point par rapport à cette frontière détermine la prédiction du modèle.