Les fondations Python pour l'IA
Pas de for, pas de classes : tu maîtrises tout ça. Ce qui change en IA, c'est l'objet manipulé. On ne pousse plus des lignes de base de données : on pousse des tableaux de nombres à travers des opérations mathématiques.
1.1 La bascule mentale : de la boucle au tableau
En Django, additionner deux listes appelle une boucle. En IA, ce réflexe devient un piège de performance. Tout repose sur NumPy et son ndarray, qui applique une opération à des millions de nombres d'un coup : la vectorisation.
# Réflexe "dev classique" — lent c = [] for i in range(len(a)): c.append(a[i] + b[i]) # Réflexe "IA" — vectorisé, ~100× plus rapide import numpy as np c = np.array(a) + np.array(b) # une seule opération
Un réseau de neurones, c'est des milliards d'additions et de multiplications. En boucle Python, l'entraînement prendrait des jours. NumPy délègue à du code compilé et au GPU. La vectorisation n'est pas une optimisation, c'est le paradigme.
1.2 Scalaire, vecteur, matrice, tenseur
Tous les objets de l'IA sont un tableau de nombres, avec plus ou moins de dimensions. L'échelle la plus importante à intérioriser :
0.001.Le mot « tenseur » t'accompagnera toute la formation (le « Tensor » de TensorFlow). Rien de mystérieux : un tableau de nombres à N dimensions. Scalaire, vecteur et matrice sont des tenseurs de dimension 0, 1 et 2.
1.3 La forme (shape) : l'obsession n°1
La majorité des bugs en IA sont des erreurs de forme. Réflexe avant chaque opération : quelle est la forme de mon tableau, et laquelle l'opération attend-elle ? Les axes sont numérotés à partir de 0.
x = np.zeros((32, 128, 128, 3)) x.shape # (32, 128, 128, 3) x.ndim # 4 → nombre de dimensions x.size # 1 572 864 → total d'éléments # axe 0 = le lot (32 images) · axe 3 = les canaux couleur (R,V,B)
1.4 Les trois « multiplications » à ne pas confondre
Le point qui fait trébucher tout le monde : plusieurs façons de « multiplier » des tableaux, aux effets radicalement différents.
a) Élément par élément (*)
a * b # [1,2,3] * [4,5,6] → [4,10,18]
b) Produit matriciel (@ ou np.dot)
L'opération reine. Combine lignes et colonnes. Règle d'or : (m, k) @ (k, n) → (m, n) — les dimensions intérieures doivent être égales.
A = np.array([[1,2],[3,4]]) # (2,2) x = np.array([1,0]) # (2,) A @ x # [1, 3]
c) La transposée (.T)
A.T # (2,3) devient (3,2)
Le produit matriciel pas à pas
La règle unique : chaque nombre du résultat est le produit scalaire d'une ligne de A avec le vecteur x — on multiplie terme à terme, puis on additionne.
Ici x = [1, 0] est un sélecteur : le 1 garde la 1ʳᵉ colonne de A, le 0 efface la 2ᵉ. Donc A @ [1,0] = la 1ʳᵉ colonne de A → [1, 3], et A @ [0,1] = la 2ᵉ, [2, 4]. Plus largement, A transforme le vecteur x — exactement ce que fait une couche de neurones.
Anime-le toi-même
Le même mouvement, mais interactif : fais avancer les deux pointeurs et regarde la somme se construire, case après case. (Ici A = [[2,1],[0,3]] et y = [1,4].)
Matrice × matrice : même principe
Le résultat en (i, j) = produit scalaire de la ligne i de la première par la colonne j de la seconde.
Pourquoi les dimensions intérieures doivent être égales
colonnes de A = lignes de B. D'où (m,k) @ (k,n) → (m,n).Sans exécuter de code, calcule A @ y puis A @ z :
A = np.array([[2, 1], [0, 3]]) y = np.array([1, 1]) z = np.array([0, 2])
Puis : que renvoie A @ [1, 0], et pourquoi ?
A @ y — l0·y = 2×1+1×1 = 3 ; l1·y = 0×1+3×1 = 3 → [3, 3]
A @ z — l0·z = 2×0+1×2 = 2 ; l1·z = 0×0+3×2 = 6 → [2, 6]
A @ [1, 0] sélectionne la 1ʳᵉ colonne → [2, 0].
1.5 Le broadcasting : la magie (et le piège)
NumPy combine des tableaux de formes différentes en « étirant » le plus petit. Pratique — et source de bugs silencieux.
images = np.random.rand(32, 128, 128, 3) # un lot moyenne = np.array([0.4, 0.5, 0.6]) # (3,) une moyenne par canal images - moyenne # NumPy étire (3,) sur tout le lot ✓
La règle en une phrase
(32,128,128,3) et (3,) → OK ; (32,3) et (4,) → erreur.Donne la forme du résultat, ou « erreur » :
a) np.zeros((8, 3)) + np.ones((3,)) b) A @ v # A (10, 4), v (4,) c) M.T # M (2, 5) d) np.ones((32, 3)) * np.ones((4,))
a) (8, 3) — le (3,) est diffusé sur les 8 lignes.
b) (10,) — (10,4) @ (4,) → (10,).
c) (5, 2) — la transposée échange les axes.
d) erreur — alignés par la droite, 3 et 4 sont incompatibles.
1.6 Neurones, perte et gradient
La formation demande des « notions de maths appliquées ». Le minimum utile :
- Un réseau = un empilement de produits matriciels entrecoupés de fonctions d'activation non-linéaires (ex. ReLU). Sans elles, tout se réduirait à une seule matrice.
- Apprendre = ajuster les nombres des matrices de poids pour rapprocher la sortie de la bonne réponse.
- « Se rapprocher » se mesure par la fonction de perte (loss) : un nombre, plus bas = mieux.
Tu es sur une colline dans le brouillard et tu veux descendre. Tu sens la pente et fais un pas vers le bas. Tu répètes. C'est la descente de gradient : le gradient est la pente de la perte, et à chaque pas le modèle ajuste ses poids pour faire baisser l'erreur. La taille du pas = le taux d'apprentissage.
for etape in range(1000): prediction = modele(X) # passe avant perte = mse(prediction, y) # écart aux étiquettes gradients = perte.backward() # pente pour chaque poids (rétropropagation) poids = poids - 0.01 * gradients # un pas vers le bas (0.01 = learning rate)
1.7 L'écosystème : qui fait quoi
DataFrame = un tableur programmable.transformers : réutiliser des modèles déjà entraînés en quelques lignes.(16, 3, 64, 64) est la convention channels-first de PyTorch (NCHW) : correcte ailleurs, mais pas ici.(3, 4) @ (4, 2) ?(3,4) @ (4,2) : le 4 intérieur concorde et disparaît, restent les extérieurs → (3, 2). Les formes sont bien compatibles.(2, 2). Que dire de A * B et A @ B ?* multiplie case à case ; @ combine lignes et colonnes. C'est le piège n°1.A = [[1,2],[3,4]], combien vaut A @ [2, 1] ?[10, 4] correspondrait à A.T @ x (erreur de transposée).3 vs 4 ne sont ni égales ni à 1 → incompatibles. En revanche (8,1)&(8,5) (le 1 s'étire) et (10,3)&(3,) passent.Les concepts, semaine par semaine
Pour chaque bloc du programme ifage : l'objectif, les concepts, un exemple de code, un glossaire, un exercice et un quiz à valider. Reviens ici après chaque séance.
Introduction à l'IA
Objectif : installer le vocabulaire commun et distinguer les familles d'apprentissage.
Les 3 grands types d'apprentissage
- Supervisé — exemples étiquetés (photo → « chat »). ~80 % de l'IA appliquée.
- Non supervisé — pas d'étiquettes ; le modèle découvre des structures (clustering).
- Par renforcement — un agent apprend par récompenses (semaine 5).
Le vocabulaire fondateur
Un modèle reçoit des features (entrées) et produit une prédiction, comparée à l'étiquette attendue. Deux phases : l'entraînement puis l'inférence. On sépare toujours train et test ; un modèle excellent en train mais faible en test a surappris (overfitting).
from sklearn.model_selection import train_test_split from sklearn.linear_model import LinearRegression # X = features (surface, pièces, ...) · y = label (prix) X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.2) modele = LinearRegression() modele.fit(X_tr, y_tr) # entraînement modele.score(X_te, y_te) # évaluation sur des données JAMAIS vues
Prédire le prix d'un appartement. Features : surface, pièces, quartier. Label : prix de ventes passées. Le modèle apprend le lien, puis estime un bien inédit.
- Feature / Label
- Variable d'entrée / réponse correcte fournie.
- Train / test split
- Découpage pour évaluer honnêtement la généralisation.
- Overfitting
- Le modèle mémorise au lieu de généraliser.
On veut détecter si un e-mail est un spam. a) deux features plausibles ? b) le label ? c) le type d'apprentissage ?
a) nombre de liens, présence de mots-clés, expéditeur inconnu, proportion de majuscules.
b) l'étiquette binaire spam/non-spam d'un historique déjà classé.
c) supervisé (classification) — on a des exemples étiquetés.
Vision par ordinateur
Objectif : faire « voir » une machine, et découvrir l'astuce qui rend l'IA accessible : l'apprentissage par transfert.
Une image = un tenseur
Une image couleur est un tenseur (H, L, 3) ; chaque pixel = 3 nombres (R, V, B). Un CNN fait glisser de petits filtres (la convolution) : les premières couches captent bords et textures, les suivantes composent formes puis objets.
Entraîner de zéro exige des millions d'images. Le transfert réutilise un modèle pré-entraîné (ex. ResNet) qui « sait déjà voir » et ne réentraîne que la fin : d'excellents résultats avec quelques centaines d'images.
from tensorflow.keras.applications import ResNet50 from tensorflow.keras import layers, Model base = ResNet50(weights="imagenet", include_top=False) # modèle pré-entraîné base.trainable = False # on gèle ce qu'il a appris x = layers.GlobalAveragePooling2D()(base.output) sortie = layers.Dense(3, activation="softmax")(x) # 3 classes = NOTRE problème modele = Model(base.input, sortie) # on ne réentraîne que la fin
- Convolution / CNN
- Filtre glissant détectant un motif local / réseau spécialisé images.
- Modèle pré-entraîné
- Réseau déjà entraîné sur d'immenses données, réutilisable.
- Fine-tuning
- Réajuster finement un modèle pré-entraîné sur ses données.
Tu as 300 photos réparties en 3 catégories de fleurs. En une phrase : quelle stratégie, et quelle partie du modèle modifies-tu ?
Transfert : partir d'un modèle pré-entraîné, remplacer la dernière couche par une couche à 3 sorties, puis fine-tuner. 300 images seraient trop peu pour partir de zéro, mais suffisent pour réajuster un modèle qui sait déjà voir.
(3,256,256) est la convention channels-first (PyTorch) ; (256,256) serait une image en niveaux de gris.Apprentissage par renforcement
Objectif : un paradigme sans « bonne réponse » donnée : un agent apprend par essais, erreurs et récompenses.
La boucle agent ↔ environnement
Un agent observe un état, choisit une action, reçoit une récompense et un nouvel état. Il cherche la politique qui maximise la récompense cumulée. Le Q-learning estime, pour chaque (état, action), la récompense future attendue ; quand les états sont trop nombreux, le DQN remplace la table par un réseau de neurones.
ancien = Q[etat, action] futur = max(Q[nouvel_etat]) # meilleure valeur atteignable ensuite Q[etat, action] = ancien + alpha * (recompense + gamma * futur - ancien) # ^taux ^gain immédiat ^escompte du futur
Un agent apprend à jouer à Pong. État : positions balle/raquettes. Actions : monter/descendre. Récompense : +1 s'il marque, −1 sinon. Après des milliers de parties, il joue très bien — sans qu'on lui ait dit « comment ».
- Agent / Environnement
- Le décideur, et le monde avec lequel il interagit.
- Politique
- La stratégie : quelle action dans quel état.
- DQN
- Q-learning où un réseau approxime les valeurs Q.
Un robot aspirateur apprend à nettoyer par renforcement. Définis : a) l'état, b) les actions, c) un schéma de récompense.
a) position + carte des zones sales/propres + obstacles.
b) avancer, tourner, aspirer.
c) +1 par zone nettoyée, −1 par collision, −0,01 par pas (pour l'efficacité). Le choix des récompenses façonne tout le comportement.
Traitement du langage naturel (NLP)
Objectif : traiter du texte et construire un modèle de langue. Le socle direct des LLM.
Du texte aux nombres
Un modèle ne comprend que des nombres. Deux étapes : la tokenisation (découper en tokens numérotés) puis le plongement (embedding : chaque token → un vecteur qui capte le sens, au point que roi − homme + femme ≈ reine).
De la mémoire à l'attention
Les anciens RNN/LSTM lisaient mot à mot et oubliaient le contexte lointain. Le Transformer (2017) résout ça par l'attention : chaque mot pondère l'importance de tous les autres. Un modèle de langue ne fait qu'une chose : prédire le token suivant — répété, cela produit des phrases.
from transformers import AutoTokenizer, pipeline tok = AutoTokenizer.from_pretrained("gpt2") tok("Le chat dort")["input_ids"] # → [1026, 4758, 8501] (identifiants) gen = pipeline("text-generation", model="gpt2") gen("En 2026, l'IA appliquée", max_length=20) # prédit les tokens suivants
- Token / Embedding
- Unité de texte numérotée / vecteur représentant son sens.
- Attention
- Pondère l'importance de chaque mot du contexte.
- Transformer
- Architecture fondée sur l'attention, base des LLM.
Décris les deux étapes pour transformer « Le chat dort » en entrée d'un modèle, et ce que produit chacune.
1) Tokenisation → une suite d'entiers, ex. [1026, 4758, 8501].
2) Embedding → chaque entier devient un vecteur de sens → une matrice (3, d) que le modèle traite.
IA générative
Objectif : passer de l'IA qui classe à l'IA qui crée, et adapter de grands modèles.
Deux familles pour générer des images
- GAN — deux réseaux s'affrontent : un générateur fabrique de fausses images, un discriminateur les démasque. La compétition pousse au réalisme.
- Diffusion — on apprend à retirer du bruit ; à l'usage, on part d'un bruit pur qu'on « débruite » jusqu'à une image, guidé par un texte.
Une photo peu à peu couverte de « neige » (bruit). Le modèle apprend le chemin inverse : enlever la neige étape par étape. On lui donne du bruit + une description, il reconstruit une image.
Le fine-tuning
Réentraîner un GPT complet coûte des millions. Le fine-tuning reprend un grand modèle et l'ajuste sur un petit jeu de données spécifique : c'est ce qui rend ces modèles exploitables en entreprise.
from diffusers import StableDiffusionPipeline pipe = StableDiffusionPipeline.from_pretrained("stable-diffusion-v1-5") image = pipe("un chat astronaute, style aquarelle").images[0] # prompt → image image.save("chat.png")
- Générateur / Discriminateur
- Les deux réseaux rivaux d'un GAN.
- Diffusion
- Génération par débruitage progressif.
- Fine-tuning / Prompt
- Adapter un grand modèle / la consigne qui guide la génération.
Une PME veut générer des visuels dans son style propre et dispose de ~500 images de marque. Recommande une approche, puis nomme un risque.
Approche : fine-tuner un modèle de diffusion pré-entraîné sur les 500 images.
Risque : surapprentissage — avec trop peu d'images/trop d'étapes, le modèle recopie au lieu de généraliser (+ questions de droits sur les données).
IA agentique
Objectif : dépasser le modèle qui répond pour un agent qui raisonne, utilise des outils et agit en plusieurs étapes. Ta connaissance du dev web y est un atout.
Qu'est-ce qu'un agent ?
Un agent = un LLM dans une boucle, doté d'outils (recherche, API, code, fichiers). Le schéma ReAct alterne Réflexion → Action → Observation jusqu'à l'objectif. Le function calling est le pont : le LLM émet un appel structuré, ton code l'exécute. Le RAG injecte des documents récupérés pour ancrer les réponses.
while not objectif_atteint: pensee = modele.reflechir(contexte) # que faire ? action = modele.choisir_outil(pensee) # ex: rechercher(...) resultat = executer(action) # appel réel contexte = contexte + resultat # on mémorise l'observation
outils = [{
"name": "meteo",
"description": "Météo d'une ville pour un jour donné",
"parameters": {"ville": "str", "jour": "str"}
}]
reponse = modele.chat(messages, tools=outils)
if reponse.appel_outil: # le LLM DEMANDE d'appeler l'outil
obs = meteo(**reponse.arguments) # TON code l'exécute vraiment
messages.append(obs) # on renvoie l'observation au modèle
- Agent / Outil
- LLM en boucle avec objectif / fonction externe qu'il peut appeler.
- Function calling
- Le LLM produit un appel structuré exécuté par ton code.
- RAG
- Injecter des documents récupérés pour ancrer les réponses.
Un agent reçoit : « Quel temps fera-t-il demain à Genève, faut-il un parapluie ? ». Écris la suite réflexion → action → observation, avec l'outil utilisé.
Réflexion : besoin de la météo. Action : meteo("Genève","demain"). Observation : « pluie 80 % ». Réflexion : 80 % → parapluie. Action : répondre. Un enchaînement raisonnement/outil/observation : c'est ça, un agent.
Projet appliqué
Objectif : tout mettre en œuvre sur un projet réel, évalué devant un jury (20–30 h, mémoire d'une dizaine de pages).
Une démarche en 6 temps
- Cadrer le problème comme une tâche d'IA claire (classer ? prédire ? générer ?).
- Réunir et explorer les données — ~60 % du travail (pandas + Matplotlib).
- Choisir simple — souvent scikit-learn ou un modèle pré-entraîné suffit.
- Établir une baseline puis itérer ; surveiller l'écart train/test.
- Évaluer honnêtement sur des données jamais vues ; assumer les limites.
- Présenter le raisonnement, pas seulement la performance.
Choisis un sujet qui te tient à cœur et dont les données existent déjà. Vise petit mais complet. Une baseline simple qui tourne bat un modèle sophistiqué inachevé la veille de la soutenance.
(A) « recréer un assistant type ChatGPT » ou (B) « classer les tickets de support de mon entreprise en 5 catégories ». Lequel choisir, et pourquoi ?
(B) : périmètre petit mais complet, données existantes (historique de tickets), tâche claire (classification supervisée), faisable en 20–30 h. (A) est hors de portée (données, calcul, temps).
Tu arrives avec un atout : tu sais déjà construire des systèmes. L'IA appliquée, c'est en grande partie de l'ingénierie logicielle avec un nouveau type de brique. Ce carnet est ta carte ; le reste, c'est la pratique. Bon cours. 🎓