小言_互联网的博客

强化学习导论(Reinforcement Learning: An Introduction)读书笔记(三):有限马尔可夫决策过程

511人阅读  评论(0)

写在前面

由于专业学习的需要,最近开始学习强化学习的课程。目前看的书本是被誉为强化学习圣经的《Reinforcement Learning: An Introduction》,在学习过程中看到了两篇很好的笔记,强化学习导论(Reinforcement Learning: An Introduction)读书笔记(一):强化学习介绍.
强化学习导论(Reinforcement Learning: An Introduction)读书笔记(二):多臂赌博机(Multi-arm Bandits).
也想用同样的风格写下第三章。但是由于水平有限,只能作为模仿,自我整理,向大佬致敬。

1.有限马尔可夫决策过程

在了解马尔可夫决策时,最好首先理解一下什么是马尔可夫过程忆臻.对此有较好的解释。在赌博机问题不涉及关联,每一个动作都可以得到一个价值函数,我们估计每个动作a的价值为 q ( a ) q_*(a) 。但是在MDPs中,我们的考虑范围是一系列的动作,在不同的状态下,采用相同的动作会有不同的价值,所以价值函数定义为 q ( s , a ) q_*(s, a)

2.个体环境接口

MDPs最基础的模型如图1所示,整个模型被简单划分为个体环境。这里仅仅阐述一个简单的交互过程,在 t t 时刻,个体所处的环境的状态(State) S t S S_{t} \in \mathcal{S} ,个体选择动作 A t A ( s ) A_{t}\in \mathcal{A}(s) ,之后,环境会在下一个时刻 t + 1 t+1 给予个体一个奖励值(Reward),该反馈值为 R t + 1 R R R_{t+1} \in \mathcal{R} \subset \mathbb{R} ,同时个体自身到达一个新的状态 S t + 1 S_{t+1} 。这样个体和环境就在时刻 t t 完成了一个简单交互。

1.1 状态转移函数

马尔可夫过程可用如下数学表达式表示。
P ( x t + 1 . . . , x t 2 , x t 1 , x t ) = P ( x t + 1 x t ) P\left( \left. x_{t+1} \right|...,x_{t-2},x_{t-1},x_t \right) =P\left( \left. x_{t+1} \right|x_t \right)
在加入动作集合 A ( s ) {A}(s) 后,当前时刻的状态 s s^\prime 以及该状态下获得的回报 r r 是由前一个动作 a a 以及前一个状态 s s 共同决定,用数学公式表示为:
p ( s , r s , a ) P r { S t = s , R t = r S t 1 = s , A t 1 = a } p(s^\prime,r|s,a) \doteq Pr\{S_t=s^\prime,R_t=r|S_{t-1}=s,A_{t-1}=a\}
该联合概率密度对所有的 r r 进行累加,即可得到关于 s s^\prime 的边缘概率密度。由定义可知,这是前一个状态转化为后一个状态的概率,为转移概率(transition probabilities)
r R p ( s , r s , a ) = p ( s s , a ) = P r { S t = s S t 1 = s , A t 1 = a } \sum_{r\in\mathcal{R}}p(s^\prime,r|s,a)=p(s^\prime|s,a) =Pr\{S_t=s^\prime|S_{t-1}=s,A_{t-1}=a\}

1.2 回报的期望值

回报的期望用最简单的方式可以定义为(并不是很准确):
E [ R t ] = r R r p ( r ) \mathbb{E}\left[R_t\right]=\sum_{r\in\mathcal{R}}rp(r)
此外,由于时刻 t t 的回报 r r 是由时刻 t 1 t-1 的状态 s s ,动作 a a 以及时刻 t 1 t-1 的状态 s s^\prime 共同决定的。 r r 的三参数函数定义为(采用贝叶斯公式就可以计算):
r ( s , a , s ) E [ R t S t 1 = s , A t 1 = a , S t = s ] = r R r p ( s , r s , a ) p ( s s , a ) r(s,a,s^\prime)\doteq\mathbb{E}\left[R_t|S_{t-1}=s,A_{t-1}=a,S_t=s^\prime\right]=\sum_{r\in\mathcal{R}}r\frac{p(s^\prime,r|s,a)}{p(s^\prime|s,a)}
当然,由于 s s^\prime 也是由状态 s s ,动作 a a 共同决定的,三参数可以退化为二参数函数。因此, r r 的二参数计算公式可以定义为:
r ( s , a ) E [ R t S t 1 = s , A t 1 = a ] = r R r s S p ( s , r s , a ) r(s,a)\doteq\mathbb{E}\left[R_t|S_{t-1}=s,A_{t-1}=a\right]=\sum_{r\in\mathcal{R}}r\sum_{s^\prime\in\mathcal{S}}p(s^\prime,r|s,a)

1.3 关于个体与环境的说明

MPDs中的个体和环境之间的边界通常与机器人或动物身体的物理边界不同。 通常,边界更接近于个体。例如,机器人及其传感硬件的电动机和机械联动件通常应被视为环境的一部分而不是个体的一部分。 同样,如果我们将MDP框架应用于人或动物,肌肉,骨骼和感觉器官应被视为环境的一部分。
我们遵循的一般规则是,任何不能被个体任意改变的东西都被认为是在它之外,因此也是其环境的一部分。

1.4 举例说明

书中有一个关于MPDs的例子,非常形象说明了MPDs过程。其举例了一个自动捡垃圾的机器人。该机器人只有两个状态集 S = { high , low } \mathcal{S}=\{\text{high},\text{low}\} ,不同的状态集有不同的动作,在每个状态,个体可以决定是否(1)在一段时间内主动 search 汽水罐,(2)保持静止并 wait 某人给它汽水罐,或(3)返回原地充电 recharge。当电量水平很高时,充电操作是愚蠢的,因此其动作的集合为 A ( high ) = { search , wait } \mathcal{A}(\text{high})=\{\text{search}, \text{wait}\} 以及 A ( low ) = { search , wait , recharge } \mathcal{A}(\text{low})=\{\text{search}, \text{wait},\text{recharge}\}
下图表格描述了所有的情况,这里仅举2例说明。

1.电量状态为high且执行search工作

  • α \alpha 的概率状态变为high, 奖励为 r s e a r c h r_{search}
  • 1 α 1-\alpha 的概率状态变为low,奖励为 r s e a r c h r_{search}

2.电量状态为low且执行search工作

  • β \beta 的概率状态变为low, 奖励为 r s e a r c h r_{search}
  • 1 β 1-\beta 的概率状态变为high, 奖励为-3

2.目标与奖励

所有我们所说的目标和目的都可以被认为是所接收的标量信号(称为奖励)的累积和的预期值的最大化。
使用奖励信号来形式化目标的想法是强化学习的最显着特征之一,因此,我们建立的奖励真正表明我们想要实现的目标至关重要
特别是,奖励信号不是教个体how to achieve,而是what you want。正如国际象棋中你的奖励是为了赢而不是拿掉对手的棋子,不然你的机器人可能会因为想更多拿掉对手的棋子而丢失了比赛。

3.Episode task与continuing task 的回报

3.1回报函数

Episode task 是指有限步的情况,这种情况多发生在游戏中,比如下棋,或者其他存在胜负的游戏比赛,游戏的最后一步为Terminal state,所有状态加上最终状态定义为 S + \mathcal{S^+} 。最后一步的时刻为Terminal Time, 定义为 T T ,那么在 t t 步后的回报定义为:
G t R t + 1 + R t + 2 + R t + 3 + + R T G_{t} \doteq R_{t+1} +R_{t+2} + R_{t+3} + \dots + R_{T},
Continuing task针对的是长期的一种工作,比如刚刚的捡罐头的机器人,他的工作就是长期的。对于该种情况,我们要避免回报函数不收敛,因此,需要添加衰减系数 γ \gamma 。在动作 A t A_t 执行后,回报函数为:
G t R t + 1 + γ R t + 2 + γ 2 R t + 3 + = k = 0 γ k R t + k + 1 G_{t} \doteq R_{t+1} + \gamma R_{t+2} + \gamma^2 R_{t+3} + \dots = \sum_{k=0}^{\infty}\gamma^k R_{t+k+1}
其中, 0 γ 1 0 \leq\gamma \leq 1 ,被称为衰减系数。 γ \gamma 接近0,则表明趋向于近视性评估; γ \gamma 接近1则表明偏重考虑远期的利益。
在该条件下, G t G_{t} 可收敛,且其值为:
G t k = t + 1 T γ k t 1 R k G_t \doteq \sum_{k=t+1}^{T} \gamma^{k-t-1} R_k

3.2 Episode task与continuing task 回报函数的统一

上文中,回报根据步数是否有限分为两种情况,一种是有限步数,一种是无限步数。在这一部分,我们需要将两者进行统一。如下图所示,我们将有限步数的最后一步定义为吸收状态,该状态会无线返回自身状态,且Reward0

那么,上述的回报公式均可以表示为:
G t k = t + 1 T γ k t 1 R k G_t \doteq \sum_{k=t+1}^{T} \gamma^{k-t-1} R_k
在无限步数的情况, T = T = \infty ,对于有限步数的情况, γ = 1 \gamma=1 ,当然,这两种情况并不会同时发生。

4.决策与价值函数

4.1 策略函数

策略函数描述了个体在不同的状态下是如何工作的。一个策略完整定义了个体的行为方式,也就是说定义了个体在各个状态下的各种可能的行为方式以及其概率的大小,其只由当前的状态决定。
强化学习方法指定了个体的策略如何因其经验结果而变化。
下表所示就是一个策略 π ( a s ) \pi(a|s)

Action1 Action2
S 1 S_1 p ( a 1 s 1 ) p(a_1\mid s_1) p ( a 2 s 1 ) p(a_2\mid s_1)
S 2 S_2 p ( a 1 s 2 ) p(a_1\mid s_2) p ( a 2 s 2 ) p(a_2\mid s_2)
S 3 S_3 p ( a 1 s 3 ) p(a_1\mid s_3) p ( a 2 s 3 ) p(a_2\mid s_3)
S 4 S_4 p ( a 1 s 4 ) p(a_1\mid s_4) p ( a 2 s 4 ) p(a_2\mid s_4)
S 5 S_5 p ( a 1 s 5 ) p(a_1\mid s_5) p ( a 2 s 5 ) p(a_2\mid s_5)

简单来说就是在 S 1 S_1 的情况下,以 p ( a 1 s 1 ) p(a_1\mid s_1) 的概率执行Action1,以 p ( a 2 s 1 ) p(a_2\mid s_1) 的概率执行Action2,以此类推。

4.2 价值函数

如果策略确定的话,那么在该策略的指导下,可以评估当前状态的价值函数。若策略为 π \pi ,状态为 s s ,则状态价值函数(state-value function for policy π \pi )
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|S_t=s\right]= \mathbb{E}_\pi\left[\sum_{k=0}^{\infty} \gamma^k R_{t+k+1}|S_t=s\right],对所有 s\in \mathbb{S}
这里为什么需要期望呢?我们需要注意的是,上述所涉及的回报函数对应的单步奖励并不是确定的,在某一个状态 s s 下,后续的单步奖励可以有多种情况,因此需要求期望。
在执行当前策略π时,衡量个体处在状态s时的价值大小
同样,我们定义在策略 π \pi ,状态 s s 下采取动作 a a 的价值,其表示为 q π ( s , a ) q_\pi(s,a) ,设定为动作值函数(action-value function for policy π \pi )
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|S_t=s,A_t=a\right]= \mathbb{E}_\pi\left[\sum^{\infty}_{k=0}\gamma^kR_{t+k+1}|S_t=s,A_t=a\right]
行为价值函数是来评价在特定状态的条件下,某个action的好坏

4.3 Bellman 方程

4.3.1 回报函数的递推式

贝尔曼方程的作用就是寻找 v π ( s ) v_\pi(s) q π ( s , a ) q_\pi(s,a) 自身以及相互之间的关系。
在介绍Bellman方程前,我们首先要将回报函数改成递推关系:

G t R t + 1 + γ R t + 2 + γ 2 R t + 3 + γ 3 R t + 4 + = R t + 1 + γ ( R t + 2 + γ R t + 3 + γ 2 R t + 4 + ) = R t + 1 + γ G t + 1 \begin{aligned}G_{t} &\doteq R_{t+1} + \gamma R_{t+2} + \gamma^2 R_{t+3} + \gamma^3 R_{t+4} + \dots \\&= R_{t+1} + \gamma(R_{t+2} + \gamma R_{t+3} + \gamma^2 R_{t+4} + \dots) \\&= R_{t+1} + \gamma G_{t+1}\end{aligned}

4.3.2 动作价值函数

从下图(备份图)中考虑动作值函数 q π ( s , a ) q_\pi(s,a)


动作价值函数示意图

由上文,动作价值函数可以进一步表示为:
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 ] = s r p ( s , r s , a ) [ r + γ E π [ G t + 1 S t + 1 = s ] ] \begin{aligned}q_\pi(s,a) & \doteq \mathbb{E}_\pi\left[G_t|S_t=s,A_t=a\right]\\&=\mathbb{E}_\pi\left[\sum^{\infty}_{k=0}\gamma^kR_{t+k+1}|S_t=s,A_t=a\right]\\&= \sum_{s^\prime}\sum_r p(s^\prime,r|s,a) \left[r+\gamma\mathbb{E}_\pi[G_{t+1}|S_{t+1}=s^\prime]\right] \\\end{aligned}
公式解读: 如上图所示,在状态 s s 的情况下评价动作 a a 的好坏。首先需要明确,在执行动作 a a 以后,可能会转入不同的 s s^\prime ,那么我们需要评估每个 s s^\prime 所带来的 r r 以及 s s^\prime 本身的价值,即 E π [ G t + 1 S t + 1 = s ] {E}_\pi[G_{t+1}|S_{t+1}=s^\prime] 。而状态转化为 s s^\prime 的概率以及奖励是 r r 的概率每种情况也是不相同的,因此需要考虑每种情况的可能性以及该种情况对应的价值,其实就是求期望

4.3.3 状态价值函数

上文说到了动作价值函数,那么状态价值函数就是评价某个状态的价值 下图为状态价值函数的示意图。


状态价值函数示意图

在策略 π ( a s ) \pi(a|s) 下,评价一个状态的价值,就是对该状态的动作的期望。公式可以表示为:
v π ( s ) = a π ( a s ) q π ( s , a ) v_\pi(s) = \sum_a\pi(a|s)q_\pi(s,a)
在状态 s s 下选择动作 a a 的可能性以及该可能性带来的收益
那么,将上文的价值公式代入,则可得到:
v π ( s ) E π [ G t S t = s ] = E π [ R t + 1 + γ G t + 1 S t = s ] ( ( 3.9 ) ) = a π ( a s ) s r p ( s , r s , a ) [ r + γ E π [ G t + 1 S t + 1 = s ] ] = a π ( a s ) s , r p ( s , r s , a ) [ r + γ v π ( s ) ] , s S \begin{aligned}v_\pi(s) &\doteq \mathbb{E}_\pi[G_t|S_t=s] \\&= \mathbb{E}_\pi[R_{t+1} + \gamma G_{t+1}|S_t=s] (由 (3.9)) \\&= \sum_a\pi(a|s) \sum_{s^\prime}\sum_r p(s^\prime,r|s,a) \left[r+\gamma\mathbb{E}_\pi[G_{t+1}|S_{t+1}=s^\prime]\right] \\&= \sum_a\pi(a|s) \sum_{s^\prime,r}p(s^\prime,r|s,a)[r+\gamma v_\pi(s^\prime)], 对所有 s\in\mathcal{S}\end{aligned}
就形成了一种迭代的式子。值得注意的是,我们在状态 s s 下并不了解状态 s s^\prime 的价值,但是由于bellman方程是迭代的运算,所以可以给定相关的初始值。

5.最优政策和最优价值函数

最优价值函数的意义在于评估当前状态的价值。 对所有 s S s\in \mathcal{S} , 当且仅当 v π ( s ) v π ( s ) v_\pi(s)\ge v_{\pi^{^\prime}}(s) 时, π π \pi\ge\pi^\prime 成立。在策略中,总是有一个策略优于或者等于所有策略,我们称该策略为最优策略。在最优策略规定下的最优价值函数 v v_* 为:
v ( s ) max π v π ( s ) v_*(s) \doteq \max_\pi v_\pi(s),
其中, s S s\in \mathcal{S}
在最优策略下,还有最优动作价值函数,其表示为 q q_* ,并定义为:
q ( s , a ) max π q π ( s , a ) q_*(s,a) \doteq \max_\pi q_\pi(s,a)
在最优策略下,最优动作价值函数的选择就是下一个最优状态最优动作价值函数最优状态的迭代关系可以表示为:
q ( s , a ) = E [ R t + 1 + γ v ( S t + 1 ) S t = s , A t = a ] q_*(s,a) = \mathbb{E}\left[R_{t+1}+\gamma v_* (S_{t+1})|S_t=s,A_t=a\right]
因为 v v_* 是最优价值函数,其满足bellman方程。其可以改写为bellman方程的一种特殊情况,形式为:
v ( s ) = max a A ( s ) q π ( s , a ) = max a E π [ G t S t = s , A t = a ] = max a E π [ R t + 1 + γ G t + 1 S t = s , A t = a ] ( ( 3.9 ) ) = max a E [ R t + 1 + γ v ( S t + 1 ) S t = s , A t = a ] ( 3.18 ) = max a A ( s ) s , r p ( s , r s , a ) [ r + γ v ( s ) ] ( 3.19 ) \begin{aligned}v_*(s) &= \max_{a\in\mathcal{A}(s)} q_{\pi_*}(s,a) \\&=\max_a \mathbb{E}_{\pi_*}[G_t|S_t=s,A_t=a] \\&=\max_a \mathbb{E}_{\pi_*}[R_{t+1}+\gamma G_{t+1}|S_t=s,A_t=a] &(由(3.9)式) \\&=\max_a \mathbb{E}[R_{t+1}+\gamma v_*(S_{t+1})|S_t=s,A_t=a] &(3.18) \\&=\max_{a\in \mathcal{A}(s)}\sum_{s^\prime,r} p(s^\prime,r|s,a)[r+\gamma v_*(s^\prime)] &(3.19)\end{aligned}
公式解读:由上文的 v π ( s ) = a π ( a s ) q π ( s , a ) v_\pi(s) = \sum_a\pi(a|s)q_\pi(s,a) 可知, v ( s ) = max a A ( s ) q π ( s , a ) v_*(s) = \max_{a\in\mathcal{A}(s)} q_{\pi_*}(s,a) 意味着在最优策略下,状态价值可以直接通过其选择的最优动作决定。
将上述的式子与动作价值函数合并,可得到关于 q q_* 的贝尔曼最优方程:
q ( s , a ) = E [ R t + 1 + γ a q ( S t + 1 , a ) S t = s , A t = a ] = s , r p ( s , r s , a ) [ r + γ a q ( s , a ) ] \begin{aligned}q_*(s,a) &= \mathbb{E}\left[R_{t+1}+\gamma\sum_{a^\prime}q_*(S_{t+1,a^\prime})|S_t=s,A_t=a\right] \\&=\sum_{s^\prime,r}p(s^\prime,r|s,a)[r+\gamma \sum_{a^\prime}q_*(s^\prime,a^\prime)]\end{aligned}
一旦有了 v v_* ,那么可以通过其确定最优策略。下图所示的中间图片为最优状态价值的数值,那么对于每个状态,均可观察其周围四个状态,并选择最优的状态作为下一刻的状态值,依次类推,确定最优策略。


最优价值确定策略

若是 q q_* 已知,那么最优状态动作确定,最优策略的制定就是一步到位的。

6. 代码解读

代码的来源就在下面的链接,我就是做了一些批注。

#######################################################################
# Copyright (C)                                                       #
# 2016-2018 Shangtong Zhang(zhangshangtong.cpp@gmail.com)             #
# 2016 Kenta Shimada(hyperkentakun@gmail.com)                         #
# Permission given to modify the code as long as you keep this        #
# declaration at the top                                              #
#######################################################################

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.table import Table

matplotlib.use('Agg')

WORLD_SIZE = 5
A_POS = [0, 1]
A_PRIME_POS = [4, 1]
B_POS = [0, 3]
B_PRIME_POS = [2, 3]
DISCOUNT = 0.9

# left, up, right, down
ACTIONS = [np.array([0, -1]),
           np.array([-1, 0]),
           np.array([0, 1]),
           np.array([1, 0])]
ACTION_PROB = 0.25


def step(state: list, action) -> list:
    """
    state 为列表
    action 为数组
    返回 下一个状态:列表 以及 reward 奖励
    """
    if state == A_POS:
        return A_PRIME_POS, 10
    if state == B_POS:
        return B_PRIME_POS, 5

    next_state = (np.array(state) + action).tolist()  # 从数组变成列表
    x, y = next_state
    if x < 0 or x >= WORLD_SIZE or y < 0 or y >= WORLD_SIZE:
        reward = -1.0
        next_state = state
    else:
        reward = 0
    return next_state, reward


def draw_image(image):
    fig, ax = plt.subplots()
    ax.set_axis_off()
    tb = Table(ax, bbox=[0, 0, 1, 1])

    nrows, ncols = image.shape
    width, height = 1.0 / ncols, 1.0 / nrows

    # Add cells
    for (i, j), val in np.ndenumerate(image):
        tb.add_cell(i, j, width, height, text=val,
                    loc='center', facecolor='white')

    # Row and column labels...
    for i in range(len(image)):
        tb.add_cell(i, -1, width, height, text=i + 1, loc='right',
                    edgecolor='none', facecolor='none')
        tb.add_cell(-1, i, width, height / 2, text=i + 1, loc='center',
                    edgecolor='none', facecolor='none')

    ax.add_table(tb)


def figure_3_2():
    """
    这里的更新方式是全部更新,就是计算每个点的价值函数
    """
    value = np.zeros((WORLD_SIZE, WORLD_SIZE))  # 原来的价值矩阵
    while True:
        # keep iteration until convergence
        new_value = np.zeros_like(value)  # 更新后是价值矩阵
        for i in range(WORLD_SIZE):
            for j in range(WORLD_SIZE):
                for action in ACTIONS:
                    (next_i, next_j), reward = step([i, j], action)
                    # bellman equation
                    new_value[i, j] += ACTION_PROB * (reward + DISCOUNT * value[next_i, next_j])
        if np.sum(np.abs(value - new_value)) < 1e-4:
            draw_image(np.round(new_value, decimals=2))
            plt.savefig('../images/figure_3_2.png')
            plt.close()
            break
        value = new_value


def figure_3_5():
    value = np.zeros((WORLD_SIZE, WORLD_SIZE))
    while True:
        # keep iteration until convergence
        new_value = np.zeros_like(value)
        for i in range(WORLD_SIZE):
            for j in range(WORLD_SIZE):
                values = []
                """  
                最后一个for循环没有计算价值的期望,因为要选择一个最好的动作,用最好
                的动作的价值作为新的价值。
                """
                for action in ACTIONS:
                    (next_i, next_j), reward = step([i, j], action)
                    # value iteration
                    values.append(reward + DISCOUNT * value[next_i, next_j])
                new_value[i, j] = np.max(values)  # 计算每个动作带来的收益
        if np.sum(np.abs(new_value - value)) < 1e-4:
            draw_image(np.round(new_value, decimals=2))
            plt.savefig('../images/figure_3_5.png')
            plt.close()
            break
        value = new_value


if __name__ == '__main__':
    figure_3_2()
    figure_3_5()

7. 写在最后

关于这本《Reinforcement Learning: An Introduction》的英文原书,确实很难,自己看的也比较慢,希望可以继续坚持。希望能够和更多人一起交流!

链接: 这是《Reinforcement Learning: An Introduction》习题答案的链接,是一个博主自己写的。
链接: 这是《Reinforcement Learning: An Introduction》的代码示例,这个比较厉害.


转载:https://blog.csdn.net/qq_21481459/article/details/105016520
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场