强化学习实操笔记(一)

代码地址: 强化学习 简明教程 代码实战
下午无事,找个强化学习的教程回顾。这里是简要的一些笔记。

一、无状态问题

假设你进入一个赌场,面对一排老虎机(所以有多个臂),每个老虎机都有一定的概率获取奖励,你试验的总次数是一定的,这就是从经典的多臂老虎机问题。这里就有在线学习及更宽泛的强化学习中一个核心的权衡问题:Conlict between exploitation and exploring。即我们是应该探索(exploration)去尝试新的可能性,还是应该守成(exploitation)。

  1. 贪婪算法
    比较保守,记录当前每个已玩老虎机的收益,选择收益期望最大的。但是需要给出一定的探索概率,即随机选择没玩过的老虎机。
  2. 递减的贪婪算法
    对上面固定的探索概率挂钩,如玩的次数越少,则随机探索的概率越大,探索次数越多,即有很多的已知信息了,则减少随机选择的概率,转向选择已知期望收益最大的老虎机。
  3. UCB 上置信界算法
    根据每个动作的期望奖励和不确定性来计算一个上界,然后选择上界最大的动作,这里有很多证明。通俗地理解的话,多探索玩的少的机器,少探索玩的多的机器,对每个机器的玩的次数都做一个记录。 如下:分子是总共玩了多少次,取根号后让他的增长速度变慢,分母是每台老虎机玩的次数,乘以2让他的增长速度变快,随着玩的次数增加,分母会很快超过分子的增长速度,导致分数越来越小,具体到每一台老虎机,则是玩的次数越多,分数就越小,也就是ucb的加权越小,所以ucb衡量了每一台老虎机的不确定性,不确定性越大,探索的价值越大。 最后两者相加,即综合考虑了探索和exploitation
    核心代码:
def choose_one():
    #求出每个老虎机各玩了多少次
    played_count = [len(i) for i in rewards]
    played_count = np.array(played_count)
    #求出上置信界
    fenzi = played_count.sum()**0.5
    fenmu = played_count * 2
    ucb = fenzi / fenmu
    #ucb本身取根号
    #大于1的数会被缩小,小于1的数会被放大,这样保持ucb恒定在一定的数值范围内
    ucb = ucb**0.5
    #计算每个老虎机的奖励平均
    rewards_mean = [np.mean(i) for i in rewards]
    rewards_mean = np.array(rewards_mean)
    #ucb和期望求和
    ucb += rewards_mean
    return ucb.argmax()
  1. 汤普森采样算法
    采用了beta 分布。Beta 分布是一种定义在 (0,1) 区间的连续概率分布,有两个形状参数 α 和 β,可以用来描述伯努利试验的成功概率的不确定性。可以参考,beta分布的理解 进行理解。
    个人理解为,伯努利试验中,试验次数为n, 成功次数为X, X服从二项分布X~B(n,p) 。但是如果我们不知道概率p,那么,在多次重复进行n次伯努利试验,我们想要知道p的所有可能取值的概率,随机变量p就服从Beta分布。用一句话来说,Beta分布可以看作一个概率的概率分布,当你不知道一个东西的具体概率是多少时,它可以给出了所有概率出现的可能性大小。其中Beta分布的两个参数,可以看做先验信息中成功的次数&失败的次数。
    在这里插入图片描述
    在本问题中,这个概率,就是我们估计的每个老虎机的收益的期望。
    设每个老虎机收益服从beta分布,那么我们记录每个老虎机出1的次数+1, 出0的次数+1。这样就有了这个收益的分布,那么我们就对每个老虎机采样得到一个它的概率,找出最大的值对应的老虎机即可。(想想这里一般的做法是用出1次数/总次数认为是老虎机的期望,但这个是不准确的,因为次数少的时候,随机性很强。)

三、动态规划法

动态规划算法是对环境完全已知的,有模型的算法。
下图游戏,机器人会在左侧第0列随机一个格子出现。灰色格子是陷阱,绿色格子是终点。机器人的动作空间是上下左右。
所谓对环境已知,是指能完整确定地推演,我在选择动作时候,已经知道下个状态,下下个动作空间,我能做完整推演,不用探索。
所谓有模型,是指选择一个动作后,我知道我会100%到什么状态,我的reward的值是多少也是确定已知的。
在这里插入图片描述

  • 策略迭代算法

策略迭代算法思想就是计算每个状态的价值,它借助于动态规划基本方程,交替使用“求值计算”和“策略改进”两个步骤,求出逐次改进的、最终达到或收敛于最优策略的策略序列。(1)以某种策略 开始,计算此策略下的状态值函数(2)根据此值函数,找到最好的策略 (3)用新策略继续前行,不断迭代。
策略迭代算法需要设计 策略评估函数 和 策略提升函数。 策略评估函数,评估每个格子的价值,格子的价值用它采取 action的reward 和action后到达下一个状态的价值综合加权评价。走一步,就用这个函数刷新一遍整个位置的values价值矩阵。
策略提升函数,根据每一个格子的价值,更新策略,简单地就是,如果对每一个格子,扫描其上下左右,如果某个分数最高,则该动作概率是100%,并列最高的平分概率。

  • 价值迭代算法
    这个相对于之前的策略迭代算法,其实就是策略评估里面,每个格子的价值,用当前action空间采取动作之后,能达到的最大的价值,作为当前格子的价值。前面一个是和action概率加权平均而已。
    价值迭代算法不需要考虑每个动作的概率

四、 时序差分算法

是无模型,在线学习的算法,区别于前面的动态规划算法。(有模型是开天眼,无模型,在线学习,就是走一步看一步算一步)

根据时序差分算法, 当前state, action的分数 = 下一个state, action的分数*gamma + reward, 立意在于,到下一个状态时候,由于往前走了一步,对未来的估计应当更加准确。

  • Sarsa算法 根据S-A-R-S-A 计算更新量。
    同样针对上面的游戏,需要准备一个Q矩阵,这个矩阵为 4124 大小,412是格子,4是动作,代表每个格子采取每个动作的分数。
    get_action 函数,即策略函数,由状态选择一个动作。这个动作可以是按Q最高的动作选择。
    get_update函数,由当前state, action的分数, 下一个state, 某action的分数
    gamma + reward,计算出差值,用这个差值更新Q。 sarsa的含义就是,用当前状态,当前动作,reward, 下个状态,下个动作更新价值矩阵。
    总结:Sarsa算法里,策略是根据Q价值矩阵选择行动,因此训练的目标是一个好的Q。更新方式是用时序差分的公式计算一个更新量,计算中用的变量是sarsa
    训练过程:
#训练
def train():
    for epoch in range(1500):
        #初始化当前位置
        row = random.choice(range(4))
        col = 0
        #初始化第一个动作
        action = get_action(row, col)
        reward_sum = 0
        #循环直到到达终点或者掉进陷阱
        while get_state(row, col) not in ['terminal', 'trap']:
            #执行动作
            next_row, next_col, reward = move(row, col, action)
            reward_sum += reward
            #求新位置的动作
            next_action = get_action(next_row, next_col)
            #更新分数
            update = get_update(row, col, action, reward, next_row, next_col,
                                next_action)
            Q[row, col, action] += update
            #更新当前位置
            row = next_row
            col = next_col
            action = next_action
  • Q learning
    Q learning 和sarsa 算法 仅仅区别在Q-target 上,算是对sarsa 算法的改进。
    区别就在于在确定下一个状态的价值时候,一个是从Q矩阵直接找最大的那个,而sarsa 不一定选的是Q值最大的动作,而是按照自己的get_action函数选择。
Qlearning
    #target为下一个格子的最高分数,这里的计算和下一步的动作无关
    target = 0.9 * Q[next_row, next_col].max()
sarsa
    #计算target
    target = 0.9 * Q[next_row, next_col, next_action]

Q learning是off-policy , sarsa是on-policy的。

  • N 步 sarsa
    思想,玩N步之后在考虑更新第一步的参数。先玩,探索够了,在返回去更新参数。
    例如玩了5步,记录每一步的action reward state。然后以最新的这一步(第五步)的state+action 计算target5, 由 target5*gamma +reward5 反算 target4,target3… 这样得到的target无疑会更精确。再计算出每一步所在状态的value_list()Q矩阵查表即可)这样就得到一个系列的update 值,最终只更新第一步的分数。

  • DynaQ
    数据反刍,温故而知新,有一定的离线学习的成分。前面的算法对数据利用率不高,数据用一次就丢了。
    这个是Qlearning的优化版。
    需要保存历史数据, #保存历史数据,history,键是(row,col,action),值是(next_row,next_col,reward),
    核心代码如下:

def q_planning():
    #Q planning循环,相当于是在反刍历史数据,随机取N个历史数据再进行离线学习
    for _ in range(20):
        #随机选择曾经遇到过的状态动作对
        row, col, action = random.choice(list(history.keys()))
        #再获取下一个状态和反馈
        next_row, next_col, reward = history[(row, col, action)]
        #计算分数
        update = get_update(row, col, action, reward, next_row, next_col)
        #更新分数
        Q[row, col, action] += update

思想:记录下之前的数据,待后面Q更新差不多了,再随机选老数据update一遍,确实很像反刍

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值