Q-Learning
用行为数据学习贪心目标策略的动作价值,是经典 off-policy TD 控制。
学习目标
- 定义Q-Learning并复述输入输出。
- 从公式计算一个最小数值例子。
- 说明它与相邻算法的区别、失败模式和适用场景。
为什么重要
Q-learning 把 Bellman 最优关系变成可从单条转移样本执行的更新。它展示了智能体怎样一边探索、一边改进对各个动作长期收益的估计。
理解它还需要分清行为策略与目标策略:实际采集数据时可以随机探索,而更新目标使用下一状态的贪心动作价值,这正是 off-policy 的关键。
学习前需要掌握
背景与问题
如果不知道完整转移概率,仍可以记录一次交互中的状态、动作、即时奖励、下一状态与是否真正终止。Q-learning 使用这样的样本,让当前动作价值向一个一步目标靠近。
当前学到的价值会影响下一次动作选择,动作选择又决定之后能获得哪些数据,因此探索覆盖很重要。只反复执行目前看起来最好的动作,可能永远无法发现其他动作的收益。
概念定义
表格型 Q-learning 为离散状态和动作保存 Q(s,a)。对一个非终止转移,一步目标是即时奖励加上 gamma 乘下一状态最大的 Q 值,再按学习率 alpha 将当前 Q 向该目标移动。
这个目标不是本次实际执行到终点的完整回报,而是利用当前下一价值估计的 bootstrap 目标。真正终止时,不再加入下一状态价值。
直观理解
可以把 Q 表看成一本不断修正的行动账本。经历一次转移后,不是立即把原估计全部抹掉,而是按 alpha 接受一部分新证据。
例如当前行为策略在下一步仍可能探索一个较差动作,但 Q-learning 的更新目标会使用下一状态当前看起来最好的动作。它学习的目标策略与采集数据的行为策略可以不同。
核心原理
通常使用 epsilon-greedy 收集数据:大多数时候选择当前 Q 最大的动作,小部分时候随机探索。epsilon 决定探索方式,alpha 决定更新幅度,gamma 决定未来奖励权重,三者不是同一类参数。
Q-learning 目标中的 max 不依赖下一步实际抽中的探索动作,因此属于 off-policy TD 控制。SARSA 则使用行为策略实际选择的下一动作价值,在同一个样本上下文中可能得到不同更新。
表格型方法的经典收敛结论需要状态动作得到充分访问、合适的学习率序列和相应环境条件。一个固定学习率、有限回合的小演示只说明更新过程,不能当成一般收敛证明。
真正环境终止时 bootstrap 为零;如果只是外部时间上限截断,而任务仍会继续,则不能未经判断就把下一价值清零。实际接口中的 terminated 与 truncated 应按照任务语义处理。
数学表达
Q-Learning 更新
off-policy TD 控制更新。
变量含义
α学习率。γ折扣因子。εepsilon-greedy 探索概率。Q(s,a)从状态 s 先做 a 的长期回报估计。
计算步骤
- 1Q-learning 使用最大下一价值 2,目标为 1+0.9×2=2.8。
- 2TD 误差为 2.8−0.5=2.3,新值为 0.5+0.1×2.3=0.73。
- 3SARSA 使用实际选中的下一动作价值 1.5,目标为 1+0.9×1.5=2.35,新值为 0.685。
- 4另构造一个同样奖励为 1、但真正终止的转移,目标应为 1,更新后为 0.55。
代码对应位置
示例 1表格型 Q-learning:保留探索的确定性走廊:从状态 0 向终点 5 移动;展示有限训练后贪心动作与第一个状态的 Q 值。示例 2单次更新:贪心目标、实际下一动作与终止:精确复现上面的三个更新结果,区分算法目标与终止处理。
变量解释
| 变量 | 含义 |
|---|---|
α | 学习率。 |
γ | 折扣因子。 |
ε | epsilon-greedy 探索概率。 |
Q(s,a) | 从状态 s 先做 a 的长期回报估计。 |
完整数值示例
同一组估计,Q-learning 与 SARSA 怎样更新
已知条件
- 当前 Q(s,a)=0.5,观察到即时奖励 r=1;先考虑一个非终止转移。
- 下一状态有两个动作,当前 Q 分别为 2 和 1.5;行为策略这次选择了值为 1.5 的动作。
- 学习率 alpha=0.1,折扣因子 gamma=0.9。
计算步骤
- Q-learning 使用最大下一价值 2,目标为 1+0.9×2=2.8。
- TD 误差为 2.8−0.5=2.3,新值为 0.5+0.1×2.3=0.73。
- SARSA 使用实际选中的下一动作价值 1.5,目标为 1+0.9×1.5=2.35,新值为 0.685。
- 另构造一个同样奖励为 1、但真正终止的转移,目标应为 1,更新后为 0.55。
计算结果
非终止例中 Q-learning 更新到 0.73,SARSA 更新到 0.685;终止例更新到 0.55。
处理前后对比
- 0.73 与 0.685 的差异来自目标采用哪个下一动作价值,不是使用了不同学习率。
- 当 alpha=1 时直接替换为本次目标,但这并不意味着噪声环境中总应使用 alpha=1。
- 下一状态数值即使很大,也不能用于真正终止后的 bootstrap;外部截断则需另行判断。
计算与实现步骤
- 初始化 Q 表与探索、学习率、折扣设置,确认合法动作和终止规则。
- 根据当前状态按 epsilon-greedy 等行为策略选择动作。
- 执行动作,记录即时奖励、下一状态及终止/截断信息。
- 非终止时取下一状态最大 Q;真正终止时取零,计算一步目标与 TD 误差。
- 按 alpha 更新当前 Q(s,a),再推进到下一状态。
- 在有限训练后,用明确的评估策略检查轨迹与回报;不要把训练中的探索行为和最终贪心评估混为一谈。
代码实现
示例 1
表格型 Q-learning:保留探索的确定性走廊
example_01.py用途:从状态 0 向终点 5 移动;展示有限训练后贪心动作与第一个状态的 Q 值。
import numpy as np
rng = np.random.default_rng(7)
Q = np.zeros((6, 2)) # 动作 0=左,1=右
alpha, gamma, epsilon = 0.2, 0.95, 0.2
def step(state, action):
next_state = np.clip(state + (-1 if action == 0 else 1), 0, 5)
reward = 1.0 if next_state == 5 else -0.01
done = next_state == 5
return next_state, reward, done
for episode in range(300):
state = 0
for _ in range(30):
if rng.random() < epsilon:
action = rng.integers(2)
else:
action = int(np.argmax(Q[state]))
next_state, reward, done = step(state, action)
bootstrap = 0.0 if done else np.max(Q[next_state])
td_target = reward + gamma * bootstrap
Q[state, action] += alpha * (td_target - Q[state, action])
state = next_state
if done:
break
print('policy:', np.argmax(Q[:-1], axis=1))
print('Q[0]:', np.round(Q[0], 3))代码解析
解析始终位于完整代码下方,并按实际代码段逐项对应。
输入数据与任务
从状态 0 向终点 5 移动;展示有限训练后贪心动作与第一个状态的 Q 值。
alpha- 当前学习率,控制每次参数更新的步长。
Step 1 · 1–1 行
导入当前步骤需要的数值计算、预处理、模型或评价工具。依赖集中写在代码开头,便于复现。
import numpy as npStep 2 · 3–5 行
固定 rng=7、300 回合和每回合最多 30 步,使用 alpha=0.2、gamma=0.95、epsilon=0.2;这些设置与上面的单次手算例不同。
rng = np.random.default_rng(7)
Q = np.zeros((6, 2)) # 动作 0=左,1=右
alpha, gamma, epsilon = 0.2, 0.95, 0.2Step 3 · 7–11 行
输出只列出 5 个非终止状态的贪心动作,终止状态的 argmax 没有行动含义,因此不输出。
def step(state, action):
next_state = np.clip(state + (-1 if action == 0 else 1), 0, 5)
reward = 1.0 if next_state == 5 else -0.01
done = next_state == 5
return next_state, reward, doneStep 4 · 13–26 行
按学习率和梯度更新参数。步长过小会缓慢,过大会越过最低点并震荡或发散。
for episode in range(300):
state = 0
for _ in range(30):
if rng.random() < epsilon:
action = rng.integers(2)
else:
action = int(np.argmax(Q[state]))
next_state, reward, done = step(state, action)
bootstrap = 0.0 if done else np.max(Q[next_state])
td_target = reward + gamma * bootstrap
Q[state, action] += alpha * (td_target - Q[state, action])
state = next_state
if done:
breakStep 5 · 28–29 行
输出中间参数、形状或最终指标,用于核对代码是否符合预期。
print('policy:', np.argmax(Q[:-1], axis=1))
print('Q[0]:', np.round(Q[0], 3))预期输出或运行结果
policy: [1 1 1 1 1] Q[0]: [0.727 0.777]
常见错误 · 4 条
- 把下一次实际探索动作的 Q 值代入 Q-learning 目标,却仍把实现叫作标准 Q-learning。
- 探索不足导致部分状态动作从未被充分访问,却把最终表格当成已经收敛。
- 真正终止后仍加下一价值,或把所有时间截断都不加区分地当成任务终止。
- 只报告一次幸运轨迹或最高训练回报,不说明随机种子、探索设置和评估策略。
示例 2
单次更新:贪心目标、实际下一动作与终止
example_02.py用途:精确复现上面的三个更新结果,区分算法目标与终止处理。
current, reward, alpha, gamma = 0.5, 1.0, 0.1, 0.9
next_values = [2.0, 1.5]
actual_next_action = 1
q_target = reward + gamma * max(next_values)
sarsa_target = reward + gamma * next_values[actual_next_action]
terminal_target = reward
for name, target in [("q_learning", q_target),
("sarsa", sarsa_target),
("terminal", terminal_target)]:
updated = current + alpha * (target - current)
print(f"{name}={updated:.4f}")代码解析
解析始终位于完整代码下方,并按实际代码段逐项对应。
输入数据与任务
精确复现上面的三个更新结果,区分算法目标与终止处理。
alpha- 当前学习率,控制每次参数更新的步长。
Step 1 · 1–11 行
输出中间参数、形状或最终指标,用于核对代码是否符合预期。
current, reward, alpha, gamma = 0.5, 1.0, 0.1, 0.9
next_values = [2.0, 1.5]
actual_next_action = 1
q_target = reward + gamma * max(next_values)
sarsa_target = reward + gamma * next_values[actual_next_action]
terminal_target = reward
for name, target in [("q_learning", q_target),
("sarsa", sarsa_target),
("terminal", terminal_target)]:
updated = current + alpha * (target - current)
print(f"{name}={updated:.4f}")预期输出或运行结果
q_learning=0.7300 sarsa=0.6850 terminal=0.5500
常见错误 · 4 条
- 把下一次实际探索动作的 Q 值代入 Q-learning 目标,却仍把实现叫作标准 Q-learning。
- 探索不足导致部分状态动作从未被充分访问,却把最终表格当成已经收敛。
- 真正终止后仍加下一价值,或把所有时间截断都不加区分地当成任务终止。
- 只报告一次幸运轨迹或最高训练回报,不说明随机种子、探索设置和评估策略。
实际应用
- 序贯决策
- 控制与资源分配
常见错误
- 把下一次实际探索动作的 Q 值代入 Q-learning 目标,却仍把实现叫作标准 Q-learning。
- 探索不足导致部分状态动作从未被充分访问,却把最终表格当成已经收敛。
- 真正终止后仍加下一价值,或把所有时间截断都不加区分地当成任务终止。
- 只报告一次幸运轨迹或最高训练回报,不说明随机种子、探索设置和评估策略。
扩展内容说明
未找到可直接映射的本地强化学习文档;中文直觉、数值例子、代码和交互演示属于扩展解释,算法定义与公式以所列教材或原论文为依据。
算法属性与数据边界
失败模式、风险与性能
失败模式
- 探索不足
- 目标漂移
- 函数近似不稳定
风险
- 奖励函数与真实目标不一致会诱发奖励黑客。
- 部署策略的行动权限必须由环境和应用层约束。
性能考虑
- 样本效率、墙钟时间和显存占用需要分别报告。
- 应使用多个随机种子、置信区间和固定评测策略。
常见问题
为什么行为在随机探索,Q-learning 仍是 off-policy?
因为数据可以由 epsilon-greedy 行为策略产生,而更新目标使用下一状态的贪心最大 Q 值。目标策略与行为策略可以不同;off-policy 并不意味着可以忽视数据覆盖与学习条件。
固定种子的小网格训练能证明算法一定收敛吗?
不能。下面演示只核对一个确定性小环境中的更新、探索与策略提取过程;理论收敛还需要相应条件,复杂函数近似环境也可能出现不同的稳定性问题。
推荐学习资料
Hugging Face Deep Reinforcement Learning Course
从 Q-Learning、DQN、Policy Gradient 和 Actor-Critic 逐步进入 PPO 与多智能体。
Hugging Face · Hugging Face