编者按:环信开源国内首本免费深度学习理论和实战专著《深度学习理论与实战:提高篇 》,内容涵盖听觉,视觉,语言和强化学习,七百多页详尽的理论和代码分析。本文节选自《深度学习理论与实战:提高篇 》一书,原文链接http://fancyerii.github.io/2019/03/14/dl-book/ 。作者李理,环信人工智能研发中心vp,有十多年自然语言处理和人工智能研发经验,主持研发过多款智能硬件的问答和对话系统,负责环信中文语义分析开放平台和环信智能机器人的设计与研发。
我们再来看一下Bellman公式,它是递归定义的——是由来定义的,对于有些简单问题,我们可以根据这个公式把通过解方程解出来。
我们结合上图来分析上面公式的。当前状态是s,根据策略,我们采取行为a的概率是,而我们在状态a和行为s的条件下,环境反馈r和s’的概率是,所有可能的(a,r,s’)组合我们都要求和,所以就得到,在每一条路径(每一种s,r,s’的组合)下就是r,因此可以得到。而在给定路径的情况下,都固定了,因此s’也是固定的了,而根据马尔科夫属性,只与t+1时刻的状态有关,因此第二项变成了。
最优价值函数(Optimal Value Functions)
解决强化学习任务,粗略来说,就是找到一个策略,使得长期的reward尽可能多。首先我们定义什么是一个策略比另外一个策略好(或者一样好),记作。形式化的定义是。 可以证明(这里略过)存在一个(可能有多个)最优的,它比所有其它策略都“好”。最优策略对于的价值函数叫做最优价值函数,记作:
同理对于行为也有一个最优的行为价值函数:
和有如下关系:
我们可以这样解读这个公式:s和a确定后,它会进入状态并得到Reward ,这是过程是有概率的,因此前面有一个期望。但是这和Agent无关,和Agent有关的是在t+1时刻的行为,如果要得到最优的,那么它必须在t+1时刻根据最优策略来计算,因此就是。
需要注意:上面公式的随机变量只是和,它由环境确定,而和是两个常量(给定s,a的情况下)。
OpenAI Gym简介
OpenAI Gym是一个用来开发和比较强化学习算法的工具。它对Agent的实现没有任何约束,因此你可以用TensorFlow或者其它任何工具来实现Agent。它提供统一的Environment的接口,你可以用这个接口来定义一个具体的强化学习任务,此外它也提供很多常见的任务,比如很多Atari的游戏。
运行Environment
首先我们介绍一个很简单的游戏CartPole-v0,如下图所示。
图:CartPole-v0运行时的截图
这个游戏有一个小车,可以对车子施加+1或者-1的力(加速度),车上有一个杆子,我们的目标是要求车子的位置在-2.4到2.4之间,并且杆子相对于垂直的角度在-15°和15°之间。如果从物理的角度来分析,它有4个状态变量,车子的位置,车子的速度,杆的角度,杆的角速度。而我们施加的力会改变车子的速度,从而间接改变车子的位置。我们可以用几行代码运行CartPole-v0这个游戏:
import gym env = gym.make('CartPole-v0') env.reset() for _ in range(1000): env.render() env.step(env.action_space.sample()) # take a random action
代码很简单,首先创建一个CartPole-v0 Environment对象env,重置(reset)使环境进入初始状态。接着循环1000次,每次首先把当前的游戏状态绘制出来(render),然后随机的选择一个Action env.action_space.sample(),接着调用env.step函数真正的“执行”这个Action。
观察(Observations)
观察就是MDP里的状态(State),Environment的step有4个返回值:
observation 一个对象,代表观察,不同的环境返回的对象是不同的。
reward float类型 表示Reward。
done bool类型 表示任务是否结束。对于Episode类任务会有结束状态,进入结束状态后再调用step是没有意义的,必须要先调用reset
info 调试用的一些信息
我们可以用如下代码打印出其中的一些信息:
import gym env = gym.make('CartPole-v0') for i_episode in range(20): observation = env.reset() for t in range(100): env.render() print(observation) action = env.action_space.sample() observation, reward, done, info = env.step(action) if done: print("Episode finished after {} timesteps".format(t+1)) break
Spaces
Environment对象里有两个空间(Space):状态空间(State Space)和行为空间(Action Space),它们定义了所有可能的状态和行为。我们可以查看一些CartPole-v0的Space:
import gym env = gym.make('CartPole-v0') print(env.action_space) #> Discrete(2) print(env.observation_space) #> Box(4,)
从输出可以看出,Discrete(2)表示这个任务有两个选的Action(分布表示向左和向右移动),Box(4,)表示状态由4维向量表示,物理意义分别是车子相对原点的位置和速度,杆相对于垂直方向的角度和角速度。我们可以用如下的代码检查其取值范围:
print(env.observation_space.high) #> array([ 2.4 , inf, 0.20943951, inf]) print(env.observation_space.low) #> array([-2.4 , -inf, -0.20943951, -inf])