本文介绍了PPO算法及其实践。PPO是对策略梯度的改进,通过重要性采样将在线学习转为离线学习,能重复利用数据提升效率,PPO2通过clip限制偏差。文中还给出了基于MountainCar-v0环境的PPO实现代码,包括网络结构、数据处理和更新流程,最后展示了训练过程与效果。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜
Proximal Policy Optimization,简称PPO,即近端策略优化,是对Policy Graident,即策略梯度的一种改进算法。PPO的核心精神在于,通过一种被称之为Importce Sampling的方法,将Policy Gradient中On-policy的训练过程转化为Off-policy,即从在线学习转化为离线学习,某种意义上与基于值迭代算法中的Experience Replay有异曲同工之处。通过这个改进,训练速度与效果在实验上相较于Policy Gradient具有明显提升。
import argparseimport picklefrom collections import namedtuplefrom itertools import countimport timeimport os, timeimport numpy as npimport matplotlib.pyplot as pltimport gymimport paddleimport paddle.nn as nnimport paddle.nn.functional as Fimport paddle.optimizer as optimfrom paddle.distribution import Normal, Categoricalfrom paddle.io import RandomSampler, BatchSampler, Datasetfrom visualdl import LogWriter
# Parametersenv_name = 'MountainCar-v0'gamma = 0.99render = Falseseed = 1log_interval = 10env = gym.make(env_name).unwrapped
num_state = env.observation_space.shape[0]
num_action = env.action_space.n
env.seed(seed)
Transition = namedtuple('Transition', ['state', 'action', 'action_prob', 'reward', 'next_state'])
Actor部分定义的是“演员”,Critic部分定义的是“评论家”。“评论家”网络观察输入并“打分”,“演员”网络接收输入并给出行动的概率。
In [9]class Actor(nn.Layer):
def __init__(self):
super(Actor, self).__init__()
self.fc1 = nn.Linear(num_state, 128)
self.action_head = nn.Linear(128, num_action) def forward(self, x):
x = F.relu(self.fc1(x))
action_prob = F.softmax(self.action_head(x), axis=1) return action_probclass Critic(nn.Layer):
def __init__(self):
super(Critic, self).__init__()
self.fc1 = nn.Linear(num_state, 128)
self.state_value = nn.Linear(128, 1) def forward(self, x):
x = F.relu(self.fc1(x))
value = self.state_value(x) return value
policy gradient为on-policy,sample一次更新完actor之后,actor就变了,不能使用原来的数据了,必须重新与Env互动收集新数据,这导致训练需要大量互动,降低效率。
而PPO算法不仅可以将一次采样的数据分minibatch训练神经网络迭代多次,而且能够重复利用数据,也就是sample reuse。
由于训练中使用了off policy的数据(只有第一个更新是on policy,后面都是off policy),数据分布不同了,所以PPO使用了importance sampling来调整
研究了使用重要性采样实现on policy 到off policy的转换,我们知道期望值几乎是差不多的,计算了方差的公式,最后发现第二项对于方差的影响是很小的,但是第一项对于方差的影响还是有的。于是我们晓得,当使用重要性采样的时候,要保证只有p(x)和q(x)的区别不大,才会使得方差的区别很小。
PPO2的核心思想很简单,对于ratio 也就是当前policy和旧policy的偏差做clip,如果ratio偏差超过一定的范围就做clip,clip后梯度也限制在一定的范围内,神经网络更新参数也不会太离谱。这样,在实现上,无论更新多少步都没有关系,有clip给我们挡着,不担心训练偏了。
# init with datasetclass RandomDataset(Dataset):
def __init__(self, num_samples):
self.num_samples = num_samples def __getitem__(self, idx):
pass
def __len__(self):
return self.num_samples
In [11]
class PPO():
clip_param = 0.2
max_grad_norm = 0.5
ppo_update_time = 10
buffer_capacity = 8000
batch_size = 64
## 初始化参数
def __init__(self):
super(PPO, self).__init__()
self.actor_net = Actor()
self.critic_net = Critic()
self.buffer = []
self.counter = 0
self.training_step = 0
self.writer = LogWriter('./exp')
clip = nn.ClipGradByNorm(self.max_grad_norm)
self.actor_optimizer = optim.Adam(parameters = self.actor_net.parameters(),learning_rate= 1e-3, grad_clip=clip)
self.critic_net_optimizer = optim.Adam(parameters = self.critic_net.parameters(), learning_rate=3e-3,grad_clip=clip) if not os.path.exists('./param'):
os.makedirs('./param/net_param')
os.makedirs('./param/img') # 选择动作
def select_action(self, state):
state = paddle.to_tensor(state,dtype="float32").unsqueeze(0) with paddle.no_grad():
action_prob = self.actor_net(state)
dist = Categorical(action_prob)
action = dist.sample([1]).squeeze(0)
action = action.cpu().numpy()[0] return action, action_prob[:, int(action)].numpy()[0] # 评估值
def get_value(self, state):
state = paddle.to_tensor(state) with paddle.no_grad():
value = self.critic_net(state) return value.numpy() def save_param(self):
paddle.save(self.actor_net.state_dict(), './param/net_param/actor_net' + str(time.time())[:10] +'.param')
paddle.save(self.critic_net.state_dict(), './param/net_param/critic_net' + str(time.time())[:10] +'.param') def store_transition(self, transition):
self.buffer.append(transition)
self.counter += 1
def update(self, i_ep):
state = paddle.to_tensor([t.state for t in self.buffer], dtype="float32")
action = paddle.to_tensor([t.action for t in self.buffer], dtype="int64").reshape([-1, 1])
reward = [t.reward for t in self.buffer] # update: don't need next_state
old_action_prob = paddle.to_tensor([t.action_prob for t in self.buffer], dtype="float32").reshape([-1, 1])
R = 0
Gt = [] for r in reward[::-1]:
R = r + gamma * R
Gt.insert(0, R)
Gt = paddle.to_tensor(Gt, dtype="float32") # print("The agent is updateing....")
for i in range(self.ppo_update_time): for index in BatchSampler(sampler=RandomSampler(RandomDataset(len(self.buffer))), batch_size=self.batch_size, drop_last=False): if self.training_step % 1000 == 0: print('I_ep {} ,train {} times'.format(i_ep, self.training_step))
self.save_param()
index = paddle.to_tensor(index)
Gt_index = paddle.index_select(x=Gt, index=index).reshape([-1, 1])
# V = self.critic_net(state[index])
V = self.critic_net(paddle.index_select(state,index))
delta = Gt_index - V
advantage = delta.detach() # epoch iteration, PPO core!!!
action_prob = self.actor_net(paddle.index_select(state,index)) # new policy
action_prob = paddle.concat([action_prob[i][int(paddle.index_select(action,index)[i])] for i in range(len(action_prob))]).reshape([-1,1])
ratio = (action_prob / paddle.index_select(old_action_prob,index))
surr1 = ratio * advantage
surr2 = paddle.clip(ratio, 1 - self.clip_param, 1 + self.clip_param) * advantage # update actor network
surr = paddle.concat([surr1,surr2],1)
action_loss = -paddle.min(surr,1).mean() # MAX->MIN desent
self.writer.add_scalar('loss/action_loss', action_loss, self.training_step)
self.actor_optimizer.clear_grad()
action_loss.backward()
self.actor_optimizer.step() # update critic network
value_loss = F.mse_loss(Gt_index, V)
self.writer.add_scalar('loss/value_loss', value_loss, self.training_step)
self.critic_net_optimizer.clear_grad()
value_loss.backward()
self.critic_net_optimizer.step()
self.training_step += 1
del self.buffer[:] # clear experiencedef main():
agent = PPO() for i_epoch in range(1000):
state = env.reset() if render: env.render() for t in count():
action, action_prob = agent.select_action(state)
next_state, reward, done, _ = env.step(action)
trans = Transition(state, action, action_prob, reward, next_state) if render: env.render()
agent.store_transition(trans)
state = next_state if done : if len(agent.buffer) >= agent.batch_size: agent.update(i_epoch)
agent.writer.add_scalar('Steptime/steptime', t, i_epoch) # print("Number of steps to achieve the goal:{} , Steptime:{}".format(t,i_epoch))
breakif __name__ == '__main__':
main() print("end")I_ep 0 ,train 0 times I_ep 0 ,train 1000 times I_ep 0 ,train 2000 times I_ep 0 ,train 3000 times I_ep 0 ,train 4000 times I_ep 0 ,train 5000 times I_ep 1 ,train 6000 times I_ep 5 ,train 7000 times I_ep 11 ,train 8000 times I_ep 19 ,train 9000 times I_ep 34 ,train 10000 times I_ep 60 ,train 11000 times I_ep 89 ,train 12000 times I_ep 120 ,train 13000 times I_ep 150 ,train 14000 times I_ep 182 ,train 15000 times I_ep 211 ,train 16000 times I_ep 242 ,train 17000 times I_ep 273 ,train 18000 times I_ep 303 ,train 19000 times I_ep 333 ,train 20000 times I_ep 364 ,train 21000 times I_ep 398 ,train 22000 times I_ep 431 ,train 23000 times I_ep 461 ,train 24000 times I_ep 494 ,train 25000 times I_ep 529 ,train 26000 times I_ep 565 ,train 27000 times I_ep 596 ,train 28000 times I_ep 631 ,train 29000 times I_ep 659 ,train 30000 times I_ep 694 ,train 31000 times I_ep 728 ,train 32000 times I_ep 763 ,train 33000 times I_ep 797 ,train 34000 times I_ep 833 ,train 35000 times I_ep 872 ,train 36000 times I_ep 910 ,train 37000 times I_ep 945 ,train 38000 times I_ep 983 ,train 39000 times end
# 的是
# 出了
# 使用了
# 是个
# 都是
# 转化为
# 就将
# 互动
# 迭代
# 离线
# ai
# 算法
# transition
# len
# class
# 循环
# int
# for
# 区别
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
网络优化91478 】
【
技术知识72672 】
【
云计算0 】
【
GEO优化84317 】
【
优选文章0 】
【
营销推广36048 】
【
网络运营41350 】
【
案例网站102563 】
【
AI智能45237 】
相关推荐:
tofai官网最新入口地址 tofai网页版免下载
飞常准AI如何预判放票时间_飞常准AI放票时间预测与抢票时机【技巧】
Voice AI:下一代AI语音助手,重塑人机交互
佐糖AI抠图如何免费使用_佐糖AI免费额度获取与消耗查看【指南】
构建卓越的AI驱动测试自动化框架:QA工程师指南
歌曲分析:The Killers乐队的《Mr. Brightside》歌词深度解析
Elon Musk会解决X平台上的机器人问题吗?塔罗牌预测
Sim.AI教程:构建智能客户支持助手
Midjourney怎么用一键生成海报_Midjourney海报生成教程【方法】
小米汽车OTA冬季大版本升级:新增和优化共计9项功能
AI视频生成终极指南:免费为店铺打造引流爆款
2025最佳AI效率工具:释放生产力,革新业务运营
使用 Claude 4 和 n8n 实现 AI 工作流自动化
lovemo官网网页版入口 lovemo官网登录入口
DeepSeek解释机器学习模型 DeepSeek数据科学学习指南
Depseek怎么生成员工成长总结_Depseek成长维度提取与案例整合【方法】
教你用AI将一篇长文自动拆解成社交媒体帖子,实现一文多发
AI女友:时尚穿搭与美丽瞬间的完美融合
Midjourney怎样做PPT模板_MidjourneyPPT模板生成【方法】
AI绘画工具怎么用_AI绘画工具使用方法详细指南【教程】
如何通过 DeepSeek 优化分布式存储系统架构
AI赋能保险销售:提升邮件营销效果的终极指南
百度搜索ai助手怎么关闭 百度搜索ai对话屏蔽方法
为什么你的简历过不了筛选?用AI帮你诊断并修复漏洞
AI时代生存指南:掌握软实力,成为不可替代的人
EdrawMax AI:使用人工智能快速创建流程图和图表
Avokaado AI:简化合同管理和法律流程的终极指南
ChatGPT背后的AI革命:OpenAI的崛起与Google的危机
DeepSeek 辅助进行 Linux 内核参数调优教程
3步教你用AI将你的照片变成乐高积木风格
怎么使用网页版deepseek【教程】
豆包AI帮你写代码注释 豆包AI编程辅助教程
Descript vs. Wisecut:AI视频编辑工具深度测评与最佳选择
软件工程师必备的AI工具:提升效率的六款利器
Cred.ai信用卡深度评测:信用提升的秘密武器
怎么用AI帮你写一份客户感谢信?维系客户关系的利器
使用AI代码生成器轻松构建Web应用程序:Beela vs. Google AI Studio
壹伴AI智能排版如何自动生成文章配图_壹伴AI智能排版配图生成与版权说明【教程】
AI伴侣:连接还是孤独?真实对话揭秘AI伦理困境
如何通过文心一言进行地道的文言文翻译
Artspace.ai: AI驱动的创意设计平台,提升小企业营销效率
文心一言解读法律条文教程 文心一言专业领域应用
AI代码助手的崛起:软件工程的未来展望与实用指南
AI产品经理:AI赋能与AI原生,未来PM的技能演进
旅游营销AI:ChatGPT邮件营销策略,提升旅游业务转化率
ChatGPT 处理超长 PDF 文件的核心步骤
AI赋能抵押贷款:Total Expert AI 销售助理深度解析
批改网ai检测工具能否检测引用格式_批改网ai检测工具引用格式检查与修正提示【攻略】
百度AI搜索能否查实时新闻_百度AI搜索新闻频道与更新频率【方法】
OpenAI Sora 2:AI视频生成新纪元
2025-07-18
南京市珐之弘网络技术有限公司专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。