本文主要是介绍Stanford斯坦福 CS 224R: 深度强化学习 (3),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
基于模型的强化学习
强化学习(RL)旨在让智能体通过与环境互动来学习最优策略,从而最大化累积奖励。传统的强化学习方法如Q-learning、策略梯度等,通过大量的试错来学习值函数或策略,样本效率较低。而基于模型的强化学习(MBRL)则利用对环境的预测模型来加速学习过程,大大提高了样本利用率。本章我们将系统地介绍MBRL的基本原理、核心算法、实现技巧以及代表性应用。
1. 采样优化入门
在探讨MBRL之前,我们先来回顾一下优化问题的两大类解法:基于梯度的方法和基于采样的方法。
1.1 基于梯度的优化
基于梯度的优化通过目标函数对参数的梯度信息来指导参数更新。给定参数 θ \theta θ 和损失函数 L ( θ ) L(\theta) L(θ),更新步骤为:
θ ← θ − α ∇ θ L ( θ ) \theta \leftarrow \theta - \alpha \nabla_{\theta}L(\theta) θ←θ−α∇θL(θ)
其中 α \alpha α 为学习率。这类方法在深度学习中被广泛应用,优点是适用于高维参数空间,收敛速度快;缺点是需要损失函数可导,对优化问题的形式有一定要求。
1.2 基于采样的优化
基于采样的优化则不依赖梯度信息,而是通过在参数空间中采样并评估样本的性能来搜索最优解。以交叉熵方法(CEM)为例:
- 从某个分布(如高斯分布)中采样一组参数 { θ i ∼ p ( θ ) } i = 1 N \{\theta^i \sim p(\theta)\}_{i=1}^N {θi∼p(θ)}i=1N
- 评估各个样本的损失 { L ( θ i ) } i = 1 N \{L(\theta^i)\}_{i=1}^N {L(θi)}i=1N,选出表现最好的前k个样本
- 用均值和方差来更新采样分布 p ( θ ) p(\theta) p(θ)
- 重复以上过程直至找到最优解
基于采样的优化的优点是:
- 易于并行化
- 不要求目标函数可导
- 适用于复杂的优化形式
缺点是:
- 难以处理高维参数空间
- 收敛速度较慢
在MBRL中,基于采样的优化被广泛用于规划(planning)任务。例如我们可以通过在动作空间中采样来搜索最优动作序列。
2. 基于模型的强化学习
MBRL的核心思想是学习一个对环境的预测模型,用它来推断各种行为的后果,从而指导策略学习。相比无模型RL,MBRL能更有效地利用样本,实现更高效、更稳定的学习。
2.1 如何学习一个好的动力学模型?
学习环境模型本质上是一个监督学习问题。我们希望学习一个函数 f ϕ ( s , a ) f_{\phi}(s,a) fϕ(s,a),使其能较好地预测在状态 s s s 下执行动作 a a a 后,环境转移到状态 s ′ s' s′ 的结果。即:
min ϕ ∑ ( s , a , s ′ ) ∈ D ∥ f ϕ ( s , a ) − s ′ ∥ 2 \min_{\phi} \sum_{(s,a,s')\in\mathcal{D}} \| f_{\phi}(s,a) - s'\|^2 ϕmin(s,a,s′)∈D∑∥fϕ(s,a)−s′∥2
其中 D = { ( s , a , s ′ ) i } \mathcal{D}=\{(s,a,s')_i\} D={(s,a,s′)i} 为收集到的转移数据集。
根据任务的特点,我们可以采用不同的建模方式,例如:
- 机器人控制:输入为状态和动作,输出为下一状态
- 视频预测:输入为之前的图像序列,输出为未来的图像
- 物理引擎:在已知物理定律的基础上,学习一些未知参数(如摩擦系数)
- 对话系统:用语言模型来预测对话的后续发展
- 金融市场:股票趋势预测模型
可见,模型的形式依赖于具体问题,但万变不离其宗,都是在拟合状态转移函数 p ( s ′ ∣ s , a ) p(s'|s,a) p(s′∣s,a) 。接下来的问题是,如何有效利用学到的模型?
2.2 如何利用学到的动力学模型?
2.2.1 使用模型进行规划
规划(planning)是指在给定模型的情况下,寻找最优动作序列 { a t ∗ } \{a^*_t\} {at∗} 以最大化未来累积奖励。形式化地,规划问题可以表示为:
max a t : t + H ∑ t ′ = t t + H r ( s t ′ , a t ′ ) \max_{a_{t:t+H}} \sum^{t+H}_{t'=t} r(s_{t'}, a_{t'}) at:t+Hmaxt′=t∑t+Hr(st′,at′)
其中 H H H 为规划视界, r ( s , a ) r(s,a) r(s,a) 为奖励函数。这个问题可以通过基于梯度的优化或基于采样的优化来求解。
基于梯度的规划
基于梯度的规划通过反向传播梯度来优化动作序列。主要步骤如下:
- 用当前策略(如随机策略)采集数据 D = { ( s , a , s ′ ) i } \mathcal{D}=\{(s,a,s')_i\} D={(s,a,s′)i}
- 训练模型 f ϕ f_{\phi} fϕ 来最小化预测误差 ∑ i ∥ f ϕ ( s i , a i ) − s i ′ ∥ 2 \sum_{i} \| f_{\phi}(s_i,a_i) - s'_i \|^2 ∑i∥fϕ(si,ai)−si′∥2
- 通过反向传播优化动作序列 { a t ∗ } = arg max a t : t + H ∑ t ′ = t t + H r ( s t ′ , a t ′ ) \{a^*_t\} = \arg\max_{a_{t:t+H}} \sum^{t+H}_{t'=t} r(s_{t'}, a_{t'}) {at∗}=argmaxat:t+H∑t′=tt+Hr(st′,at′)
这里第3步通过梯度上升来优化目标函数。模型 f ϕ f_{\phi} fϕ 充当了从动作到状态的映射,使我们能够计算目标函数对动作的梯度。
基于采样的规划
基于采样的规划则通过在动作空间中随机采样,并利用模型评估轨迹质量,来搜索最优动作序列。主要步骤如下:
- 用当前策略采集数据 D = { ( s , a , s ′ ) i } \mathcal{D}=\{(s,a,s')_i\} D={(s,a,s′)i}
- 训练模型 f ϕ f_{\phi} fϕ 来最小化预测误差
- 通过采样搜索最优动作序列:
- 随机采样N组长度为H的动作序列 { A t : t + H i } i = 1 N \{A^i_{t:t+H}\}^N_{i=1} {At:t+Hi}i=1N
- 利用 f ϕ f_{\phi} fϕ 预测各动作序列对应的状态轨迹,并估算累积奖励
- 选择奖励最高的动作序列 A ∗ = arg max A i ∑ t ′ = t t + H r ( s t ′ i , a t ′ i ) A^* = \arg\max_{A^i} \sum^{t+H}_{t'=t} r(s^i_{t'}, a^i_{t'}) A∗=argmaxAi∑t′=tt+Hr(st′i,at′i)
这里第3步本质上是一个启发式搜索,通过模型模拟来评估候选动作序列的优劣。这种方法的好处是易于实现、可并行化、适用于任意形式的环境模型。
对于连续动作空间,一种更高效的采样策略是交叉熵方法(CEM):
- 从高斯分布 N ( μ , Σ ) \mathcal{N}(\mu, \Sigma) N(μ,Σ) 中采样N个动作序列 { A i } i = 1 N \{A^i\}^N_{i=1} {Ai}i=1N
- 评估各动作序列的累积奖励 J ( A i ) = ∑ t ′ = t t + H r ( s t ′ i , a t ′ i ) J(A^i) = \sum^{t+H}_{t'=t} r(s^i_{t'}, a^i_{t'}) J(Ai)=∑t′=tt+Hr(st′i,at′i)
- 选出奖励最高的前k个动作序列 { A i j } j = 1 k \{A^{i_j}\}^k_{j=1} {Aij}j=1k
- 用 { A i j } j = 1 k \{A^{i_j}\}^k_{j=1} {Aij}j=1k 来更新高斯分布的均值和方差
- 重复以上过程,直至分布收敛
CEM相比随机采样,能更快地集中到高奖励区域进行采样,减少搜索代价。
规划算法总结
方法 | 优点 | 缺点 |
---|---|---|
基于梯度 | 适用高维动作空间 | 需模型可导 |
随机采样 | 简单,可并行 | 采样效率低 |
交叉熵法 | 采样高效 | 依赖初始分布 |
以上规划算法都是开环(open-loop)控制,即先规划一个动作序列,然后不更新地执行到底。这对模型精度要求很高,否则容易导致误差累积。一种常用的改进是模型预测控制(model predictive control),即每次只执行规划出的前几步动作,然后重新规划。通过反复规划来及时修正误差,使控制更加鲁棒
2.2.2 使用模型指导策略学习
规划的一个局限是需要精确的奖励函数,且很难处理长期回报。一种更通用的做法是利用模型来辅助策略(policy)或值函数(value function)的学习。我们可以用学到的模型来增强真实的环境交互数据。具体来说,训练过程为:
- 用当前策略 π \pi π 在真实环境中采样数据 D e n v \mathcal{D}_{env} Denv
- 训练模型 f ϕ f_{\phi} fϕ 来拟合状态转移函数
- 用 f ϕ f_{\phi} fϕ 从 D e n v \mathcal{D}_{env} Denv 中的各个状态出发,模拟生成数据 D m o d e l \mathcal{D}_{model} Dmodel
- 把 D e n v \mathcal{D}_{env} Denv 和 D m o d e l \mathcal{D}_{model} Dmodel 合并为 D R L \mathcal{D}_{RL} DRL
- 用 D R L \mathcal{D}_{RL} DRL 来训练新策略 π ′ \pi' π′ (或值函数 V V V)
- 重复以上过程,即可迭代优化策略
这个过程可以与任意的无模型RL算法相结合,关键是用模型模拟数据来加速策略学习。通过对 D e n v \mathcal{D}_{env} Denv 中的各个状态seed模拟轨迹,我们能更充分地利用采集到的真实转移数据。相比单纯地想象完整轨迹,这种做法能更好地覆盖状态空间。
3. 案例分析:用MBRL实现机器人灵巧操控
DeepMind在2019年提出的一个工作,展示了用MBRL让一只仿真五指机械手学会各种灵巧操控,如旋转棒、翻转刀等。尽管已经过去两年,但这个结果至今仍是五指灵巧操控领域最激动人心的成果之一。让我们来剖析一下他们是如何做到的。
3.1 问题定义
状态空间: 机械手和物体的位置
动作空间: 24维,控制5个手指的关节角度
模型结构: 3个全连接网络组成的集成模型,每个网络有2个大小为500的隐藏层
奖励函数: 跟踪物体轨迹的误差 + 惩罚掉落
规划算法: 修改版的CEM,引入时间平滑正则化和更softer的加权平均
整体训练过程为:交替地用CEM规划采集大约30条轨迹数据,并用新数据更新集成模型,如此反复迭代。
3.2 仿真实验
他们首先在MuJoCo物理引擎中构建仿真环境,测试不同RL算法的表现:
- 无模型RL:
- SAC:一种actor-critic算法
- NPG:一种策略梯度算法
- 有模型RL:
- PDDM:本文提出的MBRL算法
- MBPO:利用模型数据增强的RL算法
- PETS:基于CEM的MBRL算法
- Nagabandi et al.:基于随机采样的MBRL,不使用集成
从结果可以看出,MBRL算法的采样效率明显高于无模型RL,其中PDDM的表现最佳。进一步的消融实验表明:
- 模型容量要足够大,但太大也会过拟合
- 集成模型至少需要3个成员
- 规划视界是个重要的权衡:太短则短视,太长则不可靠
- CEM的改进策略是关键,尤其是temporally-correlated探索
可见,PDDM之所以性能卓越,缘于以下几点优化:
- 大容量集成模型,增强了预测鲁棒性
- 适度的规划视界,权衡了可靠性和远见性
- 改进的CEM采样,引入了探索的时间相关性
3.3 实物实验
为了验证算法在实物场景中的有效性,他们搭建了一套机械手系统,包括一只24关节的ShadowHand和一套PhaseSpace运动捕捉系统。
实物训练面临两大挑战:
- 采样成本高,需要样本高效的算法
- 很难完全复现初始状态,增加了训练难度
他们先在仿真环境中预训练策略,再迁移到实物上微调。同时为了自动化采集数据,他们额外加了一只机械臂用于在每个回合将物体重置到初始位置。最终,系统在4小时内就学会了花式转棒的技能,展现了MBRL的强大潜力。
4. 代码实战
下面我们通过一个简单的例子来演示MBRL的实现。考虑倒立摆(Inverted Pendulum)环境,状态为摆角 θ \theta θ 和角速度 θ ˙ \dot{\theta} θ˙,动作为施加在摆基座的水平力。我们的目标是学习一个策略,使摆尽快达到并保持直立平衡。
首先导入需要的库:
import numpy as np
import torch
import gym
import matplotlib.pyplot as plt
然后定义一个神经网络作为环境模型:
class Model(torch.nn.Module):def __init__(self, state_dim, action_dim):super().__init__()self.fc1 = torch.nn.Linear(state_dim + action_dim, 256)self.fc2 = torch.nn.Linear(256, 256)self.fc3 = torch.nn.Linear(256, state_dim)def forward(self, state, action):x = torch.cat([state, action], dim=-1)x = torch.relu(self.fc1(x)) x = torch.relu(self.fc2(x))next_state = self.fc3(x)return next_state
模型输入当前状态和动作,输出预测的下一状态。接下来我们定义MBRL算法的主要组件:
class MBRL:def __init__(self, env, model, n_plan, n_iter, n_batch=128):self.env = env self.model = modelself.n_plan = n_plan # 规划视界self.n_iter = n_iter # 总迭代次数self.n_batch = n_batch
其中env
为强化学习环境,model
为环境模型,n_plan
为规划视界,n_iter
为总迭代次数,n_batch
为批大小。接下来实现数据采集函数:
def collect_data(self, n_samples):states, actions, rewards, next_states = [], [], [], []state = self.env.reset()for _ in range(n_samples):action = self.env.action_space.sample()next_state, reward, done, _ = self.env.step(action)states.append(state)actions.append(action)rewards.append(reward)next_states.append(next_state)state = next_state if not done else self.env.reset()states = torch.tensor(states, dtype=torch.float32)actions = torch.tensor(actions, dtype=torch.float32)rewards = torch.tensor(rewards, dtype=torch.float32)next_states = torch.tensor(next_states, dtype=torch.float32) return states, actions, rewards, next_states
这个函数使用随机策略采集指定数量的转移数据,并返回状态、动作、奖励和下一状态的张量。有了真实数据,我们就可以训练模型了:
def train_model(self, states, actions, next_states):dataset = torch.utils.data.TensorDataset(states, actions, next_states)dataloader = torch.utils.data.DataLoader(dataset, batch_size=self.n_batch, shuffle=True)criterion = torch.nn.MSELoss()optimizer = torch.optim.Adam(self.model.parameters())for epoch in range(5):for batch in dataloader:state, action, next_state = batchpred_next_state = self.model(state, action)loss = criterion(pred_next_state, next_state)optimizer.zero_grad()loss.backward()optimizer.step()
模型训练采用均方损失和Adam优化器,训练5个epoch,每个epoch遍历整个数据集。接下来我们实现基于CEM的规划器:
def plan(self, state):best_reward = -np.infbest_action_seq = Nonefor _ in range(100): # CEM迭代次数action_seqs = np.random.uniform(-2, 2, size=(128, self.n_plan))rewards = np.zeros(128)for t in range(self.n_plan):actions = torch.tensor(action_seqs[:, t], dtype=torch.float32)next_states = self.model(state, actions)rewards += self.env.get_reward(state.numpy(), actions.numpy())state = next_stateselite_idxs = rewards.argsort()[-10:] # 选取前10个最优轨迹 elite_action_seqs = action_seqs[elite_idxs]if rewards.max() > best_reward:best_reward = rewards.max()best_action_seq = action_seqs[rewards.argmax()]action_seqs = elite_action_seqs.mean(axis=0) + 0.5 * elite_action_seqs.std(axis=0) * np.random.randn(*elite_action_seqs.shape)return best_action_seq[0] # 返回第一个动作
规划器从均匀分布中采样128条动作序列,长度为n_plan
。然后用模型模拟各条序列对应的状态轨迹,并估算累积奖励。接着选出奖励最高的10条轨迹,用它们的均值和方差来更新采样分布。迭代若干次后,返回奖励最高的动作序列的第一个动作。
最后,我们定义主循环,交替地采集数据、训练模型和规划动作:
def run(self):for i in range(self.n_iter):states, actions, _, next_states = self.collect_data(1000)self.train_model(states, actions, next_states)state = self.env.reset()for t in range(200): action = self.plan(torch.tensor(state, dtype=torch.float32))next_state, _, done, _ = self.env.step(action)state = next_stateif done:breakprint(f"Iteration {i}: lasted {t} steps")
主循环共执行n_iter
次,每次采集1000条数据,并用新数据训练模型。然后用规划器与环境交互200步,记录并打印生存时长。
下面我们创建环境、模型和MBRL对象,启动训练:
env = gym.make("InvertedPendulum-v2")
model = Model(state_dim=env.observation_space.shape[0], action_dim=env.action_space.shape[0])
mbrl = MBRL(env, model, n_plan=20, n_iter=10)mbrl.run()
运行这段代码,你将看到倒立摆在几次迭代后就能很快达到平衡位置并长时间维持。这充分展示了MBRL的高效性和可行性。当然,这只是一个简单示例,实际应用还需考虑更多技术细节,如模型集成、数据缓冲、策略约束等。感兴趣的读者可以进一步阅读MBRL的前沿文献。
5. 展望
MBRL利用环境模型来提高样本利用率和策略质量,是一种颇具前景的强化学习范式。近年来,随着深度学习的发展,MBRL在高维观察空间和连续动作空间上取得了长足的进步。一些代表性工作包括:
- ME-TRPO[Kurutach et al., 2018]:集成模型+TRPO策略优化
- SLBO[Luo et al., 2018]:基于模型的数据增强
- PETS[Chua et al., 2018]:集成模型+CEM规划
- POPLIN[Wang and Ba, 2019]:集成模型辅助TRPO策略优化
- POLO[Lowrey et al., 2019]:策略优化结合离线数据
- DMPO[Luo et al., 2019]:决策时集成规划
这些工作极大地拓展了MBRL的应用范围和实用价值。但MBRL还存在不少挑战:
- 如何学习更准确、更鲁棒的环境模型?
- 如何设计更高效、更可靠的规划和探索机制?
- 如何在模型训练和策略优化之间权衡计算资源?
- 如何处理复杂环境中的长期因果关系和延迟奖励?
- 如何提高模型和策略的泛化性和适应性?
这需要RL、DL、规划、控制等领域的协同创新。展望未来,MBRL有望与以下方向深度融合:
- 元学习:提高模型和策略的快速适应能力
- 迁移学习:实现跨任务、跨域的知识复用
- 因果推断:建模环境中的因果结构,实现更可解释、更稳定的策略学习
- 多智能体学习:解决多个智能体互动时的博弈和协作问题
MBRL代表了AI研究的一个重要趋势,即用知识引导数据驱动的学习。通过模型这种先验知识,我们可以更高效、更可靠、更可解释地学习决策。这不仅能造福强化学习本身,也为构建大模型、训练通用 AI 系统带来了新的思路。
Q&A
我用一个简单的例子来解释无模型(model-free)和有模型(model-based)强化学习的区别。
假设你要训练一个机器人学习走路,目标是走得尽可能快。环境的状态是机器人的关节角度和角速度,动作是施加在关节上的力矩。
无模型RL:
- 机器人尝试随机动作,观察状态变化和获得的奖励(与走得快慢相关)。
- 根据这些数据,直接学习一个策略函数,告诉机器人在每个状态下应该采取什么动作。
- 不断重复 1-2,使策略逐渐优化,最终学会快速行走。
# Model-free RL伪代码
for episode in range(n_episodes):state = env.reset() for step in range(max_steps):action = policy(state) # 策略根据状态直接产生动作next_state, reward = env.step(action)update_policy(state, action, reward, next_state) # 更新策略state = next_state
这种方法的特点是:
- 直接学习策略函数,没有对环境建模
- 需要大量的试错和样本数据
- 更新方向完全依赖当前策略采集的数据
有模型RL:
- 机器人尝试随机动作,观察状态变化,学习一个环境模型(输入当前状态+动作,预测下一状态)。
- 用学到的模型进行虚拟试错:在头脑中预演不同动作序列的结果,选出一个最优的方案。
- 令机器人执行这个方案并更新环境模型,不断重复 2-3,使策略和模型共同优化。
# Model-based RL伪代码
model = initialize_model()
for episode in range(n_episodes):state = env.reset()for step in range(max_steps): action_plan = plan_with_model(model, state) # 用模型预演,选取最优动作序列for planned_step in range(plan_horizon):action = action_plan[planned_step] next_state, reward = env.step(action)model.update(state, action, next_state) # 更新环境模型state = next_state
这种方法的特点是:
- 显式地学习环境模型,揭示了状态转移规律
- 通过模型预演来选取动作,减少真实环境中的试错
- 可利用模型产生额外的虚拟数据,加速策略学习
无模型RL就像在一个陌生的城市摸索前行,只能根据已走过的路来决定下一步走哪。而有模型RL则像拿到了一张地图,可以提前规划路线,少走弯路。
什么时候用model-based更好?
- 当环境状态转移规律较简单、容易建模时
- 当真实环境交互代价较高时(如机器人、自动驾驶)
- 当任务涉及多步规划、长期因果推理时
之前的无模型方法还有用吗?
- 当环境状态转移复杂、难以准确建模时
- 当大量采集真实数据的成本可以接受时
- 对于反应性的决策任务,无需多步规划时
model-free和model-based是两种不同的思路,各有优劣,应根据具体任务来选择。近年来,也有许多工作尝试将两者结合,取长补短。比如用无模型RL预训练,再用模型fine-tune;或者在model-based RL框架下引入无模型数据增强等。
这篇关于Stanford斯坦福 CS 224R: 深度强化学习 (3)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!