强化学习是由两部分组成的:智能体和环境。在强化学习过程中,智能体与环境一直在交互。智能体在环境中获取某个状态后,它会利用该状态输出一个动作 (action),这个动作也称为决策(decision)。这个动作会在环境中被执行,环境会根据智能体采取的动作,输出下一个状态以及当前这个动作带来的奖励。智能体的目的就是尽可能多地从环境中获取奖励。
智能体由策略,价值函数及模型构成,智能体的决策过程分为马尔可夫决策过程及部分决策马尔可夫过。根据智能体学习对象分类,智能体分为基于价值的智能体和基于策略的智能体;根据是否用模型对环境的描述,分为有模型的智能体和免模型的智能体。
可以在Gym库上实践强化学习的基本流程。
强化学习的概念:
强化学习(reinforcement learning,RL)讨论的问题是智能体(agent)怎么在复杂、不确定的环境(environment)中最大化它能获得的奖励。
强化学习是由两部分组成的:智能体和环境。
在强化学习过程中,智能体与环境一直在交互。
智能体在环境中获取某个状态后,它会利用该状态输出一个动作 (action),这个动作也称为决策(decision)。
然后这个动作会在环境中被执行,环境会根据智能体采取的动作,输出下一个状态以及当前这个动作带来的奖励。
智能体的目的就是尽可能多地从环境中获取奖励。
与监督学习对比,强化学习的样本不是完全独立的,动作会影响后面得到的数据,学习过程的奖励信号相对来说是延迟的(因为需要等环境反馈)。
(1)强化学习会试错探索,它通过探索环境来获取对环境的理解。
(2)强化学习智能体会从环境里面获得延迟的奖励。
(3)在强化学习的训练过程中,时间非常重要。因为我们得到的是有时间关联的数据(sequential data), 而不是独立同分布的数据。在机器学习中,如果观测数据有非常强的关联,会使得训练非常不稳定。这也是为什么在监督学习中,我们希望数据尽量满足独立同分布,这样就可以消除数据之间的相关性。
(4)智能体的动作会影响它随后得到的数据,这一点是非常重要的。在训练智能体的过程中,很多时候我们也是通过正在学习的智能体与环境交互来得到数据的。所以如果在训练过程中,智能体不能保持稳定,就会使我们采集到的数据非常糟糕。我们通过数据来训练智能体,如果数据有问题,整个训练过程就会失败。所以在强化学习里面一个非常重要的问题就是,怎么让智能体的动作一直稳定地提升。
强化学习因为获取奖励的过程不需要人的标注,可以在环境中不断探索,所以其能力上限可能超越人类。
一个典型的例子是AlphaGo。
分为标准强化学习及深度强化学习两个阶段,早期都是在游戏中实践的。
近几年随着算力的发展,强化学习得到了更广泛的应用。
比如DeepMind学走路,比如OpenAI机械臂玩魔方。
强化学习研究的问题是智能体与环境交互的问题,整个决策的过程呈序列特点,决策的目标是奖励的最大化。
奖励是由环境给的一种标量的反馈信号(scalar feedback signal),这种信号可显示智能体在某一步采 取某个策略的表现如何。
强化学习的目的就是最大化智能体可以获得的奖励,智能体在环境里面存在的目 的就是最大化它的期望的累积奖励(expected cumulative reward)。
不同的环境中,奖励也是不同的。这 里给大家举一些奖励的例子。
(1)比如一个象棋选手,他的目的是赢棋,在最后棋局结束的时候,他就会得到一个正奖励(赢)或 者负奖励(输)。
(2)在股票管理里面,奖励由股票获取的奖励与损失决定。
(3)在玩雅达利游戏的时候,奖励就是增加或减少的游戏的分数,奖励本身的稀疏程度决定了游戏的难度。
在与环境的交互过程中,智能体会获得很多观测。针对每一个观测,智能体会采取一个动作,也会得到一个奖励。所以历史是观测、动作、奖励的序列:
H t = o 1 , r 1 , α 1 , . . . , o t , r t , α t H_t = o_1 , r_1, \alpha_1, ..., o_t , r_t, \alpha_t Ht=o1,r1,α1,...,ot,rt,αt
智能体在采取当前动作的时候会依赖于它之前得到的历史,所以我们可以把整个游戏的状态看成关于这个历史的函数:
S t = f ( H t ) ) S_t = f(H_t)) St=f(Ht))
同时需要注意状态和观测的关系。
状态是对世界的完整描述,不会隐藏世界的信息。观测是对状态的部分描述,可能会遗漏一些信息。
可观测
环境有自己的函数 s t e = f e ( H t ) s_{t}^{e}=f^{e}\left(H_{t}\right) ste=fe(Ht) 来更新状态,在智能体的内部也有一个函数 s t a = f a ( H t ) s_{t}^{a}=f^{a}\left(H_{t}\right) sta=fa(Ht)来更新状 态。当智能体的状态与环境的状态等价的时候,即当智能体能够观察到环境的所有状态时,我们称这个环境是完全可观测的(fully observed)。
在这种情况下面,强化学习通常被建模成一个马尔可夫决策过程 (Markov decision process,MDP)的问题。 o t = s t e = s t a o_{t}=s_{t}^{e}=s_{t}^{a} ot=ste=sta
部分可观测
但是有一种情况是智能体得到的观测并不能包含环境运作的所有状态,因为在强化学习的设定里面, 环境的状态才是真正的所有状态。当智能体只能看到部分的观测,我们就称这个环境是部分可观测的(partially observed)。 在这种情况下,强化学习通常被建模成部分可观测马尔可夫决策过程(partially observable Markov decision process, POMDP)的问题。
**部分可观测马尔可夫决策过程是马尔可夫决策过程的一种泛化 **。部分可观测马尔可夫决策过程依然具有马尔可夫性质,但是假设智能体无法感知环境的状态,只能知道部分观测值。
部分可观测马尔可夫决策过程可以用一个七元组描述: ( S , A , T , R , Ω , O , γ ) (S,A,T,R,\Omega,O,\gamma) (S,A,T,R,Ω,O,γ)
其中 S S S 表示状态空间,为隐变量, A A A 为动作空间, T ( s ′ ∣ s , a ) T(s'|s,a) T(s′∣s,a) 为状态转移概率, R R R 为奖励函数, Ω ( o ∣ s , a ) \Omega(o|s,a) Ω(o∣s,a) 为观测概率, O O O 为观测空间, γ \gamma γ 为折扣系数。
不同的环境允许不同种类的动作。在给定的环境中,有效动作的集合经常被称为动作空间(action space)。
动作空间分为:
如,走迷宫机器人如果只有往东、往南、往西、往北这 4 种移动方式,则其动作空间为离散动作空 间;如果机器人可以向 360 ◦ 中的任意角度进行移动,则其动作空间为连续动作空间。
部分可观测马尔可夫决策过程(Partially Observable Markov Decision Processes, POMDP) 是一个马尔可夫决策过程的泛化。
对于一个强化学习 agent,它可能有一个或多个如下的组成成分:
策略(policy)。智能体会用策略来选取下一步的动作。
价值函数(value function)。我们用价值函数来对当前状态进行评估。价值函数用于评估智能体进 入某个状态后,可以对后面的奖励带来多大的影响。价值函数值越大,说明智能体进入这个状态越有 利。
模型(model)。模型表示智能体对环境的状态进行理解,它决定了环境中世界的运行方式。 下面我们深入了解这 3 个组成部分的细节。
策略是智能体的动作模型,它决定了智能体的动作。它其实是一个函数,用于把输入的状态变成动作。策略可分为两种:随机性策略和确定性策略。
随机性策略(stochastic policy)就是 π \pi π 函数,即 π ( a ∣ s ) = p ( a t = a ∣ s t = s ) \pi(a | s)=p\left(a_{t}=a | s_{t}=s\right) π(a∣s)=p(at=a∣st=s)。输入一个状态 s s s,输出一个概率。
这个概率是智能体所有动作的概率,然后对这个概率分布进行采样,可得到智能体将采取的动作。比如可能是有 0.7 的概率往左,0.3 的概率往右,那么通过采样就可以得到智能体将采取的动作。
确定性策略(deterministic policy)就是智能体直接采取最有可能的动作,即 a ∗ = arg max a π ( a ∣ s ) a^{*}=\underset{a}{\arg \max} \pi(a \mid s) a∗=aargmaxπ(a∣s)。
通常情况下,强化学习一般使用随机性策略,随机性策略有很多优点。比如,在学习时可以通过引入一定的随机性来更好地探索环境;
随机性策略的动作具有多样性,这一点在多个智能体博弈时非常重要。采用确定性策略的智能体总是对同样的状态采取相同的动作,这会导致它的策略很容易被对手预测。
价值函数的值是对未来奖励的预测,我们用它来评估状态的好坏。
价值函数里面有一个折扣因子(discount factor),用来评价获取时刻的价值,价值函数的定义为
V π ( s ) ≐ E π [ G t ∣ s t = s ] = E π [ ∑ k = 0 ∞ γ k r t + k + 1 ∣ s t = s ] , 对于所有的 s ∈ S V_{\pi}(s) \doteq \mathbb{E}_{\pi}\left[G_{t} \mid s_{t}=s\right]=\mathbb{E}_{\pi}\left[\sum_{k=0}^{\infty} \gamma^{k} r_{t+k+1} \mid s_{t}=s\right], \text{对于所有的} s \in S Vπ(s)≐Eπ[Gt∣st=s]=Eπ[k=0∑∞γkrt+k+1∣st=s],对于所有的s∈S
期望 E π \mathbb{E}_{\pi} Eπ 的下标是 π \pi π 函数, π \pi π 函数的值可反映在我们使用策略 π \pi π 的时候,到底可以得到多少奖励。
还有一种价值函数:Q 函数。Q 函数里面包含两个变量:状态和动作。其定义为
Q π ( s , a ) ≐ E π [ G t ∣ s t = s , a t = a ] = E π [ ∑ k = 0 ∞ γ k r t + k + 1 ∣ s t = s , a t = a ] Q_{\pi}(s, a) \doteq \mathbb{E}_{\pi}\left[G_{t} \mid s_{t}=s, a_{t}=a\right]=\mathbb{E}_{\pi}\left[\sum_{k=0}^{\infty} \gamma^{k} r_{t+k+1} \mid s_{t}=s, a_{t}=a\right] Qπ(s,a)≐Eπ[Gt∣st=s,at=a]=Eπ[k=0∑∞γkrt+k+1∣st=s,at=a]
所以我们未来可以获得奖励的期望取决于当前的状态和当前的动作。
Q 函数是强化学习算法里面要学习的一个函数。因为当我们得到 Q 函数后,进入某个状态要采取的最优动作可以通过 Q 函数得到。
模型决定了下一步的状态。下一步的状态取决于当前的状态以及当前采取的动作。它由状态转移概率和奖励函数两个部分组成。状态转移概率即
p s s ′ a = p ( s t + 1 = s ′ ∣ s t = s , a t = a ) p_{s s^{\prime}}^{a}=p\left(s_{t+1}=s^{\prime} \mid s_{t}=s, a_{t}=a\right) pss′a=p(st+1=s′∣st=s,at=a)
奖励函数是指我们在当前状态采取了某个动作,可以得到多大的奖励,即
R ( s , a ) = E [ r t + 1 ∣ s t = s , a t = a ] R(s,a)=\mathbb{E}\left[r_{t+1} \mid s_{t}=s, a_{t}=a\right] R(s,a)=E[rt+1∣st=s,at=a]
策略、价值函数和模型组成了一个马尔可夫决策过程(Markov decision process)。
有两种分类方式
根据智能体学习的事物不同分类。
对于一个状态转移概率已知的马尔可夫决策过程,我们可以使用动态规划算法来求解。从决策方式来看,强化学习又可以划分为基于策略的方法和基于价值的方法。决策方式是智能体在给定状态下从动作集合中选择一个动作的依据,它是静态的,不随状态变化而变化。
在基于策略的强化学习方法中,智能体会制定一套动作策略(确定在给定状态下需要采取何种动作),并根据这个策略进行操作。强化学习算法直接对策略进行优化,使制定的策略能够获得最大的奖励。
而在基于价值的强化学习方法中,智能体不需要制定显式的策略,它维护一个价值表格或价值函数,并通过这个价值表格或价值函数来选取价值最大的动作。基于价值迭代的方法只能应用在不连续的、离散的环境下(如围棋或某些游戏领域),对于动作集合规模庞大、动作连续的场景(如机器人控制领域),其很难学习到较好的结果(此时基于策略迭代的方法能够根据设定的策略来选择连续的动作)。
基于价值的强化学习算法有Q学习(Q-learning)、 Sarsa 等,而基于策略的强化学习算法有策略梯度(Policy Gradient,PG)算法等。此外,演员-评论员算法同时使用策略和价值评估来做出决策。其中,智能体会根据策略做出动作,而价值函数会对做出的动作给出价值,这样可以在原有的策略梯度算法的基础上加速学习过程,取得更好的效果。
通过智能体到底有没有学习环境模型来对智能体进行分类。
有模型强化学习相比免模型强化学习仅仅多出一个步骤,即对真实环境进行建模。因此,一些有模型的强化学习方法,也可以在免模型的强化学习方法中使用。在实际应用中,如果不清楚该用有模型强化学习还是免模型强化学习,可以先思考在智能体执行动作前,是否能对下一步的状态和奖励进行预测,如果能,就能够对环境进行建模,从而采用有模型学习。
免模型强化学习通常属于数据驱动型方法,需要大量的采样来估计状态、动作及奖励函数,从而优化动作策略。
免模型学习的泛化性要优于有模型强化学习,原因是有模型强化学习算需要对真实环境进行建模,并且虚拟世界与真实环境之间可能还有差异,这限制了有模型强化学习算法的泛化性。
目前,大部分深度强化学习方法都采用了免模型强化学习,这是因为:免模型强化学习更为简单、直观且有丰富的开源资料
OpenAI 的 Gym库是一个环境仿真库,里面包含很多现有的环境。
安装了Gym库,就可以直接调入Taxi-v3的环境。
初始化这个环境后,我们就可以进行交互了。
智能体得到某个观测后,它就会输出一个动作。这个动作会被环境拿去执行某个步骤 ,然后环境就会往前走一步,返回新的观测、奖励以及一个 flag 变量 done,done 决定这个游戏是不是结束了。我们通过几行代码就可实现强化学习的框架:
import gym
env = gym.make("Taxi-v3") #确定环境
observation = env.reset() #观测
agent = load_agent() #定义智能体
for step in range(100):
action = agent(observation) #根据观测采取动作
observation, reward, done, info = env.step(action) #进一步
由于load_agent没有定义,所以上述只是一个框架,实现100步探索的框架。
Gym当中有很多小游戏等环境可以用。
选取**小车上山(MountainCar-v0)**作为例子。
import gym
env = gym.make('MountainCar-v0')
print('观测空间 = {}'.format(env.observation_space))
print('动作空间 = {}'.format(env.action_space))
print('观测范围 = {} ~ {}'.format(env.observation_space.low,
env.observation_space.high))
print('动作数 = {}'.format(env.action_space.n))
输出:
观测空间 = Box(2,)
动作空间 = Discrete(3)
观测范围 = [-1.2 -0.07] ~ [0.6 0.07]
动作数 = 3
实现一个智能体类————BespokeAgent 类,代码如下:
class BespokeAgent:
def __init__(self, env):
pass
def decide(self, observation): # 决策
position, velocity = observation
lb = min(-0.09 * (position + 0.25) ** 2 + 0.03,
0.3 * (position + 0.9) ** 4 - 0.008)
ub = -0.07 * (position + 0.38) ** 2 + 0.07
if lb < velocity < ub:
action = 2
else:
action = 0
return action # 返回动作
def learn(self, *args): # 学习
pass
agent = BespokeAgent(env)
智能体的decide()
方法实现了决策功能,而learn()
方法实现了学习功能。BespokeAgent
类是一个比较简单的类,它只能根据给定的数学表达式进行决策,不能有效学习,所以它并不是一个真正意义上的强化学习智能体类。但是,它用于演示智能体和环境的交互已经足够了。
试图让智能体与环境交互,代码如下。
def play_montecarlo(env, agent, render=False, train=False):
episode_reward = 0. # 记录回合总奖励,初始化为0
observation = env.reset() # 重置游戏环境,开始新回合
while True: # 不断循环,直到回合结束
if render: # 判断是否显示
env.render() # 显示图形界面,图形界面可以用 env.close() 语句关闭
action = agent.decide(observation)
next_observation, reward, done, _ = env.step(action) # 执行动作
episode_reward += reward # 收集回合奖励
if train: # 判断是否训练智能体
agent.learn(observation, action, reward, done) # 学习
if done: # 回合结束,跳出循环
break
observation = next_observation
return episode_reward # 返回回合总奖励
上面代码中的
play_montecarlo()
函数可以让智能体和环境交互一个回合,这个函数有 4 个参数。
env
是环境类。agent
是智能体类。render
是bool
型变量,指示在运行过程中是否要图形化显示,如果函数参数render
为 True,那么在交互过程中会调用env.render()
以显示图形界面,而这个界面可以通过调用env.close()
关闭。
train
是bool
型的变量,指示在运行过程中是否训练智能体,在训练过程中应当设置为 True,以调用agent.learn()
函数;在测试过程中应当设置为 False,使得智能体不变。
这个函数有一个返回值episode_reward
,是float
型的数值,表示智能体与环境交互一个回合的回合总奖励。
使用下面的代码让智能体和环境交互一个回合,并在交互过程中进行图形化显示,可用 env.close()
语句关闭图形界面。
env.seed(0) # 设置随机数种子,只是为了让结果可以精确复现,一般情况下可删去
episode_reward = play_montecarlo(env, agent, render=True)
print('回合奖励 = {}'.format(episode_reward))
env.close() # 此语句可关闭图形界面
输出:
回合奖励 = -105.0
为了系统评估智能体的性能,下列代码求出了连续交互 100 回合的平均回合奖励。
episode_rewards = [play_montecarlo(env, agent) for _ in range(100)]
print('平均回合奖励 = {}'.format(np.mean(episode_rewards)))
输出:
平均回合奖励 = -102.61
小车上山环境有一个参考的回合奖励值 -110,如果连续 100 个回合的平均回合奖励大于 -110,则认为这个任务被解决了。BespokeAgent 类对应的策略的平均回合奖励就在 -110 左右。
测试智能体在 Gym 库中某个任务的性能时,学术界一般最关心 100 个回合的平均回合奖励。至于为什么是 100 个回合而不是其他回合数(比如 128 个回合),完全是习惯使然,没有什么特别的原因。对于有些任务,还会指定一个参考的回合奖励值,当连续 100 个回合的奖励大于指定的值时,就认为这个任务被解决了。但是,并不是所有的任务都指定了这样的值。对于没有指定值的任务,就无所谓任务被解决了或者没有被解决。
Gym库 有对应的官方文档,读者可以阅读文档来学习 Gym库 。
1.强化学习蘑菇书