本文是对Arthur Juliani在Medium平台发布的强化学习系列教程的个人中文翻译。(This article is my personal translation for the tutorial written and posted by Arthur Juliani on Medium.com。)

原文地址(URL for original article):https://medium.com/emergent-future/simple-reinforcement-learning-with-tensorflow-part-0-q-learning-with-tables-and-neural-networks-d195264329d0


我们将学习如何解决OpenAI的冰湖(FrozenLake)问题。不过我们的冰湖版本和上图呈现的图片可不太一样~

作为本强化学习教程系列的第一章,我们将一同探索强化学习算法的一个大家庭———Q-Learning算法—。它们和后面章节基于策略的算法(Policy-based algorithms)(1-3 part)有些不一样。相对于用一个复杂而臃肿的深度神经网络,我们将以实现一个简单的查阅表(lookup-table)版本的算法为初始目标,然后再展示如何用Tensorflow框架来实现一个等价的神经网络版本的算法。考虑到我们将回归基础知识,所以本教程可以视作系列教程的第0部分。希望本教程能够帮助你理解Q-Learning的工作原理,基于此,我们将最终结合策略梯度(Policy Gradient)和Q-Learning来构造最先进的强化学习代理(Agents)。(如果你对策略网络(Policy Networks)更感兴趣,或者早就掌握了Q-Learning,你可以直接从这里开始。)

不像策略梯度方法那样试图学习到可以将一个观察(Observation)与一个动作(action)直接映射的函数,Q-Learning会尝试去学习给定一个状态(State)下,采取某个具体动作的值。虽然这两种方式最终都可以实现在给定情况下的智能行为决策,但是如何最终完成行为选择的过程是非常不一样的。你可能听说过可以玩Atari游戏的深度Q网络(Deep Q-Networs),而它其实本质上也就是更复杂的Q-Learning算法的实现。

表环境下的表方法(Tabular Approaches for Tabular Environments)

冰湖环境的规则:

在这个教程里,我们将试图解决OpenAI的gym项目中包含的冰湖FrozenLake问题。对于不熟悉gym项目的人来说,OpenAI gym提供了一种能方便简易地在一系列游戏中,对学习代理(learning agents)进行各类实验或测试的方式。而其中之一的冰湖环境是一个4*4的网格。格子包含三种类型:起始格,目标格,安全的冰格和危险的冰洞。我们的目标是让一个agent能够自己从起点到终点,并且不会在中途掉入洞中。在任何时候,agent都可以选择从上,下,左,右四个中选择一个方向进行一步移动。而后会使问题变复杂的是,在冰湖环境中,还有会偶尔把agent吹得偏离到一个并非它移动目标的格子上。因此,在这种环境下agent就不太可能每次都能表现完美,但是学习如何去避免掉入洞中并达到目标格还是可以做到的。agent每走一步的回报(reward)都是0,除了在达到目标时为1。因此,我们需要一个算法可以学习到长期期望回报。这也就是Q-Learning发挥用处的地方。

在这个算法最简单的实现中,Q-Learning会以一个表(table)的形式呈现。这个表的行代表不同的状态(所在方格的坐标),列代表不同的可采取的行动(上、下、左、右移动一步)。在冰湖环境中,我们有16个状态(每个方格算一个),以及四种动作,因此我们将得到一个16*4的Q值表,这个表的每一个具体值的含义是:该状态下,采取该行为的长期期望回报。我们从初始化一个一致的Q值表(全部赋值为0)开始,再根据我们观察得到的对各种行动的回报来更新Q值表的对应值。

我们对Q值表的更新准则是贝尔曼方程(Bellman Equation)。贝尔曼方程告诉我们:一个给定行动的期望长期回报等于【当前回报】加上【下一个状态下,采取期望中所能带来最优未来长期回报的行为对应的回报】。因此,我们可以在Q表上估计如何对未来行动的Q值进行更新。贝尔曼方程用数学公式表示如下:

Q(s,a)=r+γ(max(Q(s′,a′))

这个公式的描述了一个给定状态s下,采取行动a的Q值等于当即获得的回报r加上一个折现因子y乘以能够最大化的在下一状态s’采取时能获得的最大长期回报的动作a’对应的长期回报。折现因子y允许我们决定相对于当前就可以获得的回报,未来的可能回报的相对重要性。通过这种方式,Q表会慢慢开始获得更准确的任一给定状态下,采取任意动作所对应的期望未来回报值。以下是Python版的对于Q表版本的冰湖环境解决方案的完整实现:

import gym
import numpy as np env = gym.make('FrozenLake-v0') # Implement Q-Table learning algorithm
# 实现Q表学习算法
# Initialize table with all zeros
# 初始化Q表为全0值
Q = np.zeros([env.observation_space.n,env.action_space.n])
# Set learning parameters
# 设置学习参数
lr = .8
y = .95
num_episodes = 2000
# create lists to contain total rewards and steps per episode
# 创建列表以包含每个episode的总回报与总步数
#jList = []
rList = []
for i in range(num_episodes):
# Reset environment and get first new observation
# 初始化环境并获得第一个观察
s = env.reset()
rAll = 0
d = False
j = 0
# The Q-Table learning algorithm
# Q表学习算法
while j < 99:
j+=1
# Choose an action by greedily (with noise) picking from Q table
# 基于Q表贪婪地选择一个最优行动(有噪音干扰)
a = np.argmax(Q[s,:] + np.random.randn(1,env.action_space.n)*(1./(i+1)))
# Get new state and reward from environment
# 从环境中获得回报和新的状态信息
s1,r,d,_ = env.step(a) #Update Q-Table with new knowledge
# 用新的知识更新Q表
Q[s,a] = Q[s,a] + lr*(r + y*np.max(Q[s1,:]) - Q[s,a])
rAll += r
s = s1
if d == True:
break
#jList.append(j)
rList.append(rAll) print("Score over time: " + str(sum(rList)/num_episodes)) print("Final Q-Table Values")
print(Q)

Github源代码

(感谢Praneet D找到了该实现方法对应的最优的超参数)

基于神经网络的Q-Learning(Q-Learning with Neural Networks)

现在你可能认为:表格方法挺好的,但是它不能规模化(scale),不是吗?因为对一个简单的网格世界建立一个16*4的表是很容易的,但是在任何一个现在的游戏或真实世界环境中都有无数可能的状态。对于大多数有趣的问题,表格都无法发挥出作用。因此,我们需要一些代替性的方案来描述我们的状态,并生成对应动作的Q值:这也就是神经网络(Neural Network,简称NN)可以大展身手的地方。NN可以作为一个动作估计器(function approximator),我们能够输入任意多的可能状态,因为所有状态都可以被编码成一个个向量,并把它们和各自对应的Q值进行对应(map)。

在冰湖例子中,我们将使用一个一层的NN,它接受以one-hot形式编码的状态向量(1*16),并输出一个含有4个Q值的向量,每个分量对应一个动作的长期期望回报。这样一个简单的NN就像一个强化版的Q表,而网络的权重就发挥着曾经的Q表中的各个单元格的作用。关键的不同时我们可以方便简易地扩充Tensorflow网络,包括加新的层,激活函数以及不同的输出类型,而这些都是一个一般的表格无法做到的。于是,更新的方法也发生了一点变化。相比于之前直接更新表格,我们现在将使用逆传播(backpropagation)和损失函数(loss function)**来完成更新。我们的损失函数采取平方和损失的形式,即加总当前预测的Q值与目标值间的差值的平方,并以梯度形式在网络中传播。这种情况下,所选行动的目标Q值依然采用上面提到的贝尔曼方程中的计算方法。

Loss=Σ(Q−target−Q)2

以下是用Tensorflow实现简单Q网络的完整代码:

# Q-Network Learning
# Q网络学习 import gym
import numpy as np
import random
import tensorflow as tf
import matplotlib.pyplot as plt
%matplotlib inline # Load the environment
# 加载环境 env = gym.make('FrozenLake-v0') # The Q-Network Approach
# Q网络方法
# Implementing the network itself
# 实现网络 tf.reset_default_graph() # These lines establish the feed-forward part of the network used to choose actions
# 下面的几行代码建立了网络的前馈部分,它将用于选择行动
inputs1 = tf.placeholder(shape=[1,16],dtype=tf.float32)
W = tf.Variable(tf.random_uniform([16,4],0,0.01))
Qout = tf.matmul(inputs1,W)
predict = tf.argmax(Qout,1) # Below we obtain the loss by taking the sum of squares difference between the target and prediction Q values.
# 下面的几行代码可以获得预测Q值与目标Q值间差值的平方和加总的损失。
nextQ = tf.placeholder(shape=[1,4],dtype=tf.float32)
loss = tf.reduce_sum(tf.square(nextQ - Qout))
trainer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
updateModel = trainer.minimize(loss) # Training the network
# 训练网络
init = tf.initialize_all_variables() # Set learning parameters
# 设置学习参数
y = .99
e = 0.1
num_episodes = 2000
#create lists to contain total rewards and steps per episode
# 创建列表以包含每个episode对应的总回报与总步数。
jList = []
rList = []
with tf.Session() as sess:
sess.run(init)
for i in range(num_episodes):
# Reset environment and get first new observation
# 初始化环境并获得第一个观察
s = env.reset()
rAll = 0
d = False
j = 0
# The Q-Network
# Q网络
while j < 99:
j+=1
#Choose an action by greedily (with e chance of random action) from the Q-network
# 基于Q网络的输出结果,贪婪地选择一个行动(有一定的概率选择随机行动)
a,allQ = sess.run([predict,Qout],feed_dict={inputs1:np.identity(16)[s:s+1]})
if np.random.rand(1) < e:
a[0] = env.action_space.sample()
# Get new state and reward from environment
# 从环境中获得回报以及新的状态信息
s1,r,d,_ = env.step(a[0])
# Obtain the Q' values by feeding the new state through our network
# 通过将新的状态向量输入到网络中获得Q值。
Q1 = sess.run(Qout,feed_dict={inputs1:np.identity(16)[s1:s1+1]})
# Obtain maxQ' and set our target value for chosen action.
# 获得最大的Q值,并为所选行为设定目标值
maxQ1 = np.max(Q1)
targetQ = allQ
targetQ[0,a[0]] = r + y*maxQ1
# Train our network using target and predicted Q values
# 用目标和预测的Q值训练网络
_,W1 = sess.run([updateModel,W],feed_dict={inputs1:np.identity(16)[s:s+1],nextQ:targetQ})
rAll += r
s = s1
if d == True:
# Reduce chance of random action as we train the model.
# 随着训练的进行,主键减少选择随机行为的概率
e = 1./((i/50) + 10)
break
jList.append(j)
rList.append(rAll)
print("Percent of succesful episodes: " + str(sum(rList)/num_episodes) + "%") # Percent of succesful episodes: 0.352%
# 成功的episode比例:0.352%
# Some statistics on network performance
# 一些网络性能的统计量
# We can see that the network beings to consistently reach the goal around the 750 episode mark.
# 我们可以看到,当网络训练了750个episode左右的时候,agent就可以比较稳定地到达目标了。 plt.plot(rList)

# It also begins to progress through the environment for longer than chance aroudn the 750 mark as well.
# 在750个episode之后,agent也一般需要更长的步数以到达目标。 plt.plot(jList)

虽然网络学会了解决冰湖问题,但是结果表明它似乎比如Q表方法那么高效。即虽然神经网络在Q-Learning问题上提供了更高的灵活性,但它也牺牲了一定的稳定性。还有很多可能的对我们的简单Q网络进行扩展的办法,这些扩展可以让NN获得更好的性能并实现更稳定的学习过程。两种需要提到的特别技巧分别是经验重放(Experience Replay)冰冻目标网络(Freezing Target Networks)。这些改进方式或者其它的一些技巧都是让DQN可以玩Atari游戏的关键所在,并且我们也将在后面探索这些相关知识。对于有关Q-Learning的更多理论,可以看Tambet Matiisen的这篇博文,希望本教程可以帮助对实现简单Q-Learning算法的人们一些帮助!


如果这篇博文对你有帮助,你可以考虑捐赠以支持未来更多的相关的教程、文章和实现。对任意的帮助与贡献都表示非常感激!

如果你想跟进我在深度学习、人工智能、感知科学方面的工作,可以在Medium上follow我 @Arthur Juliani,或者推特@awjliani。

用Tensorflow实现简单强化学习的系列教程:

  1. Part 0 — Q-Learning Agents
  2. Part 1 — Two-Armed Bandit
  3. Part 1.5 — Contextual Bandits
  4. Part 2 — Policy-Based Agents
  5. Part 3 — Model-Based RL
  6. Part 4 — Deep Q-Networks and Beyond
  7. Part 5 — Visualizing an Agent’s Thoughts and Actions
  8. Part 6 — Partial Observability and Deep Recurrent Q-Networks
  9. Part 7 — Action-Selection Strategies for Exploration
  10. Part 8 — Asynchronous Actor-Critic Agents (A3C)

强化学习之二:Q-Learning原理及表与神经网络的实现(Q-Learning with Tables and Neural Networks)的更多相关文章

  1. 强化学习(十二) Dueling DQN

    在强化学习(十一) Prioritized Replay DQN中,我们讨论了对DQN的经验回放池按权重采样来优化DQN算法的方法,本文讨论另一种优化方法,Dueling DQN.本章内容主要参考了I ...

  2. 强化学习(二)马尔科夫决策过程(MDP)

    在强化学习(一)模型基础中,我们讲到了强化学习模型的8个基本要素.但是仅凭这些要素还是无法使用强化学习来帮助我们解决问题的, 在讲到模型训练前,模型的简化也很重要,这一篇主要就是讲如何利用马尔科夫决策 ...

  3. 【转载】 强化学习(二)马尔科夫决策过程(MDP)

    原文地址: https://www.cnblogs.com/pinard/p/9426283.html ------------------------------------------------ ...

  4. MySQL学习(二)索引原理及其背后的数据结构

    首先区分几个概念: 聚集索引 主索引和辅助索引(即二级索引) innodb中每个表都有一个聚簇索引(clustered index ),除此之外的表上的每个非聚簇索引都是二级索引,又叫辅助索引(sec ...

  5. HTTPS学习(二):原理与实践

    div.example { background-color: rgba(229, 236, 243, 1); color: rgba(0, 0, 0, 1); padding: 0.5em; mar ...

  6. Neural Network学习(二)Universal approximator :前向神经网络

    1. 概述 前面我们已经介绍了最早的神经网络:感知机.感知机一个非常致命的缺点是由于它的线性结构,其只能做线性预测(甚至无法解决回归问题),这也是其在当时广为诟病的一个点. 虽然感知机无法解决非线性问 ...

  7. 鸟书shell 学习笔记(二) shell中正則表達式相关

    通配符与正則表達式的差别 通配符是bash原生支持的语法,正則表達式是处理字符串的一种表示方式, 正則表達式须要支持的工具支持才干够 语系设置 : export LANG=C grep alias 设 ...

  8. 吴恩达《深度学习》-第五门课 序列模型(Sequence Models)-第一周 循环序列模型(Recurrent Neural Networks) -课程笔记

    第一周 循环序列模型(Recurrent Neural Networks) 1.1 为什么选择序列模型?(Why Sequence Models?) 1.2 数学符号(Notation) 这个输入数据 ...

  9. 用深度强化学习玩FlappyBird

    摘要:学习玩游戏一直是当今AI研究的热门话题之一.使用博弈论/搜索算法来解决这些问题需要特别地进行周密的特性定义,使得其扩展性不强.使用深度学习算法训练的卷积神经网络模型(CNN)自提出以来在图像处理 ...

随机推荐

  1. app后端用户登录api

    app将用户名和密码发送到服务器,服务器验证用户名和密码都正确后,会在redis或memcached服务器中以用户id为键生成token字 符串,然后服务器把token字符串和用户id都返回给客户端( ...

  2. ProjectSend R561 SQL INJ Analysis

    注入出现在./client-edit.php中 ...... if (isset($_GET['id'])) { $client_id = mysql_real_escape_string($_GET ...

  3. IPFS初窥

    虽然区块链有很多令人兴奋的特性,但是也有其固有的缺点.比如,文件或者长度较长的文本信息就不适合存储在链上.那么如何解决这个缺点呢?一个解决方案就是IPFS(Interplanetary File Sy ...

  4. 手写实现vue的MVVM响应式原理

    文中应用到的数据名词: MVVM   ------------------        视图-----模型----视图模型                三者与 Vue 的对应:view 对应 te ...

  5. 机器学习基础——详解自然语言处理之tf-idf

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天的文章和大家聊聊文本分析当中的一个简单但又大名鼎鼎的算法--TF-idf.说起来这个算法是自然语言处理领域的重要算法,但是因为它太有名了 ...

  6. 用nodejs+express搭建前端测试服务端

    平时开发前端应用,如果没有现成的后端接口调试,又要保证前端进度,该怎么办呢,当然办法还是很多的,很多大牛都分享过很多经验,我也来说说我常用的方法. 请求本地数据文件 把本地数据放到程序指定目录,发起h ...

  7. seo搜索优化教程05-SEO常用专业术语

    SEO常用的专业术语很多,星辉信息科技专门抽空进行了整理,主要如下:. SEO 根据搜索引擎规则来进行搜索引擎优化,进而使得在搜索结果中获得较好的排名 关键词 关键词也叫keywords,表示在搜索引 ...

  8. Linux apache开启虚拟主机伪静态.htaccess

    打开apache配置文件 /etc/httpd/conf/httpd.conf 查找“#LoadModule rewrite_module modules/mod_rewrite.so” 去掉前面的# ...

  9. ggplot2(10) 减少重复性工作

    10.1 简介 灵活性和鲁棒性的敌人是:重复! 10.2 迭代 last_plot()用于获取最后一次绘制或修改的图形. 10.3 绘图模板 gradient_rb <- scale_colou ...

  10. Django中ORM中的get与filter区别

    本文出自 “orangleliu笔记本” 博客,出处http://blog.csdn.net/orangleliu/article/details/38597593 Django的orm中get和fi ...