Cadre de base de l'apprentissage par renforcement
Imaginez que vous enseignez à un chiot à apprendre la commande "assis". Vous ne lui diriez pas directement comment chaque muscle doit bouger dans le mouvement pour s'asseoir ; à la place, vous feriez ceci :
- Vous donnez la commande "assis".
- Le chiot essaie une action (il peut s'asseoir, se coucher ou tourner en rond).
- S'il s'assoit, vous lui donnez immédiatement une friandise en récompense.
- S’il se trompe, vous ne donnez aucune récompense, ou vous donnez un léger signal de « ce n’est pas ça ».
- Après de nombreuses tentatives, le chiot comprend peu à peu : après avoir entendu « assis », exécuter l’action de s’asseoir peut rapporter une friandise. Il apprend donc l’ordre.
L’apprentissage par renforcementconsiste à laisser un ordinateur (ou un agent) apprendre, comme ce chiot, comment prendre une série de décisions pour atteindre un objectif à long terme en interagissant avec l’environnement et en se fondant sur les récompenses ou punitions reçues.
Comparé àl’apprentissage superviséfamilier (un « enseignant » avec des réponses standard) et àl’apprentissage non supervisé(recherche de la structure interne des données), il est fondamentalement différent. L’apprentissage par renforcement estun apprentissage par l’expérience, et son cœur estl’essai et l’erreuretla récompense différée。
Éléments essentiels de l’apprentissage par renforcement
Pour formaliser ce processus d’apprentissage, nous introduisons plusieurs concepts clés qui constituent ensemble le cadre de base de l’apprentissage par renforcement.
Agent et environnement
C’est la relation interactive la plus élémentaire de l’apprentissage par renforcement.
- Agent :Il est le sujet de l’apprentissage, l’entité qui prend les décisions. Dans l’exemple ci-dessus, le chiot est l’agent. Dans un ordinateur, il peut s’agir d’un algorithme, d’un programme ou d’un robot.
- Environnement :Il est le monde extérieur dans lequel l’agent existe et avec lequel il interagit. Pour le chiot, l’environnement, c’est vous, les friandises, le sol et toutes les choses extérieures. L’environnement reçoit les actions de l’agent et fournit de nouveaux états et récompenses.

Leur relation forme une boucle continue :l’agent observe l’environnement -> effectue une action -> l’environnement renvoie un nouvel état et une récompense -> l’agent observe à nouveau...

État, Action et Récompense
Ce sont trois éléments d'information clés décrivant chaque interaction.
- État :À un moment donné, une description complète de la situation de l'environnement. Par exemple, dans l'exemple d'entraînement du chiot, l'état peut inclure : le chiot est debout, vous avez une friandise dans la main, et vous venez de dire « sit ». L'état est la base des décisions de l'agent.
- Action :Les choix que l'agent peut faire dans un certain état. Pour le chiot, l'ensemble d'actions pourrait être {sit, lie down, stand, spin...}.
- Récompense :Un signal scalaire que l'environnement renvoie à l'agent après que l'agent a effectué une action. Il définitce qui est bon et ce qui est mauvais. La récompense est la seule boussole pour l'apprentissage de l'agent. Donner une friandise au chiot est une récompense positive (+1) ; dire « ce n'est pas bien » peut être considéré comme une légère récompense négative (-0.1).
Politique
Une politiqueest le cerveau ou la règle de comportement de l'agent. Elle définit quelle action l'agent doit entreprendre dans tout état donné.
Une politique peut être une simple fonction de table de correspondance, ou un réseau de neurones profond complexe. L'objectif ultime de l'apprentissage par renforcement est de trouver unepolitique optimale, telle que larécompense cumulative à long terme obtenue par l'agent depuis l'environnement soit maximisée。
- .Exemple : une politique simple pourrait être : si l'état est « entendre la commande sit », alors choisir l'action sit avec une probabilité de 90% et choisir d'autres actions avec une probabilité de 10%.
Fonction de valeur
Les récompenses indiquent à l'agentle bien ou le mal immédiat de l'actionactuelle, mais l'agent doit se soucier davantage desretoursà long terme.Une fonction de valeurest l'outil utilisé pour mesurer ce retour à long terme.
Elle répond à la question : en partant de l'état actuel et en suivant une certaine politique jusqu'au bout, combien de récompense totale puis-jeespérerobtenir ?
- Fonction de valeur d'état V(s): mesure la valeur à long terme de suivre la politique actuelle dans l'état
ss. - Fonction de valeur d'action Q(s, a): mesure, dans l'état
ss,après avoir exécuté une action spécifiqueaa, la valeur à long terme de suivre ensuite la politique actuelle. Elle est plus couramment utilisée que la fonction de valeur d'état car elle peut directement guider la sélection des actions.
Pourquoi avons-nous besoin d'une fonction de valeur ?Imaginez une partie d'échecs. Capturer un pion adverse donne une petite récompense immédiate, mais cela peut mener à être maté dix coups plus tard et à recevoir une énorme récompense négative. Par le calcul et l'estimation, la fonction de valeur peut aider l'agent à éviter ce genre de comportement qui convoite de petits gains et perd toute la partie.
Processus d'interaction central : processus de décision markovien
Les problèmes d'apprentissage par renforcement sont généralement modélisés comme unprocessus de décision markovien (MDP). Ce nom semble complexe, mais ce n'est en fait qu'un cadre standard qui organise les éléments mentionnés ci-dessus sous forme mathématique et décrit l'interaction entre l'agent et l'environnement.
L'idée centrale du MDP est :L'état suivant et la récompense dépendent uniquement de l'état actuel et de l'action actuelle entreprise, et sont indépendants de l'historique précédent(c'est-à-dire la propriété de Markov).
Un cycle complet d'interaction MDP se déroule comme suit :

- Au pas de temps
tt, l'environnement se trouve dans l'étatS_t。 - S_t. L'agent observe cet état.
- L'agent, selon sa politique
ππ, sélectionne une actionA_t。 - A_t. L'environnement reçoit cette action.
- L'environnement, selon ses règles dynamiques internes, effectue une transition vers l'état suivant
S_{t+1}S_{t+1}, et produit une récompense scalaireR_{t+1}R_{t+1}, qui est renvoyée à l'agent. - Le pas de temps avance (
t = t+1t = t+1), et une nouvelle boucle commence.

L'objectif de l'agent est, en expérimentant continuellement cette boucle, d'apprendre une politiqueπ*π, telle qu'en partant de n'importe quel état initial, lavaleur attendue de la récompense cumulée (c.-à-d., le retour) soit maximisée。
Un exemple de code simple : Monde en grille
Utilisons un exemple classique de monde en grille pour rendre ces concepts concrets. Supposons qu'il existe une grille 4x4. L'agent part du point de départSS, avec pour objectif d'atteindre le point terminalGT. Atteindre un obstacle#X signifie un échec, et chaque étape a une petite pénalité (pour encourager à atteindre la fin le plus tôt possible).
S . . . . # . . . . # . . . . G
- État: les coordonnées de chaque cellule de la grille, telles que (0,0), (0,1)... (3,3). Il y a 16 états au total.
- Action: {up, down, left, right}.
- Récompense:
- : Atteindre T : +10
G: +10 - Toucher X
#ou sortir des limites : -5 - Autres déplacements normaux : -0.1 (encourage des chemins efficaces)
- : Atteindre T : +10
- Politique: Nous devons apprendre une table qui enregistre, dans chaque état (cellule de grille), quelle direction prendre.
Ci-dessous se trouve une démonstration de pseudo-code extrêmement simplifiée de Q-learning (un algorithme classique d'apprentissage par renforcement), utilisée pour apprendre le chemin optimal dans ce monde en grille.
Exemple
import random
from typing import Dict, List, Tuple
# ====================== 1. Simulation de l'environnement (monde en grille) ======================
class GridWorldEnv:
"""Un environnement de grille simple pour démontrer Q-Learning"""
def __init__(self, grid_size: Tuple[int, int] = (5, 5),
start_pos: Tuple[int, int] = (0, 0),
goal_pos: Tuple[int, int] = (4, 4),
obstacle_pos: List[Tuple[int, int]] = [(1, 1), (2, 2), (3, 1)]):
self.grid_size = grid_size
self.start_pos = start_pos
self.goal_pos = goal_pos
self.obstacle_pos = obstacle_pos
self.current_pos = start_pos
# Définitions des actions : 0-haut, 1-bas, 2-gauche, 3-droite
self.actions = ['up', 'down', 'left', 'right']
self.num_actions = len(self.actions)
def reset(self) -> int:
"""Réinitialiser l'environnement et renvoyer l'index de l'état initial"""
self.current_pos = self.start_pos
return self.pos_to_state(self.current_pos)
def pos_to_state(self, pos: Tuple[int, int]) -> int:
"""Convertir une position de coordonnées en index d'état"""
return pos[0] * self.grid_size[1] + pos[1]
def state_to_pos(self, state: int) -> Tuple[int, int]:
"""Convertir l'index d'état en position de coordonnées"""
return (state // self.grid_size[1], state % self.grid_size[1])
def random_action(self) -> int:
"""Choisir aléatoirement une action (exploration)"""
return random.randint(0, self.num_actions - 1)
def action_to_direction(self, action: int) -> str:
"""Convertir l'indice d'action en nom de direction"""
return self.actions[action]
def step(self, action: int) -> Tuple[int, float, bool]:
"""
Exécuter l'action, renvoyer (next_state, reward, done)
Point d'optimisation : corriger le bug où la récompense d'obstacle ne peut pas être déclenchée, simplifier la logique de décision
"""
x, y = self.current_pos
# Mettre à jour la position en fonction de l'action
if action == 0: # haut
x = max(0, x - 1)
elif action == 1: # bas
x = min(self.grid_size[0] - 1, x + 1)
elif action == 2: # gauche
y = max(0, y - 1)
elif action == 3: # droite
y = min(self.grid_size[1] - 1, y + 1)
# Vérifier si un obstacle est heurté (correction principale : d'abord enregistrer si l'obstacle est heurté, puis gérer la position)
new_pos = (x, y)
hit_obstacle = False # Marquer si un obstacle est heurté
if new_pos in self.obstacle_pos:
hit_obstacle = True # Enregistrer l'état de collision avec un obstacle
new_pos = self.current_pos # Collision avec un obstacle, position inchangée
self.current_pos = new_pos
next_state = self.pos_to_state(new_pos)
# Calculer la récompense (d'après hit_obstacle enregistré à l'avance, corriger la contradiction dans la logique d'origine)
if new_pos == self.goal_pos:
reward = 100.0 # Objectif atteint, récompense importante
done = True
elif hit_obstacle: # D'après l'indicateur, et non le new_pos modifié
reward = -50.0 # Collision avec un obstacle, pénalité
done = False
else:
reward = -1.0 # Petite pénalité pour chaque étape, encourageant à atteindre l'objectif rapidement
done = False
return next_state, reward, done
# ====================== 2. Programme principal Q-Learning ======================
if __name__ == "__main__":
# Optimisation 1: Fixer la graine aléatoire pour garantir des résultats d'expérience reproductibles
random_seed = 42
random.seed(random_seed)
np.random.seed(random_seed)
# Initialiser l'environnement
env = GridWorldEnv(
grid_size=(5, 5), # grille 5x5
start_pos=(0, 0), # point de départ
goal_pos=(4, 4), # point d'arrivée
obstacle_pos=[(1,1), (2,2), (3,1)] # positions des obstacles
)
# Calculer le nombre d'états
num_states = env.grid_size[0] * env.grid_size[1]
num_actions = env.num_actions
# Initialiser la table Q (fonction action-valeur) avec la forme [num_states, num_actions]
Q_table = np.zeros([num_states, num_actions])
# Définir les hyperparamètres
learning_rate = 0.1 # taux d'apprentissage
discount_factor = 0.9 # facteur d'actualisation
epsilon = 0.1 # taux d'exploration
total_episodes = 1000 # nombre d'épisodes d'entraînement
# Processus d'entraînement
for episode in range(total_episodes):
state = env.reset() # Réinitialiser l'environnement au point de départ, obtenir l'état initial S
done = False # Indique si cet épisode se termine
total_reward = 0 # Enregistre la récompense totale pour cet épisode
while not done:
# 1. Politique ε-greedy pour la sélection des actions
if random.uniform(0, 1) < epsilon:
action = env.random_action() # Exploration : choisir aléatoirement une action
else:
# Exploitation : choisir l'action ayant la valeur Q la plus élevée, gérer les égalités
q_values = Q_table[state]
max_q = np.max(q_values)
best_actions = np.where(q_values == max_q)[0]
action = random.choice(best_actions) # Choisir aléatoirement une action en cas d'égalité
# 2. Exécuter l'action et interagir avec l'environnement
next_state, reward, done = env.step(action)
total_reward += reward
# 3. Mettre à jour la table Q (cœur : formule du Q-Learning)
# Q(S, A) = Q(S, A) + α * [ R + γ * max(Q(S', a')) - Q(S, A) ]
old_value = Q_table[state, action]
next_max = np.max(Q_table[next_state]) # Valeur Q maximale de l'état suivant
# Calculer la valeur Q cible
target = reward + discount_factor * next_max
# Mettre à jour la valeur Q
new_value = old_value + learning_rate * (target - old_value)
Q_table[state, action] = new_value
# 4. Passer à l'état suivant
state = next_state
# Afficher la progression de l'entraînement toutes les 100 épisodes
if (episode + 1) % 100 == 0:
print(f"Épisode {episode + 1}/{total_episodes}, Récompense totale : {total_reward:.1f}")
# ====================== 3. Extraire la politique optimale (format d'affichage optimisé, plus intuitif) ======================
policy: Dict[int, str] = {}
print("\n=== Politique optimale après apprentissage (disposition en grille) ===")
# Optimisation 2 : Afficher sous forme de grille pour visualiser intuitivement la politique de toute la grille
grid_rows, grid_cols = env.grid_size
for row in range(grid_rows):
row_str = []
for col in range(grid_cols):
pos = (row, col)
state = env.pos_to_state(pos)
if pos in env.obstacle_pos:
row_str.append(" Obstacle ")
elif pos == env.obstacle_pos:
row_str.append(" ")
elif pos == env.start:
# Marquer aussi le départ et son
best_action_idx = np.argmax(Q_table[state])
best_action = env.action_to_direction(best_action_idx)
row_str.append(f" Départ({best_action})")
else:
best_action_idx = np.argmax(Q_table[state])
best_action = env.action_to_direction(best_action_idx)
policy[state] = best_action
row_str.append(f" {best_action} ")
print("|".join(row_str))
# ====================== 4. Test de la politique optimale ======================
print("\n=== Test de la politique optimale ===")
state = env.reset()
done = False
steps = 0
path = [env.state_to_pos(state)]
while not done and steps < 50: # Maximum 50 étapes pour éviter les boucles infinies
best_action_idx = np.argmax(Q_table[state])
next_state, reward, done = env.step(best_action_idx)
current_pos = env.state_to_pos(next_state)
path.append(current_pos)
state = next_state
steps += 1
print(f"Chemin: {path}")
print(f"Étapes pour atteindre l'objectif : {steps}")
print(f"Objectif atteint : {env.current_pos == env.goal_pos}")
Explication de code:
Q_tableest la fonction centrale de valeur d'action, avec une forme[number of states, number of actions](dans l'exemple, 25×4, correspondant aux 25 états de la grille 5×5 et aux 4 actions haut/bas/gauche/droite).Q_table[s, a]Désigne, pour l'états(l'indice de la position dans la grille), la valeur à long terme de l'exécution de l'actiona(0-3 correspondent à haut/bas/gauche/droite), toutes initialement à 0, mises à jour étape par étape au fil de l'entraînement.env.step(action)Simule la logique d'interaction centrale du processus de décision markovien (MDP) : après avoir saisi un indice d'action, il met d'abord à jour la position de l'agent dans la grille (si un obstacle est heurté, la position reste inchangée), puis renvoie un triplet :(next_state, reward, done)——next_stateest l'indice du nouvel état,rewardest la récompense différenciée (objectif +100, obstacle -50, chaque étape -1),doneindique si l'objectif a été atteint (fin de cet épisode).- La formule de mise à jour centrale du Q-Learning
Q(S,A) = Q(S,A) + α * [R + γ * max(Q(S', a')) - Q(S,A)]est décomposé et implémenté dans le code : on récupère d'abord la valeur Q actuelleold_value, puis calculer la valeur Q maximale de l'état suivantnext_max, puis calculer la valeur cibletarget = 奖励 + 折扣因子 × 下一状态最大Q值, et enfin utiliser le taux d'apprentissageαpour combiner l'ancienne valeur et la valeur cible, obtenir la valeur Q mise à jour, et ainsi corriger itérativement la valeur d'action. epsilon(taux d'exploration) équilibre « exploitation » et « exploration » via la politique ε-greedy : avecepsilonprobabilité, choisir aléatoirement une action (explorer l'inconnu) ; avec1-epsilonprobabilité, choisir l'action avec la plus grande valeur Q dans l'état courant (exploiter l'optimum connu). Le code gère aussi le cas d'égalité des valeurs Q : si plusieurs actions ont la même valeur Q, l'une est choisie aléatoirement, évitant le verrouillage de politique causé par un choix fixe unique.- Le code implémente en outre une correspondance bidirectionnelle entre les états et les positions de la grille (
pos_to_state/state_to_pos), la conversion entre les actions et les noms de direction (action_to_direction), ainsi que l'extraction et le test de la politique après l'entraînement : parcourir tous les états, prendre l'action avec la plus grande valeur Q dans chaque état comme politique optimale, et vérifier le chemin et le nombre d'étapes du point de départ au point d'arrivée selon cette politique.
Episode 100/1000, Total Reward: 93.0 Episode 200/1000, Total Reward: 90.0 Episode 300/1000, Total Reward: 92.0 Episode 400/1000, Total Reward: 90.0 Episode 500/1000, Total Reward: 93.0 Episode 600/1000, Total Reward: 93.0 Episode 700/1000, Total Reward: 91.0 Episode 800/1000, Total Reward: 93.0 Episode 900/1000, Total Reward: 93.0 Episode 1000/1000, Total Reward: 93.0 === 学习完成后的最优策略 === 位置 (0, 0): 最优动作 = right 位置 (0, 1): 最优动作 = right 位置 (0, 2): 最优动作 = down 位置 (0, 3): 最优动作 = down 位置 (0, 4): 最优动作 = down 位置 (1, 0): 最优动作 = up 位置 (1, 1): 最优动作 = 障碍物 位置 (1, 2): 最优动作 = right 位置 (1, 3): 最优动作 = down 位置 (1, 4): 最优动作 = left 位置 (2, 0): 最优动作 = down 位置 (2, 1): 最优动作 = down 位置 (2, 2): 最优动作 = 障碍物 位置 (2, 3): 最优动作 = down 位置 (2, 4): 最优动作 = down 位置 (3, 0): 最优动作 = down 位置 (3, 1): 最优动作 = 障碍物 位置 (3, 2): 最优动作 = right 位置 (3, 3): 最优动作 = right 位置 (3, 4): 最优动作 = down 位置 (4, 0): 最优动作 = right 位置 (4, 1): 最优动作 = right 位置 (4, 2): 最优动作 = right 位置 (4, 3): 最优动作 = right 位置 (4, 4): 最优动作 = 终点 === 测试最优策略 === 路径: [(0, 0), (0, 1), (0, 2), (1, 2), (1, 3), (2, 3), (3, 3), (3, 4), (4, 4)] 到达终点步数: 8 是否到达终点: True
Résumé et réflexion pratique
Le cadre de base de l'apprentissage par renforcement peut être résumé ainsi :L'agent interagit avec l'environnement selon un processus de décision markovien et, en fonction des signaux de récompense obtenus, optimise continuellement sa politique (généralement en apprenant et en mettant à jour les fonctions de valeur), avec pour objectif ultime de maximiser la récompense cumulée à long terme.
| Concept | Analogie | Rôle dans l'apprentissage par renforcement |
|---|---|---|
| Agent | Chiot en apprentissage / IA jouant aux échecs | Le sujet décisionnel qui exécute l'algorithme d'apprentissage |
| Environnement | Dresseur / Règles de l'échiquier | Système externe qui fournit les états et le retour de récompense |
| State | Posture du chiot / Position sur l'échiquier | Base d'informations actuelle permettant à l'agent de prendre des décisions |
| Action | S'asseoir / Déplacer une pièce | Choix que l'agent peut faire |
| Récompense | Friandise / Résultat de victoire ou de défaite | Signal immédiat évaluant la qualité d'une action ; la boussole de l'apprentissage |
| Politique | La réponse à l'ordre que le chiot a apprise | Règle de correspondance des états vers les actions ; l'objectif de l'apprentissage |
| Fonction de valeur | Évaluation à long terme de la situation | Évalue la valeur à long terme d'un état ou d'une action ; c'est la base de l'optimisation de la politique |