网易首页 > 网易号 > 正文 申请入驻

近端策略优化(PPO)算法的理论基础与PyTorch代码详解

0
分享至

近端策略优化(Proximal Policy Optimization, PPO)算法作为一种高效的策略优化方法,在深度强化学习领域获得了广泛应用。特别是在大语言模型(LLM)的人类反馈强化学习(RLHF)过程中,PPO扮演着核心角色。本文将深入探讨PPO的基本原理和实现细节。

PPO属于在线策略梯度方法的范畴。其基础形式可以用带有优势函数的策略梯度表达式来描述:

策略梯度的基础表达式(包含优势函数)。

这个表达式实际上构成了优势演员-评论家(Advantage Actor-Critic)方法的基础目标函数。PPO算法可以视为对该方法的一种改进和优化。

PPO算法的损失函数设计

PPO通过引入策略更新约束机制来提升训练稳定性。这种机制很好地平衡了更新幅度:过大的策略更新可能导致训练偏离优化方向,而过小的更新则可能降低训练效率。为此,PPO采用了一个特殊的替代目标函数,该函数由裁剪项和非裁剪项组成,并取两者的最小值。

PPO的损失函数结构。

替代损失函数的非裁剪部分分析

损失函数中的非裁剪部分示意图。

在PPO中,比率函数定义为在状态st下执行动作at时,当前策略与旧策略的概率比值。

策略概率比率r(θ)的定义。

这个比率函数r(θ)为我们提供了一个度量新旧策略差异的有效工具,它可以替代传统策略梯度目标函数中的对数概率项。非裁剪部分的损失通过将此比率与优势函数相乘得到。

非裁剪部分损失计算示意图。

替代损失函数的裁剪机制

为了防止过大的策略更新,PPO引入了裁剪机制,将策略比率r(θ)限制在[1-ϵ, 1+ϵ]的区间内。其中ϵ是一个重要的超参数,在PPO的原始论文中设定为0.2。这样,我们可以得到完整的PPO目标函数:

PPO完整目标函数,包含非裁剪项和裁剪项。

PPO的最终优化目标是在这两部分中取较小值,从而实现稳定的策略优化。

算法实现流程

1. 系统初始化
a. 设置随机种子
b. 初始化演员网络与评论家网络的优化器
c. 配置损失追踪器和奖励记录器
d. 加载超参数配置
2. 训练回合迭代
a. 环境重置
b. 回合内循环:
i. 通过演员网络预测动作概率分布并采样
ii. 记录动作的对数概率(作为old policy的参考)
iii. 执行环境交互,获取转移数据
c. 计算衰减回报
d. 存储回合经验数据
e. 按更新频率执行网络优化:
i. 评估状态价值
ii. 计算优势估计
iii. 构建PPO损失函数
iv. 执行梯度优化
3. 训练监控
a. 记录并可视化平均损失指标

PyTorch实现详解

1、初始化**

torch.manual_seed(self.cfg['train']['random_seed'])
actor_optim = optim.Adam(self.actor.parameters(), lr=self.cfg['train']['lr'], betas=self.cfg['train']['betas'])
critic_optim = optim.Adam(self.critic.parameters(), lr=self.cfg['train']['lr'], betas=self.cfg['train']['betas'])
avg_actor_losses = []
avg_critic_losses = []
actor_losses = []
critic_losses = []
eps = np.finfo(np.float32).eps.item()
batch_data = []

2、回合循环

2.1 重置环境

for episode in range(self.cfg['train']['n_epidode']):
rewards = []
log_probs = []
actions = []
states = []
state_values = []
self.actor.train()
self.critic.train()
terminated, truncated = False, False # 初始化终止和截断标志
state, info = self.env.reset()
# 转换为张量
state = torch.FloatTensor(state).to(self.device)

2.2 当回合未结束时:

timesteps = 0
# 遍历时间步
while not terminated and not truncated:
timesteps += 1

演员预测动作概率并从分布中采样动作。

# 演员层输出动作概率,因为演员神经网络在输出层有softmax
action_prob = self.actor(state)
# 我们知道我们不直接使用分类交叉熵损失函数,而是手动构建以获得更多控制。
# PyTorch中的分类交叉熵损失函数使用softmax将logits转换为概率到分类分布,
# 然后计算损失。所以通常不需要显式地将softmax函数添加到神经网络中。在这项工作中,
# 我们在神经网络上添加softmax层并计算分类分布。
# categorical函数可以从softmax概率或从logits(输出中没有softmax层)生成分类分布,
# 将logits作为属性
action_dist= Categorical(action_prob)
# 采样动作
action = action_dist.sample()
actions.append(action)

获取对数概率,这被视为比率的log pi_theta_old

# 获取对数概率以得到log pi_theta_old(a|s)并保存到列表中
log_probs.append(action_dist.log_prob(action))

在环境中执行动作,获取下一个状态、奖励和终止标志。

# 动作必须从张量转换为numpy以供环境处理
next_state, reward, terminated, truncated, info = self.env.step(action.item())
rewards.append(reward)
# 将下一个状态分配为当前状态
state = torch.FloatTensor(next_state).to(self.device)

2.3 计算折扣回报

R = 0
returns = [] # 用于保存真实值的列表
# 使用环境在回合中返回的奖励计算每个回合的回报
for r in rewards[::-1]:
# 计算折扣值
R = r + self.cfg['train']['gamma'] * R
returns.insert(0, R)
returns = torch.tensor(returns).to(self.device)
returns = (returns - returns.mean()) / (returns.std() + eps)

2.4 将每个回合的经验存储在batch_data中

# 存储数据
batch_data.append([states, actions, returns, log_probs, state_values])

2.5 每update_freq回合更新网络:

if episode != 0 and episode%self.cfg['train']['update_freq'] == 0:
# 这是我们更新网络一些n个epoch的循环。这个额外的for循环
# 改善了训练效果
for _ in range(5):
for states_b, actions_b, returns_b, old_log_probs, old_state_values in batch_data:
# 将列表转换为张量
old_states = torch.stack(states_b, dim=0).detach()
old_actions = torch.stack(actions_b, dim=0).detach()
old_log_probs = torch.stack(old_log_probs, dim=0).detach()

计算状态值

state_values = self.critic(old_states)

计算优势。

# 计算优势
advantages = returns_b.detach() - state_values.detach()
# 规范化优势在理论上不是必需的,但在实践中它降低了我们优势的方差,
# 使收敛更加稳定和快速。我添加这个是因为
# 解决一些环境问题如果没有它会太不稳定。
advantages = (advantages - advantages.mean()) / (advantages.std() + 1e-10)

计算演员和评论家的PPO损失。

# 现在我们需要计算比率(pi_theta / pi_theta__old)。为了做到这一点,
# 我们需要从存储的状态中获取所采取动作的旧策略,并计算相同动作的新策略
# 演员层输出动作概率,因为演员神经网络在输出层有softmax
action_probs = self.actor(old_states)
dist = Categorical(action_probs)
new_log_probs = dist.log_prob(old_actions)
# 因为我们取对数,所以我们可以用减法代替除法。然后取指数将得到与除法相同的结果
ratios = torch.exp(new_log_probs - old_log_probs)
# 替代损失函数的非裁剪部分
surr1 = ratios * advantages
# 替代损失函数的裁剪部分
surr2 = torch.clamp(ratios, 1 - self.cfg['train']['clip_param'], 1 + self.cfg['train']['clip_param']) * advantages
# 更新演员网络:loss = min(surr1, surr2)
actor_loss = -torch.min(surr1, surr2).mean()
actor_losses.append(actor_loss.item())
# 使用Huber损失计算评论家(价值)损失
# Huber损失对数据中的异常值比平方误差损失更不敏感。在基于价值的RL设置中,
# 推荐使用Huber损失。
# Smooth L1损失与HuberLoss密切相关
critic_loss = F.smooth_l1_loss(state_values, returns_b.unsqueeze(1)) #F.huber_loss(state_value, torch.tensor([R]))
critic_losses.append(critic_loss.item())

使用梯度下降更新网络

actor_optim.zero_grad()
critic_optim.zero_grad()
# 执行反向传播
actor_loss.backward()
critic_loss.backward()
# 执行优化
actor_optim.step()
critic_optim.step()

完整代码

https://avoid.overfit.cn/post/ff4d892c414a4b9c9391a1812690eceb

作者:Dhanoop Karunakaran

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
炸锅!穆里尼奥岌岌可危!皇马换帅锁定世界级名帅

炸锅!穆里尼奥岌岌可危!皇马换帅锁定世界级名帅

奶盖熊本熊
2026-10-20 07:26:46
鸿蒙智行销量连降4个月全年或现负增长 前三季问界交付跌12.6%智界下滑24.5%

鸿蒙智行销量连降4个月全年或现负增长 前三季问界交付跌12.6%智界下滑24.5%

长江商报
2026-10-19 10:59:13
美国威胁称,如果欧洲优先考虑本国卫星通信公司,将面临严重后果

美国威胁称,如果欧洲优先考虑本国卫星通信公司,将面临严重后果

山河路口
2026-10-19 13:02:09
大快人心!缅北电诈骨干廖景芳一审获死刑,当庭崩溃晕厥

大快人心!缅北电诈骨干廖景芳一审获死刑,当庭崩溃晕厥

阿莱美食汇
2026-10-19 04:57:30
29投狂轰44分8板!张镇麟这2战杀疯了:郭士强该让他重返国家队了?

29投狂轰44分8板!张镇麟这2战杀疯了:郭士强该让他重返国家队了?

篮球快餐车
2026-10-20 05:48:52
菲律宾罕见派其最新、最强护卫舰侵扰黄岩岛,中方出动4艘军舰应对!

菲律宾罕见派其最新、最强护卫舰侵扰黄岩岛,中方出动4艘军舰应对!

华人星光
2026-10-18 10:25:50
外媒:“汽车变得越来越中国化,这一趋势在巴黎尤为明显”

外媒:“汽车变得越来越中国化,这一趋势在巴黎尤为明显”

中国青年报
2026-10-19 17:58:27
手机市场搞笑一幕,国产手机涨价没人买,如今又降价千元促销

手机市场搞笑一幕,国产手机涨价没人买,如今又降价千元促销

柏铭锐谈
2026-10-19 06:52:51
深圳楼市彻底分裂:有人2280万抢香蜜湖,有人280万龙岗房难卖

深圳楼市彻底分裂:有人2280万抢香蜜湖,有人280万龙岗房难卖

说故事的阿袭
2026-10-20 06:35:31
两部门:对盾构机等物项实施出口管制

两部门:对盾构机等物项实施出口管制

界面新闻
2026-10-19 15:05:32
张雪:给这个赛季打90分!本来只想上1次领奖台 结果拿了6个冠军

张雪:给这个赛季打90分!本来只想上1次领奖台 结果拿了6个冠军

念洲
2026-10-20 07:14:29
大连足球曾殖民川足肢解全兴队 这笔旧账本周六要在凤凰山一起算

大连足球曾殖民川足肢解全兴队 这笔旧账本周六要在凤凰山一起算

劲爆体坛
2026-10-20 08:11:09
又一个被抓到缅甸,重庆24岁的郑凡,去西双版纳散心,人没回来

又一个被抓到缅甸,重庆24岁的郑凡,去西双版纳散心,人没回来

蹲坑看世界
2026-10-17 19:28:40
一根烟换不回的命——徐浦大桥惨剧背后隐藏的警示

一根烟换不回的命——徐浦大桥惨剧背后隐藏的警示

匹夫来搞笑
2026-10-19 14:26:20
四川多地用硫磺熏制鲜竹笋,严重可损伤肝肾且致癌,去年查获1900公斤仅罚款500元

四川多地用硫磺熏制鲜竹笋,严重可损伤肝肾且致癌,去年查获1900公斤仅罚款500元

界面新闻
2026-10-19 19:02:52
克莱伯:进球后想第一时间跟蔡主席分享喜悦,希望他能开心

克莱伯:进球后想第一时间跟蔡主席分享喜悦,希望他能开心

懂球帝
2026-10-19 18:54:50
美国人终于发现了:中国的东风导弹,不用击沉我们航母,擦着即伤

美国人终于发现了:中国的东风导弹,不用击沉我们航母,擦着即伤

潘鍵旅行浪子
2026-10-16 14:53:23
东莞社保需补缴9个月差额!要补多少钱?

东莞社保需补缴9个月差额!要补多少钱?

东莞纪实
2026-10-19 18:47:35
难逃重罚!英媒:曼城本赛季将被巨额扣分 确保其降级 曼苏尔将走人

难逃重罚!英媒:曼城本赛季将被巨额扣分 确保其降级 曼苏尔将走人

风过乡
2026-10-19 21:53:27
看了梅婷 ,再看郝蕾才知:会打扮与不会打扮的女人,差距多大

看了梅婷 ,再看郝蕾才知:会打扮与不会打扮的女人,差距多大

娱圈办事处
2026-10-16 17:17:26
2026-10-20 09:56:49
deephub incentive-icons
deephub
CV NLP和数据挖掘知识
2028文章数 1465关注度
往期回顾 全部

科技要闻

新版MiniMax,能和DeepSeek掰手腕吗?

头条要闻

两名男性设局和女局长接触并发生关系 其中一人未成年

头条要闻

两名男性设局和女局长接触并发生关系 其中一人未成年

体育要闻

从NBA退役10年后,他真去警局上班了

娱乐要闻

李连杰回应抛妻弃女传闻,透露四个女儿关系

财经要闻

宁德时代的大时代结束了吗?

汽车要闻

不知道二代海鸥多好玩? 上赛道跑两圈 很过瘾的

态度原创

时尚
本地
数码
健康
公开课

4种“棒针毛衣”穿搭,美翻了!

本地新闻

一场垂直登高赛跑出了"山城"的真正内核

数码要闻

57亿美元赔款还不够,Taction要求苹果支付iPhone与Apple Watch专利费至2035年

看着很健康的人,怎么会突然猝死?

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版