SARSA (State-Action-Reward-State-Action)

Le SARSA (State-Action-Reward-State-Action) est une méthode d’apprentissage par renforcement qui, tout comme le Q-learning, utilise une table Q pour représenter la fonction de valeur d’une politique. Cependant, la différence principale entre SARSA et Q-learning réside dans la manière dont les valeurs Q sont mises à jour. Tandis que Q-learning utilise la valeur de l’action la plus optimale possible à partir de l’état suivant (approche off-policy), SARSA utilise la valeur de l’action effectivement choisie à partir de l’état suivant (approche on-policy).

Formule de mise à jour de la fonction Q dans SARSA :

 

Q(st,at)Q(st,at)+α(rt+γQ(st+1,at+1)Q(st,at))Q(s_t, a_t) \leftarrow Q(s_t, a_t) + \alpha \left( r_t + \gamma Q(s_{t+1}, a_{t+1}) – Q(s_t, a_t) \right)

 

Où :

Fonctions :

  • SARSA (exemple)

    Voici un exemple simple de l'algorithme SARSA appliqué à l'environnement CartPole-v1 de OpenAI Gym :

    Exemple de code :

    import gymnasium as gym
    import numpy as np
    import random
    import tensorflow as tf
    from tensorflow import keras
    
    env = gym.make('CartPole-v1')
    state_size = env.observation_space.shape[0]
    action_size = env.action_space.n
    
    # Modèle simple (fonction d’approximation Q)
    model = keras.Sequential([
        keras.layers.Dense(24, input_shape=(state_size,), activation='relu'),
        keras.layers.Dense(24, activation='relu'),
        keras.layers.Dense(action_size, activation='linear')
    ])
    model.compile(loss='mse', optimizer=tf.keras.optimizers.Adam(learning_rate=0.001))
    
    epsilon = 1.0
    epsilon_min = 0.01
    epsilon_decay = 0.995
    gamma = 0.95
    alpha = 0.1  # taux d’apprentissage
    episodes = 10  # pour test rapide
    
    def choose_action(state):
        if np.random.rand() < epsilon:
            return random.randrange(action_size)
        q_values = model.predict(np.expand_dims(state, axis=0), verbose=0)[0]
        return np.argmax(q_values)
    
    for e in range(episodes):
        state, _ = env.reset()
        action = choose_action(state)
        total_reward = 0
    
        for t in range(500):
            next_state, reward, terminated, truncated, _ = env.step(action)
            done = terminated or truncated
    
            next_action = choose_action(next_state)
    
            # Prédictions Q(s,a) et Q(s',a')
            q_sa = model.predict(np.expand_dims(state, axis=0), verbose=0)[0][action]
            q_s_next_a_next = model.predict(np.expand_dims(next_state, axis=0), verbose=0)[0][next_action]
    
            # Mise à jour SARSA
            target = reward + (0 if done else gamma * q_s_next_a_next)
            target_f = model.predict(np.expand_dims(state, axis=0), verbose=0)
            target_f[0][action] = q_sa + alpha * (target - q_sa)
    
            model.fit(np.expand_dims(state, axis=0), target_f, epochs=1, verbose=0)
    
            state = next_state
            action = next_action
            total_reward += reward
    
            if done:
                print(f"Episode {e+1}/{episodes} - Score: {total_reward}")
                break
    
        if epsilon > epsilon_min:
            epsilon *= epsilon_decay
    

    Explication du code :

    1. Initialisation de l’environnement CartPole
    - Environnement : `CartPole-v1` de Gymnasium. - Taille de l’état (`state_size`) : 4. - Nombre d’actions (`action_size`) : 2.
    2. Modèle d’approximation Q simple avec TensorFlow/Keras
    - Réseau neuronal séquentiel : - Couche dense 1 : 24 neurones, activation `relu`, input `(state_size,)`. - Couche dense 2 : 24 neurones, activation `relu`. - Couche de sortie : `action_size` neurones, activation `linear` (Q-values). - Compilation : - Perte : `mse`. - Optimiseur : `Adam` avec `learning_rate=0.001`.
    3. Hyperparamètres SARSA
    - Politique epsilon-greedy avec : - `epsilon = 1.0` initial (exploration maximale). - `epsilon_decay = 0.995`, `epsilon_min = 0.01`. - Facteur de discount : `gamma = 0.95`. - Taux d’apprentissage : `alpha = 0.1`. - Nombre d’épisodes : `10` (pour test rapide).
    4. Politique d’action epsilon-greedy
    - Avec probabilité `epsilon`, choix aléatoire. - Sinon, choix de l’action ayant la plus grande valeur Q prédite par le modèle.
    5. Boucle d’entraînement principale avec mise à jour SARSA
    - Pour chaque épisode : - Initialiser l’état, choisir l’action initiale avec `choose_action`. - Pour un maximum de 500 pas ou jusqu’à terminaison : - Exécuter l’action choisie. - Obtenir récompense, nouvel état, flag de fin (`done`). - Choisir la prochaine action selon la politique epsilon-greedy. - Calculer Q(s,a) et Q(s’,a’) via le modèle. - Calculer la cible SARSA : \[ target = reward + \gamma \times Q(s', a') \quad \text{(0 si état terminal)} \] - Mettre à jour la prédiction du modèle sur (s,a) : \[ Q(s,a) \leftarrow Q(s,a) + \alpha \times (target - Q(s,a)) \] - Entraîner le modèle sur l’état courant avec la nouvelle cible. - Mettre à jour l’état et l’action. - Cumuler la récompense totale. - Afficher le score de l’épisode. - Décroissance progressive d’`epsilon` après chaque épisode.