【日记】早睡早起身体好 | 可惜起不来
天气: 中雨转阴
温度: 9℃ - 22℃
心情: EVA&必胜客 联名,拿到绫波丽的吧唧了
日记
Ayanami 的徽章
给大家看一眼
42 问题
这周用Stable-baselines3框架编写Double DQN模型代码,stable-baselines3已经有现成的DQN框架代码,只需要在DQN模型基础上,稍微改写其中三行代码,完成Double部分的功能就行,简单继承DQN模型,然后复制并修改train函数的实现即可。
这是一个无比轻松的事情,按照设想来说是这样的,但可惜的是,按照Github仓库的Issue指南修改代码后,Double DQN的效果可以用惨不忍睹来形容。
这是一个很奇怪的现象,因为stable-baselines3的良好定义,我们几乎不需要怎么编写自己的代码,就能实现DQN算法,而从已验证运行良好的DQN算法到Double DQN的改进也早已有Issue实现,这其中没有出错的道理。
如果你有过将DQN算法或者其他TD算法中,gamma
设置过小的经历,就会发现我所编写的Double DQN模型呈现出的效果与过小的gamma
值十分类似。这也是我的第一反应,于是详细检查了一遍代码中是否有无意间错误修改了某个参数。Git告诉我,没有,我所做的工作只不过是按照已经被证明是有效的Issue中的办法修改了DQN类的train方法。
这件事情让我十分头疼,并且持续检查了三天,包括重新审视Issue时提出到现在的所有stable-baselines3库的修改记录。我曾经以为是sb3库的某一次更新意外引入了会导致Double DQN算法失效的bug,然检查后发现没有任何修改涉及到Double DQN算法的核心。
这时候,一个离谱的想法在我脑中浮现:模型效果和其参数的随机初始化有关,是否有一种可能性,我一直在DQN算法中使用的42随机种子所产生的序列导致了Double DQN的失效。
这个想法太过疯狂,以至于我觉得自己有点儿走投无路了。毕竟一个随机种子导致模型完全失效的现象太过于罕见,而且这个随机种子已经在DQN算法中被证明是没有问题的了。
但又因为实在想不出来其他可能性,我抱着侥幸的心情,将DQN模型初始化seed从42改为了41.
我觉得这很离谱,困扰了我三天的事情居然真的通过修改随机种子解决了。
因为事情太过离奇,所以我又连改了好几次随机种子,发现似乎尽在42的时候,Agent表现才会非常差。
今天将模型参数和梯度全部提取出来,并用TensorBoard的直方图功能显示出来,发现42随机种子+Double DQN算法时,ReLU死区现象会导致卷积层所有神经节点死亡。换用Sigmoid会在一定程度上缓解这个问题,但并不能显著提高42随机种子的表现。Leaky ReLU可以有效改善42随机种子的表现。
建议sb3库将NatureCNN网络的默认激活函数改为Leaky ReLU.