Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 3 additions & 29 deletions MyIA.AI.Notebooks/RL/rl_6_dqn_policy_gradient.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1263,14 +1263,6 @@
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "d44982c0",
"metadata": {},
"source": [
"**Lecture chiffree — les finales croisees.** Les deux boucles d'entrainement de ce notebook finissent a 179.4 (DQN, 300 episodes) et 449.3 (REINFORCE, 400 episodes). Le resume qualitatif de la cellule suivante (« DQN : convergence plus reguliere ») est exact — mais le prix de cette regularite se lit dans ces deux finales : a budgets voisins, la methode a la variance la plus haute finit 2.5 fois plus haut sur CETTE execution. Une execution, un classement : la section 5 evaluera les deux politiques apprises en separation, et l'ablation de la section 3 a deja montre ce que 3 graines font a ce genre de classement.\n"
]
},
{
"cell_type": "markdown",
"id": "t9k0e020",
Expand Down Expand Up @@ -1381,14 +1373,6 @@
"print(f\"\\nSeuil CartPole-v1 (solve) : 475\")"
]
},
{
"cell_type": "markdown",
"id": "df0bfb6a",
"metadata": {},
"source": [
"**Lecture chiffree — l'evaluation finale contre le seuil.** `DQN : 188.3 +/- 14.4`, `REINFORCE : 247.7 +/- 12.6`, `Seuil CartPole-v1 (solve) : 475`. Trois lectures. (1) Personne ne resout l'environnement : les deux moyennes restent largement sous 475 (sur un maximum possible de 500). (2) Les barres ne se touchent pas : 188.3 + 14.4 = 202.7, en dessous de 247.7 - 12.6 = 235.1 — l'avance de REINFORCE sur cette evaluation est hors du bruit mesure. (3) Signal de coherence : la prose qui suit cite 488,6 et 209,0 — nombres absents de cette sortie commitee, ils decrivent une autre execution ; la lecture honnete se tient aux nombres imprimes ci-dessus, et le defaut de prose est signale a l'owner dans la PR.\n"
]
},
{
"cell_type": "markdown",
"id": "w2n3e023",
Expand All @@ -1403,13 +1387,11 @@
"tags": []
},
"source": [
"**Le DQN atteint le seuil de résolution (475) sur CartPole-v1, REINFORCE pas.**\n",
"\n",
"Le DQN obtient une récompense moyenne de 488,6 (±25,8) et REINFORCE 209,0 (±41,7). Le DQN résout l'environnement (au-dessus du seuil 475) ; REINFORCE reste bien en dessous (~266 points sous le seuil). La différence s'explique par le *replay buffer* du DQN, qui rééchantillonne des transitions passées pour lisser l'estimation du gradient et stabiliser l'apprentissage — REINFORCE, qui n'utilise que les transitions de l'épisode courant, souffre d'une variance de gradient bien plus élevée.\n",
"**Lecture chiffree — l'evaluation finale contre le seuil.** `DQN : 188.3 +/- 14.4`, `REINFORCE : 247.7 +/- 12.6`, `Seuil CartPole-v1 (solve) : 475`.\n",
"\n",
"Le DQN surpasse donc REINFORCE (488,6 vs 209,0) **avec une variance plus faible** (±25,8 vs ±41,7) : la conclusion qualitative (DQN plus stable que REINFORCE grâce au replay buffer) se confirme, et ici le DQN va jusqu'à résoudre l'environnement là où REINFORCE n'y parvient pas sur ce budget d'entraînement.\n",
"Trois lectures. (1) Personne ne resout l'environnement : les deux moyennes restent largement sous 475 (sur un maximum possible de 500). (2) Les barres ne se touchent pas : 188.3 + 14.4 = 202.7, en dessous de 247.7 - 12.6 = 235.1 — l'avance de REINFORCE sur cette evaluation est hors du bruit mesure. (3) Sur ce budget d'entrainement, la conclusion qualitative du notebook (le replay buffer et le target network stabilisent l'apprentissage, cf. l'ablation plus haut) reste vraie, mais elle ne se lit pas dans ces nombres : c'est REINFORCE qui domine ici.\n",
"\n",
"> **Note de reproductibilité** : les résultats ci-dessus sont reproductibles (seed fixée, cell[2]). Sans seed, les récompenses dérivent fortement d'une exécution à l'autre — un écueil classique du RL. Les valeurs publiées dans la littérature CartPole-v1 (seuil 475, max 500) sont le point de référence.\n"
"> **Correction** : une version anterieure de cette lecture citait 488,6 et 209,0 et concluait que le DQN resout l'environnement. Ces nombres sont absents de la sortie commitee ci-dessus (ils decrivent une autre execution) : la lecture se tient desormais aux valeurs imprimees.\n"
]
},
{
Expand Down Expand Up @@ -1608,14 +1590,6 @@
"print(\"Exercice a completer : plage utile de target_update_freq\")"
]
},
{
"cell_type": "markdown",
"id": "7e4eac83",
"metadata": {},
"source": [
"**Lecture du stub — exercice 4, la plage utile de target_update_freq.** `Exercice a completer : plage utile de target_update_freq`. L'exercice demande de balayer la frequence de resynchronisation du target network — et l'ablation de la section 3 a deja donne la borne basse : retirer ENTIEREMENT le target network coute 2.4 points en moyenne (190.9 contre 188.5), un ecart noye dans un bruit inter-graines de plus ou moins 100. La question de l'exercice devient precise : existe-t-il une plage de frequences ou l'ecart SORT du bruit (resynchroniser trop rarement degenere vers le cas sans target), ou CartPole reste-t-il silencieux sur toute la plage ? Le protocole multi-graines de l'ablation, juste au-dessus, est le gabarit a reutiliser.\n"
]
},
{
"cell_type": "markdown",
"id": "b7s8e028",
Expand Down
18 changes: 1 addition & 17 deletions MyIA.AI.Notebooks/RL/rl_6c_ppo_from_scratch.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -934,14 +934,6 @@
" f\"{np.mean(curve[-50:]):7.1f}\")"
]
},
{
"cell_type": "markdown",
"id": "075341e1",
"metadata": {},
"source": [
"**Lecture chiffree — la graine 42 dans les deux protocoles.** Le run de la section 3.4 (400 episodes) termine a 495.2 ; la meme graine 42 dans l'ablation (300 episodes, sortie ci-dessus) termine a **158.2**. Meme algo, meme graine, budgets differents : l'ecart est le prix du budget court, un choix voulu par l'ablation (rendre la divergence visible pendant que les conditions apprennent encore). Deuxieme lecture, de coherence cette fois : les sections 3.6 et interpretation citent \"489.5\" puis \"489\" comme finale du run de reference — la sortie commitee imprime 495.2 ; l'ordre de grandeur tient, le chiffre exact de la prose ne se retrouve dans aucune sortie, ecart signale a l'owner dans la PR.\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
Expand Down Expand Up @@ -1316,14 +1308,6 @@
"print(\"Exercice a completer\")\n"
]
},
{
"cell_type": "markdown",
"id": "88ec07e8",
"metadata": {},
"source": [
"**Lecture du stub — exercice 3, la comparaison A2C vs PPO.** `Exercice a completer`. La table de la section 5 donne les differences qualitatives (objectif, epochs par trajectoire, sensibilite au learning rate) ; l'exercice demande les courbes superposees qui les rendent visibles. Le gabarit methodologique est deja la, deux sections plus haut : l'ablation clipping vient de montrer ce qu'une graine unique cache (la graine 99 sauve la condition sans clipping avec 246.7 — le contre-exemple de la loterie). Comparer A2C et PPO sur UN run chacun reproduirait exactement le piege ; le protocole {42, 0, 1, 7, 99} x deux conditions est le gabarit a recopier, avec la mediane et l'IQR comme statistiques de rapport, comme dans la sortie d'ablation.\n"
]
},
{
"cell_type": "markdown",
"id": "791b09fb",
Expand Down Expand Up @@ -1451,4 +1435,4 @@
},
"nbformat": 4,
"nbformat_minor": 5
}
}
17 changes: 0 additions & 17 deletions MyIA.AI.Notebooks/RL/rl_6e_grpo_from_scratch.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -960,23 +960,6 @@
"print(\"Exercice 1 a completer : effet de la taille de groupe G sur la stabilite de l'avantage.\")\n"
]
},
{
"cell_type": "markdown",
"id": "12066577",
"metadata": {
"papermill": {
"duration": 0.002964,
"end_time": "2026-09-19T18:00:41.948640",
"exception": false,
"start_time": "2026-09-19T18:00:41.945676",
"status": "completed"
},
"tags": []
},
"source": [
"**Lecture du stub — exercice 1, la variance de l'estimateur d'avantage.** `Exercice 1 a completer`. La mise a jour de la section 4 normalise chaque retour de groupe par $A_i = (R_i - \\bar{R}) / \\sigma_R$ avec G=6 : la moyenne ET l'ecart-type du groupe sont estimes sur 6 tirages seulement. C'est le talon d'Achille que l'exercice designe : a G=2, l'avantage des deux trajectoires ne depend plus que de laquelle finit devant l'autre — une piece pile-ou-face normalisee, quel que soit l'ecart reel ; a G=16 l'estimateur se stabilise mais chaque episode coute 16 rollouts. La grille a balayer, {2, 4, 8, 16}, encadre le G=6 courant des deux cotes — la sortie attendue est la variance du delta Sharpe cross-seed en fonction de G, et la question de l'enonce (un G minimal existe-t-il ?) se lit comme : en dessous de quel G la normalisation par groupe n'a-t-elle plus de sens statistique.\n"
]
},
{
"cell_type": "markdown",
"id": "59d1de33",
Expand Down
16 changes: 4 additions & 12 deletions MyIA.AI.Notebooks/RL/rlpt_1_ppo_lm_rlhf.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@
"id": "601c97d3",
"metadata": {},
"source": [
"### Lecture du résultat\n",
"### Lecture du résultat — courbes d'apprentissage sur 4 seeds\n",
"\n",
"Deux phénomènes complémentaires sont visibles sur les courbes :\n",
"\n",
Expand Down Expand Up @@ -685,7 +685,7 @@
"id": "8bd6e98b",
"metadata": {},
"source": [
"### Lecture du résultat\n",
"### Lecture du résultat — mesure finale par prompt (seed 0)\n",
"\n",
"La mesure finale confirme l'alignement : le reward moyen atteint 1.00, `P('a'|A)` et `P('e'|B)` sont à 1.00\n",
"après entraînement (contre ~0.08 avant RL), et les échantillons froids montrent des réponses conformes au prompt.\n",
Expand Down Expand Up @@ -762,7 +762,7 @@
"id": "2bddc2e6",
"metadata": {},
"source": [
"### Lecture du résultat\n",
"### Lecture du résultat — effet de beta (faible vs fort)\n",
"\n",
"La table montre le compromis dans sa forme **douce** : quand $\\beta$ passe de 0.05 à 2.0, la KL finale\n",
"descend (0.67 → 0.41 → 0.28) — la politique reste d'autant plus proche de la référence que le KL coûte cher —\n",
Expand Down Expand Up @@ -899,14 +899,6 @@
"print(\"Exercice a completer\")\n"
]
},
{
"cell_type": "markdown",
"id": "7ea69629",
"metadata": {},
"source": [
"**Lecture du stub — exercice 3, etendre la grille aux bornes.** `Exercice a completer`. La grille mesuree ci-dessus couvre beta de 0.05 a 2.0 : KL finale 0.67 -> 0.28, reward 1.00 dans les trois cas — multiplier la penalite KL par 40 n'a divise la derive que d'un facteur ~2.4. L'exercice demande les deux bornes extremes, 0.01 et 5.0. Avant d'executer, la grille permet d'ecrire la prediction qualitative : a 0.01 (cinq fois plus petit que le plus petit point), la KL finale devrait depasser 0.67 — la derive etait deja presque libre a 0.05 ; a 5.0 (2.5 fois le plus grand point), elle devrait passer sous 0.28. La vraie question n'est pas la, elle est dans la deuxieme colonne : le reward tiendra-t-il a 1.00 malgre tout ? Si oui, le compromis de ce toy confirme la lecture de la section 6 — beta regle le prix de la derive, pas la faisabilite de l'alignement. Executer le stub et confronter.\n"
]
},
{
"cell_type": "markdown",
"id": "5376af59",
Expand Down Expand Up @@ -962,4 +954,4 @@
},
"nbformat": 4,
"nbformat_minor": 5
}
}
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "a6f90f7d",
"metadata": {
"papermill": {
"duration": 0.015981,
"end_time": "2026-06-03T00:09:51.793687+00:00",
"exception": false,
"start_time": "2026-06-03T00:09:51.777706+00:00",
"status": "completed"
{
"cell_type": "markdown",
"id": "a6f90f7d",
"metadata": {
"papermill": {
"duration": 0.015981,
"end_time": "2026-06-03T00:09:51.793687+00:00",
"exception": false,
"start_time": "2026-06-03T00:09:51.777706+00:00",
"status": "completed"
},
"tags": []
},
"tags": []
"source": [
"# App-19 — Génération procédurale de niveaux via WFC + CP-SAT\n",
"\n",
"_Application CSP : Wave Function Collapse (effondrement de fonction d'onde) modélisé avec OR-Tools CP-SAT. Adapté du projet étudiant EPITA Programmation par Contraintes 2026 (groupe H2)._\n",
"\n",
"## Objectifs du sujet\n",
"\n",
"| # | Objectif | Statut |\n",
"|---|----------|--------|\n",
"| 1 | Implémenter WFC comme CSP avec CP-SAT (variables=tuiles, contraintes=adjacence) | ✅ Cellule 3 |\n",
"| 2 | Contraintes globales : connectivité, chemin joueur, placement d'objets | ✅ Cellule 3 + 5 |\n",
"| 3 | Contraintes de difficulté (densité ennemis, variété) | ✅ Cellule 3 + 6 |\n",
"| 4 | Évaluation sur tilesets existants | ✅ Cellule 7 |\n",
"| 5 | Comparer qualité/diversité : WFC pur vs CP-SAT vs aléatoire | ✅ Cellule 8 |\n",
"\n",
"## Architecture\n",
"\n",
"```\n",
"Search/Applications/CSP/\n",
"├── wfc_cpsat.py — solveurs (Random, PureWFC, CP-SAT)\n",
"├── tileset.json — tileset donjon 5 tuiles\n",
"├── tileset_cave.json — tileset cave (plus complexe)\n",
"└── App-19-ProceduralGeneration-WFC.ipynb — ce fichier\n",
"```"
]
},
"source": [
"# App-19 — Génération procédurale de niveaux via WFC + CP-SAT\n",
"\n",
"_Application CSP : Wave Function Collapse (effondrement de fonction d'onde) modélisé avec OR-Tools CP-SAT. Adapté du projet étudiant EPITA Programmation par Contraintes 2026 (groupe H2)._\n",
"\n",
"## Objectifs du sujet\n",
"\n",
"| # | Objectif | Statut |\n",
"|---|----------|--------|\n",
"| 1 | Implémenter WFC comme CSP avec CP-SAT (variables=tuiles, contraintes=adjacence) | ✅ Cellule 3 |\n",
"| 2 | Contraintes globales : connectivité, chemin joueur, placement d'objets | ✅ Cellule 3 + 5 |\n",
"| 3 | Contraintes de difficulté (densité ennemis, variété) | ✅ Cellule 3 + 6 |\n",
"| 4 | Évaluation sur tilesets existants | ✅ Cellule 7 |\n",
"| 5 | Comparer qualité/diversité : WFC pur vs CP-SAT vs aléatoire | ✅ Cellule 8 |\n",
"\n",
"## Architecture\n",
"\n",
"```\n",
"Search/Applications/CSP/\n",
"├── wfc_cpsat.py — solveurs (Random, PureWFC, CP-SAT)\n",
"├── tileset.json — tileset donjon 5 tuiles\n",
"├── tileset_cave.json — tileset cave (plus complexe)\n",
"└── App-19-ProceduralGeneration-WFC.ipynb — ce fichier\n",
"```"
]
},
{
"cell_type": "markdown",
"id": "a6f90f7d",
Expand Down Expand Up @@ -788,21 +788,6 @@
"print(\"Exercice a completer : validation de niveau\")"
]
},
{
"cell_type": "markdown",
"id": "interp-validate",
"metadata": {},
"source": [
"### Lecture — le contrat de validation de l'exercice\n",
"\n",
"La cellule committée est le stub attendu : `violations: -1`, `valid: False`, les 4 étapes en commentaires `# Etape N`. Le stub ne lève aucune erreur (le notebook s'exécute de bout en bout, exercices non complétés compris) — c'est la convention de la série.\n",
"\n",
"Deux observations pour orienter la complétion :\n",
"\n",
"- Le seuil de validité demandé est **ambitieux** : `connectivity >= 0.5` alors que, dans la comparaison de la section 4, aucune des trois méthodes ne dépasse 7 %. Un `validate_level` correctement complété **rejettera** donc les trois grilles committées de ce notebook — c'est un test de non-régression utile : tout générateur amélioré qui passe ce seuil a réellement progressé.\n",
"- Tout le nécessaire est déjà importé en §0 : `adjacency_violations` et `bfs_reachable_floor` sont chargées dans la cellule d'imports. L'exercice est un assemblage de briques existantes, pas une réécriture."
]
},
{
"cell_type": "markdown",
"id": "402d486d",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -535,21 +535,6 @@
"tsp_medium.afficher(tournee_nn, f\"Plus Proche Voisin (cout={cout_nn:.2f})\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Lecture du brute force TSP-10 (ancre sur code[2])\n",
"\n",
"La sortie verbatim de code[2] est `Solution optimale: 277.23 / Temps de calcul: 0.007s`. La cellule implemente `brute_force(tsp)` qui enumere toutes les permutations des villes (sauf la premiere fixee) et selectionne celle de cout minimal.\n",
"\n",
"**Pourquoi 0.007 s pour TSP-10** : `itertools.permutations(range(1, 10))` produit 9! = 362 880 permutations. En Python pur avec NumPy pour les calculs de distances, cela prend environ 7 millisecondes. C'est la borne haute de ce que la force brute peut faire en mode interactif.\n",
"\n",
"**Pourquoi fixer la ville 0** : eliminer les rotations (N solutions equivalentes par rotation) et les symetries miroir (2 solutions equivalentes par reflexion). Le facteur de reduction est 2N, soit 20 pour TSP-10. Le nombre de permutations effectivement evaluees est 9! / 2 = 181 440 (divise par 2 pour la symetrie miroir).\n",
"\n",
"**Implication pedagogique** : la force brute donne un cout **optimal** (277.23). C'est la **borne inferieure methodologique** : aucune autre methode ne peut faire mieux. Les methodes heuristiques qui suivent (NN, 2-opt, SA, GA, ACO) sont evaluees en comparaison de leur gap a cette borne."
]
},
{
"cell_type": "markdown",
"id": "00770b17",
Expand Down Expand Up @@ -2327,28 +2312,6 @@
"print('Fonction algorithme_genetique_hybride_tsp definie')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Lecture du 3-opt vs 2-opt (ancre sur code[17])\n",
"\n",
"La sortie verbatim de code[17] est `Cout initial (NN): 632.87 / Cout apres 2-opt: 553.98 / Cout apres 3-opt: ...`. La cellule implemente `three_opt(tournee, max_iterations)` qui :\n",
"- Prend une tournee amelioree par 2-opt.\n",
"- Applique une recherche 3-opt : remplace 3 aretes non adjacentes par 3 nouvelles aretes selon l'une des 8 topologies possibles (vs 1 pour 2-opt).\n",
"\n",
"**Pourquoi 3-opt est plus puissant** :\n",
"- 2-opt : 1 mouvement possible (inversion d'une sous-sequence).\n",
"- 3-opt : 8 mouvements possibles (combinaisons d'inversions et de permutations).\n",
"- L'espace de voisinage est plus large, donc la chance d'echapper aux minima locaux est plus grande.\n",
"\n",
"**Sortie observee** : sur TSP-15 (l'instance ATSP-12 ou similaire), 3-opt ameliore generalement le cout de 5-10 % par rapport a 2-opt. C'est substantiel mais au prix d'un temps de calcul plus long (complexite O(N^3) au lieu de O(N^2)).\n",
"\n",
"**Cas d'usage** : 3-opt est combine avec 2-opt dans les solveurs modernes (Lin-Kernighan). C'est la base du solveur Concorde pour les instances TSP < 1000 villes.\n",
"\n",
"**Note pedagogique** : le notebook introduit 3-opt comme extension naturelle de 2-opt. C'est une illustration classique de la complexite croissante en recherche locale : plus le voisinage est large, plus l'amelioration est grande, mais plus le temps de calcul est long."
]
},
{
"cell_type": "markdown",
"id": "6ad8c972",
Expand Down Expand Up @@ -2743,7 +2706,7 @@
"- **N = 200-1000** : OR-Tools ou LK-H.\n",
"- **N > 1000** : solveurs specialises (Concorde, branch-and-bound parallele).\n",
"\n",
"### Conclusion methodologique\n",
"### Taxonomie des methodes et critere de choix\n",
"\n",
"Le TSP illustre la **diversite des approches d'optimisation combinatoire** :\n",
"1. **Methodes exactes** : explosion exponentielle, cas de petite taille.\n",
Expand Down
Loading
Loading