由此,我们知道:
Q-learning 的收敛性使用任何探索策略都成立,并且只需要每个状态动作对(s,a)
被无限频繁地执行。
这epsilon-greedy policy
是探索和利用之间的平衡,既保证了收敛性,又保证了良好的性能。但在实际问题中,我们往往需要一些启发式方法来改变学习速度alpha
,以代表更好的回报。否则infinite often
很难满足要求。
我在下面列出一个例子。这是一个经典问题,其中您有一个网格,并且每个单元格中可能有不同的奖励金额。例如,下面显示了一个 4x4 网格,其中每个单元格都包含 的奖励1
,除了左上角的单元格(您有更大的奖励,数量为10
)。一个机器人在网格中移动。合法动作是移动LEFT
、和RIGHT
,但机器人不能移出网格。UP
DOWN
所以我们的状态空间包含 16 个不同的状态,对应于 16 个单元格。由于边界限制,每个州都有不同数量的法律行动。我们的目标是计算最优策略(给定任何状态s
,输出最优动作a
)。
+++++++++++++++++++++
+ 10 + 1 + 1 + 1 +
+++++++++++++++++++++
+ 1 + 1 + 1 + 1 +
+++++++++++++++++++++
+ 1 + 1 + 1 + 1 +
+++++++++++++++++++++
+ 1 + 1 + 1 + 1 +
+++++++++++++++++++++
假设我们使用一个恒定epsilon-greedy policy
的epsilon=0.1
学习率alpha=0.1
。我们从网格上的随机位置开始。每当我们到达左上角时,我们都会再次从一个随机位置重新开始。
下面是运行 200,000 次移动模拟的结果。最左边的块直观地显示了每个单元格的当前贪婪策略。
-->
向右移动
<--
向左移动
^
向上
v
向下移动
因此,您会发现这远非最佳策略。显然,在最优策略中,每个单元格都应该指向左或上,因为我们在位置 有更大的奖励(0,0)
。
v v v v | 2 9 5 4
v v v v | 14 98 75 14
--> v v <-- | 258 3430 3312 245
--> --> <-- <-- | 3270 93143 92978 3191
右边的块显示了到目前为止我们访问每个单元格的次数。您会看到我们大部分的访问都在底部,但我们很少访问顶行。这就是为什么我们还没有达到最优策略的原因。
如果我们将学习率更改为alpha=1/(number of times you visited (s,a) so far)
,我们能够在 20,000 步内达到最优策略(如下所示)。此外,我们访问每个单元格的次数分布更均匀,尽管并不完美。
--> <-- <-- <-- | 34 7997 7697 294
^ ^ ^ <-- | 731 898 524 132
^ ^ ^ ^ | 709 176 88 94
^ ^ ^ ^ | 245 256 96 77
对于具有更多状态的更大问题,例如 10x10 网格,我发现最好使用更大的epsilon
. 例如,下面是在 10x10 网格上移动 80,000 次后的模拟结果epsilon=0.5
。除了右下角之外,它几乎是最佳的。还有一个想法是使用模拟退火来帮助提高 Q-learning 的收敛速度。
v <-- <-- <-- <-- <-- <-- <-- <-- <-- | 19 2500 1464 716 386 274 216 159 121 71
^ <-- <-- <-- <-- v <-- <-- <-- <-- | 9617 11914 3665 1071 580 410 319 225 207 131
^ ^ ^ <-- <-- <-- <-- v <-- <-- | 5355 5716 2662 1675 1465 611 302 183 162 101
^ ^ ^ ^ ^ <-- <-- <-- <-- <-- | 1604 1887 1192 621 1056 882 693 403 206 100
^ ^ ^ ^ ^ ^ ^ <-- <-- <-- | 639 735 731 333 412 399 480 294 172 114
^ ^ ^ <-- ^ ^ ^ <-- <-- ^ | 373 496 640 454 272 266 415 219 107 98
^ ^ ^ ^ ^ ^ ^ ^ <-- ^ | 251 311 402 428 214 161 343 176 114 99
^ ^ ^ ^ <-- --> ^ <-- <-- <-- | 186 185 271 420 365 209 359 200 113 70
^ ^ ^ ^ ^ ^ ^ ^ v v | 129 204 324 426 434 282 235 131 99 74
^ ^ ^ ^ ^ <-- ^ <-- <-- <-- | 100 356 1020 1233 703 396 301 216 152 78
顺便说一句,我的玩具问题的 Python 代码(约 100 行)在这里。