【FreeRL】MAPPO的简单复现
文章目录
- 前言
- 一、MAPPO简要解读
- 二、复现代码主要关注
- 另外:
- 三、实验结果和参数
- MAPPO效果
- MAPPO_max效果
- 疑问
- 补充及待做
前言
MAPPO的复现,也是复现了很久,主要的难点不在于算法很难,而是用到了很多tricks,以及调参。
不知道为啥这个的离散环境的参数怎么调也调不出好的结果,故放弃,但是代码原型应该是对的。
代码实现:https://github.com/wild-firefox/FreeRL/tree/main/MAPPO_file
一、MAPPO简要解读
mappo:论文链接:https://arxiv.org/pdf/2103.01955 代码链接:https://github.com/marlbenchmark/on-policy/
提出的建议
1.使用值value归一化来稳定价值函数。(注:不是状态归一,技巧为PopArt,(Preserving Outputs Precisely, while Adaptively Rescaling Targets) 来自文献Learning values across many orders of magnitude:https://arxiv.org/pdf/1602.07714 / 拓展:Multi-task Deep Reinforcement Learning with popart)
2.如果可以,使用必要的全局状态和本地状态。
3.在困难环境中最多使用10个epoch(10 or 5),在简单环境中最多使用15个epoch;避免分成多个batch(1个效果最好)(PPO原论文中是分成horizon//mini_batch_size个)
4.为获得最高PPO性能,将clip值在0.2以下范围内调整。(论文中0.2和0.05效果还行)
5.使用一个较大的batch_size(即horizon值)以达到最好的效果,然后调整它来优化效果。
论文代码中使用的PPO技巧trick:
参考知乎:https://zhuanlan.zhihu.com/p/386559032
1.Generalized Advantage Estimation:这个技巧来自文献:Hign-dimensional continuous control using generalized advantage estimation。
2.Input Normalization
3.Value Clipping:与策略截断类似,将值函数进行一个截断。
4.Relu activation with Orthogonal Initialization: 论文:https://arxiv.org/pdf/2004.05867v2
5.Gredient Clipping:梯度更新不要太大。
6.Layer Normalization:## 来自同名论文 ###后面文献并无提及LayerNorm 怀疑作者贴错了 这个技巧来自文献:Regularization matters in policy optimization-an empirical
study on continuous control。
7.Soft Trust-Region Penalty:## 这个技巧来自文件:Revisiting design choices in proximal policy optimization。
还有一些其他技巧 知乎上没提到但是论文和代码上有,补充如下
8.huber_loss: 用于替代mse_loss,减少outlier的影响。
9.reward normalization: 对reward进行归一化。
10.use_feature_normalization :类似于Layer Normalization,在特征输入前采取的归一化操作
11.adm_eps: 与PPO_with_tricks一致
12.lr_decay: 与PPO_with_tricks一致
二、复现代码主要关注
关于建议
1.由于在ddpg中发现建议1中的popart效果并不理想,所以这里不使用popart,具体见:【深度强化学习】DDPG+popart技巧(最详解)
2.知乎上的评论:论证了建议2中可以不用特别加入agent-specific information,所以按一般MA拼接状态和动作处理,PPO无动作 只拼接状态
3.设置epocch = 5 ; minibatch_size = 1 (即:不再进行对batch_size进行小批量,在我这相当于该值与horizon相等 )#后者我做过实验,效果确实会好一点点,见PPO_file中note
4.设置clip = 0.2
5.和原ppo一样看情况调整horizon
综上:关注3,4即可
关于args.trick: trick为PPO_file中PPO_with_tricks.py中已实现过的trick
1.使用GAE 与原PPO一致
2.Input Normalization 即trick中的ObsNorm 确实重要
3.Value Clipping 新增
4.Orthogonal Initialization 即trick中的orthogonal_init
5.Gredient Clipping PPO中默认加入以防止梯度爆炸和消失
6.Layer Normalization 新增
7.Soft Trust-Region Penalty 新增 ## 在trpo用到,在PPO没有用到
8.huber_loss 新增
9.reward normalization 即trick中reward_norm or reward_scaling
10.use_feature_normalization 新增
11.adm_eps 即trick中的adam_eps
12.lr_decay 即trick中的lr_decay
综上:重点关注3,6,7 (实际加入2,3,4,6,7,8,9,10,11 trick) 1 5 默认加入
综上:PPO_with_tricks.py中的7个trick全部加入了,(其中tanh的trick集成在net_init中,且默认使用relu,故上述中没有提及)
重点关注3,6,7,8,10
另外:
mappo与rmappo区别见原代码:https://github.com/marlbenchmark/on-policy/blob/main/onpolicy/scripts/train/train_mpe.py#L68
区别:rmappo使用了RNN
这里复现代码并没有使用RNN。
三、实验结果和参数
注:这里MAPPO_max 为复刻的论文代码
MAPPO为不加任何trick的代码
# MAPPO_max 为如下设置,而MAPPO则均为False
parser.add_argument("--trick", type=dict, default={'adv_norm':True,
'ObsNorm':True,
'reward_norm':False,'reward_scaling':True, # or
'orthogonal_init':True,'adam_eps':True,'lr_decay':False, # 原代码中设置为False
# 以上均在PPO_with_tricks.py中实现过
'ValueClip':True,'huber_loss':True,
'LayerNorm':True,'feature_norm':True,
})
在连续域环境simple_spread_v3的效果如下:智能体个体数为5。
多次调参发现,PPO果然还是对horizon和minibatch_size敏感
MAPPO效果
设置
horizon = 512
minibatch_size = 512
其效果如下
1,2,3分别为seed= 0 10 100的结果
MAPPO_max效果
设置
horizon = 512
minibatch_size = 512
其效果如下
4,5,6分别为seed= 0 10 100的结果
但是max由于增加了许多tricks,对参数反而不那么敏感,容易收敛,例:
设置参数
horizon = 60
minibatch_size = 30时
max收敛,而MAPPO则不收敛
max的效果如下,而MAPPO则出现了不收敛的情况
疑问
在离散环境下的simple_spread_v3实验时:
多次调参,均不收敛,效果最好的一次,效果如下:
horizon = 128
minibatch_size = 32时
设置
horizon = 32
minibatch_size = 8时
部分效果如下:但是后面的效果和上图基本一致
基本不收敛,
后我又看了下原代码和论文,论文中做了smac的实验,而smac是离散的,按道理离散环境下此算法应该也会收敛。
疑问:
从代码:https://github.com/marlbenchmark/on-policy/blob/main/onpolicy/runner/separated/mpe_runner.py#L126
(action_env = np.squeeze(np.eye(self.envs.action_space[agent_id].n)[action], 1))
及 https://github.com/marlbenchmark/on-policy/blob/main/onpolicy/envs/mpe/environment.py#L206
(if action[0] == 1:)
这里两处矛盾 推出原论文作者并没有使用mpe的离散环境做实验,
且此代码实现效果和https://blog.csdn.net/onlyyyyyyee/article/details/139331501类似 所以推测复现代码实现并无错误。
后续又问【MADRL】多智能体近端策略优化(MAPPO)算法此文章博主,要了他写的代码,和自己的对比了下离散动作的实现,发现也没什么区别,但此博主并无环境,也没有实验,所以也不知道是否能够收敛。
推测:可能这种softmax 离散形式 不适合用于多智能体环境,要再加一个one-hot的动作编码?
补充及待做
补充:
1.原代码中还有一个加入RNN的MAPPO并没有实现。
2.知乎中提及的Regularization matters in policy optimization-an empirical这篇论文对一些trick进行了一些实验,推荐阅读。
待做:
MAPPO原代码除了我实现的上述,还有一个训练加速的框架并没有实现,(但是虽如此也比MADDPG快了不少,见:此文章最后)