注意将代码和下面公式推导结合起来。还要注意一下q_target和q_predict之间的关系。其实算法的更新是需要使用q_predict来逼近q_target,当两者相等时,算法将停止更新,当传统的qlearning转化为deep Qlearning,也是这样操作的,只是深度qlearning使用一个神经网络来表示q表。

这篇文章将要介绍传统的qlearning算法,使用的是迭代的方法更新q表,更新q表的方法类似于向前推进,而不是使用梯度下降方法,因为这里介绍的不是Deep QLearning方法。

一、算法介绍以及推导

:这里更新的不是agent,而是一个q表,q表里面记录的是agent在某个状态采取某个的动作的好坏,q表可以起到间接决定agent采取什么决策。q表就类似一个critic,一个评论家,来指导agent。

1.1、Q(s,a)Q(s,a)Q(s,a)是什么?

Q(s,a)Q(s,a)Q(s,a)是状态动作价值函数,是在状态sss时采取动作aaa之后,可以获得的奖励的期望值。Q(s,a)Q(s,a)Q(s,a)越大表示在agent在看到状态sss是采取动作aaa比较好。

1.2、q表

q表 a1 a2 a3
s1 q(s1,a1) q(s1,a2) q(s1,a3)
s2 q(s2,a1) q(s2,a2) q(s2,a3)
s3 q(s3,a1) q(s3,a2) q(s3,a3)
s4 q(s4,a1) q(s4,a2) q(s4,a3)

q表里面记录的都是状态动作价值函数,前面说到q表可以间接决定agent采取什么样的决策,就是因为q表记录了所有的状态和动作的组合情况,比如agent看到状态s2s_{2}s2​时,就会在状态s2s_{2}s2​所在的行选取最大的q值所对应的动作。

1.3、如何根据q表进行决策?

假设下表是我们已经更新完成了的q表

q表 a1 a2 a3
s1 - 1 1 3
s2 2 0 1
s3 1 5 7
s4 5 6 3

Q表指导agent决策的过程:t=1时,agent观测到环境的状态s2,于是查找状态s2所在的行,发现Q(s2,a1)>Q(s2,a3)>Q(s2,a2),因此选择动a1,此时环境发生变化,agent观测到环境的状态s4,接着查找状态s4所在的行,agent发现q(s4,a2)>q(s4,a1)>q(s4,a3),于是agent采取决策选择动作a2,一直进行下去,直到结束。

1.4、ε−greedy\varepsilon -greedyε−greedy选择动作

有上面的决策过程我们可以看到,在给定一个状态s时,会选择q值最大的动作,这样会导致一个问题:因为是随机初始化的,由于选择最大值,可能会使得一些动作无法被选择到,也就是无法更新q值,这样q值就一直是随机初始化的那个值。

ε−greedy\varepsilon -greedyε−greedy选择动作的流程如下:agent观测到状态s时,采取动作时会以1−ε1-\varepsilon1−ε的概率在Q表里面选择q值最大所对应的动作,以ε\varepsilonε的概率随机选择动作。
不再使用完全贪婪的算法,而是有一定的动作选择的完全随机性,这样就可以保证在迭代次数足够多的情况下Q表中的所有动作都会被更新到。

1.5、如何更新Q表?

算法开始的时候,我们需要随机初始化q表,那么如何更新q表就是一件非常关键的事情。

参数解释:
更新公式为Q(s,a)new=Q(s,a)old+α[r+γmaxa′Q(s′,a′)−Q(s,a)old](1)Q(s,a) ^{new} = Q(s,a) ^{old}+\alpha [r+\gamma max_{{a}'}Q({s}',{a}')-Q(s,a)^{old}]\tag{1}Q(s,a)new=Q(s,a)old+α[r+γmaxa′​Q(s′,a′)−Q(s,a)old](1)

  1. α\alphaα指学习率,其实也是一个权值,我们将公式1进行改写得到如下的公式Q(s,a)new=(1−α)Q(s,a)old+α[r+γmaxa′Q(s′,a′)](2)Q(s,a) ^{new} = (1-\alpha )Q(s,a) ^{old}+\alpha [r+\gamma max_{{a}'}Q({s}',{a}')]\tag{2}Q(s,a)new=(1−α)Q(s,a)old+α[r+γmaxa′​Q(s′,a′)](2)
    我们从公式2可以看到,Q(s,a)newQ(s,a) ^{new}Q(s,a)new是两部分的凸组合

  2. γ\gammaγ 是衰减值

首先我们随机初始化一个Q表,然后任意初始化一个状态sss,也可以理解为,agent观测到的环境的状态,根据Q表使用ε−greedy\varepsilon -greedyε−greedy算法选择状态sss对应的动作aaa,因为agent做出了一个动作,会从环境中获得一个奖励 rrr,环境发生变化,agent又观测到一个新的状态 s′{s}'s′,根据Q表在状态 s′{s}'s′ 所在的行,查询Q表,求得最大值,然后更新按照公式更新Q表。

Question 1:什么时候才会迭代收敛?
答:由公式(1)可以看到当 r+γmaxa′Q(s′,a′)==Q(s,a)oldr+\gamma max_{{a}'}Q({s}',{a}')==Q(s,a)^{old}r+γmaxa′​Q(s′,a′)==Q(s,a)old时,迭代格式收敛,也就是Q表的更新完成。

1.6、TD方法(时间差分更新法)

假设...,st,at,rt,st+1,......,s_{t},a_{t},r_{t},s_{t+1},......,st​,at​,rt​,st+1​,...
我们要更新Q值使 rt和Q(st,at)old−γmaxa′Q(st+1,a′)r_{t}和Q(s_{t},a_{t})^{old}-\gamma max_{{a}'}Q(s_{t+1},{a}')rt​和Q(st​,at​)old−γmaxa′​Q(st+1​,a′)越接近越好,这里用了两个相邻时刻的状态价值函数

二、两个个小疑问

  1. 等eposide结束之后,进行反向更新
    从公式 Q(s,a)new=Q(s,a)old+α[r+γmaxa′Q(s′,a′)−Q(s,a)old]Q(s,a) ^{new} = Q(s,a) ^{old}+\alpha [r+\gamma max_{{a}'}Q({s}',{a}')-Q(s,a)^{old}]Q(s,a)new=Q(s,a)old+α[r+γmaxa′​Q(s′,a′)−Q(s,a)old] 可以看到,Q(s,a)Q(s,a)Q(s,a)的更新会使用到状态
    s′{s}'s′的Q值,从而基于TD方法进行更新Q表。但是每次更新我们都利用了下一个时刻的Q值,比如Q(s′,a′)Q({s}',{a}')Q(s′,a′),假设agent完了一个episode的游戏,得到τ={s1,a1,r1,s2,a2,r2,...,sT,aT,rT,END}\tau =\{s_{1},a_{1},r_{1},s_{2},a_{2},r_{2},...,s_{T},a_{T},r_{T},END\}τ={s1​,a1​,r1​,s2​,a2​,r2​,...,sT​,aT​,rT​,END},假如我们先从后面的状态开始更新,这样前面的状态更新的时候就可以使用已经更新了的后面的状态,也就是反向更新
    不知道这样是否可行,这样有个问题就是:原始的方法每一时间步都可以更新,就是在episode进行的时候更新,换成上面我说的这样的更新方法,还要将状态,动作,价值先存储起来,要等到episode结束才能更新。

  2. agent观测一个状态,能不能选择做出多个动作回应这个状态?
    例子:太空入侵者游戏

    在这个游戏中,agent可以做出动作有三种:开火(fire),向右移动(right),向左移动(left).
    假设上图为agent观测到的一个状态,但是这是agent同时选择了开火和向右移动的动作。感觉这样也是合理的,只要做出的动作不相互矛盾就可以。比如动作向右移动和向左移动就不能同时发生。

三、代码

import numpy as np
import pandas as pd
import timenp.random.seed(2)  # reproducibleN_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'''
所构造的q表的大小是:行数是财产的探索者总共所处的位置数,列数就是动作的数量
'''
def build_q_table(n_states, actions):table = pd.DataFrame(np.zeros((n_states, len(actions))),     # q_table initial valuescolumns=actions,    # actions's name)# print(table)    # show tablereturn tabledef choose_action(state, q_table):# This is how to choose an actionstate_actions = q_table.iloc[state, :] #将现在agent观测到的状态所对应的q值取出来if (np.random.uniform() > EPSILON) or ((state_actions == 0).all()):  #当生撑随机数大于EPSILON或者状态state所对应的q值全部为0时,就随机选择状态state所对应的动作action_name = np.random.choice(ACTIONS)else:   # act greedyaction_name = state_actions.idxmax()    # 选择状态state所对应的使q值最大的动作return action_namedef get_env_feedback(S, A):# 选择动作之后,还要根据现在的状态和动作获得下一个状态,并且返回奖励,这个奖励是环境给出的,用来评价当前动作的好坏。#这里设置的是,只有在获得宝藏是才给奖励,没有获得奖励时,无论是向左移动还是向右移动,给出的即时奖励都是0.if A == 'right':    # move rightif S == N_STATES - 2:   # terminateS_ = 'terminal'R = 1else:S_ = S + 1R = 0else:   # move leftR = 0if S == 0:S_ = S  # reach the wallelse:S_ = S - 1return S_, Rdef update_env(S, episode, step_counter):# 更新环境的函数,比如向右移动之后,o表示的agent就距离宝藏进了一步,将agent随处的位置实时打印出来env_list = ['-']*(N_STATES-1) + ['T']   # '---------T' our environmentif 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():# 开始更新q表q_table = build_q_table(N_STATES, ACTIONS)#随机初始化一下q表for episode in range(MAX_EPISODES):step_counter = 0#记录走了多少步S = 0#每个episode开始时都将agent初始化在最开始的地方is_terminated = Falseupdate_env(S, episode, step_counter)#打印的就是o-----Twhile not is_terminated:#判断episode是否结束A = choose_action(S, q_table)#agent根据当前的状态选择动作S_, R = get_env_feedback(S, A)  # 上一步已经获得了s对应的动作a,接着我们要获得下一个时间步的状态q_predict = q_table.loc[S, A]if S_ != 'terminal':#要判断一下,下一个时间步的是不是已经取得宝藏了,如果不是,可以按照公式进行更新q_target = R + GAMMA * q_table.iloc[S_, :].max()   # next state is not terminalelse:#如果已经得到了宝藏,得到的下一个状态不在q表中,q_target的计算也不同。q_target = R     # next state is terminalis_terminated = True    # terminate this episodeq_table.loc[S, A] += ALPHA * (q_target - q_predict)  # updateS = S_  # move to next stateupdate_env(S, episode, step_counter+1)step_counter += 1return q_tableif __name__ == "__main__":q_table = rl()print('\r\nQ-table:\n')print(q_table)

可以参看下面的链接
莫烦python

强化学习(RL)QLearning算法详解相关推荐

  1. 【强化学习】Q-Learning算法详解以及Python实现【80行代码】

    强化学习 在文章正式开始前,请不要被强化学习的tag给吓到了,这也是我之前所遇到的一个困扰.觉得这个东西看上去很高级,需要一个完整的时间段,做详细的学习.相反,强化学习的很多算法是很符合直观思维的. ...

  2. 【强化学习】Q-Learning算法详解

    1 Q-Learning算法简介 1.1 行为准则 我们做很多事情都有自己的行为准则,比如小时候爸妈常说:不写完作业就不准看电视.所以我们在写作业这种状态下,写的好的行为就是继续写作业,知道写完他,我 ...

  3. 【强化学习】Sarsa算法详解以及用于二维空间探索【Python实现】

    Sarsa算法 Sarsa算法,是基于Q-Learning算法.改动其实很小. 本文工作基于之前的Q-Learning的项目,如果有疑问可以看下面两个问题: [强化学习]Q-Learning算法详解以 ...

  4. 【强化学习】Actor-Critic算法详解

    https://morvanzhou.github.io/tutorials/machine-learning/reinforcement-learning/6-1-actor-critic/ htt ...

  5. Deep QLearning算法详解(强化学习 Reinforcement Learning)

    一.算法详解 文章最后附有博主自己实现的深度qlearning玩space invader游戏 本文介绍的是基于神经网络的qlearning算法.我们知道传统的qlearning算法只能处理状态和动作 ...

  6. [联邦学习] FedAvg聚合算法详解及代码实现

    该文章首发于若绾 [联邦学习] FedAvg聚合算法详解及代码实现,转载请标注出处. 论文原文:Communication-Efficient Learning of Deep Networks fr ...

  7. 离线强化学习(Offline RL)系列3: (算法篇) IQL(Implicit Q-learning)算法详解与实现

    [更新记录] 论文信息:Ilya Kostrikov, Ashvin Nair, Sergey Levine: "Offline Reinforcement Learning with Im ...

  8. python强化学习之Q-learning算法

    强化学习是什么? 简单来说就是通过感知周围环境而行动,以取得最大化收益的一个过程. 其中Q-learning算法的感知状态为离散,无规律. 华丽的分割线------------------------ ...

  9. 【强化学习】Q-Learning算法求解悬崖行走问题 + Python代码实战

    文章目录 一.Q-Learning算法简介 1.1 更新公式 1.2 预测策略 1.3 详细资料 二.Python代码实战 2.1 运行前配置 2.2 主要代码 2.3 运行结果展示 2.4 关于可视 ...

  10. 直播 | 256核CPU实现每秒一百万帧的Atari!强化学习并行模拟器EnvPool详解

    近日,新加坡Sea AI Lab提出了一个全新的环境模拟并行执行库EnvPool,使用C++的线程池以及异步执行的机制优化了大规模RL环境的并行,能够兼容已有的gym与dm_env API以及几乎所有 ...

最新文章

  1. 树套树 ---- 树状数组套权值线段树模板题 P2617 Dynamic Rankings 动态第K大
  2. 一口气说出 过滤器 和 拦截器 6个区别,别再傻傻分不清了
  3. 【转】Java中关于异常处理的十个最佳实践
  4. 头条二面:你们公司怎么处理 MySQL 的 Binlog 日志?
  5. access开发精要(4)-参考与查阅
  6. linux网络管理技术,linux网络管理 一
  7. HP-UNIX操作系统root账号被锁定的两种解决方法
  8. Python Day 21 面向对象 (面向对象的三大特性(二)继承,多态,封装,几个装饰器函数)...
  9. 数位dp模板 最高位最低位_无纸化办公入门指南(数位板篇)
  10. 单元测试工具cmocka英文教程,非常漂亮
  11. 没有装Express版Sql Server 2005就不能用WebPart ?
  12. 39万的一节课:让你悟透“近朱者赤,近墨者黑”的道理
  13. Java-NIO(一):简介
  14. python运维平台开发_python运维平台的设计
  15. opencv-图像阈值
  16. C语言——求2-1000之间的素数,每行打印8个
  17. Android版本名称
  18. 技术的共通性—从姿态估计到自动驾驶
  19. 对象不支持attachEvent
  20. Excel 仪表盘教程之 01 什么是 Excel 仪表板,它与报表有何不同?(Dashboard教程含数据)

热门文章

  1. CSS设置字体种类,如宋体,楷体,黑体,仿宋等等。。。。
  2. 计算机中win是哪个版本,win7系统应该选择哪个版本比较好
  3. 你干的是高档活儿还是Low逼活儿,就在一念之间
  4. 数值分析--第二章--追赶法
  5. 十大高人气商城高口碑蓝牙耳机排行榜,颜值在线性能无敌
  6. 最全整理:中国人工智能百强企业(100)榜单
  7. 数值优化(Numerical Optimization)学习系列-序列二次规划和内点法(SQP、Interior-Point)
  8. python调用大漠插件寻路_python调用大漠插件或天使插件
  9. 机器学习-DBSCAN密度聚类
  10. 测试用例的定义、内容、作用