强化学习:课程设计——基础任务PPO论文精读+实验复现

陈籽杏 57120309
June 12,2023

0 作业内容introduction:

本次作业作为23年强化学习课程的最后一次作业,最初选择了overcooked的进阶任务,但是由于时间关系学习PPO算法时阅读论文后实现了基础任务,以后若有机会再去学习overcooked的双智能体任务吧。第1节是论文实验部分的复现,第2节是论文精读。感谢董璐老师以及师姐师兄本学期的讲授,这都使我受益良多。

实验方面Proximal Policy Optimization (PPO)的clipped surrogate objective版本的Pytorch实现(使用PyTorch来定义策略网络,并利用PyTorch提供的优化器(如Adam)来进行神经网络参数的更新。),基于gym库中的连续动作空间的RoboschoolWalker2d-v1离散动作空间的CartPole-v1,文章会展示出最后的训练,测试结果,超参数,和可视化的对比效果。

1 实现过程:

实验目录如下:
-------PPO.py
-------train.py
-------test.py

1.1 ppo.py——PPO Policy 的实现

脚本结构:

1.1.1 值得注意的问题:

论文中PPO Algorithm Actor-Critic形式如下图:

而其中策略梯度的计算如下:

这里在学习过程中出现了一点迷糊:

  • g和L的公式看上去是一样的g是实现梯度上升的梯度估计器gradient
    estimator,L(theta)是目标函数,它定义了我们要优化的问题,而g是目标函数的梯度估计器,它用于在优化算法中进行梯度上升。
  • 而将累乘化为ln形式既避免0-1之间的数累乘造成下溢,也方便计算,化乘为加,而且根据左边的蓝色字标注,它还可以使梯度计算变为微分形式。

那么回到代码中PPO.py:
Actor(策略网络):它是一个神经网络模型,接收状态作为输入,并输出动作。在连续动作空间中,Actor 模型的输出是动作的均值向量。这个均值向量可以表示在给定状态下各个动作的期望取值。而将其定义为高斯分布类似的模型下,是非确定性的动作取值。使用概率分布的好处是可以灵活地控制模型输出的多样性和探索性。通过对概率分布进行采样,可以获得不同的动作取值,以增加策略的探索能力。

在离散动作空间中,Actor输出动作的概率分布。Actor的目标是通过优化策略网络,使得输出的动作可以获得最大的累积回报。

Critic(值函数网络):它也是一个神经网络模型,接收状态作为输入,并输出状态值函数的估计值。Critic的目标是通过学习估计状态值函数,帮助Actor评估当前状态的优劣。它可以提供反馈信号,指导Actor在不同状态下采取合适的动作。

如何形成连续的动作空间?:Actor-Critic算法通常使用高斯分布来表示动作的概率分布,其中均值由Actor网络输出,标准差由self.action_var表示。set_action_std方法允许动态地调整动作的标准差。

在训练过程中,Actor-Critic算法通过交替优化Actor和Critic的方式进行更新。Actor使用Critic的估计值函数作为优化目标,通过最大化估计值函数来改进策略。Critic使用回报信号或其他价值函数估计来训练值函数网络,以提供对策略的评估和反馈。

softmax()函数理解

在PPOclass的init初始化方法中,我注意到了有关PPO策略更新的函数

    self.policy = ActorCritic(state_dim, action_dim, has_continuous_action_space, action_std_init).to(device)self.optimizer = torch.optim.Adam([{'params': self.policy.actor.parameters(), 'lr': lr_actor},{'params': self.policy.critic.parameters(), 'lr': lr_critic}])self.policy_old = ActorCritic(state_dim, action_dim, has_continuous_action_space, action_std_init).to(device)self.policy_old.load_state_dict(self.policy.state_dict())

self.policy.state_dict() 返回当前策略网络的参数字典,包含了所有网络层的权重和偏置项等信息。通过调用 load_state_dict() 方法,并传入当前策略网络的参数字典,可以将当前策略网络的参数复制到旧策略网络中,使两个网络具有相同的参数。

这样做的目的是为了在比较策略的更新前后的性能时,使用的是同一组参数。PPO算法中的更新过程会通过比较新旧策略网络的输出来计算损失函数,并更新参数,从而逐步优化策略。

在update函数中,我们终于可以读懂PPO的思想
最关键的:

  • PPO类使用ActorCritic类来构建策略网络和值网络,并提供了策略更新和动作选择的功能。
  • PPO类中的select_action方法用于选择动作并将相关信息保存到RolloutBuffer对象中。
  • PPO类中的update方法使用RolloutBuffer对象中的数据执行PPO算法的策略更新步骤。在update()函数中,计算了新策略和旧策略之间的概率比值(ratios),并使用torch.clamp()函数对概率比值进行了限制,确保其在区间[1-ε, 1+ε]内。这样可以通过"clipping"操作限制更新幅度,这里很明显采用了带有clipped probability ratios的目标方程的PPO实现方式
  • RolloutBuffer类用于存储采样数据的缓冲区,在每个时间步将动作、状态、对数概率、奖励、状态值和终止状态等信息存储到缓冲区中。
  • ActorCritic类定义了策略网络和值网络的结构,并提供了选择动作和评估动作的功能。

3. 复现方式

传入命令行参数:

python train.py --env_name Hopper-v2 --epochs 200

训练

if agent_args.on_policy == True:  # 如果使用on-policy方法进行训练score = 0.0  # 初始化得分state_ = (env.reset())  # 重置环境并获取初始状态state = np.clip((state_ - state_rms.mean) / (state_rms.var ** 0.5 + 1e-8), -5, 5)  # 对状态进行归一化处理for n_epi in range(args.epochs):  # 迭代训练的回合数for t in range(agent_args.traj_length):  # 迭代每个回合中的时间步if args.render:env.render()  # 显示环境界面state_lst.append(state_)  # 存储当前状态mu, sigma = agent.get_action(torch.from_numpy(state).float().to(device))  # 通过智能体获取动作和动作概率的均值和标准差dist = torch.distributions.Normal(mu, sigma[0])  # 创建正态分布对象action = dist.sample()  # 从分布中采样得到动作log_prob = dist.log_prob(action).sum(-1, keepdim=True)  # 计算采样动作的对数概率next_state_, reward, done, info = env.step(action.cpu().numpy())  # 执行动作并获取下一个状态、奖励和结束标志next_state = np.clip((next_state_ - state_rms.mean) / (state_rms.var ** 0.5 + 1e-8), -5, 5)  # 对下一个状态进行归一化处理transition = make_transition(state,action.cpu().numpy(),np.array([reward * args.reward_scaling]),next_state,np.array([done]),log_prob.detach().cpu().numpy())  # 构建经验转换agent.put_data(transition)  # 存储经验转换数据score += reward  # 累积得分if done:  # 如果回合结束state_ = (env.reset())  # 重置环境并获取初始状态state = np.clip((state_ - state_rms.mean) / (state_rms.var ** 0.5 + 1e-8), -5, 5)  # 对状态进行归一化处理score_lst.append(score)  # 存储当前回合的得分all_scores.append(score)  # 存储所有回合的得分if args.tensorboard:writer.add_scalar("score/score", score, n_epi)  # 将得分写入TensorBoardscore = 0  # 重置得分else:state = next_state  # 更新当前状态为下一个状态state_ = next_state_agent.train_net(n_epi)  # 使用存储的经验数据进行网络训练state_rms.update(np.vstack(state_lst))  # 更新状态均值和标准差if n_epi % args.print_interval == 0 and n_epi != 0:print("第{}个回合,平均rewards:{:.1f}".format(n_epi, sum(score_lst) / len(score_lst)))  # 打印平均得分score_lst = []  # 重置得分列表if n_epi % args.save_interval == 0 and n_epi != 0:torch.save(agent.state_dict(), './model_weights/agent_' + str(n_epi))  # 定期保存模型权重

4.实验效果:

4.1

训练环境名称 : Hopper-v2
--------------------------------------------------------------------------------------------
最大训练epochs:  200
PPO epsilon_clip:  0.2
--------------------------------------------------------------------------------------------
学习率: actor network:  0.0003
学习率: critic network:  0.0003
第10个回合,平均rewards:64.4
第20个回合,平均rewards:230.5
第30个回合,平均rewards:318.6
第40个回合,平均rewards:436.3
第50个回合,平均rewards:658.2
第60个回合,平均rewards:714.3
第70个回合,平均rewards:770.4
第80个回合,平均rewards:800.5
第90个回合,平均rewards:888.7
第100个回合,平均rewards:927.6
第110个回合,平均rewards:1049.4
第120个回合,平均rewards:1201.8
第130个回合,平均rewards:1495.0
第140个回合,平均rewards:1666.9
第150个回合,平均rewards:2018.0
第160个回合,平均rewards:2074.3
第170个回合,平均rewards:1943.7
第180个回合,平均rewards:2092.5
第190个回合,平均rewards:2115.9

可以看出奖励在增加

4.2 InvertedDoublePendulum-v2

训练环境名称 : InvertedDoublePendulum-v2
--------------------------------------------------------------------------------------------
最大训练epochs:  200
PPO epsilon_clip:  0.2
--------------------------------------------------------------------------------------------
学习率: actor network:  0.0003
学习率: critic network:  0.0003
第10个回合,平均rewards:76.1
第20个回合,平均rewards:203.5
第30个回合,平均rewards:286.6
第40个回合,平均rewards:331.8
第50个回合,平均rewards:368.5
第60个回合,平均rewards:437.9
第70个回合,平均rewards:492.9
第80个回合,平均rewards:667.3
第90个回合,平均rewards:857.0
第100个回合,平均rewards:1168.3
第110个回合,平均rewards:1455.1
第120个回合,平均rewards:1917.5
第130个回合,平均rewards:2186.8
第140个回合,平均rewards:2171.7
第150个回合,平均rewards:2445.2
第160个回合,平均rewards:1796.3
第170个回合,平均rewards:2578.1
第180个回合,平均rewards:4302.6
第190个回合,平均rewards:3216.2

5.小结:

在论文中描述的Proximal Policy Optimization (PPO)算法有两种实现方式,分别是通过KL penalty和使用"clipped probability ratios"的目标方程。
使用KL penalty的目标方程:
在这种实现方式中,PPO算法将KL散度作为约束项,添加到目标方程中。目标方程的目标是最大化策略的期望回报,同时限制新策略和旧策略之间的KL散度不超过一个给定的阈值。但我们没有实现这种方法,我们使用带有"clipped probability ratios"的目标方程:这种实现方式是通过对比新策略和旧策略之间的概率比值,来限制更新的幅度,即进行"clipping"操作。这种方式可以防止策略更新过大,从而稳定训练过程。ε也作为一个可调的超参数,由于我的电脑没有gpu,跑实验很慢,想多测试几个ε的值但是效果并不明显。这是一个缺憾
还有一个非常迷惑的地方,PPO到底是on policy还是off policy?按照我的理解和代码中的实现是每收集了N条数据才会去更新一次,这N条数据是一个batch,并且这N条数据是用同一个policy生成的。按我的理解来说是off-policy,况且还有经验回放的buffer,但根据其他资料PPO是离线还是在线策略尽管代码中使用了经验回放缓冲区(ReplayBuffer),但该实现仍然是基于策略梯度的 on-policy 方法,而不是 off-policy 方法。
那么,经验回放缓冲区的作用是存储智能体采集到的经验数据,以便在训练过程中能够更有效地利用这些数据进行多次训练。在每个训练周期中,从经验回放缓冲区中随机采样一批经验数据,并将其用于更新策略和值函数网络。这样可以提高数据的利用效率,使得模型可以多次训练在不同时间点采集到的数据。
实验效果若和论文比较的其实收敛趋势都很像,但是由于电脑性能限制,我跑的轮数不太多,之前用了谷歌的colab,gpu加速,但是mujoco在colab上的搭建我不太清楚,但这个效果已经很可观了。

以上是论文和我的实验结果图像对比,总而言之强化学习这门课真的是我非常喜欢的课程,老师的教导,老师讲的课,让人受益匪浅。老师本人都非常有魅力,老师带来的博士生师姐师兄讲授的课程也干货满满。很开心可以和这门课程走完大学三年级,希望以后我们都一同进步,前程似锦

强化学习大作业实践,不怕困难,迎难而上相关推荐

  1. Numpy学习——大作业

    1. 导入鸢尾属植物数据集 import numpy as np import pandas as pd iris=pd.read_csv('iris.csv',index_col=0) 2. 求出鸢 ...

  2. 阿里强化学习重排实践

    导读:AliExpress 搜索重排项目在去年 6 月份时全量发布了第一个 fined tuned 的 DNN 版重排模型,本次的工作作为上一版本的升级,在日常.大促时的表现均有显著优势.本文将深入浅 ...

  3. 从零实践强化学习之RL初印象(GYM+PARL)

    昨天听了曾两度夺得NeurIPS强化学习赛事冠军的飞桨强化学习PARL团队核心成员科老师的课程,不得不说,满满的干货,于是今天打算再看一遍回放,并好好地做一下笔记. 在学习强化学习之前,我们先思考一下 ...

  4. AlphaGo之父亲授深度强化学习十大法则

    原则 #1 评价驱动发展 客观.量化的评价驱动进展: 评价指标的选择决定了进展的方向 这可以说是项目过程中最重要的决策 排行榜驱动的研究: 确保评价指标紧贴最终目标 避免主观评估(如人为监测) 假设驱 ...

  5. 【华为云技术分享】华为开发者大会HDC.Cloud带你探索强化学习三大挑战及落地实践

    2015-2017年间,AlphaGo系列事件宣告在围棋领域AI算法战胜人类世界冠军,这主要得益于其背后的核心技术-深度强化学习技术.之后研究者开始转向更加复杂的对战博弈场景,典型例子如Deepmin ...

  6. 深度强化学习:基于Python的理论及实践(英文版)

    深度强化学习结合了深度学习和强化学习,使人工智能体能够在没有监督的情况下学习如何解决顺序决策问题.在过去的十年中,深度强化学习在一系列问题上取得了显著的成果,涵盖从单机游戏和多人游戏到机器人技术等方方 ...

  7. 深度丨深度强化学习研究的短期悲观与长期乐观(长文)

    文章来源:机器之心 深度强化学习是最接近于通用人工智能(AGI)的范式之一.不幸的是,迄今为止这种方法还不能真正地奏效.在本文中,作者将为我们解释深度强化学习没有成功的原因,介绍成功的典型案例,并指出 ...

  8. 强化学习综述(机器学习角度)

    Reinforcement Learning:A Survey 作者:Leslie Pack Kaelbling, Michael L. Littman, Andrew W. Moore (整理转自h ...

  9. 【强化学习】强化学习的基本概念与代码实现

    选自DeepLearning4j 机器之心编译 参与:Nurhachu Null.李泽南 从 AlphaGo 到自动驾驶汽车,我们能在很多最先进的人工智能应用中找到强化学习的身影.这种技术是如何从零开 ...

最新文章

  1. JAVA自动补全插件
  2. c语言逗号占几个字符,C语言 scanf输入多个数字只能以逗号分隔的操作
  3. Python-10-条件和条件语句
  4. StatusBar style的那点事
  5. 经常看到一种说法,说未来普通人翻身,将会越来越难
  6. 统计查询,实现将结果集竖排显示
  7. Java的数据类型转换
  8. 氨基化氧化石墨烯PEG修饰/氨基化氧化石墨烯PEI修饰/Nanoinnova还原石墨烯(各种解说)
  9. 一起学习荷花定律/金蝉定律和竹子定律
  10. 俄罗斯方块游戏的算法
  11. 淘宝/天猫买家信息 API
  12. 科技热点周刊|GitLab 上市、LinkedIn 中国停止运营、Visual Studio 2022 正式版将发布
  13. 联想F360移动硬盘拆解
  14. python软著申请_软著申请流程时间
  15. 水浒108将(按出场顺序)
  16. easyexcel导出
  17. 任正非:宁赔10亿,也要辞退7000员工!华为卸磨杀驴?却获网友点赞!
  18. 邮箱投递简历,如何正确书写正文和主题?
  19. Problem B: 小度挑战赛
  20. matlab浊音段和清音段,基于Matlab编写的语音端点检测1

热门文章

  1. C语言—打字母单机游戏(简易)
  2. 多元微积分_二维散度定理
  3. 即构助力Live.me,Uplive直播出海,实时音视频技术优势向全球输出
  4. DBA生存警示:保护现场不要让事情更糟
  5. 2014年电子商务格局发展趋势
  6. html css聊天窗口气泡,CSS实现短信气泡对话框
  7. oracle erp技巧,Oracle ERP 使用者操作指南II(深入浅出系列).pdf
  8. 数据结构:十大经典排序算法
  9. 安卓手机烧内存卡(就是内存卡损坏)的补救办法
  10. IntelliJ IDEA 怎么导入项目