1新智元推荐
编辑:熊笑
【新智元导读】 知乎专栏强化学习大讲堂作者郭宪博士开讲《强化学习从入门到进阶》,我们为您节选了其中的第二节《基于gym和tensorflow的强化学习算法实现》,希望对您有所帮助。同时,由郭宪博士等担任授课教师的深度强化学习国庆集训营也将于 10 月 2 日— 6 日在北京举办。
上一讲已经深入剖析了 gym 环境的构建强化学习实战《第一讲 gym学习及二次开发 - 知乎专栏》。这一讲,我们将利用gym和tensorflow来实现两个最经典的强化学习算法qleanring 和基于策略梯度的方法。本节课参考了莫烦的部分代码(见知乎问答《强化学习(reinforcement learning)有什么好的开源项目、网站、文章推荐一下?》),在此对其表示感谢。这一讲分为两个小节,2.1小节讲讲用qlearning的方法解决机器人找金币(该环境已经在上一节给出);2.2 小节以小车倒立摆为例子,详细讲解基于策略梯度的强化学习方法。之所以选择这两个方法,一是因为两者都是经典算法,还有是考虑到机器人找金币是典型的表格型强化学习问题,而小车倒立摆是典型的状态空间连续型强化学习问题。
第1小节 qlearning算法实现
1.1 qlearning伪代码
qlearning算法是off-policy的基于值函数的TD(0)强化学习算法。基于值函数的强化学习算法的本质是更新值函数。其理论和伪代码已经在第四讲给出。现在我们回顾一下:
图2.1 qlearning 算法伪代码
从图2.1中我们看到,qlearning算法的实现可以分为以下关键点:行为值函数的表示,探索环境的策略,epsilon贪婪策略,值函数更新时选择动作的贪婪策略,值函数更新。下面,我就逐个讲解一下。
1.2 qlearning的行为值函数表示
对于表格型强化学习算法,值函数是一张表格。对于行为值函数,这张表可以看成是两维表,其中一维为状态,另外一维为动作。对于机器人找金币的例子:
状态空间为:[1,2,3,4,5,6,7,8]
动作空间为:[‘n’, ‘e’, ’s’, ’w’]
行为值函数可以用字典数据类型来表示,其中字典的索引由状态-动作对来表示。因此行为值函数的初始化为:
qfunc = dict() #行为值函数为qfun
for s in states:
for a in actions:
key = “d%_s%”%(s,a)
qfun[key] = 0.0
1.3 探索环境的策略:epsilon贪婪策略
智能体通过eplilon贪婪策略来探索环境,epsilon贪婪策略的数学表达式为:
该式子的python代码实现为:
def epsilon_greedy(qfunc, state, epsilon):
#先找到最大动作
amax = 0
key = "%d_%s"%(state, actions[0])
qmax = qfunc[key]
for i in range(len(actions)): #扫描动作空间得到最大动作值函数
key = "%d_%s"%(state, actions[i])
q = qfunc[key]
if qmax < q:
qmax = q
amax = i
#概率部分
pro = [0.0 for i in range(len(actions))]
pro[amax] += 1-epsilon
for i in range(len(actions)):
pro[i] += epsilon/len(actions)
##根据上面的概率分布选择动作
r = random.random()
s = 0.0
for i in range(len(actions)):
s += pro[i]
if s>= r: return actions[i]
return actions[len(actions)-1]
从上面的代码注释可以看到,该代码可分成3小段:第1小段是先找到当前状态下最大的动作;第2小段给每个动作分配概率;第3小段是根据概率分布采样一个动作。
1.4 值函数更新时,选择动作的贪婪策略
选择动作的贪婪策略就是选择状态为s’时,值函数最大的动作。其python实现为:
def greedy(qfunc, state):
amax = 0
key = "%d_%s" % (state, actions[0])
qmax = qfunc[key]
for i in range(len(actions)): # 扫描动作空间得到最大动作值函数
key = "%d_%s" % (state, actions[i])
q = qfunc[key]
if qmax < q:
qmax = q
amax = i
return actions[amax]
该段代码与上段代码几乎一样,不同的是所取的状态值不一样。该段代码的状态是当前状态s的下一个状态s’. 另外,DQN所做的改变是用来选择行为的值函数网络称为目标值函数网络,跟当前值函数网络不同。
1.5 值函数更新
值函数更新公式为:
代码实现为:
key = "%d_%s"%(s, a)
#与环境进行一次交互,从环境中得到新的状态及回报
s1, r, t1, i =grid.step(a)
key1 = ""
#s1处的最大动作
a1 = greedy(qfunc, s1)
key1 = "%d_%s"%(s1, a1)
#利用qlearning方法更新值函数
qfunc[key] = qfunc[key] + alpha*(r + gamma * qfunc[key1]-qfunc[key])
评论:对于表格型值函数更新过程,我们看到每次更新只影响表格中的一个值,而不会影响行为值函数的其他值,这与行为值函数逼近方法不同。表格型强化学习算法效率很高,一般经过几次迭代后便能收敛。全部代码请参看github.gxnk中的qlearning。qlearning 算法的测试在文件learning_and_test.py中
第2小节:基于策略梯度算法实现详解
该部分需要用到tensorflow和画图库,所以大家先安装一下cpu版的tensorflow。
2.1 Tensorflow的安装:
Step1: 在终端激活虚拟环境(如何安装在上一讲):source activate gymlab
Step2: 安装的tensorflow版本为1.0.0, python=3.5如下命令:
根据该命令所安装的tensorflow是无gpu的,无gpu的tensorflow对于学习毫无障碍。当然,如果大家做项目,建议安装gpu版的tensorflow.
Step3: 安装一个绘图模块, 命令为:
pip3 install matplotlib
2.2 策略梯度算法理论基础
本专栏的第六讲已经给出了策略梯度的理论推导,策略梯度理论表明随机策略的梯度由下式给出:
当随机策略是高斯策略的时候,第六讲已经给出了随机梯度的计算公式。当随机策略并非高斯策略时,如何优化参数?
对于小车倒立摆系统如下图2.2所示。
图2.2 小车倒立摆系统
上一节我们已经深入剖析了gym环境的构建。从小车倒立摆的环境模型中,我们不难看到,小车倒立摆的状态空间为 ,动作空间为 ,当动作为1时,施加正向的力10N;当动作为0时,施加负向的力-10N。
因为动作空间是离散的,因此我们设计随机策略为softmax策略。Softmax策略如何构建,以及如何构建损失函数,从而将强化学习问题变成一个优化问题。
2.3 soft策略及其损失函数
我们设计一个前向神经网络策略,如图2.3所示。
图2.3 softmax策略
该神经softmax策略的输入层是小车倒立摆的状态,维数为4;最后一层是softmax层,维数为2。有机器学习的同学都很清楚,softmax常常作为多分类器的最后一层。
一个最基本的概念是何为softmax层?
如图2.3,设layer2的输出为z, 所谓softmax层是指对z作用一个softmax函数。即:
对于softmax策略,策略梯度理论中的随机策略为:
如图2.3所示, 对应着 layer2 的输出。 表示动作 a 所对应的softmax输出。上面的式子便给出了智能体在状态s处采用动作a的概率。该式是关于的函数,可直接对其求对数,然后求导带入到策略梯度公式,利用策略梯度的理论更新参数。然而,在这里我们将问题转化一下,对于一个episode,策略梯度理论的一步更新,其实是对损失函数为 的一步更新。
而损失函数可写为:
其中 为交叉熵。
在实际计算中, 由未更新的参数策略网络进行采样, 则是将状态直接带入,是参数 的一个函数。比如,当前动作由采样网络 ,产生为 a=1; 则 ,
,则
这是从信息论中交叉熵的角度来理解softmax层。理论部分就暂时介绍到这,接下来我们关心的是如何将理论变成代码。
上面,我们已经将策略梯度方法转化为一个分类问题的训练过程,其中损失函数为:
那么该网络的输入数据是什么呢?
输入数据有三个:
第一:小车倒立摆的状态s
第二:作用在小车上的动作a
第三:每个动作对应的累积回报v
我们一一解释,这些输入如何获得。
首先,小车倒立摆的状态s,这是与环境交互得到的;其次,作用在小车上的动作a,是由采样网络得到的,在训练过程中充当标签的作用;最后,每个动作的累积回报是由该动作后的累积回报累积并进行归一化处理得到的。
因此,该代码可以分为几个关键的函数:策略神经网络的构建,动作选择函数,损失函数的构建,累积回报函数v的处理。下面我们一一介绍如何实现。
2.4 基于 tensorflow 的策略梯度算法实现
策略网络的构建
构建一个神经网络,最简单的方法就是利用现有的深度学习软件,由于兼容性和通用性,这里我们选择了tensorflow。我们要构建的策略网络结构为如图2.4:
图2.4 策略神经网络
该神经网络是最简单的前向神经网络,输入层为状态s,共4个神经元,第一个隐藏层包括为10个神经元,激活函数为relu。因为输出为动作的概率,而动作有两个,因此第二层为2个神经元,没有激活函数,最后一层为softmax层。
将这段代码翻译成tensorflow语言则为:
def _build_net(self):
with tf.name_scope('input'):
#创建占位符作为输入
self.tf_obs = tf.placeholder(tf.float32, [None, self.n_features], name="observations")
self.tf_acts = tf.placeholder(tf.int32, [None, ], name="actions_num")
self.tf_vt = tf.placeholder(tf.float32, [None, ], name="actions_value")
#第一层
layer = tf.layers.dense(
inputs=self.tf_obs,
units=10,
activation=tf.nn.tanh,
kernel_initializer=tf.random_normal_initializer(mean=0, stddev=0.3),
bias_initializer=tf.constant_initializer(0.1),
name='fc1',
)
#第二层
all_act = tf.layers.dense(
inputs=layer,
units=self.n_actions,
activation=None,
kernel_initializer=tf.random_normal_initializer(mean=0, stddev=0.3),
bias_initializer=tf.constant_initializer(0.1),
name='fc2'
)
#利用softmax函数得到每个动作的概率
self.all_act_prob = tf.nn.softmax(all_act, name='act_prob')
全部代码可去github上看,在policynet.py文件中。
动作选择函数:
动作选择函数是根据采样网络生成概率分布,利用该概率分布去采样动作,具体代码为:
#定义如何选择行为,即状态s处的行为采样.根据当前的行为概率分布进行采样
def choose_action(self, observation):
prob_weights = self.sess.run(self.all_act_prob, feed_dict={self.tf_obs:observation[np.newaxis,:]})
#按照给定的概率采样
action = np.random.choice(range(prob_weights.shape[1]), p=prob_weights.ravel())
return action
其中函数np.random.choice是按照概率分布p=prob_weights.ravel()进行采样的函数。
损失函数的构建:
在理论部分我们已经说明了损失函数为
即交叉熵乘以累积回报函数。以下为代码部分:
#定义损失函数
with tf.name_scope('loss'):
neg_log_prob = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=all_act,labels=self.tf_acts)
loss = tf.reduce_mean(neg_log_prob*self.tf_vt)
累积回报函数v的处理:
def _discount_and_norm_rewards(self):
#折扣回报和
discounted_ep_rs =np.zeros_like(self.ep_rs)
running_add = 0
for t in reversed(range(0, len(self.ep_rs))):
running_add = running_add * self.gamma + self.ep_rs[t]
discounted_ep_rs[t] = running_add
#归一化
discounted_ep_rs-= np.mean(discounted_ep_rs)
discounted_ep_rs /= np.std(discounted_ep_rs)
return discounted_ep_rs
有了策略神经网络,动作选择函数,损失函数,累积回报函数之后,学习的过程就简单了,只需要调用一个语句即可:
#定义训练,更新参数
with tf.name_scope('train'):
self.train_op = tf.train.AdamOptimizer(self.lr).minimize(loss)
该训练过程为采用自适应动量的优化方法。学习优化的过程如下:
#学习,以便更新策略网络参数,一个episode之后学一回
def learn(self):
#计算一个episode的折扣回报
discounted_ep_rs_norm = self._discount_and_norm_rewards()
#调用训练函数更新参数
self.sess.run(self.train_op, feed_dict={
self.tf_obs: np.vstack(self.ep_obs),
self.tf_acts: np.array(self.ep_as),
self.tf_vt: discounted_ep_rs_norm,
})
#清空episode数据
self.ep_obs, self.ep_as, self.ep_rs = [], [],[]
return discounted_ep_rs_norm
2.5 基于策略梯度算法的小车倒立摆问题
有了策略网络和训练过程,对于解决小车的问题就很简单了。基本的框架为:
1. 创建一个环境
2. 生成一个策略网络
3. 迭代学习
通过与环境交互,学习更新策略网络参数
4. 利用学到的策略网络对小车倒立摆系统进行测试
利用softmax策略定义一个贪婪策略。
具体代码在github上的learning_cartpole.py文件中。
本讲结束。
PS:该部分讲得有点乱,强烈建议大家去github上下载代码,我已经做好了中文注释,大家可以改改参数,亲自体会下。所有代码都在github的第一讲文件夹中gxnk/reinforcement-learning-code。
国庆深度强化学习实战特训营
由郭博士和香港理工大学增强学习方向博士 Traffas 担任授课教师的深度强化学习国庆集训营将于 10 月 2 日— 6 日在北京举办。
报名请扫上图中的二维码。
探灵教育科技在8月初已经成功举办第一期强化学习入门进阶培训课程,受到学员一致好评。根据学员的反馈以及我们最新的教研成果,我们进一步对课程进行了升级、完善。国庆期间,特别推出为期五天的强化学习特训营活动,通过五天的理论讲解以及编程实战,帮助大家全面、系统的了解、掌握强化学习技术。
面向对象:强化学习的小白、初学者、自己已有一定基础但是没有建立系统知识体系的以及其他对于强化学习感兴趣的人士。有一定的微积分、线线性代数、概率论基础,有python编程基础。学员上课需要自带电脑。
授课时间地点:10.2-10.6日 北京海淀区(具体地点另行通知)
招生人数:精品小班制,上限 30 人,报名15 人以上开班。
学费:7999 早鸟票 7499(9.24日之前报名)
特别声明:凡报名参加本次国庆特训营的学员,一年之内可以免费参加两次由我公司主办的为期两天的线下课程(价值5999元)。
讲师介绍:
郭宪,南开大学计算机与控制工程学院博士后。2009年毕业于华中科技大学机械设计制造及自动化专业,同年保送到中国科学院沈阳自动化研究所进行硕博连读,主攻机器人动力学建模与控制,于2016年1月获得工学博士学位,期间在国内外知名杂志和会议发表论文数10篇。2016年以来,郭博士主攻方向为机器人智能感知和智能决策,目前主持两项国家级课题,内容涉及深度学习,深度强化学习等智能算法在机器人领域中的应用。郭博士于2017年3月开始在知乎专栏强化学习知识大讲堂,其深入浅出的讲解收到广大知友一致好评。即将出版《强化学习深入浅出完全教程》一书。
知乎链接:https://zhuanlan.zhihu.com/sharerl
Traffas,于2014年7月在瑞典皇家理工学院获得硕士学位,曾在瑞典Accedo公司做程序开发,现在在香港理工大学计算机系攻读博士学位,任研究助理。Traffas 的研究方向为机器学习、增强学习。目前已发表六篇论文,其中包括中国计算机学会(CCF)推荐的B类论文1篇,C类会议论文1篇.
日程安排:
第一天:授课老师 Traffas
1. 什么是强化学习以及强化学习的方法汇总?
强化学习可以让AlphaGo无需人类的指导,自己‘左右互搏’,就能悟到更佳出奇制胜的围棋技巧;可以让机器人的行动不再需要人类繁杂的编程,自己就可以适应所处的环境。为什么强化学习有如此神奇的功能?到底什么是强化学习?本课将为你娓娓道来....
2. 强化学习领域的基础概念。
解锁强化学习领域的术语。介绍增强学习可以解决的问题。介绍Bellman Equation原理,介绍RL和动态规划的异同点。介绍传统的tubular based RL。
3. 介绍安装Python2.7+Anconda+jupyter Notebook
4. 动手编写第一个增强学习的python 程序(30分钟),找到玩老虎机的最优策略。
5.基于蒙特卡罗强化学习介绍、同策略、异策略强化学习算法介绍。
6. 答疑、交流
第二天:授课老师 Traffas
1、 强化学习算法实践,基于强化学习玩21点游戏以及gridworld游戏。
2、 强化学习时间差分算法。介绍同策略Q-learning强化学习方法以及异策略Sara算法。比较和蒙特卡洛算法异同点。介绍eligibility Tree以及TD(lamda)算法。
3、 Gym环境构建以及强化学习算法实现。包括Gym环境的安装、测试,Gym环境关键函数讲解以及如何创建自定义Gym环境。
4、 学员动手实践
5、 老师答疑、交流。
第三天:授课老师 Traffas
1、DQN详解
DQN是深度强化学习中的强大武器,DeepMind团队就是利用DQN技术使得计算机在Atari电子游戏中的表现超过了人类的顶级玩家。同时,我们会讲解DQN的变种Double DQN、Prioritized Replay,Dual DQN。
2、实践准备
介绍深度神经网络DNN以及RNN。Keras安装,动手设计RNN网络,解决分类问题。
3、深度强化学习实战,亲自动手编写一个可以打败游戏高手的AI。
4、Bug调试、老师答疑、指导、交流。
第四天:授课老师 郭宪
1、策略梯度方法:
教学内容包括:策略梯度方法介绍,似然率策略梯度推导及重要性采样视角推导,似然率策略梯度的直观理解,常见的策略表示,常见的减小方差的方法:引入基函数法,修改估计值函数法
2、编程实践课:基于tensorflow和gym实现小车倒立摆系统、乒乓球游戏
3、TRPO方法介绍及推导:具体包括替代回报函数的构建,单调的改进策略,TRPO实用算法介绍,共轭梯度法搜索可行方向,PPO方法,基于python 的TRPO 方法实现
4、编程指导、交流、答疑。
第五天:主讲老师 郭宪
1、AC方法,具体内容包括随机策略与确定性策略比较、随机策略 AC 的方法、确定性策略梯度方法、DDPG方法及实现、A3C方法讲解、基于python 的 DDPG 方法实现。
2、AC方法及DDPG、A3C实现。
3、逆向强化学习介绍,包括逆向强化学习分类、学徒学习、MMP 方法、结构化分类方法、 神经逆向强化学习、最大熵逆向强化学习、相对熵逆向强化学习、深度逆向强化学习。
4、编程指导、答疑、交流。
报名请扫海报中的二维码。
【号外】新智元正在进行新一轮招聘,飞往智能宇宙的最美飞船,还有N个座位
点击阅读原文可查看职位详情,期待你的加入~