首页 游戏 软件 资讯 排行榜 专题
首页
AI
近端策略优化PPO-算法简析-paddle2.0

近端策略优化PPO-算法简析-paddle2.0

热心网友
15
转载
2025-07-18
本文介绍了PPO算法及其实践。PPO是对策略梯度的改进,通过重要性采样将在线学习转为离线学习,能重复利用数据提升效率,PPO2通过clip限制偏差。文中还给出了基于MountainCar-v0环境的PPO实现代码,包括网络结构、数据处理和更新流程,最后展示了训练过程与效果。

近端策略优化ppo-算法简析-paddle2.0 - 游乐网

PPO算法介绍

Proximal Policy Optimization,简称PPO,即近端策略优化,是对Policy Graident,即策略梯度的一种改进算法。PPO的核心精神在于,通过一种被称之为Importce Sampling的方法,将Policy Gradient中On-policy的训练过程转化为Off-policy,即从在线学习转化为离线学习,某种意义上与基于值迭代算法中的Experience Replay有异曲同工之处。通过这个改进,训练速度与效果在实验上相较于Policy Gradient具有明显提升。

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈

环境配置

In [7]
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
登录后复制

MountainCar-v0介绍

汽车位于一维轨道上,位于两个“山”之间。 目标是驶向右边的山峰; 但是,汽车的引擎强度不足以单程通过。 因此,成功的唯一方法就是来回驱动以建立动力。在每个时刻,智能体可以对小车施加3种动作中的一种:向左施力、不施力、向右施力。智能体施力和小车的水平位置会共同决定小车下一时刻的速度。本项目'MountainCar-v0'环境开启了unwrapped模式,即只有到达右边的山峰才能结束一轮游戏,在开始的阶段可能模型要试探上万步才能完成任务,这可真是个稀疏回报的强化学习环境。

近端策略优化PPO-算法简析-paddle2.0 - 游乐网

In [8]
# Parametersenv_name = 'MountainCar-v0'gamma = 0.99render = Falseseed = 1log_interval = 10env = gym.make(env_name).unwrappednum_state = env.observation_space.shape[0]num_action = env.action_space.nenv.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)

Policy Gradient是DRL中一大类方法,核心思想就是直接优化策略网络Policy Network: π(as;θ)π(a∣s;θ) 来提升Reward的获取。怎么直接优化policy呢? 采样很多样本,判断样本的好坏,如果样本好,就将对应的动作action概率增大,如果样本差,就将对应的动作action概率减少。Policy gradient方法是on policy的,因此要求每次使用on policy的数据进行训练,所谓on policy就是采样数据的策略和要评估及训练的策略是同一个策略。

PPO算法

1.importance sampling 的使用

policy gradient为on-policy,sample一次更新完actor之后,actor就变了,不能使用原来的数据了,必须重新与Env互动收集新数据,这导致训练需要大量互动,降低效率。

而PPO算法不仅可以将一次采样的数据分minibatch训练神经网络迭代多次,而且能够重复利用数据,也就是sample reuse。

由于训练中使用了off policy的数据(只有第一个更新是on policy,后面都是off policy),数据分布不同了,所以PPO使用了importance sampling来调整近端策略优化PPO-算法简析-paddle2.0 - 游乐网

研究了使用重要性采样实现on policy 到off policy的转换,我们知道期望值几乎是差不多的,计算了方差的公式,最后发现第二项对于方差的影响是很小的,但是第一项对于方差的影响还是有的。于是我们晓得,当使用重要性采样的时候,要保证只有p(x)和q(x)的区别不大,才会使得方差的区别很小。

近端策略优化PPO-算法简析-paddle2.0 - 游乐网

2.PPO2的核心思想

PPO2的核心思想很简单,对于ratio 也就是当前policy和旧policy的偏差做clip,如果ratio偏差超过一定的范围就做clip,clip后梯度也限制在一定的范围内,神经网络更新参数也不会太离谱。这样,在实现上,无论更新多少步都没有关系,有clip给我们挡着,不担心训练偏了。

近端策略优化PPO-算法简析-paddle2.0 - 游乐网

3.本项目代码简析

本项目采用 namedtuple('Transition', ['state', 'action', 'action_prob', 'reward', 'next_state'])的方式收集数据集构造了一个 class RandomDataset(Dataset)的类,便于后续使用for index in BatchSampler(sampler=RandomSampler(RandomDataset(len(self.buffer))), batch_size=self.batch_size, drop_last=False)的方式来采样收集的数据,并循环迭代了self.ppo_update_time次,这样就实现了一次采样的数据分minibatch训练神经网络迭代多次。用action_prob = paddle.concat([action_prob[i][int(paddle.index_select(action,index)[i])] for i in range(len(action_prob))]).reshape([-1,1]) 来选择动作概率。用paddle.clip(ratio, 1 - self.clip_param, 1 + self.clip_param) * advantage来截断advantage演员网络的损失为 action_loss = -paddle.min(surr,1).mean() ,评论家网络的损失为value_loss = F.mse_loss(Gt_index, V)In [10]
# 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 timesI_ep 0 ,train 1000 timesI_ep 0 ,train 2000 timesI_ep 0 ,train 3000 timesI_ep 0 ,train 4000 timesI_ep 0 ,train 5000 timesI_ep 1 ,train 6000 timesI_ep 5 ,train 7000 timesI_ep 11 ,train 8000 timesI_ep 19 ,train 9000 timesI_ep 34 ,train 10000 timesI_ep 60 ,train 11000 timesI_ep 89 ,train 12000 timesI_ep 120 ,train 13000 timesI_ep 150 ,train 14000 timesI_ep 182 ,train 15000 timesI_ep 211 ,train 16000 timesI_ep 242 ,train 17000 timesI_ep 273 ,train 18000 timesI_ep 303 ,train 19000 timesI_ep 333 ,train 20000 timesI_ep 364 ,train 21000 timesI_ep 398 ,train 22000 timesI_ep 431 ,train 23000 timesI_ep 461 ,train 24000 timesI_ep 494 ,train 25000 timesI_ep 529 ,train 26000 timesI_ep 565 ,train 27000 timesI_ep 596 ,train 28000 timesI_ep 631 ,train 29000 timesI_ep 659 ,train 30000 timesI_ep 694 ,train 31000 timesI_ep 728 ,train 32000 timesI_ep 763 ,train 33000 timesI_ep 797 ,train 34000 timesI_ep 833 ,train 35000 timesI_ep 872 ,train 36000 timesI_ep 910 ,train 37000 timesI_ep 945 ,train 38000 timesI_ep 983 ,train 39000 timesend
登录后复制

训练效果演示:

近端策略优化PPO-算法简析-paddle2.0 - 游乐网

近端策略优化PPO-算法简析-paddle2.0 - 游乐网

来源:https://www.php.cn/faq/1414404.html
免责声明: 游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关攻略

让 AI 替你叫车,哈啰顺风车上线出行行业首个 MCP 服务
AI
让 AI 替你叫车,哈啰顺风车上线出行行业首个 MCP 服务

让 AI 替你叫车:哈啰顺风车上线出行行业首个 MCP 服务 4月3日,哈啰顺风车推出一项业内瞩目的创新举措:正式上线名为MCP的新型服务。通俗来讲,这项服务将顺风车从寻找车主、智能匹配到最终下单支付的完整流程能力,封装成了一套标准化的技术接口,直接向各类大语言模型和AI智能体开放调用权限。 这一变

热心网友
04.07
QQ接入openclaw的几个步骤
AI
QQ接入openclaw的几个步骤

2026年4月新版OpenClaw QQ机器人接入全攻略:实践步骤、问题排查与深度解读 随着2026年4月OpenClaw重要更新的发布,其原生集成QQ平台支持的功能引起了大量开发者的关注。这一特性意味着用户无需借助任何第三方插件,即可将智能AI助手便捷地部署为QQ私聊或群聊机器人。本文将系统性地解

热心网友
04.07
阿里千问 AI 眼镜接入蚂蚁 GPASS:语音解锁共享单车、停车缴费
AI
阿里千问 AI 眼镜接入蚂蚁 GPASS:语音解锁共享单车、停车缴费

当AI眼镜学会“跑腿”:语音解锁单车,无感支付停车费 近来,智能穿戴领域的一个新动向值得关注:阿里旗下的千问AI眼镜,正式接入了蚂蚁集团的GPASS平台。这可不是一次简单的功能叠加,它意味着,诸如共享单车骑行、停车缴费这一系列高频的“AI办事”功能,开始从手机屏幕转移到了你的眼前。 简单说,借助GP

热心网友
04.06
Workbuddy注册额外积分
AI
Workbuddy注册额外积分

角色定位与核心任务目标 明确了基本定位后,我们直接切入核心:作为一名专业的文章优化师,我的核心职责在于,将那些带有明显AI生成特征的文本,深度重塑为拥有个人特色与行业洞见的优质内容。 换句话说,这项任务的关键在于实施一次“精准的换血手术”。你必须严格保证原文所有的事实依据、核心观点、逻辑框架,以及每

热心网友
04.06
OpenClaw使用kimi web_search返回401问题
AI
OpenClaw使用kimi web_search返回401问题

1 故障现象:OpenClaw无法联网搜索的典型报错 许多开发者在配置OpenClaw AI助手的搜索功能时,常常会遭遇一个典型故障:日常对话交互完全正常,但一旦触发需要联网查询信息的指令,界面便会立刻弹出“抱歉,我目前无法使用网络搜索功能(需要配置 API 密钥)”或“HTTP 401: Inv

热心网友
04.05

最新APP

火柴人传奇
火柴人传奇
动作冒险 04-07
数独趣味闯关
数独趣味闯关
休闲益智 04-07
碧优蒂的世界
碧优蒂的世界
休闲益智 04-07
海岛奇兵
海岛奇兵
棋牌策略 04-07
列王的纷争:西部大陆
列王的纷争:西部大陆
棋牌策略 04-07

热门推荐

苹果折叠 iPhone Fold 渲染图再曝:后摄缩小凸起,整体更精致
科技数码
苹果折叠 iPhone Fold 渲染图再曝:后摄缩小凸起,整体更精致

苹果折叠屏手机 iPhone Fold 最新渲染图曝光:摄像头凸起优化,设计更显精致 有关苹果公司首款折叠屏 iPhone 的传闻持续受到关注。4月5日,知名爆料者 Majin Bu 在社交平台X上再度分享了一组据称是 iPhone Fold 的高清渲染图,从多角度揭示了这款备受期待设备可能的外观设

热心网友
04.07
这城有良田官府无垢队阵容推荐
游戏攻略
这城有良田官府无垢队阵容推荐

通用性首选:官府无垢队阵容深度解析 在当前版本中,若要挑选一套兼具强度与广泛适用性的阵容,以官府流派【长孙无垢】为核心的搭配方案无疑是热门之选。这套经典组合通常由长孙无垢(官府)、李一桐、李善德、李光弼,以及关羽或平安组成。其核心战斗逻辑清晰且高效:一方面,依靠长孙无垢与李光弼的技能联动,通过对目标

热心网友
04.07
洛克王国世界进化什么条件 洛克王国世界全隐藏进化条件整理
游戏攻略
洛克王国世界进化什么条件 洛克王国世界全隐藏进化条件整理

洛克王国全精灵隐藏进化条件完整攻略大全 在《洛克王国》丰富多彩的冒险世界中,除了常规的等级进化,众多精灵还埋藏着独特的“隐藏进化”路径。这些特殊的进化条件,往往是解锁精灵终极形态、完成图鉴收集的关键所在。与普通进化方式不同,隐藏进化需要触发特定的环境、时间、道具或任务条件,充满了探索与解密的乐趣。你

热心网友
04.07
燕云十六声石震通关方法-燕云十六声石震如何通关
游戏资讯
燕云十六声石震通关方法-燕云十六声石震如何通关

燕云十六声石震关卡怎么过?高效通关技巧与实战攻略详解 掌握核心机制:石震关卡难点全解析 石震关卡的核心挑战在于敌人配置:不仅数量密集,且拥有高额血量和攻击力。这些敌人并非随机分布,而是依据特定区域、巡逻路线及攻击逻辑进行部署。提前掌握不同敌人的攻击前摇、技能范围与仇恨机制,是制定有效战术的前提,真正

热心网友
04.07
英雄联盟手游安妮符文怎么搭配
游戏攻略
英雄联盟手游安妮符文怎么搭配

英雄联盟手游安妮符文终极指南:爆发流核心配置与实战策略 在英雄联盟手游的对局中,黑暗之女安妮以其强大的瞬间爆发与控制能力,始终是中单位置的热门选择。虽然操作看似简单易懂,但想要真正掌握这位火焰法师的精髓,打出毁天灭地的效果,一套科学高效的符文搭配是不可或缺的基石。正确的符文选择,能让她从温顺的火苗化

热心网友
04.07