Natural Policy Gradient 实现要点

概述

这个文章主要讲解实现Natural Policy Gradient算法的一些要点和一些坑.

讲解中以

https://github.com/studywolf/blog/blob/master/tensorflow_models/npg_cartpole/natural_policy_gradient.py

来讲解

数值溢出

我们可以看到这上面这个人的代码中,每次强制要200步之后才开始学习

如果你每次done了以后就开始学习,那么会数值溢出

个人猜测原因是前几次agnet并不能产生很多样本,一般在11左右,这就导致了不稳定

所以前期一定要大量样本一起喂入

要点

计算advantages

用另外一个network去estimate state value
real value 等于真实reward计算出来的state value
advantages = real value - estimate value

矩阵乘法问题

在那个链接的代码中,参数大小是(4,2),如果不reshape为(8,1),那么你会发现Fischer information matrix与gradient无法相乘,因为矩阵大小不匹配

求逆矩阵

这上述代码中,他采用了直接求伪逆矩阵,这种方法相对来说计算量比较大,CG方法可以减少计算量.

同时,不能使用tensorflow直接求逆矩阵,因为有时Fischer information matrix的行列式的值为0

优化提高

1

一个自然而然的问题出现了,我们现在不想要固定步数的agent怎么办.

当你尝试修改的时候你会发现在计算gradient的时候迭代时必须是一个固定的int值,否则就报错

也就是说不能再使用之前的方法计算g了

用过tensorflow的人都知道求gradient时是会自动求和的,而这不是我们想要的,我们想要的是jacobian matrix

有些人可能想到split将样本切割然后依次求梯度,但在切割时候必须提供如何切割,需要具体值,不能用tf.cast(tf.shape(self.tf_a)[0], tf.float32)这样的语句来生成

查了很久以后我终于找到了这个

https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/ops/parallel_for/gradients.py#L28

导入方法

from tensorflow.python.ops.parallel_for import jacobian

有了这个就可以很方便的求梯度了

2

另外一个可以改进的点是乘以advantages的地方,这个方法会使代码更好看,性能我没有进行测试.

g = tf.gradients(self.action_log_prob_flat, self.policy_parameter, grad_ys=self.tf_adv)

这样就直接相当于对梯度加了一个权重

以上两个提高都可以面对不定长的样本.