
第十九章 强化学习入门
让智能体(Agent)在环境中通过试错学习,找到能获得最大累积奖励的行为策略。
概念 | 定义 | 迷宫例子 |
|---|---|---|
智能体(Agent) | 学习和决策的主体 | 小老鼠 |
环境(Environment) | Agent 所处的世界 | 迷宫本身 |
状态(State, s) | 环境在某一时刻的描述 | 老鼠当前所在格子 |
动作(Action, a) | Agent 可执行的操作 | 上、下、左、右移动 |
奖励(Reward, r) | 环境对动作的即时反馈 | 吃到奶酪 +10,撞墙 -1 |
策略(Policy, π) | Agent 的行为规则 | “看到奶酪就去吃” |
graph LR
A[Agent] -->|选择动作 a| B(Environment)
B -->|返回 新状态 s' 和 奖励 r| A
A -->|更新策略| A💡 关键区别:监督学习:有“标准答案”(标签) 强化学习:只有“模糊反馈”(奖励),且奖励可能延迟!
概念 | 说明 |
|---|---|
回报(Return) | 未来奖励的总和:$Gt = r{t+1} + \gamma r{t+2} + \gamma^2 r{t+3} + \dots$ |
折扣因子(γ) | 0~1之间,表示对未来奖励的重视程度(γ=0 → 只看眼前;γ=1 → 平等看待所有未来) |
价值函数(Value Function) | $V(s)$:从状态 s 开始,按策略 π 能获得的期望回报 |
Q函数(Action-Value Function) | $Q(s,a)$:在状态 s 执行动作 a 后,按策略 π 能获得的期望回报 |
✅ 目标:找到最优策略 $\pi^$,使得 $Q^(s,a)$ 最大!
特性 | Q-Learning | SARSA |
|---|---|---|
策略类型 | Off-policy | On-policy |
更新目标 | $\max_{a'} Q(s',a')$ | $Q(s',a')$(实际选的动作) |
探索性 | 更激进(追求最优) | 更保守(跟随当前策略) |
适用场景 | 需要最优解 | 安全关键场景(如机器人) |
领域 | 应用 | 说明 |
|---|---|---|
游戏AI | AlphaGo、Atari游戏 | 状态=屏幕像素,动作=按键,奖励=得分 |
机器人控制 | 机械臂抓取、行走 | 状态=传感器数据,动作=电机指令,奖励=任务完成度 |
推荐系统 | 个性化推荐 | 状态=用户历史,动作=推荐物品,奖励=点击/购买 |
自动驾驶 | 路径规划 | 状态=摄像头+雷达,动作=方向盘/油门,奖励=安全+效率 |
资源调度 | 云计算、网络路由 | 状态=负载情况,动作=分配策略,奖励=吞吐量 |
💡 共同特点:序列决策问题 奖励信号稀疏或延迟 环境动态变化
强化学习的数学基础!
“未来只与现在有关,与过去无关” 即:$P(s{t+1}|s_t, a_t) = P(s{t+1}|st, a_t, s{t-1}, a_{t-1}, \dots)$
import numpy as np
import random
from IPython.display import clear_output
import time
class GridWorld:
def __init__(self):
self.size = 4
self.start = (0, 0)
self.goal = (3, 3)
self.state = self.start
self.actions = ['up', 'down', 'left', 'right']
self.action_map = {
'up': (-1, 0),
'down': (1, 0),
'left': (0, -1),
'right': (0, 1)
}
def reset(self):
self.state = self.start
return self.state
def step(self, action):
# 计算新位置
dr, dc = self.action_map[action]
new_r = self.state[0] + dr
new_c = self.state[1] + dc
# 边界检查
if new_r < 0 or new_r >= self.size or new_c < 0 or new_c >= self.size:
# 撞墙,留在原地
new_state = self.state
reward = -1
else:
new_state = (new_r, new_c)
if new_state == self.goal:
reward = 10 # 到达终点
else:
reward = -1 # 普通步
self.state = new_state
done = (new_state == self.goal)
return new_state, reward, done
def render(self):
grid = np.full((self.size, self.size), '.')
grid[self.goal] = 'G'
grid[self.state] = 'A'
print(grid)def q_learning(env, episodes=500, alpha=0.1, gamma=0.99, epsilon=0.1):
# 初始化Q表:Q[state][action] = value
Q = {}
for r in range(env.size):
for c in range(env.size):
Q[(r, c)] = {a: 0.0 for a in env.actions}
rewards = []
for episode in range(episodes):
state = env.reset()
total_reward = 0
done = False
while not done:
# ε-贪婪策略:以ε概率随机探索,否则选择最优动作
if random.random() < epsilon:
action = random.choice(env.actions)
else:
action = max(Q[state], key=Q[state].get)
next_state, reward, done = env.step(action)
total_reward += reward
# Q-Learning 更新
best_next_action = max(Q[next_state], key=Q[next_state].get)
td_target = reward + gamma * Q[next_state][best_next_action]
td_error = td_target - Q[state][action]
Q[state][action] += alpha * td_error
state = next_state
rewards.append(total_reward)
# 每100轮显示一次
if (episode + 1) % 100 == 0:
avg_reward = np.mean(rewards[-100:])
print(f"Episode {episode+1}, Average Reward: {avg_reward:.2f}")
return Q, rewardsdef sarsa(env, episodes=500, alpha=0.1, gamma=0.99, epsilon=0.1):
Q = {}
for r in range(env.size):
for c in range(env.size):
Q[(r, c)] = {a: 0.0 for a in env.actions}
rewards = []
for episode in range(episodes):
state = env.reset()
# 选择初始动作
if random.random() < epsilon:
action = random.choice(env.actions)
else:
action = max(Q[state], key=Q[state].get)
total_reward = 0
done = False
while not done:
next_state, reward, done = env.step(action)
total_reward += reward
# 选择下一个动作(用于SARSA更新)
if random.random() < epsilon:
next_action = random.choice(env.actions)
else:
next_action = max(Q[next_state], key=Q[next_state].get)
# SARSA 更新
td_target = reward + gamma * Q[next_state][next_action]
td_error = td_target - Q[state][action]
Q[state][action] += alpha * td_error
state = next_state
action = next_action
rewards.append(total_reward)
if (episode + 1) % 100 == 0:
avg_reward = np.mean(rewards[-100:])
print(f"SARSA Episode {episode+1}, Average Reward: {avg_reward:.2f}")
return Q, rewards# 创建环境
env = GridWorld()
# 训练 Q-Learning
print("Training Q-Learning...")
Q_q, rewards_q = q_learning(env, episodes=500)
# 训练 SARSA
print("\nTraining SARSA...")
Q_s, rewards_s = sarsa(env, episodes=500)
# 可视化学习曲线
import matplotlib.pyplot as plt
plt.plot(np.convolve(rewards_q, np.ones(50)/50, mode='valid'), label='Q-Learning')
plt.plot(np.convolve(rewards_s, np.ones(50)/50, mode='valid'), label='SARSA')
plt.xlabel('Episode')
plt.ylabel('Average Reward (50-episode window)')
plt.legend()
plt.title('Q-Learning vs SARSA Learning Curves')
plt.show()
# 测试学到的策略
def test_policy(Q, env, max_steps=20):
state = env.reset()
env.render()
time.sleep(1)
for step in range(max_steps):
action = max(Q[state], key=Q[state].get)
state, reward, done = env.step(action)
clear_output(wait=True)
env.render()
time.sleep(0.5)
if done:
print("Reached goal!")
break
else:
print("Max steps reached.")
print("\nTesting Q-Learning policy:")
test_policy(Q_q, env)📊 典型结果:Q-Learning:更快收敛到最优路径(如 6 步到达) SARSA:路径稍长但更稳定(避免靠近危险区域)
概念 | 关键点 |
|---|---|
核心要素 | Agent, Environment, State, Action, Reward, Policy |
学习目标 | 最大化累积折扣奖励 |
Q-Learning | Off-policy,使用 $\max Q$,激进探索 |
SARSA | On-policy,使用实际 $Q$,保守稳定 |
ε-贪婪 | 平衡探索(exploration)与利用(exploitation) |
应用场景 | 游戏、机器人、推荐、控制等序列决策问题 |
gym / gymnasium:标准环境stable-baselines3:PyTorch 实现Ray RLlib:分布式强化学习🌟 建议: 强化学习不是万能的——当有大量标注数据时,监督学习往往更简单有效。 但在“没有老师、只能试错”的场景中,RL 是唯一选择!
公众号:咚咚王
《Python编程:从入门到实践》
《利用Python进行数据分析》
《算法导论中文第三版》
《概率论与数理统计(第四版) (盛骤) 》
《程序员的数学》
《线性代数应该这样学第3版》
《微积分和数学分析引论》
《(西瓜书)周志华-机器学习》
《TensorFlow机器学习实战指南》
《Sklearn与TensorFlow机器学习实用指南》
《模式识别(第四版)》
《深度学习 deep learning》伊恩·古德费洛著 花书
《Python深度学习第二版(中文版)【纯文本】 (登封大数据 (Francois Choliet)) (Z-Library)》
《深入浅出神经网络与深度学习+(迈克尔·尼尔森(Michael+Nielsen)》
《自然语言处理综论 第2版》
《Natural-Language-Processing-with-PyTorch》
《计算机视觉-算法与应用(中文版)》
《Learning OpenCV 4》
《AIGC:智能创作时代》杜雨+&+张孜铭
《AIGC原理与实践:零基础学大语言模型、扩散模型和多模态模型》
《从零构建大语言模型(中文版)》
《实战AI大模型》
《AI 3.0》
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。