强化学习汇总 – Mofan教程

强化学习汇总 – Mofan教程文章目录1.什么是强化学习RL算法2.强化学习方法汇总model-free和model-based基于概率和基于价值回合更新和单步更新在线学习和离线学习3.Q-learningQLearning决

1. 什么是强化学习

RL算法

强化学习是一个大家族, 他包含了很多种算法, 我们也会一一提到之中一些比较有名的算法,

在这里插入图片描述

  • 比如有通过行为的价值来选取特定行为的方法, 包括使用表格学习的 q learning, sarsa,
  • 使用神经网络学习的 deep q network, 还有直接输出行为的 policy gradients,
  • 又或者了解所处的环境, 想象出一个虚拟的环境并从虚拟的环境中学习 等等.

2. 强化学习方法汇总

model-free 和 model-based

在这里插入图片描述

Model-free 的方法有很多, 像 Q learning, Sarsa, Policy Gradients 都是从环境中得到反馈然后从中学习. 而 model-based RL 只是多了一道程序, 为真实世界建模, 也可以说他们都是 model-free 的强化学习, 只是 model-based 多出了一个虚拟环境, 我们不仅可以像 model-free 那样在现实中玩耍,还能在游戏中玩耍, 而玩耍的方式也都是 model-free 中那些玩耍方式, 最终 model-based 还有一个杀手锏是 model-free 超级羡慕的. 那就是想象力.

Model-free 中, 机器人只能按部就班, 一步一步等待真实世界的反馈, 再根据反馈采取下一步行动. 而 model-based, 他能通过想象来预判断接下来将要发生的所有情况. 然后选择这些想象情况中最好的那种. 并依据这种情况来采取下一步的策略, 这也就是 围棋场上 AlphaGo 能够超越人类的原因. 接下来, 我们再来用另外一种分类方法将 强化学习分为基于概率和基于价值.

基于概率 和 基于价值

在这里插入图片描述

  • 基于概率:通过感官分析所处的环境, 直接输出下一步要采取的各种动作的概率, 然后根据概率采取行动, 所以每种动作都有可能被选中, 只是可能性不同
  • 基于价值的方法输出则是所有动作的价值, 我们会根据最高价值来选着动作

相比基于概率的方法, 基于价值的决策部分更为铁定, 毫不留情, 就选价值最高的, 而基于概率的, 即使某个动作的概率最高, 但是还是不一定会选到他。

我们现在说的动作都是一个一个不连续的动作, 而对于选取连续的动作, 基于价值的方法是无能为力的. 我们却能用一个概率分布在连续动作中选取特定动作, 这也是基于概率的方法的优点之一. 那么这两类使用的方法又有哪些呢?

比如在基于概率这边, 有 Policy Gradients, 在基于价值这边有 Q learning, Sarsa 等. 而且我们还能结合这两类方法的优势之处, 创造更牛逼的一种方法, 叫做 Actor-Critic, actor 会基于概率做出动作, 而 critic 会对做出的动作给出动作的价值, 这样就在原有的 policy gradients 上加速了学习过程。

回合更新 和 单步更新

在这里插入图片描述

强化学习还能用另外一种方式分类,回合更新和单步更新。

想象强化学习就是在玩游戏, 游戏回合有开始和结束。

  • 回合更新指的是游戏开始后, 我们要等待游戏结束, 然后再总结这一回合中的所有转折点, 再更新我们的行为准则;
  • 单步更新则是在游戏进行中每一步都在更新, 不用等待游戏的结束, 这样我们就能边玩边学习了.

再来说说方法,

Monte-carlo learning 和基础版的 policy gradients 等 都是回合更新制,

Qlearning, Sarsa, 升级版的 policy gradients 等都是单步更新制. 因为单步更新更有效率, 所以现在大多方法都是基于单步更新. 比如有的强化学习问题并不属于回合问题.

在线学习 和 离线学习

在这里插入图片描述

这个视频的最后一种分类方式是 在线学习和离线学习,

  • 所谓在线学习, 就是指我必须本人在场, 并且一定是本人边玩边学习,
  • 离线学习是你可以选择自己玩, 也可以选择看着别人玩, 通过看别人玩来学习别人的行为准则, 离线学习 同样是从过往的经验中学习, 但是这些过往的经历没必要是自己的经历, 任何人的经历都能被学习. 或者我也不必要边玩边学习, 我可以白天先存储下来玩耍时的记忆, 然后晚上通过离线学习来学习白天的记忆.那么每种学习的方法又有哪些呢?

最典型的在线学习就是 Sarsa 了, 还有一种优化 Sarsa 的算法, 叫做 Sarsa lambda, 最典型的离线学习就是 Q learning, 后来人也根据离线学习的属性, 开发了更强大的算法, 比如让计算机学会玩电动的 Deep-Q-Network.

这就是我们从各种不同的角度来对比了强化学习中的多种算法.

3. Q-learning

先举个例子
假设现在我们处于写作业的状态而且我们以前并没有尝试过写作业时看电视, 所以现在我们有两种选择:1, 继续写作业, 2, 跑去看电视。因为以前没有被罚过, 所以我选看电视, 然后现在的状态变成了看电视, 我又选了 继续看电视, 接着我还是看电视, 最后爸妈回家, 发现我没写完作业就去看电视了, 狠狠地惩罚了我一次, 我也深刻地记下了这一次经历, 并在我的脑海中将 “没写完作业就看电视” 这种行为更改为负面行为, 我们在看看 Q learning 根据很多这样的经历是如何来决策的吧.

QLearning 决策

在这里插入图片描述

假设我们的行为准则已经学习好了,
现在我们处于状态 s 1 s1 s1, 我在写作业, 我有两个行为 a 1 , a 2 a1, a2 a1,a2, 分别是看电视和写作业,
根据我的经验, 在这种 s 1 s1 s1 状态下, a 2 a2 a2 写作业 带来的潜在奖励要比 a 1 a1 a1 看电视高,
这里的潜在奖励我们可以用一个有关于 s s s a a a Q Q Q 表格代替, 在我的记忆Q表格中, Q ( s 1 , a 1 ) = − 2 Q(s1, a1)=-2 Q(s1,a1)=2 要小于 Q ( s 1 , a 2 ) = 1 Q(s1, a2)=1 Q(s1,a2)=1, 所以我们判断要选择 a 2 a2 a2 作为下一个行为.
现在我们的状态更新成 s 2 s2 s2 , 我们还是有两个同样的选择, 重复上面的过程, 在行为准则 Q Q Q 表中寻找 Q ( s 2 , a 1 ) Q(s2, a1) Q(s2,a1) Q ( s 2 , a 2 ) Q(s2, a2) Q(s2,a2) 的值, 并比较他们的大小, 选取较大的一个.
接着根据 a 2 a2 a2 我们到达 s 3 s3 s3 并在此重复上面的决策过程.
Q learning 的方法也就是这样决策的. 看完决策, 我看在来研究一下这张行为准则 Q Q Q 表是通过什么样的方式更改, 提升的.

QLearning 更新

在这里插入图片描述

所以我们回到之前的流程, 根据 Q Q Q 表的估计,
因为在 s 1 s1 s1 中, a 2 a2 a2 的值比较大, 通过之前的决策方法, 我们在 s 1 s1 s1 采取了 a 2 a2 a2, 并到达 s 2 s2 s2
这时我们开始更新用于决策 Q Q Q 表, 接着我们并没有在实际中采取任何行为, 而是再想象自己在 s 2 s2 s2 上采取了每种行为, 分别看看两种行为哪一个的 Q Q Q 值大

  • 比如说 Q ( s 2 , a 2 ) Q(s2, a2) Q(s2a2) 的值比 Q ( s 2 , a 1 ) Q(s2, a1) Q(s2a1) 的大, 所以我们把大的 Q ( s 2 , a 2 ) Q(s2, a2) Q(s2a2) 乘上一个衰减值 γ \gamma γ (比如是0.9) 并加上到达 s 2 s2 s2 时所获取的奖励 R R R (这里还没有获取到我们的棒棒糖, 所以奖励为 0), 因为会获取实实在在的奖励 R R R我们将这个作为我现实中 Q ( s 1 , a 2 ) Q(s1, a2) Q(s1a2) 的值
  • 但是我们之前是根据 Q Q Q 表估计 Q ( s 1 , a 2 ) Q(s1, a2) Q(s1a2) 的值.
  • 所以有了现实和估计值, 我们就能更新 Q ( s 1 , a 2 ) Q(s1, a2) Q(s1a2) , 根据 估计与现实的差距, 将这个差距乘以一个学习效率 α \alpha α 累加上老的 Q ( s 1 , a 2 ) Q(s1, a2) Q(s1a2) 的值 变成新的值。
  • 但时刻记住, 我们虽然用 m a x Q ( s 2 ) maxQ(s2) maxQ(s2) 估算了一下 s 2 s2 s2 状态, 但还没有在 s 2 s2 s2 做出任何的行为, s 2 s2 s2 的行为决策要等到更新完了以后再重新另外做. 这就是 off-policy 的 Q learning 是如何决策和学习优化决策的过程.

Q Learning 整体算法

在这里插入图片描述
这一张图概括了我们之前所有的内容。 这也是 Q learning 的算法, 每次更新我们都用到了 Q Q Q 现实 Q Q Q 估计, 而且 Q learning 的迷人之处就是 在 Q ( s 1 , a 2 ) Q(s1, a2) Q(s1,a2)现实 中, 也包含了一个 Q ( s 2 ) Q(s2) Q(s2)最大估计值, 将对下一步的衰减的最大估计和当前所得到的奖励当成这一步的现实, 很奇妙吧.

最后我们来说说这套算法中一些参数的意义. ϵ − g r e e d y \epsilon – greedy ϵgreedy 是用在决策上的一种策略, 比如 ϵ = 0.9 \epsilon = 0.9 ϵ=0.9 时, 就说明有 90 % 90\% 90% 的情况我会按照 Q Q Q 表的最优值选择行为, 10 % 10\% 10% 的时间使用随机选行为. α \alpha α 是学习率, 来决定这次的误差有多少是要被学习的, α \alpha α 是一个小于1 的数. γ \gamma γ 是对未来 reward 的衰减值. 我们可以这样想象.

Q Learning 中的 Gamma

在这里插入图片描述
我们重写一下 Q ( s 1 ) Q(s1) Q(s1) 的公式, 将 Q ( s 2 ) Q(s2) Q(s2) 拆开, 因为 Q ( s 2 ) Q(s2) Q(s2) 可以像 Q ( s 1 ) Q(s1) Q(s1) 一样,是关于 Q ( s 3 ) Q(s3) Q(s3) 的, 所以可以写成这样, 然后以此类推, 不停地这样写下去, 最后就能写成这样, 可以看出 Q ( s 1 ) Q(s1) Q(s1) 是有关于之后所有的奖励, 但这些奖励正在衰减, 离 s 1 s1 s1 越远的状态衰减越严重. 不好理解? 行,

我们想象 Qlearning 的机器人天生近视眼, γ = 1 \gamma = 1 γ=1 时, 机器人有了一副合适的眼镜, 在 s 1 s1 s1 看到的 Q Q Q 是未来没有任何衰变的奖励, 也就是机器人能清清楚楚地看到之后所有步的全部价值;
但是当 γ = 0 \gamma =0 γ=0, 近视机器人没了眼镜, 只能摸到眼前的 reward, 同样也就只在乎最近的大奖励;
如果 γ \gamma γ 0 0 0 变到 1 1 1, 眼镜的度数由浅变深, 对远处的价值看得越清楚, 所以机器人渐渐变得有远见, 不仅仅只看眼前的利益, 也为自己的未来着想。

小例子

在这里插入图片描述
即:
在这里插入图片描述

实例化

import numpy as np
import pandas as pd
import time

np.random.seed(2)  # reproducible


N_STATES = 6   # the length of the 1 dimensional world
ACTIONS = ['left', 'right']     # available actions
EPSILON = 0.9   # greedy police
ALPHA = 0.1     # learning rate
GAMMA = 0.9    # discount factor
MAX_EPISODES = 13   # maximum episodes
# FRESH_TIME = 0.3 # fresh time for one move
FRESH_TIME = 0.01    # fresh time for one move


def build_q_table(n_states, actions):
    table = pd.DataFrame(
        np.zeros((n_states, len(actions))),     # q_table initial values
        columns=actions,    # actions's name
    )
    # print(table) # show table
    return table


def choose_action(state, q_table):
    # This is how to choose an action
    state_actions = q_table.iloc[state, :] # 通过行号取一行数据
    if (np.random.uniform() > EPSILON) or ((state_actions == 0).all()):  # act non-greedy or state-action have no value
        action_name = np.random.choice(ACTIONS) # ACTIONS = ['left', 'right']
    else:   # act greedy
        action_name = state_actions.idxmax()    # replace argmax to idxmax as argmax means a different function in newer version of pandas # 某行中最大的那个数据的列名
    return action_name


def get_env_feedback(S, A):
    # This is how agent will interact with the environment
    if A == 'right':    # move right
        if S == N_STATES - 2:   # terminate
            S_ = 'terminal'
            R = 1
        else:
            S_ = S + 1
            R = 0
    else:   # move left
        R = 0
        if S == 0:
            S_ = S  # reach the wall
        else:
            S_ = S - 1
    return S_, R


def update_env(S, episode, step_counter):
    # This is how environment be updated
    env_list = ['-']*(N_STATES-1) + ['T']   # '---------T' our environment
    if S == 'terminal':
        interaction = 'Episode %s: total_steps = %s' % (episode+1, step_counter)
        print('\r{}'.format(interaction), end='')
        time.sleep(2)
        print('\r ', end='')
    else:
        env_list[S] = 'o'
        interaction = ''.join(env_list)
        print('\r{}'.format(interaction), end='')
        time.sleep(FRESH_TIME)


def rl():
    # main part of RL loop
    q_table = build_q_table(N_STATES, ACTIONS)
    for episode in range(MAX_EPISODES):
        step_counter = 0
        S = 0
        is_terminated = False
        update_env(S, episode, step_counter)
        while not is_terminated: # 回合没有结束的时候

            A = choose_action(S, q_table)
            S_, R = get_env_feedback(S, A)  # take action & get next state and reward
            q_predict = q_table.loc[S, A] # 估计值
            if S_ != 'terminal': # 回合没结束的时候的真实值
                q_target = R + GAMMA * q_table.iloc[S_, :].max()   # next state is not terminal
            else:
                q_target = R     # next state is terminal
                is_terminated = True    # terminate this episode

            q_table.loc[S, A] += ALPHA * (q_target - q_predict)  # update
            S = S_  # move to next state

            update_env(S, episode, step_counter+1)
            step_counter += 1
    return q_table


if __name__ == "__main__":
    q_table = rl()
    print('\r\nQ-table:\n')
    print(q_table)

Q-learning 算法更新 与 Q-learning 思维决策 代码部分

移步莫凡的gihub:https://github.com/MorvanZhou/Reinforcement-learning-with-tensorflow/tree/master/contents/2_Q_Learning_maze

4. Sarsa [state-action-reward-state-action]

Sarsa 更新行为准则

在强化学习中 Sarsa 和 Q learning 及其类似。我们会对比 Q learning, 来看看 Sarsa 是特殊在哪些方面. 和上次一样, 我们还是使用写作业和看电视这个例子. 没写完作业去看电视被打, 写完了作业有糖吃.

Sarsa 的决策部分和 Q learning 一模一样, 因为我们使用的是 Q 表的形式决策, 所以我们会在 Q 表中挑选值较大的动作值施加在环境中来换取奖惩. 但是不同的地方在于 Sarsa 的更新方式是不一样的.
在这里插入图片描述

同样, 我们会经历正在写作业的状态 s 1 s1 s1, 然后再挑选一个带来最大潜在奖励的动作 a 2 a2 a2, 这样我们就到达了 继续写作业状态 s 2 s2 s2, 而在这一步, 如果你用的是 Q learning你会观看一下在 s 2 s2 s2 上选取哪一个动作会带来最大的奖励, 但是在真正要做决定时, 却不一定会选取到那个带来最大奖励的动作, Q-learning 在这一步只是估计了一下接下来的动作值。 而 Sarsa 是实践派, 他说到做到, 在 s 2 s2 s2 这一步估算的动作也是接下来要做的动作。 所以 Q ( s 1 , a 2 ) Q(s1, a2) Q(s1a2) 现实的计算值, 我们也会稍稍改动, 去掉 m a x Q maxQ maxQ, 取而代之的是在 s 2 s2 s2 上我们实实在在选取的 a 2 a2 a2 的 Q 值。 最后像 Q learning 一样, 求出现实和估计的差距 并更新 Q 表里的 Q ( s 1 , a 2 ) Q(s1, a2) Q(s1a2)

对比 Sarsa 和 Qlearning 算法

在这里插入图片描述
从算法来看, 这就是他们两最大的不同之处了. 因为 Sarsa 是说到做到型, 所以叫他 on-policy, 在线学习, 边做边学;
Q learning 是说到但并不一定做到, 其可以通过观察别人的经历来学习,所以它也叫作 Off-policy, 离线学习. 而因为有了 maxQ, Q-learning 也是一个特别勇敢的算法.

在这里插入图片描述
为什么说他勇敢呢, 因为 Q learning 机器人 永远都会选择最近的一条通往成功的道路, 不管这条路会有多危险. 而 Sarsa 则是相当保守, 他会选择离危险远远的, 拿到宝藏是次要的, 保住自己的小命才是王道. 这就是使用 Sarsa 方法的不同之处.

Sarsa 算法更新

Sarsa 的整个循环都将是在一个路径上, 也就是 on-policy, 下一个 state, 和下一个 action 将会变成他真正采取的 action 和 state. 和 Qlearning 的不同之处就在这. Qlearning 的下个一个 state_ action_ 在算法更新的时候都还是不确定的 (off-policy). 而 Sarsa 的 state, action 在这次算法更新的时候已经确定好了 (on-policy).

在这里插入图片描述
整个算法还是一直不断更新 Q table 里的值, 然后再根据新的值来判断要在某个 state 采取怎样的 action. 不过于 Qlearning 不同之处:

  • 他在当前 state 已经想好了 state 对应的 action, 而且想好了 下一个 state_ 和下一个 action_ (Qlearning 还没有想好下一个 action_)
  • 更新 Q(s,a) 的时候基于的是下一个 Q(s_, a_) (Qlearning 是基于 maxQ(s_))

这种不同之处使得 Sarsa 相对于 Qlearning, 更加的胆小. 因为 Qlearning 永远都是想着 maxQ 最大化, 因为这个 maxQ 而变得贪婪, 不考虑其他非 maxQ 的结果. 我们可以理解成 Qlearning 是一种贪婪, 大胆, 勇敢的算法, 对于错误, 死亡并不在乎. 而 Sarsa 是一种保守的算法, 他在乎每一步决策, 对于错误和死亡比较铭感. 这一点我们会在可视化的部分看出他们的不同. 两种算法都有他们的好处, 比如在实际中, 你比较在乎机器的损害, 用一种保守的算法, 在训练时就能减少损坏的次数.

算法的代码形式

移步莫凡的gihub:https://github.com/MorvanZhou/Reinforcement-learning-with-tensorflow/tree/master/contents/3_Sarsa_maze

什么是 Sarsa( λ \lambda λ)

强化学习中基于 Sarsa 的一种提速方法, 叫做 sarsa-lambda.

在每次take action获得reward后,Sarsa只对前一步Q(s,a)进行更新,Sarsa(lambda) 则会对获得reward之前的步进行更新。

Sarsa(n)不建议看这个,容易被误导

在这里插入图片描述
Sarsa 的算法是一种在线学习法, on-policy. Sarsa 是一种单步更新法,在环境中每走一步, 更新一次自己的行为准则, 我们可以在这样的 Sarsa 后面打一个括号, 说他是 Sarsa(0), 因为他等走完这一步以后直接更新行为准则.

  • 如果延续这种想法, 走完这步, 再走一步, 然后再更新, 我们可以叫他 Sarsa(1).
  • 同理, 如果等待回合完毕我们一次性再更新呢, 比如这回合我们走了 n 步, 那我们就叫 Sarsa(n).
  • 为了统一这样的流程, 我们就有了一个 λ \lambda λ 值来代替我们想要选择的步数, 这也就是 Sarsa( λ \lambda λ) 的由来. 我们看看最极端的两个例子, 对比单步更新和回合更新, 看看回合更新的优势在哪里.

单步更新 and 回合更新

在这里插入图片描述

  • 虽然我们每一步都在更新, 但是在没有获取宝藏的时候, 我们现在站着的这一步也没有得到任何更新, 也就是直到获取宝藏时, 我们才为获取到宝藏的上一步更新为: 这一步很好, 和获取宝藏是有关联的, 而之前为了获取宝藏所走的所有步都被认为和获取宝藏没关系.
  • 回合更新虽然我要等到这回合结束, 才开始对本回合所经历的所有步都添加更新, 但是这所有的步都是和宝藏有关系的, 都是为了得到宝藏需要学习的步, 所以每一个脚印在下回合被选择的几率又高了一些. 在这种角度来看, 回合更新似乎会有效率一些.

有时迷茫

在这里插入图片描述
我们看看这种情况, 还是使用单步更新的方法在每一步都进行更新, 但是同时记下之前的寻宝之路. 你可以想像, 每走一步, 插上一个小旗子, 这样我们就能清楚的知道除了最近的一步, 找到宝物时还需要更新哪些步了. 不过, 有时候情况可能没有这么乐观. 开始的几次, 因为完全没有头绪, 我可能在原地打转了很久, 然后才找到宝藏, 那些重复的脚步真的对我拿到宝藏很有必要吗? 答案我们都知道. 所以Sarsa( λ \lambda λ)就来拯救你啦.

Lambda 含义

在这里插入图片描述
其实 λ \lambda λ 就是一个衰变值, 他可以让你知道离奖励越远的步可能并不是让你最快拿到奖励的步, 所以我们想象我们站在宝藏的位置, 回头看看我们走过的寻宝之路, 离宝藏越近的脚印越看得清, 远处的脚印太渺小, 我们都很难看清, 那我们就索性记下离宝藏越近的脚印越重要, 越需要被好好的更新. 和之前我们提到过的 奖励衰减值 γ \gamma γ 一样, λ \lambda λ 是脚步衰减值, 都是一个在 0 和 1 之间的数.

Lambda 取值

在这里插入图片描述
λ \lambda λ 取0, 就变成了 Sarsa 的单步更新, 当 λ \lambda λ 取 1, 就变成了回合更新, 对所有步更新的力度都是一样. 当 lambda 在 0 和 1 之间, 取值越大, 离宝藏越近的步更新力度越大. 这样我们就不用受限于单步更新的每次只能更新最近的一步, 我们可以更有效率的更新所有相关步了.

对比 Sarsa 和 Sarsa- λ \lambda λ

在这里插入图片描述
在这里插入图片描述

从上图可以看出,和Sarsa相比,Sarsa( λ \lambda λ)算法中多了一个矩阵E (eligibility trace),它是用来保存在路径中所经历的每一步,因此在每次更新时也会对之前经历的步进行更新。

参数 λ \lambda λ取值范围为[0, 1] :

  • 如果 λ \lambda λ= 0,Sarsa( λ \lambda λ) 将退化为Sarsa,即只更新获取到 reward 前经历的最后一步;
  • 如果 λ \lambda λ= 1,Sarsa( λ \lambda λ) 更新的是获取到 reward 前的所有步。

λ \lambda λ可理解为脚步的衰变值,即离奶酪越近的步越重要,越远的步则对于获取奶酪不是太重要。

和Sarsa相比,Sarsa( λ \lambda λ)算法有如下优势:

  • Sarsa虽然会边走边更新,但是在没有获得奶酪之前,当前步的Q值是没有任何变化的,直到获取奶酪后,才会对获取奶酪的前一步更新,而之前为了获取奶酪所走的所有步都被认为和获取奶酪没关系。Sarsa( λ \lambda λ)则会对获取奶酪所走的步都进行更新,离奶酪越近的步越重要,越远的则越不重要(由参数 λ \lambda λ控制衰减幅度)。因此,Sarsa( λ \lambda λ) 能够更加快速有效的学到最优的policy。
  • 在算法前几回合,老鼠由于没有头绪, 可能在原地打转了很久,从而形成一些重复的环路,而这些环路对于算法的学习没有太大必要。Sarsa( λ \lambda λ)则可解决该问题,具体做法是:在 E ( s , a ) ← E ( s , a ) + 1 E(s,a)←E(s,a)+1 E(s,a)E(s,a)+1 这一步之前,可先令 E ( s ) = 0 E(s)=0 E(s)=0,即把状态 s s s 对应的行置为 0 0 0 ,这样就只保留了最近一次到达状态 s s s 时所做的action。

我们用图来说明这两种更新方式的不同:

在这里插入图片描述

  • 这是针对于一个state-action值 经历次数的变化。最上面是经历state-action的时间点
  • 第二张图是使用这种方式所带来的”不可或缺性值”:
    self.eligibility_trace.ix[s, a] += 1
  • 而第三张图是使用下面这种方法带来的”不可或缺性值”:
    self.eligibility_trace.ix[s, :] *= 0; self.eligibility_trace.ix[s, a] = 1

第一种(图2)的更新方式会有一些干扰,在试验中第二种更新方式也确实效果更好,所以下面的实战会采取第二种的方式。

移步莫凡的gihub:https://github.com/MorvanZhou/Reinforcement-learning-with-tensorflow/tree/master/contents/4_Sarsa_lambda_maze

5. Deep Q Network

什么是 DQN

在前面的介绍中,使用表格来存储每一个状态 state, 和在这个 state 每个行为 action 所拥有的 Q 值。而当今问题是在太复杂, 状态可以多到比天上的星星还多(比如下围棋)。 如果全用表格来存储它们, 恐怕我们的计算机有再大的内存都不够, 而且每次在这么大的表格中搜索对应的状态也是一件很耗时的事。

不过, 在机器学习中, 有一种方法对这种事情很在行, 那就是神经网络. 我们可以将状态和动作当成神经网络的输入, 然后经过神经网络分析后得到动作的 Q 值, 这样我们就没必要在表格中记录 Q 值, 而是直接使用神经网络生成 Q 值. 还有一种形式的是这样, 我们也能只输入状态值, 输出所有的动作值, 然后按照 Q learning 的原则, 直接选择拥有最大值的动作当做下一步要做的动作. 我们可以想象, 神经网络接受外部的信息, 相当于眼睛鼻子耳朵收集信息, 然后通过大脑加工输出每种动作的值, 最后通过强化学习的方式选择动作.

神经网络是要被训练才能预测出准确的值. 那在强化学习中, 神经网络是如何被训练的呢? 首先, 我们需要 a 1 , a 2 a1, a2 a1,a2 正确的 Q Q Q 值, 这个 Q Q Q 值我们就用之前在 Q learning 中的 Q Q Q 现实 r + γ m a x . . . r+\gamma max… r+γmax...】来代替. 同样我们还需要一个 Q Q Q 估计 来实现神经网络的更新. 所以神经网络的的参数就是老的 NN 参数 加学习率 α \alpha α 乘以 Q Q Q 现实 和 Q Q Q 估计 的差距. 我们整理一下.
在这里插入图片描述

  • 通过 NN 预测出 Q ( s 2 , a 1 ) Q(s2, a1) Q(s2,a1) Q ( s 2 , a 2 ) Q(s2,a2) Q(s2,a2) 的值, 这就是 Q Q Q 估计.
  • 选取 Q Q Q 估计中最大值的动作来换取环境中的奖励 reward.
  • Q Q Q 现实中也包含从神经网络分析出来的两个 Q Q Q 估计值, 不过这个 Q 估计是针对于下一步在 s ′ s’ s 的估计.
  • 再通过刚刚所说的算法更新神经网络中的参数.

但是这并不是 DQN 会玩电动的根本原因. 还有两大因素支撑着 DQN 使得它变得无比强大. 这两大因素就是 Experience replay 和 Fixed Q-targets.

DQN 两大利器

在这里插入图片描述

  • 简单来说, DQN 有一个记忆库用于学习之前的经历. 在之前的简介影片中提到过, Q learning 是一种 off-policy 离线学习法, 它能学习当前经历着的, 也能学习过去经历过的, 甚至是学习别人的经历. 所以每次 DQN 更新的时候, 我们都可以随机抽取一些之前的经历进行学习. 随机抽取这种做法打乱了经历之间的相关性, 也使得神经网络更新更有效率.

  • Fixed Q-targets 也是一种打乱相关性的机理, 如果使用 fixed Q-targets, 我们就会在 DQN 中使用到两个结构相同但参数不同的神经网络, 预测 Q 估计 的神经网络具备最新的参数, 而预测 Q 现实 的神经网络使用的参数则是很久以前的. 有了这两种提升手段, DQN 才能在一些游戏中超越人类.

DQN 算法更新 (Tensorflow)

在这里插入图片描述

其实DQN就是个 Q learning 主框架上加了些装饰,这些装饰包括:

  • 记忆库 (用于重复学习)
  • 神经网络计算 Q 值
  • 暂时冻结 q_target 参数 (切断相关性)

DQN 神经网络 (Tensorflow)

target_net 用于预测 q_target 值, 他不会及时更新参数. eval_net 用于预测 q_eval, 这个神经网络拥有最新的神经网络参数. 不过这两个神经网络结构是完全一样的, 只是里面的参数不一样:
在这里插入图片描述
两个神经网络是为了固定住一个神经网络 (target_net) 的参数, target_neteval_net 的一个历史版本, 拥有 eval_net 很久之前的一组参数, 而且这组参数被固定一段时间, 然后再被 eval_net 的新参数所替换. 而 eval_net 是不断在被提升的, 所以是一个可以被训练的网络 trainable=True. 而 target_nettrainable=False.

完整代码移动莫凡的:https://github.com/MorvanZhou/Reinforcement-learning-with-tensorflow/tree/master/contents/5_Deep_Q_Network

DQN 思维决策 (Tensorflow)

最重要的一步来是在 DeepQNetwork 中, 是如何学习, 更新参数的. 这里涉及了 target_neteval_net 的交互使用.

 # 下面这几步十分重要. q_next, q_eval 包含所有 action 的值,
# 而我们需要的只是已经选择好的 action 的值, 其他的并不需要.
# 所以我们将其他的 action 值全变成 0, 将用到的 action 误差值 反向传递回去, 作为更新凭据.
# 这是我们最终要达到的样子, 比如 q_target - q_eval = [1, 0, 0] - [-1, 0, 0] = [2, 0, 0]
# q_eval = [-1, 0, 0] 表示这一个记忆中有我选用过 action 0, 而 action 0 带来的 Q(s, a0) = -1, 所以其他的 Q(s, a1) = Q(s, a2) = 0.
# q_target = [1, 0, 0] 表示这个记忆中的 r+gamma*maxQ(s_) = 1, 而且不管在 s_ 上我们取了哪个 action,
# 我们都需要对应上 q_eval 中的 action 位置, 所以就将 1 放在了 action 0 的位置.

# 下面也是为了达到上面说的目的, 不过为了更方面让程序运算, 达到目的的过程有点不同.
# 是将 q_eval 全部赋值给 q_target, 这时 q_target-q_eval 全为 0,
# 不过 我们再根据 batch_memory 当中的 action 这个 column 来给 q_target 中的对应的 memory-action 位置来修改赋值.
 # 使新的赋值为 reward + gamma * maxQ(s_), 这样 q_target-q_eval 就可以变成我们所需的样子.
# 具体在下面还有一个举例说明.
q_target = q_eval.copy()
batch_index = np.arange(self.batch_size, dtype=np.int32)
eval_act_index = batch_memory[:, self.n_features].astype(int)
reward = batch_memory[:, self.n_features + 1]

q_target[batch_index, eval_act_index] = reward + self.gamma * np.max(q_next, axis=1)

举个例子通俗易懂:

""" 假如在这个 batch 中, 我们有2个提取的记忆, 根据每个记忆可以生产3个 action 的值: q_eval = [[1, 2, 3], [4, 5, 6]] q_target = q_eval = [[1, 2, 3], [4, 5, 6]] 然后根据 memory 当中的具体 action 位置来修改 q_target 对应 action 上的值: 比如在: 记忆 0 的 q_target 计算值是 -1, 而且我用了 action 0; 记忆 1 的 q_target 计算值是 -2, 而且我用了 action 2: q_target = [[-1, 2, 3], [4, 5, -2]] 所以 (q_target - q_eval) 就变成了: [[(-1)-(1), 0, 0], [0, 0, (-2)-(6)]] 最后我们将这个 (q_target - q_eval) 当成误差, 反向传递会神经网络. 所有为 0 的 action 值是当时没有选择的 action, 之前有选择的 action 才有不为0的值. 我们只反向传递之前选择的 action 的值, """

为了看看学习效果, 我们在最后输出学习过程中的 cost 变化曲线.

在这里插入图片描述

可以看出曲线并不是平滑下降的, 这是因为 DQN 中的 input 数据是一步步改变的, 而且会根据学习情况, 获取到不同的数据. 所以这并不像一般的监督学习, DQN 的 cost 曲线就有所不同了.

完整代码移动莫凡的:https://github.com/MorvanZhou/Reinforcement-learning-with-tensorflow/tree/master/contents/5_Deep_Q_Network

OpenAI gym 环境库

手动编环境是一件很耗时间的事情, 所以如果有能力使用别人已经编好的环境, 可以节约我们很多时间. OpenAI gym 就是这样一个模块, 他提供了我们很多优秀的模拟环境. 我们的各种 RL 算法都能使用这些环境.

Double DQN (Tensorflow)

一句话概括, DQN 基于 Q-learning, Q-Learning 中有 Qmax, Qmax 会导致 Q现实 当中的过估计 (overestimate). 而 Double DQN 就是用来解决过估计的. 在实际问题中, 如果你输出你的 DQN 的 Q 值, 可能就会发现, Q 值都超级大. 这就是出现了 overestimate.

Double DQN 算法

我们知道 DQN 的神经网络部分可以看成一个 最新的神经网络 + 老神经网络, 他们有相同的结构, 但内部的参数更新却有时差. 而它的 Q现实 部分是这样的:
在这里插入图片描述
因为我们的神经网络预测 Qmax 本来就有误差, 每次也向着最大误差的 Q现实 改进神经网络, 就是因为这个 Qmax 导致了 overestimate. 所以 Double DQN 的想法就是引入另一个神经网络来打消一些最大误差的影响. 而 DQN 中本来就有两个神经网络, 我们何不利用一下这个地理优势呢. 所以, 我们用 Q估计 的神经网络估计 Q现实Qmax(s', a') 的最大动作值. 然后用这个被 Q估计 估计出来的动作来选择 Q现实 中的 Q(s'). 总结一下:

有两个神经网络: Q_eval (Q估计中的), Q_next (Q现实中的).

原本的 Q_next = max(Q_next(s', a_all)).

Double DQN 中的 Q_next = Q_next(s', argmax(Q_eval(s', a_all))). 也可以表达成下面那样.
在这里插入图片描述

更新方法

我们对比 Double DQN 和 Natural DQN 在 tensorboard 中的图, 发现他们的结构并没有不同, 但是在计算 q_target 的时候, 方法是不同的.

在这里插入图片描述

来对比 Natural DQN 和 Double DQN 带来的不同结果
在这里插入图片描述
可以看出, Natural DQN 学得差不多后, 在立起来时, 大部分时间都是 估计的 Q值 要大于0, 这时就出现了 overestimate, 而 Double DQN 的 Q值 就消除了一些 overestimate, 将估计值保持在 0 左右.

完整代码移动莫凡的: https://github.com/MorvanZhou/Reinforcement-learning-with-tensorflow/tree/master/contents/5.1_Double_DQN

Prioritized Experience Replay (DQN) (Tensorflow)

这一次还是使用 MountainCar 来进行实验, 因为这次我们不需要重度改变他的 reward 了. 所以只要是没有拿到小旗子, reward=-1, 拿到小旗子时, 我们定义它获得了 +10 的 reward. 比起之前 DQN 中, 这个 reward 定义更加准确. 如果使用这种 reward 定义方式, 可以想象 Natural DQN 会花很久的时间学习, 因为记忆库中只有很少很少的 +10 reward 可以学习. 正负样本不一样. 而使用 Prioritized replay, 就会重视这种少量的, 但值得学习的样本.

Prioritized replay 算法

在这里插入图片描述

这一套算法重点就在我们 batch 抽样的时候并不是随机抽样, 而是按照 Memory 中的样本优先级来抽. 所以这能更有效地找到我们需要学习的样本.

那么样本的优先级是怎么定的呢? 原来我们可以用到 TD-error, 也就是 Q现实 - Q估计 来规定优先学习的程度. 如果 TD-error 越大, 就代表我们的预测精度还有很多上升空间, 那么这个样本就越需要被学习, 也就是优先级 p 越高.

有了 TD-error 就有了优先级 p, 那我们如何有效地根据 p 来抽样呢? 如果每次抽样都需要针对 p 对所有样本排序, 这将会是一件非常消耗计算能力的事. 好在我们还有其他方法, 这种方法不会对得到的样本进行排序. 这就是这篇 paper 中提到的 SumTree.

SumTree 是一种树形结构, 每片树叶存储每个样本的优先级 p, 每个树枝节点只有两个分叉, 节点的值是两个分叉的合, 所以 SumTree 的顶端就是所有 p 的合. 正如下面图片(来自Jaromír Janisch), 最下面一层树叶存储样本的 p, 叶子上一层最左边的 13 = 3 + 10, 按这个规律相加, 顶层的 root 就是全部 p 的合了.

在这里插入图片描述
抽样时, 我们会将 p 的总合 除以 batch size, 分成 batch size 那么多区间, (n=sum(p)/batch_size). 如果将所有 node 的 priority 加起来是42的话, 我们如果抽6个样本, 这时的区间拥有的 priority 可能是这样.

[0-7], [7-14], [14-21], [21-28], [28-35], [35-42]

然后在每个区间里随机选取一个数. 比如在第区间 [21-28] 里选到了24, 就按照这个 24 从最顶上的42开始向下搜索. 首先看到最顶上 42 下面有两个 child nodes, 拿着手中的24对比左边的 child 29, 如果 左边的 child 比自己手中的值大, 那我们就走左边这条路, 接着再对比 29 下面的左边那个点 13, 这时, 左边child 13 比手中的 24 小, 那我们就走右边的路, 并且将手中的值根据 13 修改一下, 变成 24-13 = 11. 接着拿着 1113 左下角的 12 比, 结果 1211 大, 那我们就选 12 当做这次选到的 priority, 并且也选择 12 对应的数据.

SumTree 有效抽样

详见代码:https://github.com/MorvanZhou/Reinforcement-learning-with-tensorflow/blob/master/contents/5.2_Prioritized_Replay_DQN/RL_brain.py#L18-L86

Dueling DQN (Tensorflow)

在这里插入图片描述
下面这个公式解释了不同之处. 原来 DQN 神经网络直接输出的是每种动作的 Q值, 而 Dueling DQN 每个动作的 Q值 是有下面的公式确定的.
在这里插入图片描述
它分成了这个 state 的值, 加上每个动作在这个 state 上的 advantage. 因为有时候在某种 state, 无论做什么动作, 对下一个 state 都没有多大影响. 比如 paper 中的这张图.
在这里插入图片描述

全部代码请移步莫凡的git:https://github.com/MorvanZhou/Reinforcement-learning-with-tensorflow/tree/master/contents/5.3_Dueling_DQN

详细原理解释请见:https://www.cnblogs.com/pinard/p/9923859.html

6. Policy Gradient

建立 Policy 神经网络

在这里插入图片描述

这是强化学习, 所以神经网络中并没有我们熟知的监督学习中的 y label. 取而代之的是我们选的 action.

  • loss= -log(prob)*vt
    • neg_log_prob: 最大化 总体 reward (log_p * R) 就是在最小化 -(log_p * R), 而 tf 的功能里只有最小化 loss
      我们能将这个 neg_log_prob 理解成 cross-entropy 的分类误差. 分类问题中的标签是真实 x 对应的 y, 而我们 Policy gradient 中, xstate, y 就是它按照这个 x 所做的动作号码. 所以也可以理解成, 它按照 x 做的动作永远是对的 (出来的动作永远是正确标签), 它也永远会按照这个 正确标签 修改自己的参数. 可是事实却不是这样, 他的动作不一定都是 正确标签, 这就是强化学习(Policy gradient)和监督学习(classification)的不同.
  • 为了确保这个动作真的是 正确标签, 我们的 loss 在原本的 cross-entropy 形式上乘以 vt, 用 vt来告诉这个 cross-entropy 算出来的梯度是不是一个值得信任的梯度. 如果 vt 小, 或者是负的, 就说明这个梯度下降是一个错误的方向, 我们应该向着另一个方向更新参数, 如果这个 vt 是正的, 或很大, vt 就会称赞 cross-entropy 出来的梯度, 并朝着这个方向梯度下降. 下面有一张从 karpathy 大神 网页上扣下来的图, 也正是阐述的这个思想.
    在这里插入图片描述

7. Actor Critic

什么是 Actor Critic

为什么要有 Actor 和 Critic ?

我们有了像 Q-learning 这么伟大的算法, 为什么还要瞎折腾出一个 Actor-Critic?

  • 原来 Actor-Critic 的 Actor 的前生是 Policy Gradients, 这能让它毫不费力地在连续动作中选取合适的动作, Q-learning 做这件事会瘫痪.
  • 那为什么不直接用 Policy Gradients 呢? 原来 Actor Critic 中的 Critic 的前生是 Q-learning 或者其他的 以值为基础的学习法 , 能进行单步更新, 而传统的 Policy Gradients 则是回合更新, 这降低了学习效率.

Actor 和 Critic

现在我们有两套不同的体系, ActorCritic, 他们都能用不同的神经网络来代替 . 在 Policy Gradients 的影片中提到过, 现实中的奖惩会左右 Actor 的更新情况. Policy Gradients 也是靠着这个来获取适宜的更新. 那么何时会有奖惩这种信息能不能被学习呢? 这看起来不就是 以值为基础的强化学习方法做过的事吗. 那我们就拿一个 Critic 去学习这些奖惩机制, 学习完了以后. 由 Actor 来指手画脚, 由 Critic 来告诉 Actor 你的那些指手画脚哪些指得好, 哪些指得差, Critic 通过学习环境和奖励之间的关系, 能看到现在所处状态的潜在奖励, 所以用它来指点 Actor 便能使 Actor 每一步都在更新, 如果使用单纯的 Policy Gradients, Actor 只能等到回合结束才能开始更新.

增加单步更新属性

在这里插入图片描述
但是事物终有它坏的一面, Actor-Critic 涉及到了两个神经网络, 而且每次都是在连续状态中更新参数, 每次参数更新前后都存在相关性, 导致神经网络只能片面的看待问题, 甚至导致神经网络学不到东西. Google DeepMind 为了解决这个问题, 修改了 Actor Critic 的算法,

改进版 Deep Deterministic Policy Gradient (DDPG)

在这里插入图片描述

将之前在电动游戏 Atari 上获得成功的 DQN 网络加入进 Actor Critic 系统中, 这种新算法叫做 Deep Deterministic Policy Gradient, 成功的解决的在连续动作预测上的学不到东西问题.

Actor Critic (Tensorflow)

一句话概括 Actor Critic 方法:

结合了 Policy Gradient (Actor) 和 Function Approximation (Critic) 的方法. Actor 基于概率选行为, Critic 基于 Actor 的行为评判行为的得分, Actor 根据 Critic 的评分修改选行为的概率.

Actor Critic 方法的优势: 可以进行单步更新, 比传统的 Policy Gradient 要快.

Actor Critic 方法的劣势: 取决于 Critic 的价值判断, 但是 Critic 难收敛, 再加上 Actor 的更新, 就更难收敛. 为了解决收敛问题, Google Deepmind 提出了 Actor Critic 升级版 Deep Deterministic Policy Gradient. 后者融合了 DQN 的优势, 解决了收敛难的问题.

算法

Actor 修改行为时就像蒙着眼睛一直向前开车, Critic 就是那个扶方向盘改变 Actor 开车方向的.

在这里插入图片描述
或者说详细点, 就是 Actor 在运用 Policy Gradient 的方法进行 Gradient ascent 的时候, 由 Critic 来告诉他, 这次的 Gradient ascent 是不是一次正确的 ascent, 如果这次的得分不好, 那么就不要 ascent 那么多.

两者学习方式

Actor 想要最大化期望的 reward, 在 Actor Critic 算法中, 我们用 比平时好多少 (TD error) 来当做 reward, 所以就是:

with tf.variable_scope('exp_v'):
    log_prob = tf.log(self.acts_prob[0, self.a])    # log 动作概率
    self.exp_v = tf.reduce_mean(log_prob * self.td_error)   # log 概率 * TD 方向
with tf.variable_scope('train'):
    # 因为我们想不断增加这个 exp_v (动作带来的额外价值),
    # 所以我们用过 minimize(-exp_v) 的方式达到
    # maximize(exp_v) 的目的
    self.train_op = tf.train.AdamOptimizer(lr).minimize(-self.exp_v)

Critic 的更新很简单, 就是像 Q learning 那样更新现实和估计的误差 (TD error) 就好了.

with tf.variable_scope('squared_TD_error'):
    self.td_error = self.r + GAMMA * self.v_ - self.v
    self.loss = tf.square(self.td_error)    # TD_error = (r+gamma*V_next) - V_eval
with tf.variable_scope('train'):
    self.train_op = tf.train.AdamOptimizer(lr).minimize(self.loss)

什么是 Deep Deterministic Policy Gradient (DDPG)

DDPG 最大的优势就是能够在连续动作上更有效地学习

它吸收了 Actor-Critic 让 Policy gradient 单步更新的精华, 而且还吸收让计算机学会玩游戏的 DQN 的精华

在这里插入图片描述

  • Policy Gradient 这边, 我们有 估计网络现实网络 ;
    • 估计网络 用来输出实时的动作, 供 actor 在现实中实行.
    • 现实网络 则是用来更新价值网络系统的.
  • 价值系统这边, 我们也有现实网络估计网络, 他们都在输出这个状态的价值, 而输入端却有不同,
    • 状态现实网络 这边会拿着从动作现实网络来的动作加上状态的观测值加以分析,
    • 而状态 估计网络 则是拿着当时 Actor 施加的动作当做输入.在实际运用中, DDPG 的这种做法的确带来了更有效的学习过程.

Deep Deterministic Policy Gradient (DDPG) (Tensorflow)

DDPG 的算法实际上就是一种 Actor Critic

在这里插入图片描述
关于 Actor 部分, 他的参数更新同样会涉及到 Critic, 上面是关于 Actor 参数的更新,

  • 它的前半部分 grad[Q] 是从 Critic 来的, 这是在说: 这次 Actor 的动作要怎么移动, 才能获得更大的 Q,
  • 而后半部分 grad[u] 是从 Actor 来的, 这是在说: Actor 要怎么样修改自身参数, 使得 Actor 更有可能做这个动作.

所以两者合起来就是在说: Actor 要朝着更有可能获取大 Q 的方向修改动作参数了.

在这里插入图片描述
上面这个是关于 Critic 的更新, 它借鉴了 DQNDouble Q learning 的方式, 有两个计算 Q 的神经网络, Q_target 中依据下一状态, 用 Actor 来选择动作, 而这时的 Actor 也是一个 Actor_target (有着 Actor 很久之前的参数). 使用这种方法获得的 Q_target 能像 DQN 那样切断相关性, 提高收敛性.

莫凡说 这个代码比较结构清晰,简单易懂:https://github.com/MorvanZhou/Reinforcement-learning-with-tensorflow/tree/master/contents/9_Deep_Deterministic_Policy_Gradient_DDPG/DDPG_update.py

什么是 Asynchronous Advantage Actor-Critic (A3C)

在这里插入图片描述

A3C 其实只是这种平行方式的一种而已, 它采用的是我们之前提到的 Actor-Critic 的形式. 为了训练一对 Actor 和 Critic, 我们将它复制多份红色的, 然后同时放在不同的平行宇宙当中, 让他们各自玩各的. 然后每个红色副本都悄悄告诉黑色的 Actor-Critic 自己在那边的世界玩得怎么样, 有哪些经验值得分享. 然后还能从黑色的 Actor-Critic 这边再次获取综合考量所有副本经验后的通关秘籍. 这样一来一回, 形成了一种有效率的强化学习方式.

Asynchronous Advantage Actor-Critic (A3C) (Tensorflow)

A3C 的算法实际上就是将 Actor-Critic 放在了多个线程中进行同步训练. 可以想象成几个人同时在玩一样的游戏, 而他们玩游戏的经验都会同步上传到一个中央大脑. 然后他们又从中央大脑中获取最新的玩游戏方法.

这样, 对于这几个人, 他们的好处是: 中央大脑汇集了所有人的经验, 是最会玩游戏的一个, 他们能时不时获取到中央大脑的必杀招, 用在自己的场景中.

对于中央大脑的好处是: 中央大脑最怕一个人的连续性更新, 不只基于一个人推送更新这种方式能打消这种连续性. 使中央大脑不必有用像 DQN, DDPG 那样的记忆库也能很好的更新.
在这里插入图片描述

Distributed Proximal Policy Optimization (DPPO) (Tensorflow)

如果一句话概括 PPO: OpenAI 提出的一种解决 Policy Gradient 不好确定 Learning rate (或者 Step size) 的问题. 因为如果 step size 过大, 学出来的 Policy 会一直乱动, 不会收敛, 但如果 Step Size 太小, 对于完成训练, 我们会等到绝望. PPO 利用 New Policy 和 Old Policy 的比例, 限制了 New Policy 的更新幅度, 让 Policy Gradient 对稍微大点的 Step size 不那么敏感.

在这里插入图片描述

在这里插入图片描述

总的来说 PPO 是一套 Actor-Critic 结构, Actor 想最大化 J_PPO, Critic 想最小化 L_BL. Critic 的 loss 好说, 就是减小 TD error. 而 Actor 的就是在 old Policy 上根据 Advantage (TD error) 修改 new Policy, advantage 大的时候, 修改幅度大, 让 new Policy 更可能发生. 而且他们附加了一个 KL Penalty (惩罚项, 不懂的同学搜一下 KL divergence), 简单来说, 如果 new Policy 和 old Policy 差太多, 那 KL divergence 也越大, 我们不希望 new Policy 比 old Policy 差太多, 如果会差太多, 就相当于用了一个大的 Learning rate, 这样是不好的, 难收敛.

在这里插入图片描述

https://github.com/MorvanZhou/Reinforcement-learning-with-tensorflow/blob/master/contents/12_Proximal_Policy_Optimization/DPPO.py

今天的文章强化学习汇总 – Mofan教程分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/59926.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注