Apprentissage semi-supervisé (Vision par ordinateur)
ChatGPT a dit :
Fonctions :
-
Vision par ordinateur (exemple)
La vision par ordinateur est un domaine de l'intelligence artificielle qui permet aux machines de comprendre et d’interpréter des images ou des vidéos, comme reconnaître des objets, détecter des visages, ou analyser des scènes, afin d'automatiser des tâches visuelles complexes. Par exemple, un système de vision par ordinateur peut analyser des photos de routes pour détecter les panneaux de signalisation et aider à la conduite autonome.
Exemple de code :
import tensorflow as tf import numpy as np # Charger MNIST (x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data() # Normalisation + reshape (batch, 28,28,1) x_train = x_train.astype("float32") / 255. x_test = x_test.astype("float32") / 255. x_train = np.expand_dims(x_train, -1) x_test = np.expand_dims(x_test, -1) num_classes = 10 y_train_cat = tf.keras.utils.to_categorical(y_train, num_classes) y_test_cat = tf.keras.utils.to_categorical(y_test, num_classes) # Séparer 10% étiquetés, 90% non étiquetés num_labeled = int(0.1 * len(x_train)) x_labeled, y_labeled = x_train[:num_labeled], y_train_cat[:num_labeled] x_unlabeled = x_train[num_labeled:] # Modèle simple CNN def create_model(): model = tf.keras.Sequential([ tf.keras.layers.Conv2D(32, 3, padding="same", activation="relu", input_shape=(28,28,1)), tf.keras.layers.MaxPooling2D(), tf.keras.layers.Conv2D(64, 3, padding="same", activation="relu"), tf.keras.layers.MaxPooling2D(), tf.keras.layers.Flatten(), tf.keras.layers.Dense(128, activation="relu"), tf.keras.layers.Dense(num_classes) ]) return model model = create_model() optimizer = tf.keras.optimizers.Adam() loss_fn = tf.keras.losses.CategoricalCrossentropy(from_logits=True) batch_size = 64 consistency_weight = 1.0 epochs = 10 # Fonction d'augmentation simple : rotation + bruit def augment(images): images = tf.image.rot90(images, k=1) noise = tf.random.normal(shape=tf.shape(images), mean=0.0, stddev=0.1) return images + noise # Dataset pour étiquetés labeled_dataset = tf.data.Dataset.from_tensor_slices((x_labeled, y_labeled)) labeled_dataset = labeled_dataset.shuffle(1000).batch(batch_size).repeat() # Dataset pour non-étiquetés unlabeled_dataset = tf.data.Dataset.from_tensor_slices(x_unlabeled) unlabeled_dataset = unlabeled_dataset.shuffle(10000).batch(batch_size).repeat() # Dataset test test_dataset = tf.data.Dataset.from_tensor_slices((x_test, y_test_cat)).batch(batch_size) # Iterator labeled_iter = iter(labeled_dataset) unlabeled_iter = iter(unlabeled_dataset) # Training loop for epoch in range(epochs): print(f"Epoch {epoch+1}/{epochs}") total_loss = 0.0 steps_per_epoch = num_labeled // batch_size for step in range(steps_per_epoch): x_lab, y_lab = next(labeled_iter) x_unlab = next(unlabeled_iter) with tf.GradientTape() as tape: # Prédiction sur données étiquetées logits_lab = model(x_lab, training=True) loss_sup = loss_fn(y_lab, logits_lab) # Prédiction sur données non étiquetées logits_unlab = model(x_unlab, training=True) logits_unlab_aug = model(augment(x_unlab), training=True) prob = tf.nn.softmax(logits_unlab, axis=-1) prob_aug = tf.nn.softmax(logits_unlab_aug, axis=-1) loss_consistency = tf.reduce_mean(tf.square(prob - prob_aug)) loss = loss_sup + consistency_weight * loss_consistency grads = tape.gradient(loss, model.trainable_variables) optimizer.apply_gradients(zip(grads, model.trainable_variables)) total_loss += loss.numpy() print(f"Loss: {total_loss/steps_per_epoch:.4f}") # Évaluation test_acc_metric = tf.keras.metrics.CategoricalAccuracy() for x_batch, y_batch in test_dataset: logits = model(x_batch, training=False) test_acc_metric.update_state(y_batch, logits) print(f"Test accuracy: {test_acc_metric.result().numpy():.4f}")
Explication du code :
import tensorflow as tf
importe la bibliothèque TensorFlow, un framework majeur pour le machine learning et le deep learning.import numpy as np
importe la bibliothèque NumPy, utile pour la manipulation efficace des tableaux et des opérations numériques.1. Chargement et préparation des données MNIST
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
charge le jeu de données MNIST, constitué d’images de chiffres manuscrits pour l’entraînement et le test.x_train = x_train.astype("float32") / 255.
etx_test = x_test.astype("float32") / 255.
normalisent les pixels des images pour que leurs valeurs soient entre 0 et 1.x_train = np.expand_dims(x_train, -1)
etx_test = np.expand_dims(x_test, -1)
ajoutent une dimension au tableau pour indiquer que les images sont en niveau de gris (canal unique).num_classes = 10
définit le nombre de classes, ici 10 pour les chiffres de 0 à 9.y_train_cat = tf.keras.utils.to_categorical(y_train, num_classes)
ety_test_cat = tf.keras.utils.to_categorical(y_test, num_classes)
convertissent les étiquettes en vecteurs one-hot, adaptés pour la classification multi-classes.2. Séparation entre données étiquetées et non étiquetées
num_labeled = int(0.1 * len(x_train))
calcule 10 % du jeu d’entraînement qui sera considéré comme étiqueté.x_labeled, y_labeled = x_train[:num_labeled], y_train_cat[:num_labeled]
extrait ces données étiquetées.x_unlabeled = x_train[num_labeled:]
récupère les 90 % restants sans étiquette (non utilisés directement pour la perte supervisée).3. Définition du modèle CNN simple
La fonctioncreate_model()
crée un réseau de neurones convolutifs (CNN) simple avec : - Deux couches convolutives avec ReLU et max-pooling, - Une couche flatten pour aplatir, - Une couche dense de 128 neurones avec ReLU, - Une couche finale dense avec 10 sorties (logits) correspondant aux classes.4. Configuration de l’entraînement
optimizer = tf.keras.optimizers.Adam()
utilise l’optimiseur Adam pour la mise à jour des poids.loss_fn = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
définit la fonction de perte de type entropie croisée adaptée aux logits.batch_size = 64
,consistency_weight = 1.0
(poids de la perte de consistance),epochs = 10
définissent les paramètres d’entraînement.5. Augmentation des images
La fonctionaugment(images)
effectue une rotation à 90° des images et ajoute un bruit aléatoire normal, pour créer une version modifiée d’une image afin de renforcer la robustesse du modèle.6. Préparation des datasets TensorFlow
-labeled_dataset
contient les données étiquetées, mélangées et découpées en batchs, répétées à l’infini. -unlabeled_dataset
contient les données non étiquetées, également mélangées et batchées. -test_dataset
contient les données de test batchées.7. Boucle d’entraînement semi-supervisé
Pour chaque époque : - Pour chaque batch de données étiquetées et non étiquetées, on calcule : -logits_lab
, prédictions sur données étiquetées → perte superviséeloss_sup
avec la fonction d’entropie croisée. -logits_unlab
etlogits_unlab_aug
, prédictions sur données non étiquetées normales et augmentées. - Les probabilités issues de ces logits sont calculées via softmax. - Une perte de consistanceloss_consistency
est calculée comme la moyenne des carrés des différences entre les deux distributions, pour encourager la stabilité des prédictions malgré l’augmentation. - La perte totale est la somme de la perte supervisée et de la perte de consistance pondérée parconsistency_weight
. - Le gradient est calculé et appliqué pour mettre à jour les poids du modèle. - La perte moyenne par époque est affichée.8. Évaluation finale
On calcule la précision sur l’ensemble de test en comparant les prédictions aux vraies étiquettes.print(f"Test accuracy: {test_acc_metric.result().numpy():.4f}")
affiche la précision finale. Ce code met en œuvre une méthode d’apprentissage semi-supervisé combinant supervision sur un petit sous-ensemble d’exemples étiquetés avec une régularisation par consistance sur un plus grand ensemble non étiqueté, améliorant ainsi la robustesse et la performance du modèle.