从baselines库的common/vec_env/vec_normalize.py看reinforcement learning算法中的reward shape方法

参考前文:https://www.cnblogs.com/devilmaycry812839668/p/15889282.html

 

2.  REINFORCE算法实际代码中为什么会对一个episode内的所有状态动作对的折扣奖励和进行规则化(Regularize)

总所周知在REINFORCE算法的论文和实际理论中并没有对一个episode内的所有状态动作对的折扣奖励sum做Regularize,但是在实际代码中却进行了Regularize。在REINFORCE的实际代码编写中一个episode内的每个状态动作对的折扣奖励sum都是相当于通过蒙特卡洛方式得到的,然后再对一个episode内的所有状态动作的折扣奖励和做规则化(减去均值除去方差),最后获得一个episode内每个状态动作对的规则化后的折扣奖励和。

可以知道对episode内的每个状态动作对的折扣奖励sum进行规则化是代码编写中的trick,这个trick并不是论文中给出的而是实际代码编写和运行中得到的trick,经过大量实验后发现该trick确实好用。为什么这个trick好用呢,分析一下可以知道REINFORCE属于蒙特卡洛方式的采样估计,该种方式虽然无偏但却高方差不利于收敛,所以要是严格按照论文不采用这个trick会不利于收敛。同时可以参考安德鲁.NG.吴恩达的博士论文“reinforcement learning reward shape”可以知道通过对reward的shape可以提高算法的训练性能。REINFORCE算法采用这个trick后可以很好的减少训练时候的方差,有利于收敛。

 

 

=============================================

 

在reinforce算法中对reward一般是进行regularize操作的,也就是对每个step的折扣奖励和进行正则化,而在baselines库的common/vec_env/vec_normalize.py模块中对reward的正则化又有了不同。

 

    def step_wait(self):
        obs, rews, news, infos = self.venv.step_wait()
        self.ret = self.ret * self.gamma + rews
        obs = self._obfilt(obs)
        if self.ret_rms:
            self.ret_rms.update(self.ret)
            rews = np.clip(rews / np.sqrt(self.ret_rms.var + self.epsilon), -self.cliprew, self.cliprew)
        self.ret[news] = 0.
        return obs, rews, news, infos

 

可以知道,self.ret为一个episode内的每个step的折扣奖励和,self.ret_rms.update(self.ret)可以根据每步的折扣奖励和来进行求方差,

最后根据每步step的折扣奖励和的方差来对每步的step进行正则化:

rews = np.clip(rews / np.sqrt(self.ret_rms.var + self.epsilon), -self.cliprew, self.cliprew)

 

 

个人理解是每个step的折扣奖励和的方差会小于每个step所获奖励的方差,使用折扣奖励和的方差来正则化reward可以使后续的reinforcement learning算法在计算过程中更加的平稳和低方差。

不过不是很理解的是为什么要用折扣奖励和来求解方差而不是直接使用每步的step的reward来计算方差。

 

 

总的来说就是这里的reward正则化十分的难以理解为什么要选每步的折扣奖励和来进行正则化操作的方差求解。

 

不得不说baselines库中的很多操作都难以有很好的解释。

 

 

 

==========================================

 

posted on 2022-04-08 23:31  Angry_Panda  阅读(130)  评论(0)    收藏  举报

导航