什么是强化学习?
强化学习(Reinforcement Learning, RL)是机器学习的一个分支,通过智能体(Agent)与环境(Environment)的交互来学习最优策略。
核心要素:
- 智能体(Agent):执行动作的决策者
- 环境(Environment):智能体交互的外部世界
- 状态(State):环境的当前情况
- 动作(Action):智能体可以执行的操作
- 奖励(Reward):环境对动作的反馈
- 策略(Policy):从状态到动作的映射
强化学习,观止矣
还在为学习强化学习烦恼?一个网站带你从0到1学会RL!
了解强化学习的核心概念和基本原理
强化学习(Reinforcement Learning, RL)是机器学习的一个分支,通过智能体(Agent)与环境(Environment)的交互来学习最优策略。
理解强化学习中的状态和动作
状态(State)是环境在某个时刻的完整描述,包含了智能体做出决策所需的所有信息。状态是强化学习中的核心概念之一。
动作(Action)是智能体在某个状态下可以执行的操作。智能体通过选择动作来影响环境,从而改变状态并获得奖励。
状态-动作对(s, a)表示在状态s下执行动作a。这是强化学习中的基本单位,很多算法(如Q-Learning)都是基于状态-动作对进行学习的。
理解状态如何从一个转换到另一个
状态转移(State Transition)是指智能体执行动作后,环境从当前状态转换到下一个状态的过程。这是强化学习中的核心机制。
状态转移可以用以下公式表示:
st+1 ~ P(·|st, at)
这表示在状态st下执行动作at后,下一个状态st+1遵循概率分布P(·|st, at)。
状态转移概率P(s'|s, a)表示在状态s下执行动作a后,转移到状态s'的概率:
P(s'|s, a) = P(St+1 = s' | St = s, At = a)
状态转移满足马尔可夫性质,即下一个状态只依赖于当前状态和动作,而不依赖于历史状态:
P(st+1|st, at, st-1, at-1, ...) = P(st+1|st, at)
在代码中,状态转移通过环境的step函数实现:
import gymnasium as gym
env = gym.make('FrozenLake-v1')
# 初始状态
state, info = env.reset()
print(f"初始状态: {state}")
# 执行动作,状态转移
action = 1 # 向下
next_state, reward, terminated, truncated, info = env.step(action)
print(f"执行动作: {action}")
print(f"新状态: {next_state}")
print(f"奖励: {reward}")
print(f"是否结束: {terminated or truncated}")
状态转移可以用有向图表示,节点是状态,边是动作和转移概率。这对于理解环境的结构很有帮助。
策略定义了智能体如何根据状态选择动作
策略(Policy)是智能体的决策规则,定义了在给定状态下应该选择什么动作。策略是强化学习的核心,智能体的目标就是学习最优策略。
策略通常用π表示,可以是确定性的或随机性的:
最优策略π*是能够最大化期望累积奖励的策略:
π* = argmaxπ Eπ[∑t=0∞ γtRt+1]
强化学习算法可以分为两类:
import numpy as np
# 确定性策略示例
def deterministic_policy(state, Q_table):
"""根据Q表选择最优动作"""
return np.argmax(Q_table[state, :])
# ε-贪婪策略示例
def epsilon_greedy_policy(state, Q_table, epsilon, action_space):
"""ε-贪婪策略"""
if np.random.random() < epsilon:
return action_space.sample() # 探索
else:
return np.argmax(Q_table[state, :]) # 利用
# 随机性策略示例(softmax)
def softmax_policy(state, Q_table, temperature=1.0):
"""基于softmax的随机性策略"""
q_values = Q_table[state, :]
exp_q = np.exp(q_values / temperature)
probabilities = exp_q / np.sum(exp_q)
return np.random.choice(len(q_values), p=probabilities)
奖励是环境对智能体动作的反馈信号
奖励(Reward)是环境在智能体执行动作后给出的标量反馈信号,表示该动作的好坏。奖励是强化学习中的学习信号,智能体的目标就是最大化累积奖励。
奖励函数R(s, a, s')定义了在状态s下执行动作a转移到状态s'时获得的奖励:
R(s, a, s') = E[Rt+1 | St = s, At = a, St+1 = s']
奖励塑形是通过添加辅助奖励来帮助智能体学习的技术:
智能体关心的是累积奖励(回报),而不是单步奖励:
Gt = Rt+1 + γRt+2 + γ²Rt+3 + ... = ∑k=0∞ γkRt+k+1
其中γ是折扣因子,用于平衡即时奖励和未来奖励。
理解强化学习中的轨迹、回报和回合
回合(Episode)是智能体与环境的一次完整交互过程,从初始状态开始,到终止状态结束。一个回合包含多个时间步的交互。
轨迹(Trajectory)是一个回合中状态、动作、奖励的序列,记录了智能体与环境交互的完整过程。
一个轨迹可以表示为:
τ = (s0, a0, r1, s1, a1, r2, s2, ..., sT-1, aT-1, rT, sT)
其中T是回合的长度,sT是终止状态。
在策略π下,轨迹τ的概率为:
P(τ|π) = P(s0) ∏t=0T-1 π(at|st) P(st+1|st, at)
import gymnasium as gym
env = gym.make('FrozenLake-v1')
trajectory = []
state, info = env.reset()
trajectory.append(('state', state))
while True:
action = env.action_space.sample()
next_state, reward, terminated, truncated, info = env.step(action)
trajectory.append(('action', action))
trajectory.append(('reward', reward))
trajectory.append(('state', next_state))
if terminated or truncated:
break
print("轨迹:", trajectory)
print("轨迹长度:", len(trajectory))
回报(Return)是一个回合中从某个时间步开始的累积奖励,是智能体真正关心的目标。
从时间步t开始的总回报为:
Gt = Rt+1 + Rt+2 + Rt+3 + ... + RT
这是未折扣的回报,适用于有限回合的情况。
对于无限回合或需要平衡即时和未来奖励的情况,使用折扣回报:
Gt = Rt+1 + γRt+2 + γ²Rt+3 + ... = ∑k=0∞ γkRt+k+1
其中γ ∈ [0, 1]是折扣因子:
回报可以通过前向计算或后向计算:
import numpy as np
# 假设一个回合的奖励序列
rewards = [0, 0, 0, 0, 1] # 最后一步到达目标获得奖励1
gamma = 0.9
# 计算折扣回报(从后向前)
returns = []
G = 0
for reward in reversed(rewards):
G = reward + gamma * G
returns.insert(0, G)
print("奖励序列:", rewards)
print("回报序列:", returns)
# 输出: [0.6561, 0.729, 0.81, 0.9, 1.0]
智能体的目标是最大化期望回报:
J(π) = Eτ~π[G0] = Eτ~π[∑t=0T γtRt+1]
这是策略π的价值,强化学习的目标就是找到最大化J(π)的策略π*。
强化学习的数学基础
MDP是强化学习的数学框架,用于描述在不确定环境中进行决策的问题。
V(s) = E[∑t=0∞ γtRt+1 | S0 = s]
理解如何评估状态和动作的价值
价值函数用于评估状态或动作的好坏,策略定义了智能体的行为方式。
Q*(s,a) = maxπ Qπ(s,a)
无模型的时序差分学习算法
Q-Learning是一种无模型的强化学习算法,由Watkins在1989年提出,属于时序差分学习(Temporal Difference Learning)方法。它是强化学习领域最经典和广泛应用的算法之一。
Q-Learning通过学习动作价值函数Q(s,a)来找到最优策略。Q(s,a)表示在状态s下执行动作a后,遵循最优策略所能获得的期望累积奖励。算法的核心思想是:通过不断更新Q值,逐步逼近最优Q函数Q*(s,a)。
Q-Learning使用贝尔曼最优方程来更新Q值:
Q(s,a) ← Q(s,a) + α[r + γ maxa' Q(s',a') - Q(s,a)]
其中:
Q-Learning使用ε-贪婪策略来平衡探索和利用:
import gymnasium as gym
import numpy as np
# 创建环境
env = gym.make('FrozenLake-v1', is_slippery=True)
# Q-Learning参数
learning_rate = 0.1
discount_factor = 0.95
epsilon = 1.0
epsilon_decay = 0.995
epsilon_min = 0.01
episodes = 2000
# 初始化Q表
Q = np.zeros([env.observation_space.n, env.action_space.n])
# 训练
for episode in range(episodes):
state, info = env.reset()
done = False
while not done:
# ε-贪婪策略
if np.random.random() < epsilon:
action = env.action_space.sample()
else:
action = np.argmax(Q[state, :])
# 执行动作
next_state, reward, terminated, truncated, info = env.step(action)
done = terminated or truncated
# Q-Learning更新
Q[state, action] = Q[state, action] + learning_rate * (
reward + discount_factor * np.max(Q[next_state, :]) - Q[state, action]
)
state = next_state
epsilon = max(epsilon_min, epsilon * epsilon_decay)
# 测试训练好的策略
state, info = env.reset()
for step in range(100):
action = np.argmax(Q[state, :])
state, reward, terminated, truncated, info = env.step(action)
if terminated or truncated:
break
env.close()
在线策略的时序差分学习算法
SARSA(State-Action-Reward-State-Action)是一种在线策略(On-policy)的时序差分学习算法,由Rummery和Niranjan在1994年提出。它的名字来源于更新过程中使用的五元组:(s, a, r, s', a')。
SARSA与Q-Learning的主要区别在于:Q-Learning使用下一个状态的最大Q值来更新,而SARSA使用下一个状态实际执行的动作的Q值来更新。这使得SARSA学习的是当前遵循的策略,而不是最优策略。
SARSA的更新公式为:
Q(s,a) ← Q(s,a) + α[r + γ Q(s',a') - Q(s,a)]
其中a'是在状态s'下实际执行的动作(根据当前策略选择),而不是最优动作。
| 特性 | Q-Learning | SARSA |
|---|---|---|
| 策略类型 | 离线策略(Off-policy) | 在线策略(On-policy) |
| 更新方式 | 使用max Q(s',a') | 使用Q(s',a') |
| 学习目标 | 最优策略 | 当前策略 |
| 探索性 | 更激进 | 更保守 |
在Cliff Walking问题中,如果智能体掉下悬崖会得到很大的负奖励。Q-Learning可能会学习到沿着悬崖边缘走的最优路径(因为它在更新时假设会选择最优动作),但在实际执行时可能因为探索而掉下悬崖。而SARSA会学习到更安全的路径,因为它考虑实际执行的动作,会避开危险的边缘。
import gymnasium as gym
import numpy as np
env = gym.make('FrozenLake-v1', is_slippery=True)
learning_rate = 0.1
discount_factor = 0.95
epsilon = 1.0
epsilon_decay = 0.995
epsilon_min = 0.01
episodes = 2000
Q = np.zeros([env.observation_space.n, env.action_space.n])
for episode in range(episodes):
state, info = env.reset()
if np.random.random() < epsilon:
action = env.action_space.sample()
else:
action = np.argmax(Q[state, :])
done = False
while not done:
next_state, reward, terminated, truncated, info = env.step(action)
done = terminated or truncated
if np.random.random() < epsilon:
next_action = env.action_space.sample()
else:
next_action = np.argmax(Q[next_state, :])
if not done:
Q[state, action] = Q[state, action] + learning_rate * (
reward + discount_factor * Q[next_state, next_action] - Q[state, action]
)
else:
Q[state, action] = Q[state, action] + learning_rate * (reward - Q[state, action])
state = next_state
action = next_action
epsilon = max(epsilon_min, epsilon * epsilon_decay)
env.close()
结合深度学习和Q-Learning的算法
DQN(Deep Q-Network)由DeepMind在2013年提出,将深度神经网络与Q-Learning结合,能够处理高维状态空间(如图像),是深度强化学习的里程碑算法。它在2015年的Nature论文中展示了在Atari游戏中达到人类水平的性能。
传统Q-Learning使用Q表存储所有状态-动作对的Q值,这在状态空间很大时(如Atari游戏的图像状态)是不可行的。DQN使用深度神经网络来近似Q函数,从而能够处理高维连续状态空间。
L(θ) = E(s,a,r,s')~D[(r + γ maxa' Q(s', a'; θtarget) - Q(s, a; θ))²]
其中D是经验回放缓冲区,θ是主网络参数,θtarget是目标网络参数。
from stable_baselines3 import DQN
from stable_baselines3.common.env_util import make_vec_env
import gymnasium as gym
env = make_vec_env('CartPole-v1', n_envs=1)
model = DQN(
'MlpPolicy',
env,
learning_rate=1e-3,
buffer_size=10000,
learning_starts=1000,
batch_size=32,
gamma=0.99,
target_update_interval=100,
verbose=1
)
print("开始训练DQN模型...")
model.learn(total_timesteps=10000)
model.save("dqn_cartpole")
print("训练完成!")
env = gym.make('CartPole-v1', render_mode='human')
obs, info = env.reset()
for i in range(1000):
action, _states = model.predict(obs, deterministic=True)
obs, reward, terminated, truncated, info = env.step(action)
if terminated or truncated:
obs, info = env.reset()
env.close()
稳定高效的策略梯度算法
PPO(Proximal Policy Optimization)由OpenAI在2017年提出,是一种策略梯度算法,通过限制策略更新的幅度来避免训练不稳定。它已经成为深度强化学习领域最流行和广泛应用的算法之一,在游戏、机器人控制、自然语言处理等多个领域取得了成功。
传统的策略梯度方法(如REINFORCE、Actor-Critic)存在以下问题:
PPO的核心思想是:在更新策略时,限制新策略与旧策略的差异,确保策略更新不会太大。这通过裁剪(Clipping)机制实现,防止策略更新过度偏离旧策略。
PPO使用重要性采样和裁剪机制。目标函数为:
LCLIP(θ) = Et[min(rt(θ)Ât, clip(rt(θ), 1-ε, 1+ε)Ât)]
其中:
裁剪机制的工作原理:
from stable_baselines3 import PPO
from stable_baselines3.common.env_util import make_vec_env
import gymnasium as gym
env = make_vec_env('CartPole-v1', n_envs=4)
model = PPO(
'MlpPolicy',
env,
learning_rate=3e-4,
n_steps=2048,
batch_size=64,
n_epochs=10,
gamma=0.99,
gae_lambda=0.95,
clip_range=0.2,
verbose=1
)
print("开始训练PPO模型...")
model.learn(total_timesteps=50000)
model.save("ppo_cartpole")
print("训练完成!")
env = gym.make('CartPole-v1', render_mode='human')
obs, info = env.reset()
for i in range(10):
total_reward = 0
while True:
action, _states = model.predict(obs, deterministic=True)
obs, reward, terminated, truncated, info = env.step(action)
total_reward += reward
if terminated or truncated:
print(f"回合 {i + 1}: 总奖励 = {total_reward:.2f}")
obs, info = env.reset()
break
env.close()
结合价值函数和策略梯度的算法
A2C(Advantage Actor-Critic)是A3C(Asynchronous Advantage Actor-Critic)的同步版本,由DeepMind在2016年提出。它结合了策略梯度方法和价值函数方法,使用优势函数来减少方差,提高训练稳定性。
A2C结合了Actor(策略网络)和Critic(价值网络):
A2C使用优势函数来更新策略,策略梯度为:
∇θJ(θ) = Eπθ[∇θlog πθ(a|s) Â(s,a)]
其中优势函数Â(s,a)通过TD误差估计:
Â(s,a) = r + γV(s') - V(s)
使用优势函数而不是Q值或回报的好处:
优势:
局限:
from stable_baselines3 import A2C
from stable_baselines3.common.env_util import make_vec_env
import gymnasium as gym
env = make_vec_env('CartPole-v1', n_envs=4)
model = A2C(
'MlpPolicy',
env,
learning_rate=7e-4,
n_steps=5,
gamma=0.99,
verbose=1
)
print("开始训练A2C模型...")
model.learn(total_timesteps=50000)
model.save("a2c_cartpole")
print("训练完成!")
env = gym.make('CartPole-v1', render_mode='human')
obs, info = env.reset()
for i in range(10):
total_reward = 0
while True:
action, _states = model.predict(obs, deterministic=True)
obs, reward, terminated, truncated, info = env.step(action)
total_reward += reward
if terminated or truncated:
print(f"回合 {i + 1}: 总奖励 = {total_reward:.2f}")
obs, info = env.reset()
break
env.close()
强化学习领域的里程碑论文
作者:Mnih et al. (2013)
首次将深度学习应用于强化学习,提出了DQN算法,在Atari游戏中取得了突破性成果。
作者:Mnih et al. (2015)
DQN的改进版本,引入了目标网络和经验回放,在多个Atari游戏中达到人类水平。
作者:Schulman et al. (2017)
提出了PPO算法,通过裁剪机制实现稳定高效的策略优化,成为深度强化学习的标准算法。
强化学习领域的最新进展
强化学习环境标准库
Gymnasium(原OpenAI Gym)是强化学习环境的标准库,提供了大量标准化的环境用于测试和开发强化学习算法。
pip install gymnasium
PyTorch实现的强化学习算法库
Stable-Baselines3提供了多种强化学习算法的PyTorch实现,包括PPO、DQN、A2C等,是研究和应用的首选库。
pip install stable-baselines3
可扩展的分布式强化学习库
Ray RLlib是一个可扩展的强化学习库,支持分布式训练,适合大规模强化学习应用。
pip install "ray[rllib]"
一步步配置您的强化学习开发环境
推荐使用Python 3.8或更高版本
python --version
使用虚拟环境可以避免包冲突
python -m venv rl_env
rl_env\Scripts\activate # Windows
source rl_env/bin/activate # macOS/Linux
安装强化学习开发所需的主要库
pip install numpy matplotlib
pip install gymnasium
pip install stable-baselines3
pip install torch
您的第一个强化学习程序
这是一个最简单的强化学习示例,使用随机策略在CartPole环境中进行交互。
import gymnasium as gym
import numpy as np
env = gym.make('CartPole-v1', render_mode='human')
for episode in range(5):
obs, info = env.reset()
total_reward = 0
steps = 0
while True:
action = env.action_space.sample()
obs, reward, terminated, truncated, info = env.step(action)
total_reward += reward
steps += 1
if terminated or truncated:
print(f"回合 {episode + 1}: 步数 = {steps}, 总奖励 = {total_reward:.2f}")
break
env.close()
经典的网格世界环境,适合学习基础强化学习算法
Grid World是强化学习中最经典的环境之一,智能体在一个网格世界中移动,目标是到达终点。这个环境简单直观,非常适合理解强化学习的基本概念。
Gymnasium提供了多个Grid World变体:
FrozenLake是一个经典的Grid World环境:
import gymnasium as gym
import numpy as np
# 创建FrozenLake环境
env = gym.make('FrozenLake-v1', is_slippery=True, render_mode='human')
# 查看环境信息
print(f"状态空间: {env.observation_space}")
print(f"动作空间: {env.action_space}")
print(f"状态数量: {env.observation_space.n}")
print(f"动作数量: {env.action_space.n}")
# 运行一个回合
obs, info = env.reset()
total_reward = 0
steps = 0
while True:
# 随机选择动作
action = env.action_space.sample()
# 执行动作
obs, reward, terminated, truncated, info = env.step(action)
total_reward += reward
steps += 1
print(f"步数: {steps}, 状态: {obs}, 动作: {action}, 奖励: {reward}")
if terminated or truncated:
print(f"回合结束!总奖励: {total_reward}, 总步数: {steps}")
break
env.close()
经典的Atari 2600游戏,深度强化学习的标准测试平台
Atari 2600游戏环境是深度强化学习领域最重要的测试平台之一。DeepMind在2013年首次使用DQN在Atari游戏中达到人类水平,开启了深度强化学习的新时代。
Atari环境需要额外安装:
pip install gymnasium[atari]
pip install gymnasium[accept-rom-license]
import gymnasium as gym
import numpy as np
# 创建Atari环境(Pong游戏)
env = gym.make('ALE/Pong-v5', render_mode='human')
# 查看环境信息
print(f"状态空间: {env.observation_space}")
print(f"动作空间: {env.action_space}")
print(f"状态形状: {env.observation_space.shape}")
# 运行一个回合
obs, info = env.reset()
total_reward = 0
steps = 0
for step in range(1000):
# 随机选择动作
action = env.action_space.sample()
# 执行动作
obs, reward, terminated, truncated, info = env.step(action)
total_reward += reward
steps += 1
if terminated or truncated:
print(f"回合结束!总奖励: {total_reward}, 总步数: {steps}")
obs, info = env.reset()
total_reward = 0
steps = 0
env.close()
经典的倒立摆控制问题,强化学习的入门环境
CartPole(倒立摆)是强化学习中最经典的连续控制环境之一。智能体需要控制一个小车,使杆子保持平衡不倒。这个环境简单但具有挑战性,是学习强化学习算法的理想起点。
import gymnasium as gym
import numpy as np
# 创建CartPole环境
env = gym.make('CartPole-v1', render_mode='human')
# 查看环境信息
print(f"状态空间: {env.observation_space}")
print(f"动作空间: {env.action_space}")
print(f"状态范围: {env.observation_space.low} 到 {env.observation_space.high}")
# 运行多个回合
for episode in range(5):
obs, info = env.reset()
total_reward = 0
steps = 0
while True:
# 随机选择动作
action = env.action_space.sample()
# 执行动作
obs, reward, terminated, truncated, info = env.step(action)
total_reward += reward
steps += 1
if terminated or truncated:
print(f"回合 {episode + 1}: 总奖励 = {total_reward}, 步数 = {steps}")
break
env.close()
经典的稀疏奖励问题,测试算法的探索能力
MountainCar是一个经典的稀疏奖励环境。智能体需要控制一辆小车,通过左右摆动来爬上一座山。这个环境的挑战在于:只有到达山顶才能获得奖励,这需要智能体学会"后退蓄力"的策略。
MountainCar的主要挑战是稀疏奖励和反直觉策略:
import gymnasium as gym
import numpy as np
# 创建MountainCar环境
env = gym.make('MountainCar-v0', render_mode='human')
# 查看环境信息
print(f"状态空间: {env.observation_space}")
print(f"动作空间: {env.action_space}")
print(f"状态范围: {env.observation_space.low} 到 {env.observation_space.high}")
# 运行多个回合
for episode in range(5):
obs, info = env.reset()
total_reward = 0
steps = 0
while True:
# 随机选择动作
action = env.action_space.sample()
# 执行动作
obs, reward, terminated, truncated, info = env.step(action)
total_reward += reward
steps += 1
if terminated or truncated:
print(f"回合 {episode + 1}: 总奖励 = {total_reward}, 步数 = {steps}")
break
env.close()
DeepSeek R1 背后的关键强化学习算法
GRPO (Group Relative Policy Optimization) 是一种专为大语言模型 (LLM) 推理任务设计的高效强化学习算法。它在 DeepSeek-R1 等模型的训练中发挥了关键作用,显著降低了 RLHF (Reinforcement Learning from Human Feedback) 的计算成本。
传统的 PPO 算法需要训练一个 Critic (价值) 网络来估计优势函数 (Advantage),这在 LLM 规模下会带来巨大的显存开销。GRPO 巧妙地通过群组归一化 (Group Normalization) 替代了 Critic 网络。
为了防止模型偏离原始分布太远,GRPO 同样在损失函数中加入了 KL 散度惩罚项。
| 特性 | PPO | GRPO |
|---|---|---|
| 模型结构 | Actor + Critic | 仅 Actor (无需 Critic) |
| 显存占用 | 高 (需加载 Critic) | 低 (节省约 50%) |
| 优势估计 | GAE (依赖 Value Function) | 组内相对归一化 |
序列级优化的进阶探索
GSPO (Group Sequence Policy Optimization) 是对传统策略优化方法的进一步扩展。虽然在主流文献中不如 PPO/GRPO 普及,但在处理长序列生成和复杂决策任务中展现出潜力。
GSPO 关注于在长序列生成过程中,如何更好地利用群组信息来优化整个序列的策略,而不仅仅是单步 token 的预测。
系统学习强化学习的核心概念和原理
强化学习(Reinforcement Learning, RL)是机器学习的一个分支,通过智能体(Agent)与环境(Environment)的交互来学习最优策略。
MDP是强化学习的数学框架,用于描述在不确定环境中进行决策的问题。
V(s) = E[∑t=0∞ γtRt+1 | S0 = s]
价值函数用于评估状态或动作的好坏,策略定义了智能体的行为方式。
Q*(s,a) = maxπ Qπ(s,a)
强化学习有多种算法,从简单的Q-learning到复杂的深度强化学习。
一步步配置您的强化学习开发环境
推荐使用Python 3.8或更高版本
python --version
# 或
python3 --version
如果未安装,请访问 python.org 下载安装
使用虚拟环境可以避免包冲突
# Windows
python -m venv rl_env
rl_env\Scripts\activate
# macOS/Linux
python3 -m venv rl_env
source rl_env/bin/activate
安装强化学习开发所需的主要库
# 安装基础库
pip install numpy matplotlib
# 安装强化学习库
pip install gymnasium
pip install stable-baselines3
# 安装深度学习框架(可选,用于深度强化学习)
pip install torch
运行测试代码确认环境配置成功
import gymnasium as gym
import numpy as np
# 创建环境
env = gym.make('CartPole-v1')
print("环境创建成功!")
print(f"状态空间: {env.observation_space}")
print(f"动作空间: {env.action_space}")
# 测试一个回合
obs, info = env.reset()
for _ in range(10):
action = env.action_space.sample()
obs, reward, terminated, truncated, info = env.step(action)
print(f"奖励: {reward}")
if terminated or truncated:
break
env.close()
print("环境测试完成!")
pip install --upgrade pip 升级pip运行您的第一个强化学习代码,看到实际效果
这是一个最简单的强化学习示例,使用随机策略在CartPole环境中进行交互。
import gymnasium as gym
import numpy as np
# 创建CartPole环境
env = gym.make('CartPole-v1', render_mode='human')
# 运行多个回合
for episode in range(5):
obs, info = env.reset()
total_reward = 0
steps = 0
while True:
# 随机选择动作(这是最简单的策略)
action = env.action_space.sample()
# 执行动作
obs, reward, terminated, truncated, info = env.step(action)
total_reward += reward
steps += 1
# 如果回合结束
if terminated or truncated:
print(f"回合 {episode + 1}: 步数 = {steps}, 总奖励 = {total_reward:.2f}")
break
env.close()
使用Q-Learning算法训练智能体在FrozenLake环境中找到最优路径。
import gymnasium as gym
import numpy as np
import matplotlib.pyplot as plt
# 创建环境
env = gym.make('FrozenLake-v1', is_slippery=True)
# Q-Learning参数
learning_rate = 0.1
discount_factor = 0.95
epsilon = 1.0
epsilon_decay = 0.995
epsilon_min = 0.01
episodes = 2000
# 初始化Q表
Q = np.zeros([env.observation_space.n, env.action_space.n])
# 记录奖励
rewards = []
# 训练
for episode in range(episodes):
state, info = env.reset()
total_reward = 0
done = False
while not done:
# ε-贪婪策略
if np.random.random() < epsilon:
action = env.action_space.sample()
else:
action = np.argmax(Q[state, :])
# 执行动作
next_state, reward, terminated, truncated, info = env.step(action)
done = terminated or truncated
# Q-Learning更新
Q[state, action] = Q[state, action] + learning_rate * (
reward + discount_factor * np.max(Q[next_state, :]) - Q[state, action]
)
state = next_state
total_reward += reward
rewards.append(total_reward)
epsilon = max(epsilon_min, epsilon * epsilon_decay)
if (episode + 1) % 200 == 0:
avg_reward = np.mean(rewards[-200:])
print(f"回合 {episode + 1}: 平均奖励 = {avg_reward:.2f}")
# 测试训练好的策略
print("\n测试训练好的策略:")
state, info = env.reset()
env = gym.make('FrozenLake-v1', render_mode='human', is_slippery=True)
state, info = env.reset()
for step in range(100):
action = np.argmax(Q[state, :])
state, reward, terminated, truncated, info = env.step(action)
if terminated or truncated:
print(f"到达目标!步数: {step + 1}")
break
env.close()
使用深度神经网络和stable-baselines3库实现DQN算法,在CartPole环境中训练智能体。
from stable_baselines3 import DQN
from stable_baselines3.common.env_util import make_vec_env
import gymnasium as gym
# 创建环境
env = make_vec_env('CartPole-v1', n_envs=1)
# 创建DQN模型
model = DQN(
'MlpPolicy',
env,
learning_rate=1e-3,
buffer_size=10000,
learning_starts=1000,
batch_size=32,
gamma=0.99,
target_update_interval=100,
verbose=1
)
# 训练模型
print("开始训练DQN模型...")
model.learn(total_timesteps=10000)
print("训练完成!")
# 保存模型
model.save("dqn_cartpole")
print("模型已保存为 dqn_cartpole.zip")
# 测试模型
print("\n测试训练好的模型:")
env = gym.make('CartPole-v1', render_mode='human')
obs, info = env.reset()
for i in range(1000):
action, _states = model.predict(obs, deterministic=True)
obs, reward, terminated, truncated, info = env.step(action)
if terminated or truncated:
print(f"回合结束,步数: {i + 1}")
obs, info = env.reset()
env.close()
SARSA(State-Action-Reward-State-Action)是一种在线策略的时序差分学习算法,与Q-Learning的主要区别在于它使用实际执行的动作来更新Q值。
import gymnasium as gym
import numpy as np
# 创建环境
env = gym.make('FrozenLake-v1', is_slippery=True)
# SARSA参数
learning_rate = 0.1
discount_factor = 0.95
epsilon = 1.0
epsilon_decay = 0.995
epsilon_min = 0.01
episodes = 2000
# 初始化Q表
Q = np.zeros([env.observation_space.n, env.action_space.n])
# 记录奖励
rewards = []
# 训练
for episode in range(episodes):
state, info = env.reset()
# 选择初始动作(ε-贪婪策略)
if np.random.random() < epsilon:
action = env.action_space.sample()
else:
action = np.argmax(Q[state, :])
total_reward = 0
done = False
while not done:
# 执行动作
next_state, reward, terminated, truncated, info = env.step(action)
done = terminated or truncated
# 选择下一个动作(SARSA使用实际执行的动作)
if np.random.random() < epsilon:
next_action = env.action_space.sample()
else:
next_action = np.argmax(Q[next_state, :])
# SARSA更新(使用下一个实际执行的动作)
if not done:
Q[state, action] = Q[state, action] + learning_rate * (
reward + discount_factor * Q[next_state, next_action] - Q[state, action]
)
else:
Q[state, action] = Q[state, action] + learning_rate * (reward - Q[state, action])
state = next_state
action = next_action
total_reward += reward
rewards.append(total_reward)
epsilon = max(epsilon_min, epsilon * epsilon_decay)
if (episode + 1) % 200 == 0:
avg_reward = np.mean(rewards[-200:])
print(f"回合 {episode + 1}: 平均奖励 = {avg_reward:.2f}")
# 测试训练好的策略
print("\n测试训练好的策略:")
env = gym.make('FrozenLake-v1', render_mode='human', is_slippery=True)
state, info = env.reset()
for step in range(100):
action = np.argmax(Q[state, :])
state, reward, terminated, truncated, info = env.step(action)
if terminated or truncated:
print(f"到达目标!步数: {step + 1}")
break
env.close()
PPO(Proximal Policy Optimization)是一种稳定且高效的策略梯度算法,通过限制策略更新的幅度来避免训练不稳定。它是目前最流行的深度强化学习算法之一。
from stable_baselines3 import PPO
from stable_baselines3.common.env_util import make_vec_env
import gymnasium as gym
# 创建环境(使用向量化环境可以加速训练)
env = make_vec_env('CartPole-v1', n_envs=4)
# 创建PPO模型
model = PPO(
'MlpPolicy',
env,
learning_rate=3e-4,
n_steps=2048,
batch_size=64,
n_epochs=10,
gamma=0.99,
gae_lambda=0.95,
clip_range=0.2,
ent_coef=0.01,
vf_coef=0.5,
max_grad_norm=0.5,
verbose=1
)
# 训练模型
print("开始训练PPO模型...")
model.learn(total_timesteps=50000)
print("训练完成!")
# 保存模型
model.save("ppo_cartpole")
print("模型已保存为 ppo_cartpole.zip")
# 测试模型
print("\n测试训练好的模型:")
env = gym.make('CartPole-v1', render_mode='human')
obs, info = env.reset()
for i in range(10):
total_reward = 0
while True:
action, _states = model.predict(obs, deterministic=True)
obs, reward, terminated, truncated, info = env.step(action)
total_reward += reward
if terminated or truncated:
print(f"回合 {i + 1}: 总奖励 = {total_reward:.2f}")
obs, info = env.reset()
break
env.close()
print("\nPPO训练完成!模型表现优秀。")
A2C(Advantage Actor-Critic)是一种结合了价值函数和策略梯度的算法,使用优势函数来减少方差,提高训练稳定性。
from stable_baselines3 import A2C
from stable_baselines3.common.env_util import make_vec_env
import gymnasium as gym
# 创建环境
env = make_vec_env('CartPole-v1', n_envs=4)
# 创建A2C模型
model = A2C(
'MlpPolicy',
env,
learning_rate=7e-4,
n_steps=5,
gamma=0.99,
gae_lambda=1.0,
ent_coef=0.01,
vf_coef=0.25,
max_grad_norm=0.5,
verbose=1
)
# 训练模型
print("开始训练A2C模型...")
model.learn(total_timesteps=50000)
print("训练完成!")
# 保存模型
model.save("a2c_cartpole")
print("模型已保存为 a2c_cartpole.zip")
# 测试模型
print("\n测试训练好的模型:")
env = gym.make('CartPole-v1', render_mode='human')
obs, info = env.reset()
for i in range(10):
total_reward = 0
while True:
action, _states = model.predict(obs, deterministic=True)
obs, reward, terminated, truncated, info = env.step(action)
total_reward += reward
if terminated or truncated:
print(f"回合 {i + 1}: 总奖励 = {total_reward:.2f}")
obs, info = env.reset()
break
env.close()
print("\nA2C训练完成!")