强化学习中的调参经验与编程技巧(on policy篇)

2020 年 12 月 30 日 PaperWeekly


©PaperWeekly 原创 · 作者|张恒瑞

单位|北京交通大学

研究方向|强化学习



在强化学习的训练过程中,常常会遇见以下问题:

  • 在某一环境中可以 work 的超参数拿去训练别的环境却训练不出来

  • 训练时熵在增大

  • 训练动作达到边界


本文通过调试几个环境的案例来探究强化学习的调参方法。


pendulum


摆锤这个环境可以看做连续控制中的入门环境了,环境初始时在一个随机的位置,目标是将其摆动以使其保持直立,它的状态维度为 3,动作维度为 1。

拟使用 PPO 解决这个问题,ppo 的流程如下:

  1. 使用 Actor 网络与环境交互一定步数,记录下(state, action, reward, v, done)


  2. 根据记录下来的值计算优势值 adv(更新 actor 网络使用)和 v_target(更新 critic 网络使用)


  3. 计算 loss 更新 actor 网络和 critic 网络


首先说第一步,在和环境交互的过程中,我们往往规定了步数,在规定的 step 内,环境往往没有 done,这会给我们这一次迭代计算 adv 有误差,面对这个问题,往往有两种处理方式:完成这次交互,也就是超过这一次规定的迭代步数直到 done,这样做会使每一次迭代更新时的交互 step 不同,比较不同算法在相同的step性能如何时略显不公平不完成这次交互,这样会使最后 step 采用 gae 对 adv 估值存在近似。

在 John Schulman's 程序中,对 V 估值采用这种方式:


V(s_t+1) = {0 if s_t is terminal         
               {v_s_{t+1if s_t not terminal and t != T (last step)         
               {v_s if s_t not terminal and t == T

也就是最后一个 step 如果不是终止状态,则它下一状态的 V 估值为当前状态的 V 估值。 在有的程序中,也采用 V 神经网络下一状态的值作为对下一状态的 V 函数估值。

第二步流程中计算 v_target 会根据是否采用 gae 有两种计算方式:

  • 根据每一 step 的 reward 按照 gamma return 的方式计算 v_target

  • 根据每一 step 的 adv 和 v 估值累加作为 v_target


第三步中 loss 计算包含有 aloss,vloss 和 entropy。


1.1 初始


我们先使用简单的 PPO 来训练一下环境,参数选择如下:


  • actor,critic 网络初始化为正交初始化
  • steps=2048;
  • batch=64;
  • lr=3e-4 且经过训练迭代数逐渐减小;


lam = lambda f: 1 - f / train_steps
self.opti_scheduler = torch.optim.lr_scheduler.LambdaLR(self.opti, lr_lambda=lam)


  • 采用 return 方式计算v_target;
  • adv 计算采用 gae
  • loss 计算添加熵,系数(self.c_en)为 0.01

loss = aloss - loss_entropy*self.c_en + v_loss*self.c_vf

  • max_grad_norm=0.5

torch.nn.utils.clip_grad_norm_(self.critic.parameters(), self.max_grad_norm)
torch.nn.utils.clip_grad_norm_(self.actor.parameters(), self.max_grad_norm)


这些都是比较常规的 PPO 参数设置,进行 1000 迭代后(2048*1000 step)reward 变化如下:



算法并没有很好的学习,reward 在 100 iter 以内还有上升趋势,100iter 时突然下降,之后就再也起不来。


我们来看一下学习过程中各个诊断量变化情况。


vloss 一开始值很大,接着骤降,之后一直处于比较高的水平。



entropy 的变化幅度过快,最终值小于 0。这里简单提一下在连续密度分布中,熵值可能小于 0,拿高斯分布举例,如果其 sigma 过小,均值点处的密度概率可以远大于 1,熵值也为负数。综合来看,熵值出现小于 0 一般为 Actor 网络更新时sigma参数过小,可能是 actor 更新过快的原因。


1.2 clip V


为了让 critic 更新更合适,一般程序中采用 clipv 的技巧,防止更新前后 V 差距过大,对其进行惩罚,程序代码如下:


clip_v = oldv + torch.clamp(v - oldv, -self.epsilon, self.epsilon)
v_max = torch.max(((v - v_target) ** 2), ((clip_v - v_target) ** 2))
v_loss = v_max.mean()

同时程序中采用 gae 方式计算 v_target。


self.v_target = self.adv + self.v

进行 1000 迭代后(2048*1000 step)reward 变化如下:



reward 最终能呈上升趋势最终达到一个不错的值,但美中不足在于中间出现两次波折。



vloss 最终也能收敛到较小的值,但和 reward 类似在相同的地方出现了波折。



熵值的下降显得平稳多了。



观察 kl 散度变化,发现类似的地方出现 kl 散度过大的现象。


ppo 在一次迭代中使用同一批数据进行策略更新,要求策略变化不能过大,不然重要性采样就不再适用,所以在 ppo 的策略更新中采用了裁剪的技巧,但事实上即使这个技巧也不能保证限制 kl 散度大小,论文 IMPLEMENTATION MATTERS IN DEEP POLICY GRADIENTS: A CASE STUDY ON PPO AND TRPO 也指出裁剪没有起到真正作用。


1.3 kl early stop


为了防止 kl 散度过大,我们设置一个最大 kl 值,在每次迭代中当达到这个最大 kl 就停止这次迭代,继续下次采样数据,这里我们设置 kl_max=0.03。

继续进行 1000 迭代后(2048*1000 step)reward 变化如下:


似乎是有了一定改善,但中间还有一次波动。



看 kl 散度也比较平均。

1.4 normalization


考虑到 state, reward 我们还没有标准化,起初的 vloss 也比较大,我们决定这次从这里入手。

state 和 reward 都是在交互过程中产生的,我们无法在预先知道其平均值和方差,于是我们采用运行时均值和方差作为近似代替。

对每个 state 减去均值并除以标准差。

x = self.pre_filter(x)
if update:
    self.rs.push(x)
if self.demean:
    x = x - self.rs.mean
if self.destd:
    x = x / (self.rs.std + 1e-8)
if self.clip:
    x = np.clip(x, -self.clip, self.clip)

对 reward 我们只除以标准差。

x = self.pre_filter(x)
self.ret = self.ret*self.gamma + x
if update:
    self.rs.push(self.ret)
    x = x/(self.rs.std + 1e-8)
if self.clip:
    x = np.clip(x, -self.clip, self.clip)
return x

继续进行 1000 迭代后(2048*1000 step)reward 变化如下:


终于,reward 变得比较平稳了。

用最后的结果总结一下,如果 reward 长时间不能很好的上升,需要即时诊断其他重要变量变化情况,一般情况下 vloss 先下降再稍微上升最终平稳,entropy 的曲线则是下降最终平稳,不能太快也不能上升,kl散度变化不能过大。



mujoco


用我们以上学到的经验去调试 mujoco 中的 halfcheetah,hopper 和 walker2d。


这里主要调节每次 early_stop 的 max_kl,采样 3 个随机种子完成实验。



在 halfcheetah 环境中,目标 kl0.07 稳定性最差,可以看出在其他参数保持不变时,0.07 的限制依然导致每次策略更新时幅度过大,整体效果不够稳定。



在 hopper 环境中,依然是 kl0.07 的限制最不稳定。



在 walker2d 环境中,kl0.07 的效果却是最好的,这也说明在不同的任务环境中,超参数的选择也是不同的。


这些结果的表现来看也都达到或超过部分论文上 ppo 的效果了,如果想试试调节超参数的可以看看:

https://github.com/feidieufo/RL-Implementation/blob/master/algos/ppo/run_ppo_torch.py


如果你还不太清楚如何用 seaborn 绘制强化学习训练图,可以参考这篇:

https://zhuanlan.zhihu.com/p/75477750



deepmind control suite


dmc 是谷歌开发的强化学习环境套件(基于物理控制),和 mujoco 有类似的场景,但丰富了其任务设置,同时也提高了难度。

dmc 有相应的 gym 接口库,安装过 dmc2gym 后即可通过下面方式使用。

env = dmc2gym.make(
    domain_name=args.domain_name,
    task_name=args.task_name,
    seed=args.seed,
    visualize_reward=False,
    from_pixels=(args.encoder_type == 'pixel'),
    height=args.image_size,
    width=args.image_size,
    frame_skip=args.action_repeat
)

dmc 的状态输入有普通的 state 也有基于图片的 pixel,这里先用普通的 state 测试。

使用 cheetah run 作为任务环境。


先使用 mujoco 训练时使用的超参数,reward 如下:



reward 结果极其不稳定,最终也没有达到比较好的结果。



entropy在训练过程中由原来的8左右逐渐增大,这在以前的实验中都没有遇见。



查看 Actor 网络动作 std 的变化情况,由一开始设置的 1 越变越大,也正是如此导致了 entropy 的不降反升。


在 ppo 的 loss 中熵项的存在确实是希望动作随机保持探索,但最终 entropy 越来越大,也体现出 ppo 策略网络的不自信,我们考虑将 entropy 的系数变小。


试试系数为 0 的效果。



reward 有比较好的上升效果了。



熵也能正常的下降了。


比较这两次的实际运行情况:



可以看出第一次后期翻车了,第二次还是能比较不错的跑下去。


大家也可以试试熵前面系数 0~0.01 之间其他值:

https://github.com/feidieufo/RL-Implementation/blob/master/algos/ppo/run_ppo_dmc_torch.py


尝试总结一下,虽然 dmc 中的 cheetah-run 和 mujoco 的 halfcheetah 有类似的模型和动态转移,一开始的动作熵也在 8 左右,但 dmc 用同样的超参数熵就会上升,可能在于两者的 reward 不同,dmc 只有速度 reward,mujoco 还加上了控制 reward。


如果后面有时间的话还会补充上 dmc pixel 状态和 Atari 的调参过程,全部程序在:

https://github.com/feidieufo/RL-Implementation


欢迎点赞 star 和交流。



参考文献

[1] The 32 Implementation Details of Proximal Policy Optimization (PPO) Algorithm costa.sh/blog-the-32-im
[2] IMPLEMENTATION MATTERS IN DEEP POLICY GRADIENTS: A CASE STUDY ON PPO AND TRPO. ICLR2020



更多阅读




#投 稿 通 道#

 让你的论文被更多人看到 



如何才能让更多的优质内容以更短路径到达读者群体,缩短读者寻找优质内容的成本呢?答案就是:你不认识的人。


总有一些你不认识的人,知道你想知道的东西。PaperWeekly 或许可以成为一座桥梁,促使不同背景、不同方向的学者和学术灵感相互碰撞,迸发出更多的可能性。 


PaperWeekly 鼓励高校实验室或个人,在我们的平台上分享各类优质内容,可以是最新论文解读,也可以是学习心得技术干货。我们的目的只有一个,让知识真正流动起来。


📝 来稿标准:

• 稿件确系个人原创作品,来稿需注明作者个人信息(姓名+学校/工作单位+学历/职位+研究方向) 

• 如果文章并非首发,请在投稿时提醒并附上所有已发布链接 

• PaperWeekly 默认每篇文章都是首发,均会添加“原创”标志


📬 投稿邮箱:

• 投稿邮箱:hr@paperweekly.site 

• 所有文章配图,请单独在附件中发送 

• 请留下即时联系方式(微信或手机),以便我们在编辑发布时和作者沟通



🔍


现在,在「知乎」也能找到我们了

进入知乎首页搜索「PaperWeekly」

点击「关注」订阅我们的专栏吧



关于PaperWeekly


PaperWeekly 是一个推荐、解读、讨论、报道人工智能前沿论文成果的学术平台。如果你研究或从事 AI 领域,欢迎在公众号后台点击「交流群」,小助手将把你带入 PaperWeekly 的交流群里。



登录查看更多
5

相关内容

专知会员服务
128+阅读 · 2021年3月13日
深度强化学习在智能制造中的应用展望综述
专知会员服务
96+阅读 · 2021年1月28日
【2020新书】C语言编程傻瓜式入门,第二版,464页pdf
专知会员服务
62+阅读 · 2020年10月15日
《强化学习》简介小册,24页pdf
专知会员服务
272+阅读 · 2020年4月19日
深度强化学习策略梯度教程,53页ppt
专知会员服务
179+阅读 · 2020年2月1日
【强化学习】深度强化学习初学者指南
专知会员服务
180+阅读 · 2019年12月14日
机器学习入门的经验与建议
专知会员服务
92+阅读 · 2019年10月10日
深度学习网络调参技巧
AINLP
15+阅读 · 2019年11月15日
你有哪些深度学习(rnn、cnn)调参的经验?
七月在线实验室
10+阅读 · 2019年3月27日
除了DQN/A3C,还有哪些高级强化学习成果
论智
15+阅读 · 2018年10月28日
教程 | PyTorch经验指南:技巧与陷阱
机器之心
15+阅读 · 2018年7月30日
基础 | 深度学习中的优化算法
黑龙江大学自然语言处理实验室
5+阅读 · 2018年5月11日
step-by-step: 夕小瑶版神经网络调参指南(上)
夕小瑶的卖萌屋
6+阅读 · 2018年3月20日
【强化学习】强化学习/增强学习/再励学习介绍
产业智能官
10+阅读 · 2018年2月23日
【强化学习】强化学习+深度学习=人工智能
产业智能官
53+阅读 · 2017年8月11日
强化学习 cartpole_a3c
CreateAMind
9+阅读 · 2017年7月21日
Arxiv
0+阅读 · 2021年4月21日
Arxiv
7+阅读 · 2020年12月10日
Universal Transformers
Arxiv
5+阅读 · 2019年3月5日
Arxiv
12+阅读 · 2018年9月5日
VIP会员
相关VIP内容
专知会员服务
128+阅读 · 2021年3月13日
深度强化学习在智能制造中的应用展望综述
专知会员服务
96+阅读 · 2021年1月28日
【2020新书】C语言编程傻瓜式入门,第二版,464页pdf
专知会员服务
62+阅读 · 2020年10月15日
《强化学习》简介小册,24页pdf
专知会员服务
272+阅读 · 2020年4月19日
深度强化学习策略梯度教程,53页ppt
专知会员服务
179+阅读 · 2020年2月1日
【强化学习】深度强化学习初学者指南
专知会员服务
180+阅读 · 2019年12月14日
机器学习入门的经验与建议
专知会员服务
92+阅读 · 2019年10月10日
相关资讯
深度学习网络调参技巧
AINLP
15+阅读 · 2019年11月15日
你有哪些深度学习(rnn、cnn)调参的经验?
七月在线实验室
10+阅读 · 2019年3月27日
除了DQN/A3C,还有哪些高级强化学习成果
论智
15+阅读 · 2018年10月28日
教程 | PyTorch经验指南:技巧与陷阱
机器之心
15+阅读 · 2018年7月30日
基础 | 深度学习中的优化算法
黑龙江大学自然语言处理实验室
5+阅读 · 2018年5月11日
step-by-step: 夕小瑶版神经网络调参指南(上)
夕小瑶的卖萌屋
6+阅读 · 2018年3月20日
【强化学习】强化学习/增强学习/再励学习介绍
产业智能官
10+阅读 · 2018年2月23日
【强化学习】强化学习+深度学习=人工智能
产业智能官
53+阅读 · 2017年8月11日
强化学习 cartpole_a3c
CreateAMind
9+阅读 · 2017年7月21日
Top
微信扫码咨询专知VIP会员