04.md 30.6 KB
Newer Older
W
wizardforcel 已提交
1
# 策略梯度
W
wizardforcel 已提交
2

W
wizardforcel 已提交
3
到目前为止,我们已经看到了如何使用基于值的方法从值函数中派生隐式策略。 在这里,智能体将尝试直接学习策略。 做法是相似的,任何有经验的智能体都会在目睹之后更改策略。
W
wizardforcel 已提交
4

W
wizardforcel 已提交
5
值迭代,策略迭代和 Q 学习属于通过动态编程解决的基于值的方法,而策略优化方法则涉及策略梯度和该知识与策略迭代的结合,从而产生了行动者批判算法。
W
wizardforcel 已提交
6

W
wizardforcel 已提交
7
根据动态编程方法,存在一组自洽方程,可以满足`Q``V`值。 策略优化是不同的,策略学习直接进行,而不是从值函数中得出:
W
wizardforcel 已提交
8 9 10

![](img/783c3d44-900b-4334-a5e6-b4a2a297a1a8.png)

W
wizardforcel 已提交
11
因此,基于值的方法学习了值函数,我们得出了一个隐式策略,但是使用基于策略的方法,就不会学习任何值函数,而直接学习了该策略。 由于我们同时学习了值函数和策略,而行为者批评方法更为先进,而网络学习值函数则充当了作为参与者的策略网络的批评者。 在本章中,我们将深入研究基于策略的方法。
W
wizardforcel 已提交
12 13 14

我们将在本章介绍以下主题:

W
wizardforcel 已提交
15 16
*   策略优化方法
*   为什么要采用策略优化方法?
W
wizardforcel 已提交
17
*   策略目标函数
W
wizardforcel 已提交
18
*   时差规则
W
wizardforcel 已提交
19
*   策略梯度
W
wizardforcel 已提交
20
*   使用策略梯度的智能体学习 Pong
W
wizardforcel 已提交
21

W
wizardforcel 已提交
22
# 策略优化方法
W
wizardforcel 已提交
23

W
wizardforcel 已提交
24
策略优化方法的目标是找到随机策略`π[θ]`,它是针对给定状态的操作分布,该状态使期望的奖励总和最大化。 它旨在直接找到该策略。 基本概述是创建一个神经网络(即策略网络),该网络处理一些状态信息并输出智能体可能采取的行动的分布。
W
wizardforcel 已提交
25 26 27

策略优化的两个主要组成部分是:

W
wizardforcel 已提交
28
*   神经网络的权重参数由`θ`向量定义,这也是我们控制策略的参数。 因此,我们的目标是训练权重参数以获得最佳策略。 由于我们将保单视为给定保单的预期奖励总和。 在此,对于`θ`的不同参数值,策略将有所不同,因此,最佳策略将是具有最大总体奖励的策略。 因此,具有最大预期奖励的`θ`参数将是最佳策略。 以下是预期奖励金额的公式:
W
wizardforcel 已提交
29 30 31 32 33

![](img/b0592927-b05c-471e-a9f1-18b6c1bedaa4.png)

那就是最大化期望的奖励总和。

W
wizardforcel 已提交
34
这里, `H`地平线的时间步长,因此,如果开始时间步长`t = 0`,则总时间步长为`H + 1`
W
wizardforcel 已提交
35

W
wizardforcel 已提交
36
*   随机策略类消除了策略优化问题,为我们提供了一组可以选择最佳策略的策略。 在网格世界环境中采用确定性策略的情况下,由于动作变化而导致的变化并不平滑,但是如果每个州都有动作分布,我们可以稍微改变分布,而这只会稍微改变预期的总和。 奖励。 这是使用随机策略的优势,其中`π[θ](a | s)`给出给定状态`s`的动作`a`的概率。 因此,`π[θ]`给出了给定状态下动作的概率分布。
W
wizardforcel 已提交
37 38 39

因此,由于随机策略,我们有一个平滑的优化问题,可以应用梯度下降来获得良好的局部最优,从而导致最优策略。

W
wizardforcel 已提交
40
# 为什么要采用策略优化方法?
W
wizardforcel 已提交
41

W
wizardforcel 已提交
42
在本节中,我们将介绍策略优化方法相对于基于值的方法的优缺点。 优点如下:
W
wizardforcel 已提交
43 44

*   它们提供了更好的融合。
W
wizardforcel 已提交
45
*   在高维/连续状态动作空间的情况下,它们非常有效。 如果动作空间很大,则基于值的方法中的`max`函数将在计算上昂贵。 因此,基于策略的方法通过更改参数来直接更改策略,而不是在每个步骤中求解`max`函数。
W
wizardforcel 已提交
46 47 48 49 50
*   学习随机策略的能力。

与基于策略的方法相关的缺点如下:

*   收敛到局部而不是全局最优
W
wizardforcel 已提交
51
*   策略评估效率低下且差异很大
W
wizardforcel 已提交
52 53 54

我们将在本章后面讨论解决这些缺点的方法。 现在,让我们集中讨论对随机策略的需求。

W
wizardforcel 已提交
55
# 为什么采用随机策略?
W
wizardforcel 已提交
56

W
wizardforcel 已提交
57
让我们看两个例子,这些例子将解释基于值方法将随机策略与接近确定性策略相结合的重要性。
W
wizardforcel 已提交
58

W
wizardforcel 已提交
59
# 示例 1-石头,剪刀,布
W
wizardforcel 已提交
60

W
wizardforcel 已提交
61
石头,剪刀,布是两人游戏,包含以下规则:
W
wizardforcel 已提交
62

W
wizardforcel 已提交
63 64 65
*   石头打剪刀
*   剪刀打布
*   布打石头
W
wizardforcel 已提交
66 67 68

因此,不可能有确定的策略来取胜。 说,如果有确定性的策略,那摇滚总是赢家,但是如果对手有剪刀,情况就是这样。 但是,当对手拿到纸时,石头就被击败了。 因此,在这种环境下无法确定解决方案。 解决此问题的唯一方法是使用本质上是随机的统一随机策略。

W
wizardforcel 已提交
69
# 示例 2-名为网格世界的状态
W
wizardforcel 已提交
70 71 72 73 74

考虑以下别名为 grid-world 的状态:

![](img/c3a614ea-6981-49ca-b3a3-65614cdb7db6.png)

W
wizardforcel 已提交
75
在上图中,我们看到有八个状态,其中两个奖励为 -10 的状态是要避免的不良状态,并且有一个奖励为 10 的状态是良好状态,还有目标状态。 但是,我们主要担心的是灰色阴影状态,在该状态下,智能体无法区分这两个状态,因为它们具有相同的特征。
W
wizardforcel 已提交
76

W
wizardforcel 已提交
77
假设任何状态的特征都为`φ(s, a)`,动作为北,东,西和南。
W
wizardforcel 已提交
78

W
wizardforcel 已提交
79
考虑到这些函数,让我们比较基于值的方法和基于策略的方法:
W
wizardforcel 已提交
80

W
wizardforcel 已提交
81 82
*   基于值的强化学习将使用近似值函数`Q(s, a) = f(φ(s, a), w)`
*   基于策略的强化学习将使用参数化策略`π[θ](s, a) = g(φ(s, a), θ)`
W
wizardforcel 已提交
83

W
wizardforcel 已提交
84
在此,`w`是值函数的参数,`θ`是策略的参数。 众所周知,灰色方块具有相同的特征,即在北部和南部都有墙。 因此,由于相同的特征,这导致状态混淆。 结果,基于值的强化学习方法学习了如下确定性策略:
W
wizardforcel 已提交
85 86 87 88 89 90 91 92 93 94 95 96 97

*   要么在两个灰色阴影状态下向西移动
*   或在两个灰色阴影状态下向东移动

无论哪种方式,都极有可能被卡住或花费很长时间达到目​​标状态。

另一方面,在基于策略的方法的情况下,最优随机策略将随机选择处于灰色状态的东西方行为,因为这两种行为具有以下相同的概率:

*   ![](img/6a5d3643-6236-4ad0-beb6-3a15a52416aa.png)(南北墙,行动=东)= 0.5
*   ![](img/ba7a9786-5034-4fb6-9c46-7f35d5ce2caf.png)(南北墙,行动=西)= 0.5

结果,它将以更少的步骤达到目标状态,因为西方和东方都将具有相同的发生概率。 因此,与基于值的强化学习方法相比,不同的灰色阴影状态可能会随机发生不同的动作,从而导致目标状态更快。 因此,基于策略的强化学习可以学习最佳的随机策略。

W
wizardforcel 已提交
98
因此,从前面的示例中,我们已经知道,每当发生状态别名时,随机策略都可以执行得更好。 因此,只要存在状态混叠的情况(即环境的表示),就会部分观察状态(例如,您处于部分可观察的马尔可夫决策过程中)或函数逼近器使用状态的特征,这会限制环境的整体视角,使用基于随机策略的基于策略的方法要比基于值的方法要好。
W
wizardforcel 已提交
99

W
wizardforcel 已提交
100
# 策略目标函数
W
wizardforcel 已提交
101

W
wizardforcel 已提交
102
现在让我们讨论如何优化策略。 在策略方法中,我们的主要目标是具有参数向量`θ`的给定策略`J(θ)`找到参数向量的最佳值。 为了测量哪个最好,我们针对参数向量`θ`的不同值测量`J(θ)`策略`π[θ](s, a)`的质量。
W
wizardforcel 已提交
103

W
wizardforcel 已提交
104
在讨论优化方法之前,让我们首先弄清楚度量策略`π[θ](s, a)`的质量的不同方法:
W
wizardforcel 已提交
105

W
wizardforcel 已提交
106
*   如果是情景环境,则`J(θ)`可以是开始状态`V[π[θ]](s[1])`的值函数,也就是说,如果它从任何状态`s[1]`开始,则其值函数将是该状态开始时的预期奖励总和 。 因此,
W
wizardforcel 已提交
107 108 109

![](img/01578517-3d8f-4227-a234-94a8e6fc9985.png)

W
wizardforcel 已提交
110
*   如果是连续环境,则`J(θ)`可以是状态的平均值函数。 因此,如果环境持续不断,那么策略质量的衡量标准可以是处于任何状态`s`的概率之和,该概率是`d[π[θ]](s)`乘以该状态的值,也就是说,从该状态开始的预期奖励。 因此,
W
wizardforcel 已提交
111 112 113

![](img/2cfba9ad-f36c-4239-80f2-8c4acd2b5738.png)

W
wizardforcel 已提交
114
*   对于连续环境,`J(θ)`可以是每个时间步长的平均奖励,它是处于任何状态`s`的概率的总和,即`d[π[θ]](s)`乘以对该状态的不同动作的期望奖励`E[R[s]^a] = Σ[a] π[θ](s, a) R[s]^a`的总和。 因此:
W
wizardforcel 已提交
115 116 117

![](img/d42506b9-9710-4ec3-93a3-50c62b3b2991.png)

W
wizardforcel 已提交
118
在此,`R[s]^a`是在状态`s`采取行动`a`的奖励。
W
wizardforcel 已提交
119

W
wizardforcel 已提交
120
到目前为止,我们知道基于策略的强化学习是一个优化问题,目标是找到使`J(θ)`最大化的`θ`。 同样,在这里,我们将使用基于梯度的方法进行优化。 使用基于梯度的优化的原因是要获得更高的效率,因为与无梯度方法相比,梯度指向了更高效率的方向。
W
wizardforcel 已提交
121

W
wizardforcel 已提交
122 123
让衡量策略质量的``J(θ)``成为我们的策略目标函数。 因此,策略梯度算法通过相对于参数`θ`提升策略的梯度,在`J(θ)`中寻找局部最大值。 这是因为我们的目标是使`J(θ)`相对于`θ`最大化,因此我们进行了梯度上升,其中
`Δθ`的参数的增量如下:
W
wizardforcel 已提交
124 125 126

![](img/9ff648e7-9f6f-4a44-a52f-7d749cb6e1cf.png)

W
wizardforcel 已提交
127
在这里,`ᐁ[θ] J(θ)`是策略梯度,`α`是学习率,也称为**步长参数**,步长参数决定该参数应在每个步长上偏移多少梯度。 策略梯度还可以用以下形式阐述:
W
wizardforcel 已提交
128 129 130 131 132

![](img/0d918775-9864-4b04-9b05-f59c0941e222.png)

# 策略梯度定理

W
wizardforcel 已提交
133
假设给定策略`π[θ](s, a)`每当不为零时都是可微的,则给定策略相对于`θ`的梯度为`ᐁ[θ] π[θ](s, a)`。 因此,我们可以以似然比的形式进一步利用此梯度量,如下所示:
W
wizardforcel 已提交
134 135 136

![](img/0af8a486-8579-4e97-8e22-ec4b276714f5.png)

W
wizardforcel 已提交
137
此处,`ᐁ[θ] log π[θ](s, a)`是得分函数,供将来参考。
W
wizardforcel 已提交
138

W
wizardforcel 已提交
139
现在,让我们考虑一个简单的一步式 MDP,即马尔可夫决策过程,其中:
W
wizardforcel 已提交
140

W
wizardforcel 已提交
141 142
*   起始状态为`s`,发生的可能性为`d[π[θ]](s)`
*   终止仅发生在获得奖励`r = R[s]^a`的一步之后
W
wizardforcel 已提交
143 144 145 146 147

考虑到它是一个持续的环境,因此:

![](img/a8296a39-e2c7-4a1e-a8c4-02e15df4fd4e.png)

W
wizardforcel 已提交
148
因此,策略梯度`ᐁ[θ] J(θ)`将如下所示:
W
wizardforcel 已提交
149 150 151 152 153 154 155 156 157 158 159

![](img/ba08ca33-c4b3-4d33-85f9-cd7ee7413342.png)

在这里,我们证明了以下几点:

![](img/0c0c9dc6-9641-4931-855c-216477a3a009.png)

结果是:

![](img/b6666854-9607-4fcd-9536-6ad2779a7ffd.png)

W
wizardforcel 已提交
160
因此,将该方法推广到多步马尔可夫决策过程将导致状态奖励 Q 值函数`Q[π](s, a)`代替瞬时奖励`r`。 这称为**策略梯度定理**。 该定理对前面讨论的其他类型的策略目标函数有效。 因此,对于任何这样的策略目标函数和任何可区分的`π[θ](s, a)`,策略梯度如下:
W
wizardforcel 已提交
161 162 163 164 165

![](img/22aa628a-e90d-49c5-ae2d-c8f5e168393c.png)

# 时差规则

W
wizardforcel 已提交
166
首先,**时间差****TD**)是两个时间步之间的值估计值之差。 这与基于结果的蒙特卡洛方法不同,后者基于前瞻性的观点直到情节结束才完成,以更新学习参数。 在时间差异学习的情况下,仅需完成一个步骤,而下一步的状态值估计将用于更新当前状态的值估计。 因此,学习参数会不断更新。 进行时差学习的不同规则是`TD(1)``TD(0)``TD(λ)`规则。 所有方法中的基本概念是,下一步的值估计用于更新当前状态的值估计。
W
wizardforcel 已提交
167

W
wizardforcel 已提交
168
# `TD(1)`规则
W
wizardforcel 已提交
169

W
wizardforcel 已提交
170
`TD(1)`纳入了资格跟踪的概念。 让我们看一下该方法的伪代码,然后将详细讨论它:
W
wizardforcel 已提交
171 172 173 174 175 176 177 178 179 180 181 182

```py
Episode T
    For all s, At the start of the episode : e(s) = 0 and 
        After  : (at step t)

        For all s,

```

每个`Episode T`都以以下初始化开始:

W
wizardforcel 已提交
183
*   对于所有状态`s`,合格分数`e(s) = 0`
W
wizardforcel 已提交
184
*   对于所有状态`s`,给定`Episode T`中的状态值`V[T](s)`等于`V[T-1](s)`
W
wizardforcel 已提交
185

W
wizardforcel 已提交
186
在情节的每个时间步,即当前步`t`,我们更新要离开的状态`s[t-1]`的资格,然后为所有状态更新以下内容:
W
wizardforcel 已提交
187

W
wizardforcel 已提交
188
*   针对当前离开状态`s[t-1]`(即`r[t] + γ V[T-1](s[t]) + V[T-1](s[t-1])`)和要更改其值的状态的合格分数`e(s)`使用时间差误差的状态值函数
W
wizardforcel 已提交
189
*   通过给定折扣系数进行折扣的资格分数
W
wizardforcel 已提交
190 191 192

由于这些更新针对所有状态独立发生,因此可以针对所有状态并行执行这些操作。

W
wizardforcel 已提交
193
在完成情节的最后一步之后扩展每个州的计算值估计值时,我们发现基于值的更新与基于结果的更新相同,例如在蒙特卡洛方法中,我们会进行全面的展望,直到剧集的结尾。 因此,我们需要一种更好的方法来更新我们的值函数估计值,而无需多做一步。 通过合并`TD(0)`规则,我们可以解决此问题。
W
wizardforcel 已提交
194

W
wizardforcel 已提交
195
# `TD(0)`规则
W
wizardforcel 已提交
196

W
wizardforcel 已提交
197
如果无限重复重复有限数据,则`TD(0)`规则会找到值估计值,通常就是如果我们获取此有限数据并不断重复运行以下估计值更新规则。 然后,实际上我们正在平均每个转换。
W
wizardforcel 已提交
198 199 200 201 202 203 204

![](img/262fb91d-f5d6-4d42-97fc-710d525ac99f.png)

因此,值函数由以下给出:

![](img/49b93224-b17b-4deb-b5cf-bf76e9eb19db.png)

W
wizardforcel 已提交
205
在基于结果的模型中,这是不正确的,在该模型中,我们不使用状态估计值`V[T](s[t])`,而是使用整个奖励序列,直到事件结束为止。 因此,在蒙特卡洛方法基于结果的模型的情况下,值函数由以下公式给出:
W
wizardforcel 已提交
206 207 208

![](img/24c5dac2-f8c8-45a1-b87c-bf33254da2aa.png)

W
wizardforcel 已提交
209
此外,在基于结果的方法中,我们只看到一个序列,重复该过程不会更改值函数的值。 但是,在`TD(0)`的情况下,每一步都会根据中间状态计算和完善值函数估计。
W
wizardforcel 已提交
210

W
wizardforcel 已提交
211
`TD(0)``TD(1)`之间的区别是,在`TD(1)`情况下使用资格跟踪更新状态值函数,而在`TD(0)`情况下则不使用。
W
wizardforcel 已提交
212

W
wizardforcel 已提交
213
`TD(0)`规则的伪代码如下:
W
wizardforcel 已提交
214 215 216 217 218 219 220 221 222

```py
Episode T
    For all s, At the start of the episode : 
        After  : (at step t)
        For s = ,

```

W
wizardforcel 已提交
223
因此,这里我们仅使用时间差误差`r[t] + γ V[T-1](s[t]) + V[T-1](s[t-1])`更新当前离开状态`s[t-1]`的值函数。
W
wizardforcel 已提交
224

W
wizardforcel 已提交
225
# `TD(λ)`规则
W
wizardforcel 已提交
226

W
wizardforcel 已提交
227
`TD(1)``TD(0)`规则产生一个通用规则,即`TD(λ)`,因此对于`λ ∈ [0, 1]`并应满足以下条件:
W
wizardforcel 已提交
228

W
wizardforcel 已提交
229 230
*   如果`λ = 0`,则`TD(λ)`趋于`TD(0)`
*   如果`λ = 1`,则`TD(λ)`趋于`TD(1)`
W
wizardforcel 已提交
231

W
wizardforcel 已提交
232
`TD(0)``TD(1)`都基于时间连续预测之间的差异进行更新。
W
wizardforcel 已提交
233

W
wizardforcel 已提交
234
因此,`TD(λ)`的伪代码如下:
W
wizardforcel 已提交
235 236 237 238 239 240 241 242 243 244

```py
Episode T
    For all s, At the start of the episode : e(s) = 0 and 
        After  : (at step t)

        For all s,

```

W
wizardforcel 已提交
245
这满足前面两个条件,并且可以合并`λ ∈ [0, 1]`的任何值。
W
wizardforcel 已提交
246

W
wizardforcel 已提交
247
# 策略梯度
W
wizardforcel 已提交
248

W
wizardforcel 已提交
249
根据策略梯度定理,对于先前指定的策略目标函数和任何可微分策略`π[θ](s, a)`,策略梯度如下:
W
wizardforcel 已提交
250 251 252 253 254

![](img/406f3ccb-146a-485c-b05a-89a8f4d935cd.png)

下一节显示了使用基于蒙特卡洛策略梯度的方法更新参数的步骤。

W
wizardforcel 已提交
255
# 蒙特卡洛策略梯度
W
wizardforcel 已提交
256

W
wizardforcel 已提交
257
**蒙特卡洛策略梯度**方法中,我们使用随机梯度上升方法更新参数,并按照策略梯度定理进行更新,并使用`v[t]`作为`Q[π[θ]](s[t], a[t])`的无偏样本。 在此,`v[t]`是从该时间步开始的累计奖励。
W
wizardforcel 已提交
258

W
wizardforcel 已提交
259
蒙特卡洛策略梯度法如下:
W
wizardforcel 已提交
260 261 262 263 264 265 266 267 268 269 270 271

```py
Initialize  arbitrarily
for each episode as per the current policy  do
    for step t=1 to T-1 do

    end for
end for

Output: final 
```

W
wizardforcel 已提交
272
# 演员评论家算法
W
wizardforcel 已提交
273 274 275 276 277

先前使用蒙特卡洛策略梯度方法进行的策略优化导致较大的差异。 为了解决此问题,我们使用评论家来估计状态作用值函数,如下所示:

![](img/bdee56e7-7167-4d77-a478-710505461008.png)

W
wizardforcel 已提交
278
这产生了著名的**演员评论家算法**。 顾名思义,演员评论家算法出于以下目的维护两个网络:
W
wizardforcel 已提交
279

W
wizardforcel 已提交
280
*   一个网络充当评论者,它更新状态动作函数逼近器的权重`w`参数向量
W
wizardforcel 已提交
281
*   其他网络充当演员,它根据批评者给出的方向更新策略参数向量`θ`
W
wizardforcel 已提交
282

W
wizardforcel 已提交
283
下图代表了演员评论家算法:
W
wizardforcel 已提交
284 285 286

![](img/ca78b5e5-1459-4f34-ad61-de744f663054.png)

W
wizardforcel 已提交
287
因此,在执行者批评算法的情况下,实际策略梯度公式中的真实状态作用值函数`Q[π[θ]](s, a)`被替换为近似状态作用值函数`Q[w](s, a)`。 因此:
W
wizardforcel 已提交
288

W
wizardforcel 已提交
289 290 291
![](img/d8b7251d-91aa-4183-add1-5a5a0f9f8d0c.png)

并且:
W
wizardforcel 已提交
292 293 294

![](img/d9896c48-a57d-45e1-974e-3d9bed7c4af3.png)

W
wizardforcel 已提交
295
因此,为了估计状态作用值函数,评论者网络使用`TD(0)`(先前讨论)来更新权重参数`w`,并更新策略参数向量`θ`演员网络使用策略梯度。 演员评论家算法的一种简单方法如下所示:
W
wizardforcel 已提交
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310

```py
Initialize s, 
for each episode
    Sample  as per the current policy     
    for each step do 
        Take action  and observe reward  and next state 
        Sample action  as per the current policy 

    end for
end for

Output : final 
```

W
wizardforcel 已提交
311
因此,我们可以看到参与者评论家既具有基于值的优化又具有基于策略的优化。 因此,在采用蒙特卡洛策略梯度法的情况下,策略改进会贪婪地进行。 但是在演员批评家中,演员通过按照批评家的方向采取措施来更新策略参数,以便制定更好的策略。
W
wizardforcel 已提交
312

W
wizardforcel 已提交
313
# 使用基线减少方差
W
wizardforcel 已提交
314 315 316 317 318 319 320 321 322 323 324 325 326

除了我们最初使用行为准则的方法来减少方差之外,我们还可以通过从策略梯度中减去**基线函数** ![](img/57466ce5-670a-4989-9de6-c43208771e1b.png)来减少方差。 这将减少方差而不影响期望值,如下所示:

![](img/3564b3a4-9d0f-4cc2-87a6-a3ae59c46f7e.png)

有许多选择基线函数的选项,但是状态值函数被认为是很好的基线函数。 因此:

![](img/b0a2160a-823c-437d-a1a1-64413a9be3cc.png)

因此,我们可以通过减去基线函数来重写策略梯度公式,如下所示:

![](img/e4d88794-1d88-4b34-89cb-b726ea224273.png)

W
wizardforcel 已提交
327
在这里,`Q[π[θ]](s, a) - A[π[θ]](s)`被称为**优势函数**`A[π[θ]](s, a)`。 因此,策略梯度公式变为:
W
wizardforcel 已提交
328 329 330 331 332

![](img/5b410fc8-1d5b-4a36-9250-730d1a651b86.png)

因此,通过使用基线函数,期望值受到方差降低的控制,而方向没有任何变化。

W
wizardforcel 已提交
333
# 原始策略梯度
W
wizardforcel 已提交
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350

在常规策略梯度方法中,目标是使用策略梯度估计和更好的基线估计来更新策略。

以下是实现原始策略梯度以找到最佳策略的伪代码:

```py
Initialize: Policy parameter , and baseline b
for iteration = 1,2,......N   do
        Collect a set of trajectories using the current policy
        At each time step t in each trajectory, compute the following:
            returns ,and
            advantage estimate 
        Refit the baseline function 

end for
```

W
wizardforcel 已提交
351
# 使用策略梯度的学习 Pong 的智能体
W
wizardforcel 已提交
352

W
wizardforcel 已提交
353
在本节中,我们将创建一个策略网络,该策略网络将使用来自 pong 环境的原始像素(来自 OpenAI Gym 的 **pong-v0**)作为输入。 策略网络是一个单独的隐藏层神经网络,它全连接到输入层上 pong 的原始像素,还全连接到包含单个节点的输出层,该单个节点返回了桨上升的可能性。 我要感谢 Andrej Karpathy 提出了一种使智能体使用策略梯度进行学习的解决方案。 我们将尝试实现类似的方法。
W
wizardforcel 已提交
354

W
wizardforcel 已提交
355
灰度大小为`80 * 80`的像素图像(我们将不使用 RGB,即`80 * 80 * 3`)。 因此,我们有一个`80 * 80`的二进制网格,它告诉我们桨和球的位置,并将其作为输入输入到神经网络。 因此,神经网络将包含以下内容:
W
wizardforcel 已提交
356

W
wizardforcel 已提交
357
*   **输入层(`X`)**:将`80 * 80`压缩为`6400 * 1`,即 6400 个节点
W
wizardforcel 已提交
358 359 360 361 362
*   **隐藏层**:200 个节点
*   **输出层**:1 个节点

因此,总参数如下:

W
wizardforcel 已提交
363 364
*   **连接输入层和隐藏层的权重和偏置**`6400 * 200`(权重)`+ 200`(偏置)参数
*   **连接隐藏层和输出层的权重和偏置**`200 * 1`(权重)`+ 1`(偏置)参数
W
wizardforcel 已提交
365 366 367

因此,总参数将约为 130 万。

W
wizardforcel 已提交
368
这是巨大的,因此训练需要几天的时间才能见证您的经纪人流畅地打乒乓球。
W
wizardforcel 已提交
369

W
wizardforcel 已提交
370
不能从静态帧播放 Pong,因此,需要捕获某种运动信息,可以通过连接两个这样的帧或新帧与前一帧之间的差异来完成。 因为我们没有使用卷积神经网络,所以除了 6400 个像素值在 0 和 1 之间翻转之外,没有可用的空间信息。 而不是桨和球的位置。
W
wizardforcel 已提交
371

W
wizardforcel 已提交
372
训练 130 万个参数的有效计算方法是使用策略梯度。 您可以将其与监督学习相关联,其中针对每个状态都提到了一个动作标签。 因此,数据和训练如下:
W
wizardforcel 已提交
373 374 375

![](img/297c6703-97ca-4ba2-8e19-70dabec7b4a1.png)

W
wizardforcel 已提交
376
但是,实际上我们没有标签。 因此,我们将实现强化学习,在其中我们将尝试许多任务并记下观察结果。 然后,更频繁地执行表现更好的任务。
W
wizardforcel 已提交
377 378 379 380

在输入 Python 代码之前,让我们放下步骤。 它们如下:

1.  初始化随机策略。
W
wizardforcel 已提交
381
2.  对于给定的当前策略,我们将通过以下方式收集不同的样本轨迹(展示):
W
wizardforcel 已提交
382
    1.  运行游戏的一个剧集并捕获该剧集的轨迹。
W
wizardforcel 已提交
383 384 385
    2.  同样,收集一批轨迹,如下所示:

| **轨迹** | **游戏结果** | **轨迹好/坏** |
W
wizardforcel 已提交
386 387 388 389 390
| --- | --- | --- |
| 上,下,上,上,下,下,下,上 | 输 | 坏 |
| 下,上,上,下,上,上 | 赢 | 好 |
| 上,上,下,下,下,下,上 | 输 | 坏 |
| 下,上,上,下,上,上 | 赢 | 好 |
W
wizardforcel 已提交
391

W
wizardforcel 已提交
392
因此,我们能够创建示例数据,在这些示例中,我们认为赢得的案例是该操作的正确标签。 因此,我们将增加这些动作的对数概率,即`log p(y[i], x[i])`,并且丢失每个动作的情况将被视为错误标签。 因此,在这些情况下,我们将减少这些操作的对数概率。
W
wizardforcel 已提交
393

W
wizardforcel 已提交
394
因此,在收集了一批轨迹之后,我们将最大化优势与对数概率的乘积,即`Σ[i] A[i] x log p(y[i], x[i])`
W
wizardforcel 已提交
395

W
wizardforcel 已提交
396
在此,`A[i]`是与状态操作对关联的优势。 优势是一个标量,它量化了操作最终的效果。 如果我们想在将来鼓励给定的行动,则`A[i]`会很高,而如果我们想阻止该行动,则`A[i]`会很低。 正优势使该状态的将来更有可能发生该行为,而负优势使该状态的将来不太可能发生该行为。
W
wizardforcel 已提交
397 398 399 400 401 402 403 404 405 406

首先,我们将导入所需的重要依赖项,如下所示:

```py
#import dependencies
import numpy as np #for matrix math
import cPickle as pickle #to save/load model
import gym
```

W
wizardforcel 已提交
407
*   **超参数初始化**:由于我们正在使用`RMSProp`优化器进行梯度下降,因此超参数(例如隐藏层节点的数量,批量大小,学习率,折扣系数`gamma`,衰减率)。 我们将使用以下代码进行初始化:
W
wizardforcel 已提交
408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434

```py
#hyperparameters
H = 200 #number of nodes in the hidden layer
batch_size = 10 
learning_rate = 1e-4 
gamma = 0.99 #discount factor
decay_rate = 0.99 #for RMSProp Optimizer for Gradient Descent
resume = False #to resume from previous checkpoint or not
```

*   **策略神经网络模型初始化**:策略神经网络的权重参数的初始化。 在这里,我们使用一个隐藏层神经网络。 我们将使用以下代码进行初始化:

```py
#initialize : init model
D = 80*80 #input dimension
if resume:
    model = pickle.load(open('model.v','rb'))
else:
    model = {}
    #xavier initialisation of weights
    model['W1'] = np.random.randn(H,D)*np.sqrt(2.0/D)
    model['W2'] = np.random.randn(H)*np.sqrt(2.0/H)
    grad_buffer = {k: np.zeros_like(v) for k,v in model.iteritems()} #to store our gradients which can be summed up over a batch
    rmsprop_cache = {k: np.zeros_like(v) for k,v in model.iteritems()} #to store the value of rms prop formula
```

W
wizardforcel 已提交
435
*   **激活函数**`sigmoid(x)``relu(x)`分别指执行 Sigmoid 和 ReLU 激活计算的函数。 我们将使用以下代码定义函数:
W
wizardforcel 已提交
436 437 438 439 440 441 442 443 444 445 446

```py
#activation function
def sigmoid(x):
    return 1.0/(1.0+np.exp(-x)) #adding non linearing + squashing

def relu(x):
    x[x<0] = 0
    return x
```

W
wizardforcel 已提交
447
*   **预处理函数**`preprocess(image)`函数将图像像素作为参数,并通过裁剪,下采样,使其成为灰度,擦除背景并将图像展平为一维向量来对其进行预处理。 我们将使用以下代码定义函数:
W
wizardforcel 已提交
448 449 450 451 452 453 454 455 456 457 458 459 460 461

```py
#preprocessing function
def preprocess(image): #where image is the single frame of the game as the input
    """ take 210x160x3 frame and returns 6400 (80x80) 1D float vector """
    #the following values have been precomputed through trail and error by OpenAI team members
    image = image[35:195] #cropping the image frame to an extent where it contains on the paddles and ball and area between them
    immage = image[::2,::2,0] #downsample by the factor of 2 and take only the R of the RGB channel.Therefore, now 2D frame
    image[image==144] = 0 #erase background type 1
    image[image==109] = 0 #erase background type 2
    image[image!=0] = 1 #everything else(other than paddles and ball) set to 1
    return image.astype('float').ravel() #flattening to 1D
```

W
wizardforcel 已提交
462
*   **折扣奖励**`discount_rewards(r)`函数将与不同时间步长对应的奖励列表`r`作为参数,并返回与不同时间步长对应的折扣奖励列表,如以下代码所示 :
W
wizardforcel 已提交
463 464 465 466 467 468 469 470 471 472 473 474 475 476

```py
def discount_rewards(r):
    """ take 1D float array of rewards and compute discounted reward """
    discount_r = np.zeros_like(r)
    running_add = 0 #addition of rewards
    for t in reversed(xrange(0,r.size)):
        if r[t] != 0: #episode ends
            running_add = 0
        running_add = gamma*running_add+r[t]
        discount_r[t] = running_add
    return discount_r
```

W
wizardforcel 已提交
477
*   **正向传播**`policy_forward(x)`函数接收预处理的图像向量`x`,返回动作概率为`UP`,并且向量包含隐藏状态节点的值,例如以下代码:
W
wizardforcel 已提交
478 479 480 481 482 483 484 485 486 487

```py
def policy_forward(x):
    h = np.dot(model['W1'],x) 
    h = relu(h) 
    logit = np.dot(model['W2'],h)
    p = sigmoid(logit)
    return p,h #probability of action 2(that is UP) and hidden layer state that is hidden state
```

W
wizardforcel 已提交
488
*   **反向传播**`policy_backward(arr_hidden_state, gradient_logp, observation_values)`函数采用隐藏状态值,错误`gradient_logp`和观测值来针对不同权重参数计算导数,如以下代码所示:
W
wizardforcel 已提交
489 490 491 492 493 494 495 496 497 498 499 500 501 502

```py
def policy_backward(arr_hidden_state,gradient_logp,observation_values):
    """ backward pass """
    #arr_hidden_state is array of intermediate hidden states shape [200x1]
    #gradient_logp is the loss value [1x1]
    dW2 = np.dot(arr_hidden_state.T,gradient_logp).ravel() 
    # [200x1].[1x1] => [200x1] =>flatten=>[1x200]
    dh = np.outer(gradient_logp,model['W2']) # [1x1]outer[1x200] => [1x200]
    dh = relu(dh) #[1x200]
    dW1 = np.dot(dh.T,observation_values) #[200x1].[1x6400] => [200x6400]
    return {'W1':dW1,'W2':dW2}
```

W
wizardforcel 已提交
503
创建环境并结合先前的函数以使智能体逐步学习多个情节的最终任务如下:
W
wizardforcel 已提交
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582

```py
#implementation details
env = gym.make('Pong-v0')
observation = env.reset()
prev_x = None 
#prev frame value in order to compute the difference between current and previous frame
#as discussed frames are static and the difference is used to capture the motion
#Intially None because there's no previous frame if the current frame is the 1st frame of the game
episode_hidden_layer_values, episode_observations, episode_gradient_log_ps, episode_rewards = [], [], [], []
running_reward = None
reward_sum = 0
episode_number = 0

#begin training
while True:
    env.render()
    #get the input and preprocess it
    cur_x = preprocess(observation)
    #get the frame difference which would be the input to the network
    if prev_x is None:
        prev_x = np.zeros(D)
    x = cur_x - prev_x
    prev_x = cur_x

    #forward propagation of the policy network
    #sample an action from the returned probability
    aprob, h = policy_forward(x)
    #stochastic part
    if np.random.uniform() < aprob:
        action = 2
    else:
        action = 3

    episode_observations.append(x) #record observation
    episode_hidden_layer_values.append(h) #record hidden state
    if action == 2:
        y = 1
    else:
        y = 0

    episode_gradient_log_ps.append(y-aprob) #record the gradient

    #new step in the environment
    observation,reward,done,info = env.step(action)
    reward_sum+=reward #for advantage purpose
    episode_rewards.append(reward) #record the reward

    if done: #if the episode is over
        episode_number+=1

        #stack inputs,hidden_states,actions,gradients_logp,rewards for the episode
        arr_hidden_state = np.vstack(episode_hidden_layer_values)
        gradient_logp = np.vstack(episode_gradient_log_ps)
        observation_values = np.vstack(episode_observations)
        reward_values = np.vstack(episode_rewards)

        #reset the memory arrays
        episode_hidden_layer_values, episode_observations, episode_gradient_log_ps, episode_rewards = [], [], [], []

        #discounted reward computation
        discounted_episoderewards = discount_rewards(reward_values)
        #normalize discounted_episoderewards
        discounted_episoderewards = (discounted_episoderewards - np.mean(discounted_episoderewards))/np.std(discounted_episoderewards) #advantage

        #modulate the gradient with the advantage
        gradient_logp *= discounted_episoderewards

        grad = policy_backward(arr_hidden_state,gradient_logp,observation_values)

        #summing the gradients over the batch size
        for layer in model:
            grad_buffer[layer]+=grad[layer]

        #perform RMSProp to update weights after every 10 episodes
        if episode_number % batch_size == 0:
            epsilon = 1e-5
            for weight in model.keys():
                g = grad_buffer[weight] #gradient
W
wizardforcel 已提交
583
                rmsprop_cache[weight] = decay_rate*rmsprop_cache[weight]+(1-decay_rate)`g`2
W
wizardforcel 已提交
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604
                model[weight]+=learning_rate*g/(np.sqrt(rmsprop_cache[weight]) + epsilon)
                grad_buffer[weight] = np.zeros_like(model[weight])

        if running_reward is None:
            running_reward = reward_sum
        else:
            running_reward = running_reward*learning_rate+reward_sum*(1-learning_rate)

        print('Episode Reward : {}, Running Mean Award : {}'.format(reward_sum,running_reward))
        if episode_number % 100 == 0:
            pickle.dump(model,open('model.v','wb'))

        reward_sum = 0
        prev_x = None
        observation = env.reset() #resetting the environment since episode has ended

    if reward != 0: #if reward is either +1 or -1 that is an episode has ended
        print("Episode {} ended with reward {}".format(episode_number,reward))

```

W
wizardforcel 已提交
605
智能体玩的游戏的屏幕截图:
W
wizardforcel 已提交
606 607 608 609 610

![](img/a93603fa-c7c9-450d-9df9-5549bb6fb056.png)

如果您在笔记本电脑上运行先前的代码,则融合可能需要几天的时间。 尝试使用 GPU 驱动的云实例在大约 5-6 个小时内获得更好的结果。

W
wizardforcel 已提交
611
# 总结
W
wizardforcel 已提交
612

W
wizardforcel 已提交
613
在本章中,我们介绍了强化学习中最著名的算法,策略梯度和参与者批评算法。 在制定策略梯度以强化学习中更好的基准测试方面,正在进行大量研究。 策略梯度的进一步研究包括**信任区域策略优化****TRPO**),**自然策略梯度****深度依赖策略梯度****DDPG**),这些内容不在本书的讨论范围之内。
W
wizardforcel 已提交
614 615

在下一章中,我们将研究 Q 学习的基础知识,应用深度神经网络以及更多技术。