强化学习(Dyna-Q,Dyna2)

基于模型的强化学习(Model Based RL)
Value Based --Policy Based --Model Based

Value Based学习价值来指导策略,Policy Based直接学习策略以收获最大价值,还有将两者融合的AC。但是在学习价值或策略都十分困难的时候(如某千变万化的围棋),学习模型可能更好,即睁开眼睛看世界,尝试理解所处的环境,通过完成对环境的基本理解来指导强化学习。

怎么学习到模型?
同样是从经历中学习模型,即需学习对环境的描述与理解。而“经历”不正是所经历过的所有状态,以及采取的行动,那么还是要从状态s和动作a出发,通过先模拟与环境的交互,得到对环境的描述与理解,再在实际环境中进行监督学习,不断训练。

优点:使用类似监督学习的方法来获得模型。通过模型,个体不再局限与如何最大化奖励本身,而是能通过理解采取的动作为什么好或者不好,从而具有了一定的推理能力。
缺点:模型是模拟的结果,会有误差。
强化学习(Dyna-Q,Dyna2)
Dyna
由于不可能精确和完美的拟合真正环境,纯基于模型的强化学习效果往往很差。那有没有什么办法可以在一定程度上避免这一点呢?
那就把基于模型 + 不基于模型的强化学习结合起来吧!也就是Dyna算法框架了。

它既在模型中学习,也在交互中学习。即Dyna框架在每个迭代轮中,会先和环境交互,并更新价值函数、策略函数,接着进行n次模型的模拟预测,同样更新价值函数、策略函数。这样同时利用上了和环境交互的经历以及模型的预测。

根据描述,就需要有两个相互独立的模型,一个根据状态s和动作a得到下一个状态s’(策略函数),另一个根据当前状态s和动作a预测环境的奖励r(价值函数)。其中

从 s,a 学习 r 的预测过程是一个回归问题(regression problem)。
从 s,a 学习 s’ 的选择过程是一个密度估计问题(density estimation problem)。

Dyna-Q
先看Dyna算法步骤:
强化学习(Dyna-Q,Dyna2)

  • 先初始化状态s和其任意动作a所对应的状态价值Q(s,a)。
  • 初始化尝试要理解得到的模型Model(s,a)。
  • 对于每一轮迭代,先根据当前状态和Q(S,A)用 ϵ-贪婪的方式得到新状态S’和奖励R
  • 然后用Q-Learning更新价值函数Q(S,A)
  • 用R,S’更新模型Model(s,a)
    (与真实环境交互完毕后,进行n次模拟)
  • 每次模拟都随机选择一个之前出现过的状态S, 并在此基础上随机选择一个动作A
  • 基于模型Model(S,A)得到S′ 和R
  • 再使用Q-Learning更新价值函数:Q(S,A)=Q(S,A)+α[R+γmaxaQ(S,a)Q(S,A)]Q(S,A)=Q(S,A)+α[R+γmaxaQ(S′,a)−Q(S,A)]

思路明确代码就都差不多…
莫大大的代码:

def update():
    for episode in range(40): #开始循环
        s = env.reset()  #得到当前的状态
        while True:
            env.render()
            a = RL.choose_action(str(s)) #根据状态选动作
            s_, r, done = env.step(a) #执行动作得到新状态s'和奖励r,是否为终点
            RL.learn(str(s), a, r, str(s_)) #开始学习

            env_model.store_transition(str(s), a, r, s_) #存入到表中
            for n in range(10):     #交互完开始与模拟模拟交互
                ms, ma = env_model.sample_s_a()  #采样出现过的s,a
                mr, ms_ = env_model.get_r_s_(ms, ma) #得到奖励r和新状态s'
                RL.learn(ms, ma, mr, str(ms_)) #继续学习

            s = s_
            if done:
                break

    # end of game
    print('game over')
    env.destroy()

def learn(self, s, a, r, s_): 
        self.check_state_exist(s_) #检查s‘是否存在,就和Q-Learning过程一样
        q_predict = self.q_table.ix[s, a] #查表得到Q
        if s_ != 'terminal':
            q_target = r + self.gamma * self.q_table.ix[s_, :].max()  #计算得到Q‘
        else:
            q_target = r 
        self.q_table.ix[s, a] += self.lr * (q_target - q_predict)  # 更新Q表

Dyna-2
Dyna-2是将环境交互的经历以及模型的预测进行了分离。对于Q函数将被分为永久性记忆Q(S,A)Q(S,A)和瞬时记忆Q(S,A)Q'(S,A)。其中永久性记忆利用与实际环境的交互经验来更新,瞬时记忆利用与模型的模拟交互来更新。然后两者结合起来共同 对作用起选择。
Q(S,A)=Q(S,A)+Q(S,A)\overline{Q}(S,A) =Q(S,A) + Q'(S,A)
算法流程如下:
强化学习(Dyna-Q,Dyna2)
即在选择实际的执行动作前,先进行与模拟环境的交互以评价当前动作的价值,然后根据完整的Q值共同进行选择。