【强化学习笔记】2. SARSA算法及示例代码

      学习SARSA建议与Q-Learning相结合起来学习

一、 SARSA算法

       SARSA 是一种无模型 (Model-Free)、基于值函数 (Value-Based) 的在线策略 (On-Policy) 强化学习算法。与 Q-Learning 不同,SARSA 在更新时不会去幻想“未来的完美最优动作”(这里可以理解为Q-Learning中的 max Q ),而是老老实实地用当前策略实际生成的动作来更新价值。

      它的名字概括了算法执行一次更新所必须经历的五个步骤(时间线):状态(State)、动作(Action)、奖励(Reward)、下一状态(State') 和下一动作(Action')。

二、 核心要素

       在马尔可夫决策过程 (MDP) 中,SARSA 的运行同样依赖于以下核心要素,但在处理流程上有着严格的“接力”要求:

  • 状态(S):智能体当前所处的环境情况。

  • 动作(A):智能体在状态S下可以选择的动作(例如:网格游戏中的上下左右)。

  • 奖励(R):执行动作后,环境反馈的即时评分(掉坑扣分,到终点得分)。

  • 折扣因子():介于 0 到 1 之间。决定了智能体是“短视”的(接近 0),还是近 1,重视长期累积奖励。

  • 动作价值函数(Q(S, A)):代表在状态S下执行动作A,预期能拿到的总奖励的折现和。

  • 下一状态与下一动作():这是 SARSA 的灵魂要素。智能体不仅要知道自己到了哪,还必须在更新前就确切决定好下一步要干什么。(通俗的对比Q-Learning就是不是取该状态下采取可以获得最大Q值的动作,而是按当前策略选一个动作)

三、 贝尔曼期望方程与 TD 更新

      此部分对于初学者可以多看几遍,理解与Q-Learning的区别,并从中理解on-policyoff-policy,绝大部分公式推导是一致的。

3.1 回报(Return)

        智能体的终极目标是未来累积奖励最大化。我们定义从时间 t 开始的总回报 Gt 为:

可以将其写成递归的形式,这是后续所有公式的基石:

3.2 价值函数(Value Function)

        为了评估某个状态或动作的好坏,我们依然使用那两个核心函数:

3.2.1 状态价值函数 (State-Value Function)

        在策略的指导下,从状态 s 出发,未来能获得的期望回报:

3.2.2 动作价值函数 (Action-Value Function)

        它表示在状态 s 下,先执行动作 a,然后后续所有步骤都遵循策略,所能获得的期望回报:

【核心差异点】Q-Learning 的目标是寻找绝对的“最优策略”,因此它推导出了贝尔曼最优方程(含有最大化操作)。但 SARSA 算法由于是同轨策略 (On-Policy),它评估的就是智能体当前正在使用的策略 。因此,期望被保留了下来,我们得到的是贝尔曼期望方程 (Bellman Expectation Equation)

        直观理解:当前状态-动作的评估价值,等于真实的即时奖励,加上按照当前策略实际走出的下一步动作的未来折现价值。

3.3 时序差分 (TD Learning)

       观察贝尔曼期望方程,它包含一个期望。在模型未知 (Model-Free) 的环境中,我们无法计算真实的转移概率,所以依然使用单次经验去“采样”逼近

智能体在环境中实际走一步,观察到真实的下一状态 和真实奖励 此时,智能体必须立刻根据当前的 -贪心策略,抽出下一个动作 。我们用这组实际发生的数据来代替期望:

  • 旧的认知:

  • TD Target: (注意:这里没有 max!)

  • TD Error: 

我们使用学习率  将这个偏差更新到旧记忆中,这就得到了 SARSA 的最终更新公式:

四、 On-Policy 与 Off-Policy 的深刻直觉

很多初学者容易搞混这两种策略的区别,其实它们反映了智能体对“犯错”的不同态度。

  • Q-Learning(Off-Policy/离线策略):行为策略和目标策略是分离的。它在现实中虽然会因为  探索而随机瞎走,但在大脑里更新 Q 表时,永远用 max 假设自己下一步绝对不会走错。这种极度乐观导致它在面对悬崖时,敢于贴着悬崖边走最短路径。

  • SARSA(On-Policy/同轨策略):行为策略和目标策略是统一的。它深知自己的策略存在  的随机瞎走概率,在算 TD Target 时的  真的可能会抽中掉下悬崖的烂招。因此,SARSA 会把这种犯错的风险实打实地计算进 Q 值里,从而学到一条极其安全的绕远路线。

五、示例代码

本次代码与上一章【强化学习笔记】1.Q_Learning算法及示例代码基本一致,仅做了小部分修改

import numpy as np
import gymnasium as gym

class QLearningAgent:
    def __init__(self, state_size, action_size=4):
        """初始化:设置状态空间大小和动作空间大小"""
        self.state_size = state_size
        self.action_size = action_size
        self.Q_table = np.zeros((self.state_size, self.action_size))

    def choose_action(self, state, epsilon):
        """选取动作"""
        if np.random.rand() < epsilon:
            return np.random.randint(self.action_size)
        else:
            get_max_Q = np.max(self.Q_table[state])
            actions = np.where(self.Q_table[state] == get_max_Q)[0]
            return np.random.choice(actions)
        
    def update(self, state, action, reward, next_state, next_action, done, alpha, gamma):
        """更新Q表"""
        if done == True:
            self.Q_table[state, action] += alpha * (reward - self.Q_table[state, action])
        else:
            self.Q_table[state, action] += alpha * (reward + gamma * self.Q_table[next_state, next_action] - self.Q_table[state, action])
        return self.Q_table[state, action]

# 1. 初始化环境 
# is_slippery=False 冰面不滑
env = gym.make("FrozenLake-v1", is_slippery=False, render_mode="human")
state_size = env.observation_space.n
action_size = env.action_space.n

# 2. 创建智能体
agent = QLearningAgent(state_size, action_size)

# 3. 设置训练超参数
total_episodes = 2000
alpha = 0.8           # 学习率
gamma = 0.95          # 折扣因子
epsilon = 1.0         # 初始探索率
epsilon_min = 0.01    # 最小探索率
epsilon_decay = 0.995 # 指数衰减率

# 记录奖励
rewards_per_episode = []

print("开始训练...")

# 4. 开始大循环
for episode in range(total_episodes):
    # 重置环境
    state, info = env.reset()
    done = False
    total_reward = 0
    # 选取初始动作
    action = agent.choose_action(state, epsilon)
    
    while not done:
        # 执行动作,获取新版 Gym 的 5 个返回值
        next_state, reward, terminated, truncated, info = env.step(action)
        
        # 合并结束信号
        done = terminated or truncated
        
        # 触发记忆更新
        next_action = agent.choose_action(next_state, epsilon)
        agent.update(state, action, reward, next_state, next_action, done, alpha, gamma)
        
        # 极其关键的:状态推进
        state = next_state
        action = next_action
        total_reward += reward
        
    # 单回合结束,记录奖励
    rewards_per_episode.append(total_reward)
    
    # 核心进阶:Epsilon 指数衰减
    epsilon = max(epsilon_min, epsilon * epsilon_decay)
    
    # 每 500 回合打印一次进度报告
    if (episode + 1) % 500 == 0:
        recent_win_rate = np.mean(rewards_per_episode[-100:])
        print(f"--- 回合: {episode + 1}/{total_episodes} ---")
        print(f"当前 Epsilon: {epsilon:.3f}")
        print(f"最近 100 局胜率: {recent_win_rate * 100:.1f}%")

print("\n训练彻底完成")
print("\n智能体脑海中的 Q-Table (4个动作方向的价值评估):")
print(np.round(agent.Q_table, 3))

env.close()

可视化结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值