1. 磐创AI-开放猫官方网站首页
  2. 机器学习
  3. TensorFlowNews

一文带你实战强化学习(上) | DQN

一文带你实战强化学习(上) | DQN

作者 | 小猴锅

编辑 | 奇予纪

出品 | 磐创AI团队出品

磐创AI导读:本篇文章是深度强化学习专栏的第四篇,讲了第五节实战强化学习中Q-learning 算法,希望对大家有所帮助。查看关于本专栏的介绍:深度强化学习(DRL)专栏开篇。想要获取更多的机器学习、深度学习资源,欢迎大家点击上方蓝字关注我们的公众号:磐创AI


目录:

1. 引言

  • 专栏知识结构

  • 从AlphaGo看深度强化学习

2. 强化学习基础知识

  • 强化学习问题

  • 马尔科夫决策过程

  • 最优价值函数和贝尔曼方程

3. 有模型的强化学习方法

  • 价值迭代

  • 策略迭代

4. 无模型的强化学习方法

  • 蒙特卡洛方法

  • 时序差分学习

  • 值函数近似

  • 策略搜索

5. 实战强化学习算法

  • Q-learning 算法

  • Monte Carlo Policy Gradient 算法

  • Actor Critic 算法

6. 深度强化学习算法

  • Deep Q-Networks(DQN)

  • Deep Deterministic Policy Gradient(DDPG)

7. 专栏小结



5.实战强化学习算法
一文带你实战强化学习(上) | DQN
在前几节内容里我们已经介绍过几种常见的强化学习算法,例如<span lang=EN-US>Q-Learning、Monte Carlo Policy Gradient以及<span lang=EN-US>Actor Critic。
这第五节里,我们使用三个算法(Q-learning 算法、Monte Carlo Policy Gradient 算法、Actor Critic 算法)分别实现一个小的实战项目,借此来加深对于算法的理解。
我们主要用到<span lang=EN-US>OpenAI的Gym工具包,使用三个强化学习算法去玩<span lang=EN-US>Gym工具包提供的三个小游戏。关于Gym工具包的安装,可以参考官方文档:http://gym.openai.com/docs/注意,如果使用“pip”安装,要使用我们之前配置的“apip”。
本篇文章首先介绍三个算法中的Q-learning 算法及其实战项目。

5.1 Q-Learning算法


在介绍强化学习的时候,我们已经介绍过“Frozen Lake”游戏,这一节内容里,我们将实现使用Q-Learning算法让计算机去玩这个小游戏。
在Gym工具包中,“Frozen Lake”游戏有两个版本:“FrozenLakeV0”和“FrozenLake8X8-V0”。

两个版本的不同点是前一个版本的游戏场景是“4X4”大小的,后者是“8X8”大小的,另外前一个版本可以选择“有风”或“无风”模式,后者只有默认的“有风”模式。

这里,我们选择“FrozenLake8X8-V0”版本。


一文带你实战强化学习(上) | DQN

“FrozenLake8X8-V0”游戏示意图


上图是“FrozenLake8X8-V0”游戏的示意图,图左是图形化后的游戏环境,白色标记为“冰窟窿”,图右是游戏本身的可视化形式,“S”代表“起始位置”,“G”代表“目标位置”,“F”代表“冰面”,“H”代表“冰窟窿”。该游戏一共有64(8X8)个状态,每个状态下有四个(“上”、“下”、“左”和“右”)可以执行的动作。当agent到达目标位置后,会得到奖励值1,其它位置奖励值都为0。
需要注意的是,如果agent处在边界状态,例如开始状态“S”,此时采取向边界外移动的动作“左”或“上”都是合法的,只是agent的状态不发生改变(除非受风的影响,状态改变)。另外,当agent移动到“H”或“G”状态后,游戏结束。

我们首先导入所需要的包,并初始化一些相关的参数:

1  import gym
2  import numpy as np
import random as rd
3  
4  # 注册游戏环境
5  env = gym.make('FrozenLake8x8-v0')
6  # 定义Q值表,初始值设为0
7  Q = np.zeros([env.observation_space.n, env.action_space.n])
8  # 设置学习参数
9  learningRate = 0.85
10  discountFactor = 0.95

11  # 定义一个数组,用于保存每一回合得到的奖励
12  rewardList = []


第5行代码的作用是注册一个游戏环境,传入的参数是要注册的游戏名称,我们这里注册的是“FrozenLake8x8-v0”游戏,也可以换成其它的游戏,例如我们后面会用到的“CartPole-v1”和“Acrobot-v1”。在本节所附代码中,我们还给出了“FrozenLake-v0”的两种模式(“有风”和“无风”)的代码实现,在10.4.1节内容里我们提到了“确定性的”和“非确定性的”环境状态,这两种情况下更新Q值的方式有所不同,感兴趣的读者可以查看和运行所附代码,做一下对比。

第7行代码定义了Q值表,并将初始值设为0。其中:

env.observation_space.n”和“env.action_space.n分别是FrozenLake8x8-v0这个游戏的状态空间和动作空间,其值分别为64和4,所以该Q值表的大小为64×4
第9行和第10行代码设置了学习参数,“learningRate”和“discountFactor”分别是Q-Learning算法中更新Q值的公式中的学习率和折扣因子。如果读者忘了这两个参数的作用,可以在本章的4.2节内容中查看。
第12行代码定义了一个数组“rewardList”用来保存每个回合得到的累积奖励,“FrozenLake8x8-v0”游戏只有在agent到达目标位置后才会得到奖励值1,其余状态的奖励值均为0,所以在所有回合都结束后,将“rewardList”数组的元素值相加,其值即为所有回合中成功到达目标位置的回合数,用该值除以“rewardList”数组的长度就可以得到成功率(成功到达目标位置的回合数/总的回合数)。

接下来我们实现Q-Learning算法的核心部分:

13  def train():
14      for i_episodes in range(20000):
15          # 重置游戏环境
16          s = env.reset()
17          i = 0
18          # 学习 Q-Table
19          while i < 2000:
20              i += 1
21              # 使用带探索(ε-greedy)的策略选择动作
22              a = epsilon_greedy(Q, s, i_episodes)
23              # 执行动作,并得到新的环境状态、奖励等
24              observation, reward, done, info = env.step(a)
25              # 更新 Q-Table
26              Q[s, a] = (1-learningRate) * Q[s, a] + learningRate * (
reward + discountFactor * np.max(Q[observation, :]))
27              s = observation
28              if done:
29                  break


这部分代码实现了对Q值表的学习,这里我们一共执行了20000个回合。第16行代码是重置游戏环境,此时agent位于开始位置。第19行代码设置循环的目的,是确保agent能够走到游戏结束状态(可能是agent到达了目标位置,也可能是掉进了“冰窟窿”)。
第22行代码,我们使用了带探索ε—greedy的策略来选取动作,“epsilon_greedy”函数的实现我们稍后介绍。第24行代码执行了前一步选择的动作,并得到相应的反馈信息,其中,“observation”是执行这个动作后得到的新的环境状态,“reward”是执行这个动作后得到的奖励,“done”是一个布尔类型的数据,当“done”的值为“true”时代表游戏结束。“info”是用于调试程序的诊断信息。

第26行代码就是我们Q-Learning算法中对于Q值的更新,算法中更新Q值的公式为:

一文带你实战强化学习(上) | DQN

式1

将公式1稍作变换即为:

一文带你实战强化学习(上) | DQN

式2

第27行代码更新了当前的环境状态,第28行代码判断一个回合的游戏是否结束。接下来我们再看如何使用带探索的策略来选择动作,即如何对环境进行探索。代码如下:
30  def epsilon_greedy(q_table, s, num_episodes):
31      rand_num = rd.randint(0, 20000)
32      if rand_num > num_episodes:
33          # 随机选择一个动作
34          action = rd.randint(0, 3)
35      else:
36          # 选择一个最优的动作
37          action = np.argmax(q_table[s, :])
38      return action


这里我们使用贪心(ε—greedy)搜索方法来对环境进行探索,ε—greedy搜索以概率ε从所有可能的动作中随机选取一个动作(即对环境进行探索),1-ε以的概率选择已知的最好的动作(即当前状态下,Q值最大的那个动作)。需要注意的是,对于环境的探索应主要集中在学习Q值表的开始阶段,随着Q值表的完善,我们应更注重对于Q值表的使用。所以,在初期,ε的值应更大一些(即注重对环境的探索),随后逐渐减小ε的值(即注重对于Q值表的使用)。
在第31行代码中我们生成一个介于0到20000之间(包括0和20000)的随机整数“rand_num”,“num_episodes”是当前的回合数(一共有20000个回合,标号从0到19999),当“rand_num”的值大于当前的回合数“num_episodes”时,从所有合法动作中随机选择一个动作,否则选择一个最优的动作。当“num_episodes”的值很小时,“rand_num”的值大于“num_episodes”的概率更大,而随着回合数的增加,“rand_num”的值小于“num_episodes”的概率变得更大,从而实现ε的值随着回合数的增加而递减。

34行我们随机选择了一个动作,0到3分别对应动作“左移”、“下移”、“右移”和“上移”。第37行我们选择了当前状态下s最优的动作。

还有一种简单的方法也可以实现对环境的探索,我们不需要“epsilon_greedy”函数,直接把第22行代码改为如下形式:

22 a = np.argmax(Q[s, :] + np.random.randn(1, env.action_space.n)
* (1. / (i_episodes + 1)))


这里我们通过给当前状态的Q值(4个动作对应4个Q值)分别加上一个随机数来影响动作的选择,由于随机数的原因,当前动作的选择也具有了随机性,另外我们给随机数乘上了一个折扣率,并且随着回合数的增加,折扣率的值越来越小,这个随机数对于动作选择的影响也越来越小,从而实现对环境的探索。

接下来我们写一个测试函数,利用学到的Q值表来玩“FrozenLake8x8-v0”游戏。

39 def test():
40 for i_episodes in range(100):
41 # 重置游戏环境
42 s = env.reset()
43 i = 0
44 total_reward = 0
45 while i < 500:
46 i += 1
47 # 选择一个动作
48 a = np.argmax(Q[s, :])
49 # 执行动作,并得到新的环境状态、奖励等
50 observation, reward, done, info = env.step(a)
51 # 可视化游戏画面(重绘一帧画面)
52 env.render()
53 # 计算当前回合的总奖励值
54 total_reward += reward
55 s = observation
56 if done:
57 break
58 rewardList.append(total_reward)


在测试代码中,我们一共玩了100个回合,其中使用了一个参数“total_reward”来统计每一回合得到的累积奖励,当agent掉进“冰窟窿”或者到达目标位置后一回合的游戏结束,此时“total_reward”的值分别为0和1。最后我们执行完整的程序:
59  train()
60  test()
61  
62  print("Final Q-Table Values:")
63  print(Q)
64  print("Success rate: " + str(sum(rewardList) / len(rewardList)))


在第63行代码中我们输出了最终的Q值表,是一张16×4的表,其中行代表状态(从状态1到状态64,对应图10-14,状态从上到下、从左至右进行编号),列代表动作(下标0到3分别对应动作“左移”、“下移”、“右移”和“上移”)。在第64行代码我们用成功到达目标位置的回合数“sum(rewardList)”除以总的回合数“len(rewardList)”得到了agent玩“FrozenLake8x8-v0”游戏的成功率。

只需将“train()”函数稍作修改,我们就可以得到Q-Learning算法的在策略(on-policy)版本Sarsa算法。



你也许还想
● 深度强化学习专栏(三)
● 深度强化学习(DRL)专栏(二):有模型的强化学习
● 深度强化学习(DRL)专栏(一)
● 深度强化学习(DRL)专栏开篇

欢迎扫码关注:
一文带你实战强化学习(上) | DQN


一文带你实战强化学习(上) | DQN 点击下方 |  | 了解更多
磐创AI:http://www.panchuangai.com/ 智能客服:http://www.panchuangai.com/ TensorFlow:http://panchuang.net 推荐关注公众号:磐创AI

原创文章,作者:fendouai,如若转载,请注明出处:https://panchuang.net/2019/11/09/0f98fa02b3/

发表评论

登录后才能评论

评论列表(2条)

  • 翠花
    翠花 2021年12月11日 下午6:03

    您好,我复现了您的程序,但是结果出错,显示E gym.error.DeprecatedEnv: Env FrozenLake8x8-v0 not found (valid versions include [‘FrozenLake8x8-v1’]) 是因为我gym没安装正确吗

  • 翠花
    翠花 2021年12月11日 下午6:24

    您好,之前的问题已经解决啦,游戏的版本应该更新为v1

联系我们

400-800-8888

在线咨询:点击这里给我发消息

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息