【问题记录】强化学习DQN中神经网络每次推理结果都相同
Contents
问题
最近使用DQN强化学习算法进行一些研究。将数据分为测试集和训练集,然后分别编写训练的代码和测试的代码,我设置的是每训练100个episode,就在测试集上边测试一次。
当我编写完测试代码之后,发现一个问题:
随着训练的进行,模型参数应该是一直在更新,但是输出的测试指标数据却完全没有变化,无论训练多少个episode都不会变化。
理论上来说,模型参数是一直被更新优化的。那么对于相同的输入,输出值不可能一直都是不变化的。结果可能变好,可能变坏,但是没变化,说明一定有bug。
排查思路
- 最开始怀疑的是模型没有被训练到,参数更新的
operation
没有被执行。断点调试后模型是被成功更新的,排除这个问题。 - 然后怀疑的是我在调用
tensorflow
的tf.train.Saver
的save()
和restore()
有问题,没有成功的保存或者加载模型。- 通过Tensorflow 打印模型参数 - 简书讲到的方法1,方法2,分别打印出同一个
episode
的模型的save()保存的ckpt文件的参数,以及运行过程中restore()之后的参数。-
-
-
在命令行运行上述代码,将输出重定向到txt文件,使用PyCharm自带的文本比较工具进行比较,可以发现保存的模型和加载的模型的参数完全是相同的,说明没有问题。
-
- 通过Tensorflow 打印模型参数 - 简书讲到的方法1,方法2,分别打印出同一个
- 按照2同样的方法,打印不同
episode
模型的所有参数,并进行比较,发现参数是不同的,说明训练的参数更新也是成功的,完全排除了saver
和restore
的嫌疑。 - 然后尝试修改DQN的一些超参数,以为是学习率太低,导致更新太慢。调高学习率,没有解决。
- 更换训练中使用到的
trace
数据,没有解决。 - 最后把断点设置在了测试脚本
rl_test_2
的choose_action()
语句处。找到了最终的问题所在。
解决
我之前写测试脚本的时候,DQN的实例化的这行代码是直接复制训练脚本里边的,然而训练的代码是设置了epsilon
贪婪系数从0开始递增,以进行探索。
测试脚本里这么写是不对的,测试脚本中,贪婪系数应该设置为1,选择最好的action。
所以解决方法就是修改这里的贪婪系数。
修改后,重新运行,一切正常。
总结
这个bug从早上9点调到下午4点,花了四五个小时,搞得我头晕眼花。
我在写代码的时候确实是没有注意到需要这个贪婪系数初始化的问题。
不过bug是难免的,重要的是,遇到bug也不要怕,关键的是要学会通过一些方式排查问题,缩小范围。写一些简单的测试小脚本来一步一步验证自己的猜想,上边这么啰嗦写了一堆,也是想强调这一点,对于不是特别复杂的程序来说,按类似于这样的思路,一定可以找到bug。