强化学习中的蒙特卡洛方法详解
1.为什么需要蒙特卡洛方法?
在强化学习中,我们面临以下挑战:
- 环境模型未知
-
- 之前的学习里面更新里面使用到的转移概率,很多时候是不知道的, 回报的概率也是不知道的,无法直接通过计算的方式来计算一个状态的回报的函数
- 状态空间可能很大
-
- 对于状态空间很大的情况,绝大部分情况是可能永远不会被访问的状态
- 需要从经验中学习
2. 什么是蒙特卡洛方法?
蒙特卡洛方法是一种基于随机采样的数值计算方法,这里需要尤其注意的词是 采样
在强化学习中,主要通过真实的采样来用于估计状态价值函数和动作价值函数。其核心思想是通过多次采样和平均来逼近真实值。
蒙特卡洛方法提供了一种model-free的解决方案,不需要完整的环境模型(不知道模型的转移概率)就能学习。
3. 蒙特卡洛方法能做什么?
- 策略评估(Policy Evaluation)
- 策略改进(Policy Improvement)
- 价值函数估计
- 最优策略搜索
4. 策略评估
在开始讲解如何使用蒙特卡洛的方法来实现策略评估之前,我们先回顾一下幕的概念,一幕就是一个状态到结束时刻的T的所有的状态和动作以及回报的一个序列
定义回报函数,回报(Return):
G
t
=
R
t
+
1
+
γ
R
t
+
2
+
γ
2
R
t
+
3
+
.
.
.
=
∑
k
=
0
∞
γ
k
R
t
+
k
+
1
G_t = R_{t+1} + \gamma R_{t+2} + \gamma^2 R_{t+3} + ... = \sum_{k=0}^{\infty} \gamma^k R_{t+k+1}
Gt=Rt+1+γRt+2+γ2Rt+3+...=∑k=0∞γkRt+k+1
4.1 首次访问型MC
每一幕的任意一个状态s第一次出现的时候开始,直到这一幕结束所得到的实际回报的gamma衰减的和,就是对于状态S的一个首次访问型MC,这个逻辑上很容易理解。因为一幕本来就是一个分布的一次真实采样,那么显然是一个独立的采样
4.2 每次访问性回报
显然,一个状态s可能在一幕的过程中出现多次,那么如果对于每一个出现的s都执行一次回报的更新,那么这个方法到底有没有作用,后文可能使用的资格trace,还有很多内容都需要使用每次访问性的回报
原文在收敛性的证明原文直接跳过了,如果大家有兴趣的可以参考我的这个文章,里面介绍了首次访问和每次访问的收敛性的定理的证明的过程,
收敛性证明过程及所需条件
21点的蒙特卡洛方法的证明
下面的代码是一个蒙特卡洛的方法,我们这里只是考虑两个动作,一个是hit 一个是stop,policy是默认的动作hit,returns,存放了一个state的所有的出现过的
G
t
G_t
Gt,训练完毕了以后则不再使用training的get action,我们最后经过了20w次训练,完毕后的对抗庄家的胜率是42.7,需要完整代码的可以私信沟通
Episode 200000 completed
Win rate: 42.70%
class MonteCarloAgent:
def __init__(self, epsilon=0.1):
self.epsilon = epsilon
self.Q = defaultdict(lambda: np.zeros(2)) # Q值表
self.returns = defaultdict(lambda: defaultdict(list)) # 存储回报
self.policy = defaultdict(lambda: 0) # 策略
def get_action(self, state, training=True):
"""选择动作"""
if training and np.random.random() < self.epsilon:
return np.random.randint(2)
return self.policy[state]
def update(self, episode):
"""更新策略"""
states, actions, rewards = zip(*episode)
# 计算回报
G = 0
for t in range(len(episode)-1, -1, -1):
G = rewards[t] + 0.9*G
state = states[t]
action = actions[t]
# 首次访问MC预测
if (state, action) not in [(states[i], actions[i]) for i in range(t)]:
self.returns[state][action].append(G)
#更新value值
self.Q[state][action] = np.mean(self.returns[state][action])
# 更新策略
self.policy[state] = np.argmax(self.Q[state])
输出最后的三维的热点图
5.蒙特卡洛动作价值估计
动作价值和状态价值都是按照之前一样的方法,当访问的时候去更新,但是这里有一个很重要的问题,如果策略是固定策略,那么很有可能其他的很多的动作都永远得不到访问,问了确保所有的Q值都能得到更新,我们需要保证所有的action都有被访问的可能性
- 试探性出发:确保所有的(s,a)都有不为0的被选为初始化节点的可能性,那么自然有无穷的次数会被选中(当无限幕时)
- 随机策略:确保所有的动作都有可能被访问
5.1策略更新
当策略不变的时候,我们可以对于这个策略的价值函数的估计,当然也可以像策略迭代的方法一样,进行了策略评估以后,使用贪心策略来更新新的行动策略,这里需要注意的是依然需要保证前文说的两个方法,保证所有的action都会被选中
5.2 蒙特试探性出发
保证MC方法的前提条件已经提到了,但是无论是试探性出发还是要求无数次,还是上面的策略更新的方法,都要求有足够多的幕来更新,策略才能继续往下迭代,考虑到前面的价值迭代的方法(尤其是就地价值直接迭代的方法),我们也可以学习这种就地更新评估,就地更新策略的方法,我们叫做 蒙特卡洛ES
如同前面使用的21点的算的代码逻辑的update函数一一样,每次更新完了一个Q值,我们立马更新了s的动作函数
- 练习5.4解答,这里存放了所有的return的序列,当然我们也可以直接使用一个count和上一轮的平均值,来更新即可
5.3 没有试探性出发的MC
如果试探性出发的前提条件无法被满足,那么我们需要保证在所有的状态所有的动作都有概率被选择,这里有同轨策略和离轨策略,on/off-policy,这里需要对这个概念加以讲解
同轨策略:生成样本的策略和实际更新的策略是同一个。(前面章节里面的都是这种策略)
离轨策略:生成样本的策略和实际更新的策略不同
举个例子,如果生成样本的策略20%向左,但是80%向右,但是更新的策略是80%向左,20%向右,根据贝尔曼方程可知显然同一个状态的不同返回值的权重和概率有关,那么我们需要将这个权重进行修正,才能从离轨策略得到价值函数的无偏估计
同轨策略的 ϵ \epsilon ϵ-软性策略:保证所有的动作都有一定的基于 ϵ \epsilon ϵ的概率被选中,显然21点中的get_action的训练策略是满足这个算法的条件
原文中证明了为什么
ϵ
\epsilon
ϵ-贪心策略是一个最好的
ϵ
\epsilon
ϵ-软策略,但是证明的过程非常的复杂,其实逻辑上很好理解,1:对于
ϵ
\epsilon
ϵ的随机情况,任何
ϵ
\epsilon
ϵ-软策略选择动作的概率都是一样的,那么回报也是一样的:
2:对于非
ϵ
\epsilon
ϵ的情况,贪心策略已经是选择的最大的回报的情况,显然大于任何其他的策略。
我这里不会放这个公式的证明过程,原文还证明了迭代只有一个不动点,我这里也会跳过
6.离轨策略
离轨策略的例子已经讲过了,实用性也是显而易见的,但是显然,离轨策略的不确定性更高,收敛的也是更慢
为了解决刚刚提到的无偏估计的问题,我们使用了一个新的东西叫做重要度采样,为什么使用重要度采样的原因和期望的权值有关系,上文也已经证明了
行动策略(采样策略)的序列在目标策略上发生的概率如下,从s0出发
P π ( τ ) = ∏ t = 0 T − 1 π ( a t ∣ s t ) / b ( a t ∣ s t ) P_π(τ) =\prod_{t=0}^{T-1} π(a_t|s_t)/b(a_t|s_t) Pπ(τ)=∏t=0T−1π(at∣st)/b(at∣st)
需要注意的是,实际上还有一个p(s’,r| s, a)的转移概率加权,但是这是一个环境参数,在行动策略和目标策略上都是一样的值,所以可以被去掉(原文这里带过,没有讲到具体是什么东西)
6.1 普通重要度采样
基于这个模型,我们可以简单的对一个回报进行一个无偏估计,我们可以直接对任意的s的回报
∏
t
T
π
(
a
t
∣
s
t
)
b
(
a
t
∣
s
t
)
⋅
G
t
=
ρ
t
:
H
⋅
G
t
\prod_t^{T}\frac{π(a_t|s_t)}{b(a_t|s_t)}\cdot G_t = \rho_{t:H}\cdot G_t
∏tTb(at∣st)π(at∣st)⋅Gt=ρt:H⋅Gt,那么对于v的价值函数就从原本的求平均值,变成了求带重要度采样的加权平均
普通重要的采样是期望是目标策略的期望
6.2 加权重要度采样
加权重要度采样的更新规则是如下,显然加权重要度采样的期望是行动策略b的期望
∑
π
(
a
t
∣
s
t
)
/
b
(
a
t
∣
s
t
)
⋅
G
t
∑
π
(
a
t
∣
s
t
)
/
b
(
a
t
∣
s
t
)
\frac{\sum{π(a_t|s_t)/ b(a_t|s_t)}\cdot G_t}{\sum{π(a_t|s_t)/ b(a_t|s_t)}}
∑π(at∣st)/b(at∣st)∑π(at∣st)/b(at∣st)⋅Gt,
为什么需要加权重要度采样,是普通重要的采样的偏差是无界的,正如我们前文所说,我们需要保证收敛的条件是方差有界,但是显然这里是无法保证这个点的,那么自然无法使用大数定律来家保证收敛性
6.3 离轨方法的控制
离轨方法的策略控制的问题,最主要的方式还是前面的GPI的形式,只是额外多了一些要求,一个就是要求行动策略b是软性的,确保所有的动作都有被访问到的可能性,一个是使用合适的重要度采样来实现期望和方差的控制
6.4 折扣敏感的重要度采样 DAIS
这个地方我看了很久才敏感他的核心的想要讲解的是什么,回到我们的普通重要度采样时候,开始讨论折扣敏感度采样之前,让我回顾下普通重要度采样上进行估算的公式
ρ
t
:
H
⋅
G
t
\rho_{t:H}\cdot G_t
ρt:H⋅Gt,所以对于任意的
G
t
G_t
Gt,只要t到H步数足够多,那么会导致这个方差变得非常的恐怖
我们考虑一个核心的问题,回报里面显然包含了t+2时刻的R,但是实际上这个t+2时刻的R,在重要度采样里面也乘以了t+2以后所有的比率的积,这个是有问题的
考虑
G
t
G_t
Gt的折扣问题
γ
\gamma
γ,对于任意一个
G
t
G_t
Gt,我们将其变成带
γ
\gamma
γ的形式,然后只在这个真正对这个回报产生影响的
ρ
\rho
ρ才乘进来,我们将回报的
γ
\gamma
γ放到和
ρ
\rho
ρ一起,得到公式如下(巨长)
V
(
s
)
=
∑
t
∈
τ
(
s
)
(
(
1
−
γ
)
∑
h
=
t
+
1
T
(
t
)
−
1
γ
h
−
(
t
+
1
)
ρ
t
:
h
−
1
G
ˉ
t
:
h
+
γ
T
(
t
)
−
(
t
+
1
)
ρ
t
:
T
(
t
)
−
1
G
ˉ
t
:
T
(
t
)
)
∣
τ
(
s
)
∣
V(s) = \frac{\sum_{t \in \tau(s)}((1-\gamma)\sum_{h=t+1}^{T(t) -1}\gamma^{h-(t+1)}\rho_{t:h-1}\bar G_{t:h } + \gamma^{T(t) -(t+1)}\rho_{t:T(t) -1}\bar G_{t:T(t)})}{|\tau(s)|}
V(s)=∣τ(s)∣∑t∈τ(s)((1−γ)∑h=t+1T(t)−1γh−(t+1)ρt:h−1Gˉt:h+γT(t)−(t+1)ρt:T(t)−1Gˉt:T(t))
其中
G
ˉ
t
:
h
=
R
t
+
1
+
R
t
+
2
+
.
.
.
+
R
h
\bar G_{t:h }=R_{t+1} +R_{t+2} + ... + R_h
Gˉt:h=Rt+1+Rt+2+...+Rh,称之为平价部分回报
讲解一下这个公式,和之前最大的区别在于单个
ρ
\rho
ρ只是在对应的回报才会有影响,而不是直接对整体的
G
t
G_t
Gt有效
显然这个可以显著的减少对应的方差,例如我们前面讨论过,之前的方差是无解的,但是如果这里考虑一个极端的情况,我们假设单个
ρ
\rho
ρ有上界C,只要保证选取合适的gamma使得C*
γ
\gamma
γ < 1时,则可以得到一个有界的方差,从而保证收敛性。
当然即使在不能保证有界的情况下,使用 γ \gamma γ衰减也会显著的减少方差的值
加权的折扣敏感的重要度采样的公式,怎么说呢,这复杂度谁爱用谁用吧~~~~
V
(
s
)
=
∑
t
∈
τ
(
s
)
(
(
1
−
γ
)
∑
h
=
t
+
1
T
(
t
)
−
1
γ
h
−
(
t
+
1
)
ρ
t
:
h
−
1
G
ˉ
t
:
h
+
γ
T
(
t
)
−
(
t
+
1
)
ρ
t
:
T
(
t
)
−
1
G
ˉ
t
:
T
(
t
)
)
∑
t
∈
τ
(
s
)
(
(
1
−
γ
)
∑
h
=
t
+
1
T
(
t
)
−
1
γ
h
−
(
t
+
1
)
ρ
t
:
h
−
1
+
γ
T
(
t
)
−
(
t
+
1
)
ρ
t
:
T
(
t
)
−
1
)
V(s) = \frac{\sum_{t \in \tau(s)}((1-\gamma)\sum_{h=t+1}^{T(t) -1}\gamma^{h-(t+1)}\rho_{t:h-1}\bar G_{t:h } + \gamma^{T(t) -(t+1)}\rho_{t:T(t) -1}\bar G_{t:T(t)})}{\sum_{t \in \tau(s)}((1-\gamma)\sum_{h=t+1}^{T(t) -1}\gamma^{h-(t+1)}\rho_{t:h-1}+ \gamma^{T(t) -(t+1)}\rho_{t:T(t) -1})}
V(s)=∑t∈τ(s)((1−γ)∑h=t+1T(t)−1γh−(t+1)ρt:h−1+γT(t)−(t+1)ρt:T(t)−1)∑t∈τ(s)((1−γ)∑h=t+1T(t)−1γh−(t+1)ρt:h−1Gˉt:h+γT(t)−(t+1)ρt:T(t)−1Gˉt:T(t))