Traitement automatique du langage naturel (TALN)
L’apprentissage semi-supervisé appliqué au Traitement Automatique du Langage Naturel (TALN) combine un petit corpus de textes annotés avec une grande quantité de données non annotées pour améliorer la compréhension et la génération du langage par les modèles. Cette approche permet de réduire le coût et l’effort liés à l’annotation manuelle tout en exploitant efficacement les vastes ressources textuelles disponibles. En TALN, l’apprentissage semi-supervisé est particulièrement utile pour des tâches telles que la classification de texte, l’analyse de sentiments, ou la reconnaissance d’entités nommées, où les données annotées sont souvent rares mais les données brutes abondantes.
Fonctions :
-
Traitement automatique du langage naturel (exemple)
Le traitement automatique du langage naturel (TALN) est une branche de l’intelligence artificielle qui permet aux ordinateurs de comprendre, analyser et générer du texte ou de la parole en langage humain. Par exemple, les assistants vocaux comme Siri ou Alexa utilisent le TALN pour interpréter les commandes et répondre aux questions des utilisateurs.
Exemple de code :
import tensorflow as tf import numpy as np # Simulation de données textuelles (tokenisées) # (En pratique on utilise un tokenizer + un dataset réel) vocab_size = 1000 max_len = 20 def generate_data(n_samples, labeled=True): X = np.random.randint(1, vocab_size, size=(n_samples, max_len)) if labeled: # Labels binaires aléatoires y = np.random.randint(0, 2, size=(n_samples, 1)) return X, y else: return X # 1000 phrases étiquetées X_labeled, y_labeled = generate_data(1000, labeled=True) # 9000 phrases non étiquetées X_unlabeled = generate_data(9000, labeled=False) # Validation (test) X_val, y_val = generate_data(1000, labeled=True) # Modèle simple LSTM pour classification binaire model = tf.keras.Sequential([ tf.keras.layers.Embedding(vocab_size, 64, input_length=max_len), tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)), tf.keras.layers.Dense(1) ]) optimizer = tf.keras.optimizers.Adam() loss_fn = tf.keras.losses.BinaryCrossentropy(from_logits=True) batch_size = 64 consistency_weight = 1.0 epochs = 5 # Fonction d'augmentation simple (ajoute un "bruit" lexical : remplace 10% des mots par un token aléatoire) def augment_text(batch_x): batch_x_aug = batch_x.copy() for i in range(batch_x.shape[0]): for j in range(batch_x.shape[1]): if np.random.rand() < 0.1: batch_x_aug[i, j] = np.random.randint(1, vocab_size) return batch_x_aug # Dataset labeled_dataset = tf.data.Dataset.from_tensor_slices((X_labeled, y_labeled)) labeled_dataset = labeled_dataset.shuffle(1000).batch(batch_size).repeat() unlabeled_dataset = tf.data.Dataset.from_tensor_slices(X_unlabeled) unlabeled_dataset = unlabeled_dataset.shuffle(9000).batch(batch_size).repeat() val_dataset = tf.data.Dataset.from_tensor_slices((X_val, y_val)).batch(batch_size) labeled_iter = iter(labeled_dataset) unlabeled_iter = iter(unlabeled_dataset) for epoch in range(epochs): print(f"Epoch {epoch+1}/{epochs}") total_loss = 0 steps_per_epoch = len(X_labeled) // batch_size for step in range(steps_per_epoch): x_lab, y_lab = next(labeled_iter) x_unlab = next(unlabeled_iter) x_unlab_aug = augment_text(x_unlab.numpy()) with tf.GradientTape() as tape: # Supervision classique logits_lab = model(x_lab, training=True) loss_sup = loss_fn(y_lab, logits_lab) # Consistency regularization sur non-étiquetées logits_unlab = model(x_unlab, training=True) logits_unlab_aug = model(x_unlab_aug, training=True) prob = tf.sigmoid(logits_unlab) prob_aug = tf.sigmoid(logits_unlab_aug) 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 simple acc_metric = tf.keras.metrics.BinaryAccuracy() for x_batch, y_batch in val_dataset: logits = model(x_batch, training=False) preds = tf.sigmoid(logits) acc_metric.update_state(y_batch, preds) print(f"Validation Accuracy: {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. Génération et préparation des données textuelles simulées
generate_data(n_samples, labeled=True)
génère des séquences de tokens aléatoires représentant des phrases simulées. - Silabeled=True
, on génère aussi des labels binaires aléatoires (0 ou 1). - Sinon, seules les séquences sont générées sans étiquette. On crée : 1000 phrases étiquetées (X_labeled, y_labeled
), 9000 phrases non étiquetées (X_unlabeled
), 1000 phrases pour la validation (X_val, y_val
).2. Définition du modèle LSTM simple pour classification binaire
Le modèle est un réseau séquentiel composé de : - une coucheEmbedding
qui transforme les indices de mots en vecteurs denses de dimension 64, - une couche bidirectionnelleLSTM
de 64 unités pour capturer les dépendances contextuelles dans la séquence, - une couche dense finale avec 1 neurone pour produire un logit (sortie avant sigmoid).3. Configuration de l’entraînement
-optimizer = tf.keras.optimizers.Adam()
: optimiseur Adam pour la mise à jour des poids. -loss_fn = tf.keras.losses.BinaryCrossentropy(from_logits=True)
: fonction de perte binaire adaptée aux logits. -batch_size = 64
,consistency_weight = 1.0
(poids pour la perte de consistance),epochs = 5
définissent les paramètres d’entraînement.4. Fonction d’augmentation de texte
augment_text(batch_x)
remplace aléatoirement 10 % des tokens d’une séquence par un token aléatoire, simulant du bruit lexical et créant une version augmentée des phrases.5. Création des datasets TensorFlow
-labeled_dataset
contient les données étiquetées, mélangées, découpées en batchs, et répétées. -unlabeled_dataset
contient les données non étiquetées, également mélangées, batchées et répétées. -val_dataset
contient les données de validation batchées.6. Boucle d’entraînement semi-supervisé
Pour chaque époque et batch : - On récupère un batch étiqueté (x_lab, y_lab
) et un batch non étiqueté (x_unlab
). - On crée une version augmentée du batch non étiqueté (x_unlab_aug
). - Calcul des logits sur données étiquetées et calcul de la perte supervisée (loss_sup
) avec les vraies étiquettes. - Calcul des logits sur données non étiquetées normales et augmentées. - Conversion des logits en probabilités (sigmoid). - Calcul d’une perte de consistance (loss_consistency
) : moyenne des carrés des différences entre les deux distributions de probabilités, pour encourager la stabilité des prédictions malgré l’augmentation. - La perte totale est la somme :loss = loss_sup + consistency_weight * loss_consistency
. - Les gradients sont calculés puis appliqués pour mettre à jour les poids du modèle. - Affichage de la perte moyenne par époque.7. Évaluation finale
- Calcul de la précision sur le jeu de validation en comparant les prédictions (après sigmoid) aux vraies étiquettes avecBinaryAccuracy()
. - Affichage de la précision finale sur les données de validation. Ce code met en œuvre un entraînement semi-supervisé combinant une supervision classique sur un petit ensemble étiqueté et une régularisation par consistance sur un grand ensemble non étiqueté, ce qui aide à améliorer la robustesse et la performance du modèle sur des données textuelles.