第六课:值函数估计
好久没有写这个专栏了,现在来补一课,不然前面的都忘掉了~
本文主要讨论值函数的估计问题,主要研究两类方法:增量方法(Incremental Methods)、批方法(Batch Methods)。其中增量方法主要是从online方面考虑。批方法主要是从data efficient方面考虑。
在模型无关的预测中,我们介绍了如何对给定策略进行估计,但当时讨论的是利用lookup table来表示值函数,也即我们用一个矩阵存储不同状态、动作对应的值,可想而知,这种方法难以处理较为复杂的问题,比如连续状态空间问题或者是连续动作空间问题。所以,我们就想要用一种方法来对值函数进行估计,比如说神经网络。
对于状态值函数或是动作值函数而言,我们可以这样进行估计:
其中比较值得关注的点是对于动作值函数的估计,一类叫做action-in(中间的图),将动作作为输入的一部分;一类叫做action-out(最右边的图),针对动作输出多个值函数。其中action-out中是输出各个动作维度的值函数,而并不是指所有的动作,因此也可以用于连续动作空间,换句话说,就是对动作空间的各个维度分别评分,比如一个机械臂,我们分别对各个关节的力矩对应的值函数评分,但它们只是多个输出,网络的底层是一样的。
下面我们首先讨论增量方法,毕竟我们常常想要一种能够处理non-stationary、non-iid data的训练方法,而增量方法恰恰能满足要求。
假设我们的目标是找到一组变量使得对于值函数的估计值与真实值之间的均方误差最小,也即使下面的目标函数最小:
利用梯度下降方法有:
在这里我们使用的是批量梯度下降方法,即BGD方法,虽然名字里面有批量两个字,但这是最原始的梯度下降方法,这种方法在每次迭代中使用所有的数据对参数进行更新(实际上使用所有数据对参数进行更新的意思是就是用策略PI对应的所有样本去更新参数,但这是无法实现的)。如果换为随机梯度下降方法(SGD),则表达式为:
SGD方法对于参数w的期望更新与BGD是一致的。
在智能体学习的过程中,我们常常没有一个真实的target,因此我们想方设法地寻找某个东西作为替代品,而这里所谓的增量方法就是说将上面的值函数的真实值换为其他的target,比如MC target,TD target等:
值得注意的是,在TD(0)中,target虽然也和w有关,但是我们求导的时候并没有对这项求导,为什么呢?因为我们需要ground-truth,而不希望去依据现在(t)的状况去更新(t+1)的状况,如果我们在求导的时候将这一项也考虑进去,将得到一个错误的答案(David Silver说的)。
当然,我们上面讲的是对于状态值函数V的估计,这常常用于预测问题(当然也可以用于控制,想想贝尔曼最优方程就知道了),而如果要考虑控制问题的话,一般来说会对动作值函数q进行估计,增量方法如下:
有一点需要注意,在前面直接对状态值函数V或状态动作值函数Q使用TD(lambda)方法时,其中Et = gamma * lambda * Et-1 + 1(s),而上面这张PPT中,并不是1(s),而是对w的导数。关于这一点我们可以从前向视角来看,在对w更新时,乘入了值函数对w的导数项,而后向视角与前向视角在时间尺度上累加的效果是一致的,所以Et中是值函数对w的求导,而不是1(s)。
视频课程中给出了下面的实验结果来作为我们是否应该使用bootstrap的参考:
可以看出来,我们使用TD方法,并且取lambda为0.8~1之间的值是很不错的~
在这种方法的最后,我们看一下引入值函数估计方法的收敛性,首先是预测:
然后David Silver说我们可以使用Gradient TD方法来解决上面TD方法对于线性和非线性估计器不收敛的问题:
接着我们看一下对于控制问题引入动作值函数估计器的收敛性问题:
我们知道,在满足GLIE条件下,MC、Sarsa、Q-learning方法都是可以收敛到最优动作值函数的(使用真实的动作值函数),而在这里我们可以看见,使用线性或者非线性估计器都将导致两种方法的不收敛。对了,值得一提的是,这里的查找表方法实质上用的仍然是真实的动作值函数,因为它仅仅是将真实的值记录下来,而并不引入估计。
在介绍完增量方法之后,我们来介绍批方法(Batch Methods)。
在本文的开头,我们就聊到了批梯度下降方法(BGD),但这个“批”是假的,因为无法实现,所以只能换为随机梯度下降(SGD),可是SGD方法在sample efficient上并不好。而现在我们要聊到的批方法就是要在最大化利用数据的同时去找到对于值函数最好的拟合。
我们先来看一看前面提到的MSE:
在这里,我们是对于策略pi求期望的,换句话说,我们是对于由策略pi得到的状态分布求和得到这个代价函数的值的。那在实际中,我们就是用样本来估计了,所以,我们所要优化的代价函数是:
这是LS算法(最能拟合value function)得到的结果,其中D表示对经验数据D求期望(不过这里的D是维持不变的,或者说是事先采好的),我们再看看前面说的SGD:
显然这个式子就只用到一个样本了,并没有对什么东西求期望。但是我们可以重复对于某一个经验集D重复取样本,然后使用SGD方法:
就可以得到收敛于LS的解:
DQN的方法是experience replay,它类似于上面说的这种方法,不过其memory是变动的,下面直接给出DQN方法:
关于该算法本身就不具体介绍了,我们看看DQN中各个模块对于最终效果的提升:
其中第一列是DQN的效果,从对比中可以看见Replay与Fixed-Q都是很重要的。
不过,我们上面利用batch方法求解LS问题有个缺点,就是我们可能需要很多迭代步来解决(误差减小到小于某个值)LS问题。所以,有人说,为什么不用线性函数估计器呢?这样我们不就可以直接求解LS问题而不用迭代了么?先看一下什么是线性函数估计器:
直接求解LS问题:
这个时候,我们就不用像前面一样慢慢迭代求解了。当然我们同样不知道真实的值,因此引入MC、TD:
直接求解:
对比引入了batch的方法与之前没有引入的方法的收敛性:
因为我们这里只讨论线性估计器下的LS方法,所以并不对非线性情形进行对比,从线性情形对比来看,LS方法确实收敛性要好一些。
在本文的最后,我们介绍将LS方法引入控制问题:
同样地,我们对动作值函数进行估计,但是要注意的一点是,不同于策略估计,我们在进行策略更新的时候,如果要用到所有的experience,就必然会用到多个时间步之前的策略得到的experience,因此,在估计动作值函数q时,我们需要使用off-policy方法:
然后我们继续考虑线性估计器:
我们利用这里的LSTDQ对值函数进行估计,得到下面的LSPI算法:
算法收敛性对比如下:
可见,LSPI方法(其中使用了LSTDQ)将Q-learning(off-policy)的不收敛变为了在最优值函数附近抖动,还是有较大改进的,虽然还没有gradient Q-learning方法那样完全收敛,但是已经很不错了。这里的LSPI实质上就是LSTDQ + greedy,而LSTDQ是linear Q-learning update + batch(LS),在DQN中则是以神经网络作为值函数估计器,然后加上experience replay思想(类似于batch方法,但是memory是变动的),最后加上一个Fixed Q得到的,这些组分保证了DQN算法的稳定性,这里我们就不提收敛性了,正如上面LSPI的chatters一样,仅仅保证稳定就很厉害了。