在训练qlearning网络时,通常会设置一定的概率去做一些探索,以求能做出更好的决策。而在Policy gradient中,也是需要探索的,但是它会有一些问题
我写了一个MLP来作为policy,在训练过程中,每次做决策都使用 argmax 来寻找当前模型认为最好的action,模型不会收敛,想想它当然是不会收敛的,因为policy gradient训练模型本质上就是在提高采样样本中被采取的action的概率,即使这个action是一个不好的action,模型也会提升它,而之所以policy gradient能够训练出有效的模型,是因为提升每个action的程度不同,得到的reward多,提升得就高,反之提升得就低,如此一对比,提升得低的就相对是在降低了
而如果我在训练中每次都使用argmax获取action,也就是每次采样都是采样的模型输出概率更高的那个action。假设一开始各个action的概率是一样的,经过第一次采样,得到了一个样本(S,a),表示在状态S下采取了a的动作,那么,如果该游戏没有负reward的情况下,即使我采取a这个动作带来了不好的结果,那么reward也是正的,那么在梯度上升的加持下,模型就会提升在S这个状态下,a这个动作的概率,因为原本各action概率相同,如此一来a的概率就会比其他的都高,那么后续每次采样都只会采样到a了,a的概率也会逐渐增加知道趋近于1。
一个直观的想法是引入qlearning中的e-greedy方法,设置一个随机变量,在某次训练过程中如果该变量大于某阈值,则随机选择一个action,而不是使用argmax选择模型认为最好的action。这种想法看似可行,因为这样就避免了只会采样一个action的情况,但实际上这样还是有问题的,它对reward和随机变量的阈值都是有要求的
在一个trajectory中,会出现很多(S,a)对,表示在环境S下,policy选择了a这个action。不管a这个action是好的还是不好的,在最原始的policy下,它都会将这整个trajectory的total reward作为梯度增量的因子,所以,这种情况下,采样的a越多,其被再次采样的概率就越大,即使它不是一个好的action。
假设在S状态下有 A1,A2 两种action可以选择,选择A1可以得到reward=R1,选择A2得到 R2,经过设计有r1的概率选择A1,r2的概率选择A2。模型训练过程中,在做梯度更新时会将reward作为梯度增量的乘数因子,所以可以简单地认为reward就是训练一次后,各个action概率变化的增量。当概率的增量无法弥补选择的概率带来的差值时,模型的策略就不会发生变化(这里本来是要做一些数学计算的,但算着算着发现比我想象的要复杂得多),例如,R1=8,R2=9,r1=0.9,r2=0.1,假设 r 的更新公式为 r = (r + 0.01*R)/sum(r),则训练一次后,r1=0.84,r2=0.16,可见,正确的策略应该时选择A2,但此时r1仍然大于r2,要使r2>r1则需要很多轮的迭代,但要注意,这里讨论的仅仅是一个特定状态S下的情况,而真实情况下,采样的S每次可能都不一样,再加上reward本身可能是个随机变量,那么又要要求采样很多个S模型才能选择正确的策略,这个概率似乎还是有点低。还有一点更为重要,这里其实说的是不同的reward下的情况,它最终应该能收敛,但是在同一个trajectory,不使用折扣因子的情况下,其实它们的reward是一样的,这却情况下,谁被采样得多,谁就更有可能再被采样。经过实验证实,如果引入折扣因子,这个问题也会被解决
当奖励没有区分度的时候,被采样的次数越多,被采样的概率也就越变越大,这是一个恶性循环
由此可知,在使用policy gradient方法时,应尽量使得采样样本更丰富,例如训练过程中选择action时,不直接使用argmax选择,而是将模型的输出作为action的选择概率分布,然后随机选择:
# pytorch提供的方法
action = action_space[torch.distributions.Categorical(action_probs).sample().item()]
# 甚至于在某些简单的情况下,你可以完全采用随机的action,但是使用argmax是不会收敛的
action = torch.randint(0, 2)
当然,上面讨论的都是在reward都为正的情况下,如果有正有负则有可能不会出现这种情况,所以另一个解决方法是给reward减去一个baseline,详见 深度强化学习简介