一篇文章彻底掌握PPO强化学习算法
1 引言在强化学习的众多流派中,策略梯度方法一度是直接优化策略的主力军。但传统的REINFORCE算法有一个硬伤——方差高、收敛慢,就像一个新手司机,方向盘打得太猛,容易跑偏。后来Schulman等人提出了近端策略优化算法(PPO),核心思路是在更新策略时加一个“安全带”:既保证更新幅度别太大,又
1. 引言
在强化学习的众多流派中,策略梯度方法一度是直接优化策略的主力军。但传统的REINFORCE算法有一个硬伤——方差高、收敛慢,就像一个新手司机,方向盘打得太猛,容易跑偏。后来Schulman等人提出了近端策略优化算法(PPO),核心思路是在更新策略时加一个“安全带”:既保证更新幅度别太大,又让计算过程足够简洁。结果大家也看到了,这个算法几乎成了现代强化学习任务的标准配置。
2. 算法原理
PPO的核心思想其实很直观:别让新旧策略之间差距太大,否则很容易学崩。具体来说,它通过一个精心设计的目标函数来驱动更新,公式长这样:
其中:
- 表示新旧策略的概率比,就是新策略相对旧策略的“变化幅度”。
- 是优势函数(Advantage Function)的估计,它告诉我们当前动作比平均水平好多少。
- 是一个超参数,用来控制截断的窗口大小——可以理解为允许策略变化的“安全阈值”。
2.1 优势函数估计
优势函数 通常用广义优势估计(GAE)来计算,公式如下:
这里的TD残差 定义为:
是折扣因子, 是平衡偏差和方差的参数。简单说,GAE相当于在单步TD和蒙特卡洛估计之间做插值, 越小越偏向单步,越大越像完整回报。
2.2 策略更新
PPO的策略更新就是最大化 。由于引入了 操作,当 超出 范围时,损失函数对 不再敏感——这就像一个限速器,确保每次更新步子不会迈得太大。
2.3 价值网络更新
除了策略网络,PPO还维护一个价值网络来估计状态值函数 ,损失函数如下:
其中 是对真实价值的估计,常用TD目标:
2.4 总损失函数
把策略损失、价值损失以及一个熵正则项(鼓励探索)揉在一起,就得到了PPO的总损失:
其中:
- 和 是权重系数,用来调节各部分在总损失中的比重。
- 是策略的熵,熵越大说明策略越随机,有助于在训练初期多探索。
3. 案例分析
理论讲完了,来点实际的。我们在经典的CartPole-v1环境上跑了一个PPO实验。这个任务很简单:控制小车左右移动,让上面的杆子保持直立不倒。
3.1 代码实现
下面给出PPO算法在CartPole-v1上的核心代码(完整实现参考后续说明):
class PPO:
'''PPO算法'''
def __init__(self, state_dim, hidden_dim, action_dim, actor_lr, critic_lr, gamma,
lmbda, epsilon, epochs, device):
self.action_dim = action_dim
self.actor_critic = ActorCritic(state_dim, hidden_dim, action_dim).to(device)
self.actor_optimizer = optim.Adam(self.actor_critic.actor_parameters(), lr=actor_lr)
self.critic_optimizer = optim.Adam(self.actor_critic.critic_parameters(), lr=critic_lr)
self.gamma = gamma # 折扣因子
self.lmbda = lmbda # GAE参数
self.epsilon = epsilon # PPO截断范围
self.epochs = epochs # PPO的更新次数
self.device = device
def take_action(self, state):
'''根据策略网络选择动作'''
state = torch.tensor([state], dtype=torch.float).to(self.device)
with torch.no_grad():
action_probs, _ = self.actor_critic(state)
dist = torch.distributions.Categorical(action_probs)
action = dist.sample()
return action.item()
def update(self, transition_dict):
'''更新策略网络和价值网络'''
states = torch.tensor(transition_dict['states'], dtype=torch.float).to(self.device)
actions = torch.tensor(transition_dict['actions']).view(-1).to(self.device)
rewards = torch.tensor(transition_dict['rewards'], dtype=torch.float).view(-1, 1).to(self.device)
next_states = torch.tensor(transition_dict['next_states'], dtype=torch.float).to(self.device)
dones = torch.tensor(transition_dict['dones'], dtype=torch.float).view(-1, 1).to(self.device)
# 计算TD误差和优势函数
_, state_values = self.actor_critic(states)
_, next_state_values = self.actor_critic(next_states)
td_target = rewards + self.gamma * next_state_values * (1 - dones)
delta = td_target - state_values
delta = delta.detach().cpu().numpy()
# Generalized Advantage Estimation (GAE)
advantage_list = []
advantage = 0.0
for delta_t in delta[::-1]:
advantage = self.gamma * self.lmbda * advantage + delta_t[0]
advantage_list.append([advantage])
advantage_list.reverse()
advantages = torch.tensor(advantage_list, dtype=torch.float).to(self.device)
# 计算旧策略的log概率
with torch.no_grad():
action_probs_old, _ = self.actor_critic(states)
dist_old = torch.distributions.Categorical(action_probs_old)
log_probs_old = dist_old.log_prob(actions)
# 更新策略网络和价值网络
for _ in range(self.epochs):
action_probs, state_values = self.actor_critic(states)
dist = torch.distributions.Categorical(action_probs)
log_probs = dist.log_prob(actions)
ratio = torch.exp(log_probs - log_probs_old)
surr1 = ratio * advantages.squeeze()
surr2 = torch.clamp(ratio, 1 - self.epsilon, 1 + self.epsilon) * advantages.squeeze()
actor_loss = -torch.mean(torch.min(surr1, surr2))
critic_loss = F.mse_loss(state_values, td_target.detach())
# 更新策略网络
self.actor_optimizer.zero_grad()
actor_loss.backward()
self.actor_optimizer.step()
# 更新价值网络
self.critic_optimizer.zero_grad()
critic_loss.backward()
self.critic_optimizer.step()
3.2 结果分析
Iteration 1: 100%|██████████| 30/30 [00:00<00:00, 66.19it/s, Episode=30/300, A verage Return=10.00]
Iteration 2: 100%|██████████| 30/30 [00:00<00:00, 36.67it/s, Episode=60/300, A verage Return=162.90]
Iteration 3: 100%|██████████| 30/30 [00:01<00:00, 24.94it/s, Episode=90/300, A verage Return=278.70]
Iteration 4: 100%|██████████| 30/30 [00:01<00:00, 19.59it/s, Episode=120/300, A verage Return=287.80]
Iteration 5: 100%|██████████| 30/30 [00:01<00:00, 17.57it/s, Episode=150/300, A verage Return=240.70]
Iteration 6: 100%|██████████| 30/30 [00:01<00:00, 21.10it/s, Episode=180/300, A verage Return=354.60]
Iteration 7: 100%|██████████| 30/30 [00:02<00:00, 12.90it/s, Episode=210/300, A verage Return=450.50]
Iteration 8: 100%|██████████| 30/30 [00:02<00:00, 11.59it/s, Episode=240/300, A verage Return=500.00]
Iteration 9: 100%|██████████| 30/30 [00:02<00:00, 11.52it/s, Episode=270/300, A verage Return=475.50]
Iteration 10: 100%|██████████| 30/30 [00:02<00:00, 11.31it/s, Episode=300/300, A verage Return=500.00]
从训练输出可以看到,智能体的平均回报从一开始的10,到第8个迭代就已经达到了500(环境满分),之后稳定在满分水平。说明PPO在大约200个回合左右就学会了“怎么让杆子不倒下”。
学习曲线也印证了这一点:经过约200个回合,智能体表现达到了环境最高分。这验证了PPO在处理连续状态和离散动作问题上确实有一手——既高效又稳定。
4. 总结
PPO通过一个简洁的概率比截断机制,配合GAE优势估计,实现了既安全又快速的策略更新。在CartPole这样的经典测试环境中,它快速收敛到最优策略,表现稳定。正因为它简单又有效,PPO已经成为当前强化学习领域最受欢迎的算法之一,从机器人控制到游戏AI,到处都有它的身影。
你是一名 AI 行业编辑,请围绕下面这条热点输出一份资讯解读:
热点:一篇文章彻底掌握PPO强化学习算法要求:
1. 先用一句话解释这条热点在讲什么
2. 再总结它为什么重要
3. 说明会影响哪些 AI 产品或内容方向
4. 最后给出 3 个适合资讯站使用的标题
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
相关热点先来看看Remaker AI这款工具。它的定位非常清晰——专注于解决图像处理中的常见难题:水印、文字、多余元素,以及低分辨率图像的修复与放大。无论是设计师、社交媒体运营人员,还是普通用户,只要遇到需要“清理”图片的场景,它都能轻松应对。下面直接了解它的适用人群和实际能力。 需求人群 Remaker
文心大模型覆盖文化传媒、艺术创作、教育科研、金融保险、医疗健康等需文字与创意的场景,集成文本生成、文生图、智能对话、信息抽取、文本纠错、古诗创作、文案续写等十余种文字处理能力。
今天我们来聊一款非常实用的浏览器工具——Ask AI Browser。如果你经常在Google上搜索问题,又希望随时与AI对话,或者在浏览各类网站时想直接向AI提问,那么这款工具可能会为你的日常浏览体验带来显著提升。 目标用户群体 简单来说,它主要面向以下几类用户:在Google上搜索问题时,希望无
说起来,联通云盘这事儿,其实就是中国联通在云存储这条赛道上的一次重要布局。目标很明确:为个人和家庭用户解决海量数据存储的刚需。具体能干啥呢?个人云、家庭云、微信 通讯录 相册备份、多端文件共享……说白了,就是从存储到共享的一条龙服务。 联通云盘官网网页版登录入口网址:https: pan wo c
- 日榜
- 周榜
- 月榜
热点快看
