强化学习——基于模型的规划方法扩展
Dyna-Q+和优先级扫描的实现
在上一篇文章中,我们介绍了如何在强化学习环境中建模,以及如何利用该模型加速学习过程。在本文中,我想进一步阐述这个主题,并介绍另外两个算法, Dyna-Q+ 和优先级扫描,这两个算法都基于我们在上一篇文章中学习的 Dyna-Q 方法。(如果你觉得有些游戏设定混乱,请查看我上一篇文章)
在下面的段落中,我们将利用这两种算法来解决两个问题:
- 模型错了怎么办?
- 如何更高效的更新 Q 函数?
模型错了怎么办?
在上一篇文章中,我介绍了一个 Dyna-Maze 的例子,其中的动作是确定性的,代理通过记录它所经历的步骤来学习模型,这是从(currentState, action) -> (nextState, reward)
开始的映射,然后在规划阶段,正在学习的模型被应用n
次以加强学习过程。简而言之,这个过程可以概括为
- 通过经验学习模型
- 充分信任该模型,并应用它来强化价值函数
但是事情并不总是这样,因为环境可能是复杂和动态的。
模型可能是不正确的,因为环境是随机的,并且只有有限数量的样本被观察到,或者因为模型是使用函数近似法学习的,而函数近似法并不完全概括,或者仅仅因为环境已经改变并且其新的行为还没有被观察到。当模型不正确时,规划过程可能会计算出一个次优的策略。
捷径迷宫
考虑一个叫做捷径迷宫的案例,环境是动态变化的。
一个代理从S
出发,目的是尽快到达G
,黑灰色的区域是代理不能通过的区域。左边的图片代表原始设置,我们的代理能够使用 Dyna-Q 方法找到最短的路径,通过棋盘的左侧一直到G
。但是,环境会在某个时间戳发生变化,棋盘最右边的一个快捷方式会打开。在这种设置下,Dyna-Q 代理还能找到最优解吗?
答案是否定的。即使使用ϵ-greedy 方法,代理人总是以一定的概率探索,也不太可能找到从最左边到最右边的最优路径,因为已经学习的 q 函数将总是引导代理人选择左边的路径,并且没有足够强的动机或奖励推动代理人探索其他路径。
Dyna-Q+和实现
如何解决这个问题?其本质是保持代理人能够探索新的状态以适应不断变化的环境,而驱动代理人探索的诀窍是给予奖励。因此,这里我们介绍一下 Dyna-Q+的理论:
代理跟踪每个状态-动作对,记录自从该对在与环境的真实交互中最后一次尝试以来已经过去了多少时间步。经过的时间越长,这一对的动态变化和模型不正确的可能性就越大(我们可以假设)。为了鼓励测试长期未尝试行为的行为,对涉及这些行为的模拟体验给予特殊的“额外奖励”。特别是,如果转换的模型奖励是
r
,并且在τ
时间步中没有尝试转换,那么计划更新被完成,就好像对于一些小的κ
,转换产生了r + κ*sqrt(τ)
的奖励。这鼓励代理继续测试所有可访问的状态转换,甚至找到长的动作序列来执行这样的测试。
总而言之,该算法与 Dyna-Q 完全相同,除了它跟踪一个状态被访问的次数,并奖励长期未被访问的状态(因为这些状态可能会随着时间的推移而改变)。
现在让我们对 Dyna-Q 进行一些修改,并实现 Dyna-Q+(由于基本设置基本相同,下面的代码我将主要关注不同之处)。你也可以在这里查看完整的实现。
初始化
在 init 函数中,添加了两个组件来奖励未访问的状态。self.time
记录每集内的总时间步数**(游戏结束后会重置),而self.timeWeight
本质上是奖励函数中的κ
,表示我们希望代理探索的程度。除了这些通用设置之外,环境模型再次被初始化,但这次是(currentState, action) -> (reward, nxtState, timestep)
的映射。**
模型更新
为了使代码更有条理,定义了一个更新模型函数:
该函数在每个时间步更新模型。需要注意的是我们希望在计划阶段考虑从未尝试过的行动,我们将这些行动定义为将代理带回到原始状态,奖励为 0 ,因此您可以看到,对于从未发生的行动,模型为:
self.model[state][a] = (0, state, 1)
奖励设置为 0,状态设置为相同,时间步长设置为 1(因此未访问该状态的次数可能很高)。此外,对于在该状态下发生动作,将用当前时间步长进行标记。
播放功能
播放函数遵循与 Dyna-Q 方法相同的结构:
在每一步之后,我们通过调用self.updateModel()
函数来更新模型,存储在模型中的时间步长在下面的循环中使用,以添加到奖励中:
_reward += self.timeWeight * np.sqrt(self.time - _time)
除了在一个州采取特定行动的原始奖励之外,还分配了额外的奖励。self.time - _time
本质上是未被访问的次数。
Dyna-Q 和 Dyna-Q+比较
通过对非探索状态给予额外奖励,Dyna-Q+更容易察觉到环境的变化,而 Dyna-Q 几乎做不到。
From Reinforcement Learning an Introduction
参考 Sutton 书中的结果,当环境在时间步长 3000 发生变化时,Dyna-Q+方法能够逐渐感知这些变化,并最终找到最优解,而 Dyna-Q 总是遵循它之前发现的相同路径。事实上,由于规划步骤加强了 Dyna-Q 中的经验,规划步骤越多,Dyna-Q 代理找到最佳路径的可能性就越小,相反,Dyna-Q+中的规划步骤增加了未充分探索的状态和动作的值,从而使代理更有可能探索和找到最佳路径。
优先级扫描(更新更高效)
我们现在已经了解了动态环境下形成强化学习的基础知识。你可能注意到了在计划阶段,实际上有很多无效更新,尤其是在所有状态和动作的 Q 函数都为 0,沿途奖励也为 0 的开始阶段。在这些场景中,暂时的差异,
R + Q(S', A') - Q(S, A)
等于 0,因而 Q 函数更新了许多状态,动作仍为 0。那么问题来了:我们能够更高效地更新吗?
这里我将介绍一种叫做优先级扫描的方法,重点是在规划阶段更新非零值。直觉是,由于许多更新是 0,我们是否能够只更新高于某个阈值的值,从而使学习更快?
根据更新的紧急程度确定更新的优先级,并按照优先级顺序执行更新是很自然的。这就是优先清扫背后的想法。维护每个状态-动作对的队列,这些状态-动作对的估计值如果被更新将会发生非平凡的变化,并根据变化的大小区分优先级。
Priority Sweeping
有几点你需要注意:
- 模型是
(currentState, action) -> (reward, nxtState)
的映射 - 只有大于
θ
的时间差值将被包括在队列中 - 在计划阶段,所有导致所选状态的状态也将被更新
在非平凡更新状态之后,所有在先状态需要被更新的原因是因为当前状态更新值是非平凡的,向后更新将绝对导致非零更新。 (考虑我们在值迭代中谈到的例子,当目标达到时,我们进行向后更新,在此过程中更新的所有状态值都是非零和有用的)
算法实现
是时候着手实现了,您可以在这里查看完整的实现。
初始化
在init
函数中,我们初始化了一个阈值θ
,一个根据优先级存储状态和动作对的优先级队列,以及一个前趋字典,以便更新所有导致当前更新状态的状态。
播放功能
主要区别在于播放功能:
在每一步,不是直接更新当前状态动作对的 Q 值,而是记录一个tmp_diff
,如果该值足够大,则将其插入优先级队列。然后,模型和前任都被更新,注意前任字典是一个nxtState -> List((currentState, action), ...)
的映射,因为许多状态和动作可能导致相同的状态。
在计划阶段(在for
循环中),最高优先级状态,动作对被检索(self.queue.get(1)
,并且导致该状态的所有状态(在pre_state_action_list
内)被更新。
Dyna-Q 和优先级扫描比较
如上所述,优先级扫描会在整个过程中更新重要的值,因此效率更高,速度更快。
From Reinforcement Learning an Introduction
参考 Sutton 书中的情节,priority 比 Dyna-Q 更快地找到最优解。
上面介绍的算法是针对确定性环境,针对非确定性环境,正如萨顿所说:
将优先扫描扩展到随机环境是简单的。通过记录每个状态-动作对已经经历的次数以及下一个状态是什么来维护该模型。然后,很自然地,不是像我们到目前为止一直使用的那样用样本更新来更新每一对,而是用预期更新来更新,考虑所有可能的下一状态及其发生的概率。
结论
在这篇文章中,我们学习了两个算法,要点是:
- Dyna-Q+是为不断变化的环境而设计的,它对未充分利用的状态、动作对给予奖励,以驱动代理进行探索
- 优先级扫描能够通过用非平凡更新来更新和传播值来加速学习过程
最后,请查看我的 Github。欢迎您投稿,如果您有任何问题或建议,请在下面发表评论!
参考:
- http://incompleteideas.net/book/the-book-2nd.html
- https://github . com/JaeDukSeo/reinforcement-learning-an-introduction
强化学习——多臂土匪实现
ϵ-greedy 与加州大学的比较
多臂强盗是一个经典的强化学习问题,其中一个玩家面对k
吃角子老虎机或强盗,每一个都有不同的奖励分配,并且玩家试图在试验的基础上最大化他的累积奖励。
制定
让我们直接切入这个问题。强化学习问题有 3 个关键组成部分——状态、动作和奖励。让我们回忆一下这个问题——k 台机器放在你面前,在每一集里,你选择一台机器并拉动手柄,通过这个动作,你会得到相应的奖励。因此,状态是所有机器的当前估计值,开始时为零,动作是您决定在每集选择的机器,奖励是您拉下手柄后的结果或支出。有了这三项,我们就可以编写Bandit
的init
功能了(这里查看代码):
k
是我们希望初始化的盗匪数量,actions
用数字表示,每个数字代表我们要搭载的机器,我们和往常一样有exp_rate
(探索率)和lr
(学习率)来控制探索和价值更新。total_reward
和avg_reward
用于衡量我们的结果。每台机器的赔付额是由正态分布生成的随机值,最终的初始估值被设置为 0。
行动
选择行动
要找出报酬最高的机器,最直接的方法是尝试,尽可能多地尝试,直到对每台机器都有一定的信心,并从现在开始坚持使用最好的机器。问题是,我们可能可以用更明智的方式进行测试。由于我们的目标是沿途获得最大的回报,我们当然不应该浪费太多时间在一台总是给予低回报的机器上,另一方面,即使我们偶然发现了某台机器的诱人回报,我们仍然应该能够探索其他机器,希望一些没有被探索过的机器能够给我们更高的回报。
因此,在选择行动时,我们将探索方法:
- ϵ-greedy
- UCB(置信上限)
我们已经多次谈到ϵ-greedy,在那里我们以ϵ概率采取随机行动,以 1 - ϵ概率采取最大行动。这在探索和开发之间取得了良好的平衡。让我们谈一谈基于以下公式的 UCB:
UCB
其中 *lnt*
表示 *t*
的自然对数(为了等于 *t*
而不得不将 *e = 2.71828*
的数字),而 *Nt(a)*
表示动作 a 在时间 *t*
之前被选择的次数(公式中的分母,数字 *c > 0*
控制探索的程度)。如果 *Nt(a)=0*
,那么 *a*
被认为是一个最大化动作。(摘自 强化学习:入门 )
所以随着试验次数的增加,如果一个强盗还没有被探索,它的Nt(a)
将会变小,因此公式的右边将会变大。这样,该公式有助于平衡当前估计值Q
和勘探速度。
为了实现 UCB,我们需要在init
函数中添加一些变量:
self.times
计算试验的总次数,而self.action_times
计算每个土匪的行动次数。
现在我们可以将ϵ-greedy 和 UCB 放入我们的方法chooseAction
函数中:
当self.ucb
打开时,我们将根据公式选择动作。如果值除以 0,则self.action_times
增加 0.1。如果exp_rate
if 设置为 0 并且self.ucb
为真,动作将完全由 UCB 选择,但是如果exp_rate > 0
,那么我们将有一个混合ϵ-greedy 和 UCB 的混合方法。
采取行动和更新估计
takeAction
函数接收一个动作,并在收到奖励后更新该动作的估计值。
正如问题所描述的,每个强盗的支付符合一定的分布,因此我们给每个真实的奖励增加了一些随机性。在收到奖励后,将通过添加当前观察和先前估计之间的差乘以学习速率来更新估计。
玩
最后,我们需要一个函数来开始播放。
结果
我们初始化了一个 5 臂 bandit,并比较了不同方法的平均增益。(点击查看代码)
这是使用不同探索率的ϵ-greedy 方法超过 2000 次迭代的平均回报。当勘探率收敛时,0.1 的勘探率超过 0.3 的勘探率。
我们加入不同c
值的 UCB 方法进行比较。两种 UCB 方法的勘探率都是 0.1。从结果中,我们看到,一般来说,UCB 优于ϵ-greedy,但除了 bandit 之外,在许多其他问题上也很难应用 UCB。
请在这里查看完整的代码,欢迎您贡献和提出问题!
参考:
- http://incompleteideas.net/book/the-book-2nd.html
- https://github . com/JaeDukSeo/reinforcement-learning-an-introduction
强化学习——策略函数逼近的推广
将 Q 函数应用于连续状态空间
在以前的帖子中,我们已经将强化学习的思想从离散状态空间扩展到连续状态空间,并且实现了 1000 个状态的随机行走示例,在这种情况下,给定了一个策略,因为在所有状态下向左或向右的动作总是具有相等的概率,并且唯一的问题是基于给定的策略来测量每个状态的值函数(我们将这类问题称为预测问题)。
在本文中,让我们将这个想法扩展到更一般的情况,称为控制问题,其中没有给定策略,我们的目标是使用 Q 函数来学习每个状态下的最佳行动。在这篇文章中,我将:
- 介绍连续状态空间设置的策略算法
- 实现并应用该算法解决经典的山地汽车问题
(注:我们将应用 tile 编码作为近似函数,如果您不熟悉,请参考我上一篇帖子)
控制问题
与行为分布已知的预测问题不同,在控制问题中,代理的任务是探索环境并学习每个状态下的最佳行为,因此,当公式化问题时,考虑的是Q(s, a)
函数而不是价值函数V(s)
。
半梯度 Sarsa
另一方面,像预测问题一样,参数值函数的算法可以自然地扩展到参数 Q 函数,只需用 Q 函数替换值函数。让我们直接进入我们要应用的算法:
如果你一直关注我以前的帖子,你会再次看到这个算法非常熟悉。类似于离散状态空间中的 n 步 Sarsa,这种半梯度 n 步 Sarsa 与完全相同,只是在每个时间步,参数w
被更新,而不是直接更新 Q 函数。其思想是在每次更新时间 τ
时,使用到 τ+n
的累积值来校正当前估计,并根据梯度下降的思想,将参数权重 w
与其导数和增量成比例地稍微向实际值更新。
山地车问题
如果你仍然有一些困惑,那完全没问题。我相信理解一个算法的每个细节的最好方法是实现它,并把它应用到一个实际问题上。我们来做一个经典的强化学习问题,山地车。
山地汽车场景
Mountain Car
考虑驾驶一辆动力不足的汽车在陡峭的山路上行驶的任务,如图所示。困难在于重力比汽车的发动机更强,即使在全油门的情况下,汽车也无法加速上陡坡。唯一的解决办法是先离开目标,然后爬上左边的反坡。
这个问题中的奖励在所有时间步长上都是-1,直到汽车在山顶移动经过它的目标位置,这就结束了这一集。有三种可能的操作:全油门向前(+1)、全油门向后(-1)和零油门(0)。汽车根据简化的物理学原理行驶。其位置、 *x_t*
和速度、 *x_ ̇t*
由更新
Update Rule
此处绑定操作强制执行 *-1.2 <= x_t+1 <= 0.5*
和 *-0.07 <= x_ ̇t+1 <= 0.07*
。另外,当 *x_t+1*
到达左界时, *x_ ̇t+1*
被复位为零。到了右边界,目标达到,插曲终止。每集从 *[-0.6, -0.4)*
中的任意位置 *x_t*
和零速度开始。(抱歉无格式的语法编辑,我不知道如何在媒体上编辑数学语法)
简单来说,汽车以 0 速度从-0.6 到 0.4 之间的位置出发,有 3 个离散动作,停留(0),前进(1),后退(-1),目标是到达最右边的山顶。所以这个问题中的状态包括 (position, velocity)
,动作集合为 (-1, 0, 1)
,奖励为 -1
除了目标状态(注意状态是连续的,动作是离散的)。
价值函数
了解了问题设置,我们现在需要一个 Q 值函数来跟踪所有状态的值,并在探索过程中更新值估计。记得在上一篇文章中,我们已经讲述了使用 tile 编码对连续状态空间进行编码并将其应用于更新过程的基础知识。在本帖中,我们将继续在我们的值函数中使用平铺编码,但代码略有不同:
这里使用的图块编码功能是指这里的和。我没有使用上一篇文章中介绍的 tile 编码的原因是,我介绍的那个有点基本,具有均匀分布的偏移,我亲自测试的结果不如这个,而且这似乎是 Sutton 在他的书中介绍的 tile 编码函数。
不管怎样,让我们回到正题。这里的想法是完全相同的,每个连续的状态都被编码到一些图块的索引中,在每集的每一步,其对应图块的权重都被更新。
让我们仔细看看这个函数。numberOfTilings = 8
和maxSize = 2048
,意味着我们设置了 8 个 tilings,每个 tilings 有16*16
个网格数,所以16*16*8 = 2048
。更具体地说,(position, velocity)
的状态由一个维度为16*16*8
的 3D 立方体表示,而tiles
函数,从我提到的文件中,能够获得给定状态和动作的活动瓦片。您可能已经注意到,在init
函数中,状态被重新调整为:
# position and velocity needs scaling to satisfy the tile software
self.positionScale = self.numOfTilings / (POSITION_BOUND[1] - POSITION_BOUND[0])self.velocityScale = self.numOfTilings / (VELOCITY_BOUND[1] - VELOCITY_BOUND[0])
老实说,我不知道它为什么以这种方式缩放,但看起来像是使用这种平铺编码功能,状态的连续值总是要被重新缩放。
像所有 Q 值函数一样,它至少有两个函数:
value
功能:返回当前状态的值,以及动作。当代理达到目标状态时,返回 0。update
功能:根据新的估计值更新权重(记住在 tile 编码中,权重参数的导数总是 1,因此更新是直接加上delta
值)。
costToGo
函数用于后面步骤的可视化,它简单地返回该状态和动作的最大负值(因为奖励总是-1,所以结果被赋予一个-
符号)。
山地汽车实施
到目前为止,我们实际上已经完成了最棘手的部分,剩下的是我们一直在重复做的事情。(全面实施)
初始化
像往常一样,在init
函数中,我们指定了动作和状态范围,以及所有强化学习问题中的一些通用元素。
动作功能
takeAction
采取行动并决定汽车的下一个状态。更新规则遵循我在上面介绍的公式。chooseAction
函数仍然使用ϵ-greedy 方法,在贪婪部分,它选择由我们上面描述的valueFunc
给出的最大估计值的动作结果。
报酬
除了目标状态获得奖励0
,其他所有状态都获得奖励-1
。
发动汽车!
这是所有函数中最长的一个,但不用担心,事实上,一切都和它在离散设置中一样(我实际上是从我以前的代码中复制粘贴的),除了值函数被改为我们刚才介绍的函数。目标G
是累积的 n 步值,包括第tau+n
步的值,在更新过程中state, action and G
一起发送给valueFunction.update()
函数。
(英)可视化(= visualization)
在本节中,我们将使用在ValueFunction
中定义的costToGo
函数来衡量在给定状态和行动的情况下达到目标的成本。图的代码如下所示:
让我们看看步骤 100 和步骤 9000 的结果:
Step 100
Step 9000
成本越低,越接近目标状态。事实上,较低的成本要么出现在最左边的位置,要么出现在最右边的位置,这验证了只有到达目标的相反方向,智能体才能到达最终的目标状态。
参考:
- http://incompleteideas.net/book/the-book-2nd.html
- https://github . com/Shang tong Zhang/reinforcement-learning-an-introduction
强化学习——策略近似
政策梯度法的理论与应用
到目前为止,所有引入的算法都是基于值函数或 Q 函数的梯度算法,也就是说,我们假设对于不同的状态S(or [S, A])
存在真实值V(or Q)
,并且为了接近真实值,我们使用公式中带有∇V or ∇Q
的梯度方法,并且在学习过程的最后,通过基于V or Q
函数估计在每个状态选择最有回报的动作来生成策略π(A | S)
。然而,策略梯度方法对强化学习问题提出了完全不同的观点,人们可以直接学习或更新策略,而不是学习一个值函数。所以在本帖中,我们将:
- 学习政策梯度法的理论
- 将其应用于短走廊示例
政策梯度理论
记得在以前的帖子中,学习过程中使用的策略总是ϵ-greedy,这意味着代理将在某个概率下采取随机行动,在其余概率下采取贪婪行动。然而,在梯度策略方法中,问题被公式化为,P(A|S, θ) = π(A|S, θ)
,也就是说,对于每个状态,策略给出了从该状态可能采取的每个动作的概率,并且为了优化策略,它被参数化为θ
(类似于我们之前介绍的价值函数中的权重参数w
)。
另一件值得一提的事情是,在这种情况下,性能变量被定义为:
*J(θ)*
是当前参数化策略*π*
、下*V*
的真值,目标是最大化性能 *J*
,因此我们得到一个梯度更新过程:
并且由于*J*
是策略π
的一个表示,我们知道θ
的更新会包含当前的策略,经过一系列的推导(详情请参考 Sutton 的书,第 13 章),我们得到更新过程:
我们的第一个政策梯度方法是:
G
仍为累计折扣奖励,参数θ
将更新为当前保单的衍生产品。
策略近似的优势
首先,策略梯度方法的明显优点是,与值函数近似法相比,该方法简化了过程,在值函数近似法中,我们首先学习一个值函数V(S, A)
,并从中推断出策略π(A|S)
,在策略近似法中,在每次迭代中,通过更新π(A|S, θ)
中的参数θ
来直接更新策略。
其次,在价值函数更新过程中,我们通常使用ϵ-greedy 方法,这样代理人总是有一个ϵ采取随机行动的概率。然而,策略梯度方法能够通过将某些动作的概率更新为零来逼近确定性策略。
第三,如果你还记得,在以前的文章中,我们总是要求动作空间是离散的,因为一般的价值函数逼近方法在处理具有严格连续空间的动作时有点棘手。但是在策略近似定义中,动作实际上可以相对于状态是连续的,例如,可以将策略定义为:
在这种情况下,动作a
将具有正态分布的概率,μ和σ由状态s
定义。
最后但同样重要的是,在最优策略是非确定性的情况下,它允许选择具有任意概率的动作,并且总是选择具有最优概率的动作。
短走廊示例
现在让我们举一个例子来应用我们的知识。
问题描述
考虑下图中插图所示的小走廊网格世界。奖励是-1 每一步,像往常一样。在三种非终结状态的每一种状态下,都只有两个动作,右和左。这些动作在第一和第三种状态下有它们通常的结果(在第一种状态下左不动),但是在第二种状态下它们是相反的,所以右向左移动,左向右移动。这个问题很难,因为在函数近似下,所有的状态都是相同的。特别是,我们为所有的s
定义了x(s, right) = [1, 0])
和x(s, left) = [0, 1])
。
在这种情况下,状态、动作表示使用最简单的格式,并将所有状态视为相同(二进制表示与图块编码中的表示相同)。
下面列出了算法和组件:
因此,在这里,使用 softmax 函数(也可以应用其他函数)定义策略π(a|s, θ)
,该函数生成 0 到 1 之间的概率,并且组件h
被定义为具有参数θ
的简单线性函数。
现在让我们开始实现。
初始化
在init
函数中,我们有上面讲过的self.x
和self.theta
的定义,其初始权重为self.x
,起始状态为 0。
行动
函数softmax
接受一个向量,并返回向量中每个分量的概率。动作由softmax
生成的概率选择,takeAction
函数接受一个动作并返回下一个状态(注意第二个状态是相反的)。
报酬
如问题所述,除了最终状态,所有状态的奖励都是-1。
运行游戏!
在每一集里,代理都要经历一个过程current_state -> take_action -> next_state -> get_reward
。当它到达状态(3)的终点时,我们计算累计奖励G
。梯度grad
是为该步骤中采取的特定动作计算的(j
是该动作的索引)。reward_sum
只记录每集的奖励,用于显示目的。
让我们用alpha = 2e-4
和gamma = 1
运行游戏 1000 集,得到结果:
从增加回合中的概率来看,我们看到 agent 在逐渐更新策略,实际上在这个博弈设定中,最优策略是概率[0.4, 0.6]
,我们的学习结果正在接近最优值(完全实现)。
参考:
- http://incompleteideas.net/book/the-book-2nd.html
- https://github . com/Shang tong Zhang/reinforcement-learning-an-introduction
强化学习—解决 21 点
用 Q-learning 实现 21 点
我们已经讨论了如何使用蒙特卡罗方法来评估强化学习中的策略在这里,我们以 21 点为例,设定了一个固定的策略,通过重复采样,我们能够获得策略和状态的无偏估计,以及沿途的值对。下一个直接的想法是,我们能否通过使用价值迭代来解决 21 点问题,我们在前面的文章中已经介绍过了。
答案听起来是肯定的,因为我们可以清楚地定义 21 点的三个主要组成部分(state, action, reward
,并且我们也知道对手的策略,这也将被视为环境的一部分,所以这个过程将类似于我们在井字游戏实现中讨论过的,我们站在 1 个玩家的立场上,对手的相应动作将被视为环境的反馈(这样我们就不需要对手的任何模型,这是强化学习的优势之一)。
二十一点规则
简单回顾一下21 点规则和庄家采取的一般策略:
游戏从发给庄家和玩家的两张牌开始。庄家的一张牌面朝上,另一张面朝下。如果玩家立即有 21(一张 a 和一张 10 的牌),这叫自然牌。然后他赢了,除非庄家也有一个自然牌,在这种情况下,游戏是平局。如果玩家没有自然牌,那么他可以一张接一张地要求额外的牌(命中),直到他停止(坚持)或超过 21(破产)。如果他破产了,他就输了;如果他坚持,那么就轮到庄家了。庄家根据固定的策略不加选择地打或坚持:他坚持任何 17 或更大的和,否则就打。 如果庄家破产,那么玩家获胜;否则,结果——赢、输或平——取决于谁的最终总和更接近 21。如果玩家拿着一张可以算作 11 而不会破产的王牌,那么这张王牌就可以用了。
履行
先明确一下状态,动作,奖励。游戏的状态是决定和影响胜算的因素。首先,最重要的是卡的金额,目前手头的价值。其次,还有两个因素有助于赢得游戏,这是我们在上面的规则介绍中描述的,是可用的 ace 和庄家的扑克牌。因此状态将有 3 个组成部分:玩家当前的牌总数、可用的 ace 和庄家的出牌。动作清晰,因为在 21 点中一个人只能有 2 个动作,要么击中,要么站立。奖励将基于游戏的结果,赢了给 1,平了给 0,输了给-1。
由于我已经谈到了 21 点上的 MC 方法,在下面的部分中,我将介绍两者实现的主要差异,并尝试使代码更加简洁。(全码)
初始化
在 init 函数中,我们定义了将在下面的函数中频繁使用或更新的全局值。与我们的玩家遵循固定策略的 MC 实现相反,这里我们控制的玩家不使用固定策略,因此我们需要更多组件来更新其 Q 值估计。
在这个init
函数中定义的组件通常用于强化学习问题的大多数情况。与 MC 方法中的init
函数相比,增加的部分包括self.player_Q_Values
,它是(state, action)
的初始化估计,每集之后会更新,self.lr
,它用于控制更新速度,以及self.exp
,它用于采取行动。
交易卡和经销商政策
giveCard
和dealerPolicy
功能完全相同。因为我们的对手,庄家,在这场游戏中仍然持有相同的策略,我们正在探索一种可以与庄家的策略一样有竞争力甚至更好的策略。
行动选择
这一次我们的玩家不再遵循固定的政策,所以它需要考虑在平衡探索和开发方面采取什么行动。
我们的玩家有两个动作要做,其中 0 代表站立,1 代表击中。当当前牌的和等于或小于 11 时,一个人将总是击中,因为击中另一张牌没有害处。当牌的总数超过 11 时,我们的玩家将采取ϵ-greedy 策略,其中exp_rate
百分比的时间,它采取随机行动,否则采取贪婪行动,这是基于 q 值的当前估计获得最多奖励的行动。
判断下一个状态
通过采取一个动作,我们的玩家从当前状态移动到下一个状态,因此playerNxtState
函数将采取一个动作并输出下一个状态,并判断是否游戏结束。
为了进入下一个状态,函数需要知道当前的状态。它在开始时通过将当前状态分配给固定变量来实现这一点。下面的逻辑是如果我们的动作是 1,代表 HIT,我们的玩家再抽一张牌,根据抽的牌是不是 ace,相应的加上当前的牌和。另一方面,如果动作是 STAND,游戏马上结束,返回当前状态。值得注意的是,在函数的最后我们增加了另一个部分,根据玩家手上是否有可用的 ace 来判断游戏是否结束。
给予奖励并更新 Q 值
像所有的强化学习更新一样,在游戏结束时(这被认为是一集),我们的玩家会收到基于自己和庄家的牌值的奖励,并将该值向后传播以更新对(state, action)
的估计。
Q-value update
这两个功能可以合并成一个,我把它们分开是为了在结构上更清晰。winner
函数判断游戏的获胜者并相应返回奖励,_giveCredit
函数根据上面的公式更新奖励,这与我们在网格世界 Q-learning 中介绍的完全相同,Q 值以相反的方式更新,而最后更新的值将用于更新当前的 Q 值。
培养
在培训阶段,我们将模拟许多游戏,让我们的玩家与庄家对打,以更新 Q 值。
与 21 点的 MC 方法不同,在开始时我增加了一个功能deal2cards
,它只是简单地向玩家连续发 2 张牌。原因是遵循规则如果任一玩家用前 2 张牌得到 21 分,游戏直接结束,而不是继续等待下一个玩家到达其终点。这避免了这样的情况,一个玩家用前 2 张牌得到 21 分,而另一个玩家也用 2 张以上的牌得到 21 分,但是游戏以平局结束。
玩庄家和结果
有了我们配备了智能的代理,我们就可以让它与庄家对弈了(保存和加载策略功能与 MC 21 点中的相同, *playWithDealer*
功能与训练过程的结构类似,只是将 *exp_rate*
调至 0 )。
用exp_rate=0.2
和lr=0.1
训练了一万回合后,我保存了策略,让它和庄家打一万回合,得到的结果是:
- wining: 4122
- 图纸:1639 年
- 失败:4239
这是一项无法超越经销商的政策。肯定存在比 HIT17 执行得更好的策略(事实上,这是一个公开的秘密),我相信,我们的代理没有学习到最优策略并且执行得同样好的原因是,
- 没有足够的训练
- 探索率和学习率的调整(修正它们可能对这种情况不好)
- 一步 Q 值更新有其自身的局限性
你能做什么?
我强烈建议你在当前实现的基础上进行更多的尝试,这既有趣又有利于加深你对强化学习的理解。你可以试试:
- n 步更新而不是 1 步(我也会在以后的文章中介绍)
- 根据当前保存的策略 (这是一个有趣的想法,值得一试,因为我们知道 AlphaGo 通过与大师对弈而变得强大,但 AlphaGo Zero 通过学习与自己对弈以 100:0 击败了它。你也可以利用这个想法,试着训练一个代理和自己一起玩)
请点击查看的完整代码。欢迎您投稿,如果您有任何问题或建议,请在下面发表评论!
参考
[1]http://incompleteideas.net/book/the-book-2nd.html
强化学习— TD(λ)简介(3)
用 Sarsa(λ)扩展 Q 函数上的 TD(λ)
在上一篇文章中,我们学习了 TD(λ)与合格迹的思想,这是 n 步 TD 方法的组合,并将其应用于随机游走的例子。在这篇文章中,让我们将 lambda 的思想扩展到更一般的用例——不是学习状态值函数,而是学习状态的 Q 函数,动作值。在本文中,我们将:
- 了解 Sarsa(λ)的概念
- 将其应用于山地车实例
萨尔萨(λ)
与我们已经阐述的许多扩展一样,将价值函数V(S)
扩展到 Q 函数Q(S, A)
是非常自然的,因为所有的公式和逻辑都是相同的,当公式化问题时,将只考虑动作。回想一下 TD(λ)这里介绍的,更新过程类似:
唯一不同的是∇V
被∇q
取代,并且合格跟踪将扩展为:
仍在这里的∇V
换成了∇q
。
因此,我们得到 Sarsa(λ)的备份图:
其中每列是 n 步 Sarsa,1-λ
,(1-λ)λ
…是权重。
扩展的算法将是:
注意,这里的算法是专门为二进制特征表示而设计的,即每个状态、动作对将被表示为二进制特征,例如(3.2, 1)
可以被表示为[1, 0, 0, 1]
(更具体地,我们已经广泛地讨论了如何在瓦片编码中将连续状态表示为二进制特征)
乍一看,你可能觉得算法有点复杂,但实际上和TD(λ)
是一样的,我们试着这样理解一下:
首先,我们来关注一下底部。你应该对此很熟悉,因为它看起来几乎与TD(λ)
— δ
相同,这是时间上的差异,权重w
基于δ
和资格跟踪z
进行更新,其中z
跟踪先前的状态。z
提供了两个更新:
- 积累痕迹:
z = z + 1
;那么1
从何而来?这其实是q(S, A)
的衍生!请记住,这里我们使用状态、动作的二进制表示,活动特征的导数是 1。其实也可以写成z = z + ∇q
,代入w
updates 时,跟踪之前的导数。 - 替换轨迹:
z = 1
,仅使用当前导数更新w
。
F(s, a)
在这里你可以把它想成是 tile 编码函数或者任何其他给出状态、动作二进制表示的函数。
这个算法就这么多了。忽略其他部分,将其与我们在之前的讲座中所学的内容联系起来,现在让我们开始实施一个示例。
山地车上的 Sarsa(λ)
我们已经在 n 步 Sarsa 示例中讨论了山地车,这里是,设置是(如果你对下面的实现有任何困惑,我强烈建议你阅读以前的帖子以更好地理解这个过程):
如图所示,考虑驾驶一辆动力不足的汽车爬上陡峭的山路。困难在于重力比汽车的发动机更强,即使在全油门的情况下,汽车也无法加速上陡坡。唯一的解决办法是先离开目标,然后爬上左边的反坡。
这个问题中的奖励在所有时间步长上都是-1,直到汽车在山顶移动经过它的目标位置,这就结束了这一集。有三种可能的操作:全油门向前(+1)、全油门向后(-1)和零油门(0)。汽车根据简化的物理学原理行驶。其位置、、*x_t*
、和速度、、*x_ ̇t*
、,均由更新
其中绑定操作强制执行 *-1.2 <= x_t+1 <= 0.5*
和 *-0.07 <= x_ ̇t+1 <= 0.07*
。另外,当 *x_t+1*
到达左界时, *x_ ̇t+1*
被复位为零。到了右边界,目标达到,插曲终止。每集从 *[-0.6, -0.4)*
中的任意位置 *x_t*
和零速度开始。
下面的过程将与我们在 n 步 Sarsa 中陈述的大部分相同,所以我将主要集中于解释不同之处。
价值函数
在init
函数中,区别在于self.z
的初始化,T7 是合格跟踪向量,在开始时设置为 0。
value
函数返回值给定状态,动作配对。主要的区别是在update
函数中,在更新权重之前,我们首先更新self.z
。
- 在
accumulating
方法中,使用z = γλz + 1
更新活动图块 - 在
replacing
方法中,活动图块更新为:z = 1
costToGo
功能相同。
一般功能
上面的功能与之前的实现相同,所以我将简单介绍一下。reset
函数在代理到达目标或最左侧状态时将代理复位到初始状态;takeAction
函数接收一个动作,并根据预定义的公式返回代理的下一个状态;chooseAction
函数根据ϵ-greedy 策略的当前估计选择操作;并且giveReward
根据代理的状态给予奖励。
玩游戏
最后是play
功能,启动游戏。逻辑简单明了——一个代理从current state
→ takes an action
→ reaches next state
→ receives reward
→ takes next action
…,和target = reward + Q(nextState, nextAction)
开始,它被传递给我们上面定义的值函数来更新资格跟踪z
和权重w
。
结果
整个游戏设置与我们在 n 步 Sarsa 上介绍的完全相同,因此我们比较 Sarsa(λ)和 n 步 Sarsa 之间的学习结果:
Image from Reinforcement Learning an Introduction
我们使用相同数量的镶嵌和其他参数。参考 Sutton 的书,Sarsa(λ)比 n 步 Sarsa 更有竞争力,因为它学习更快以达到目标(更多说明,请参考这里的完整实现)。
参考:
- http://incompleteideas.net/book/the-book-2nd.html
- https://github . com/Shang tong Zhang/reinforcement-learning-an-introduction
强化学习— TD(λ)简介(1)
对随机漫步应用 offline-λ
在本文中,我们将讨论 TD(λ),这是一种通用的强化学习方法,它结合了蒙特卡罗模拟和一步 TD 方法。我们一直在详尽地讨论 TD 方法,如果您还记得,在 TD(n) 方法中,我说过它也是 MC 仿真和 1 步 TD 的统一,但在 TD(n)中,我们必须跟踪沿途的所有轨迹,并根据 n 步前的值更新当前估计,在 TD(λ)中,我们将看到更优雅的统一。
在本文中,我们将:
- 学习 TD(λ)的思想
- 介绍前向视图更新方法—离线—λ返回
- 将该方法应用于随机游走实例
TD(λ)的概念
TD(λ)实际上是 TD(n)方法的扩展,记住在 TD(n)中,我们有如下形式的累积报酬:
直到步骤t+n
的该值估计用于更新步骤t
的值,TD(λ)所做的是平均该值,例如,使用
0.5*Gt:t+2 + 0.5*Gt:t+4
作为目标值。但是它没有使用直接权重,而是使用λ作为参数来控制权重,使其总和为 1:
TD(λ)
我打赌这个图像看起来很熟悉,一个代理从一个状态开始,通过采取一个动作,它到达下一个状态,然后它选择另一个动作,SARSA 过程继续下去。所以第一列实际上是 TD(1)方法,它被赋予了1-λ
的权重,第二列是 TD(2),它的权重是(1-λ)λ
,…,直到最后一个 TD(n)被赋予了λ^(T-t-1)
的权重(T 是一集的长度)。注意,权重随着 n 的增加而衰减,总和为 1。TD(λ)更一般的形式是:
从公式中可以看出,当λ = 1
时,只保留最后一项,这本质上是蒙特卡罗方法,作为状态,动作过程一直进行到最后,当λ = 0
时,该项减少到G_t:t+1
,这是一步 TD 方法,对于0 < λ < 1
,该方法变成了加权 TD(n)混合方法。
离线λ-返回(前视图)
随着目标G_t
的定义,我们现在开始我们的第一个算法定义。概括的更新公式可以定义为:
offline λ-return
更新规则与一般的半梯度法相同,唯一的区别在于上述目标值 I。
参考 Sutton 书中的一幅图像,这种方法也被称为前视学习算法,因为在每个状态下,更新过程都会前视G_t:t+1
、G_t:t+2
、……的值,并基于该值的加权值来更新当前状态。
随机漫步的正向更新
现在让我们来看看随机漫步例子中算法的实现。我们已经在这里学习了随机漫步示例,但是仅供参考,在随机漫步中,一个代理从中间位置开始,在每一步,它都有相等的概率向左或向右移动一步(行动策略是固定的),并且通过仅在左侧或最左侧结束,它可以停止一集。
我们将实现一个 19 态随机游走,尽管状态空间实际上是离散的,我们仍然可以对其应用一般化算法。
价值函数
价值函数简单明了。我们有 19 个状态和 2 个结束状态,所以总共有 21 个状态,每个状态都有一个权重,本质上就是它的值估计。value
函数返回特定状态的值,而learn
函数基于差值delta
更新电流估计,在本例中差值为Gt — v(St, wt)
( alpha
为学习速率)。
一些常规功能
由于这不是我们第一次实现随机漫步,我将列出一些常见的共享函数:
在每个状态下,一个代理人chooseAction
→ takeAction
→ giveReward
并重复直到游戏结束。
播放和更新
同样,主要区别在于播放过程和计算每个状态的增量。
在每一集,我们将需要首先跟踪所有的状态,直到游戏结束,以便在更新每个状态的值时获得一个前瞻性的视图。self.states
记录沿途所有状态,self.reward
只保存最新的奖励,因为沿途所有奖励都是 0,除了最终状态。
第二部分是在游戏结束后更新状态值估计。回想一下公式:
对于在时间t
和步骤n
的每个状态,我们需要计算G_t:t+n
的值,并将它们与衰减的权重相结合,以便得到St
的目标值。因此函数gt2tn
计算给定t
和n
的值,定义为:
而前面代码片段中的gtlambda
就是目标值。此外,我们还设置了一个截尾值,当lambda_power
太小时,我们干脆忽略该值。利用目标值gtlambda
和来自valueFunc
的当前值,我们能够计算差值delta
并使用我们上面定义的函数learn
更新估计值。
离线λ-返回和 TD(n)
记得在 TD(n)会议中,我们用完全相同的设置对随机漫步应用了 n 步 TD 方法。现在随着off-line λ-Return
的介绍,让我们比较一下两者的学习结果:
Image from Reinforcement Learning an Introduction
我们可以看到,两条均方根误差曲线相似,结果具有可比性。一般来说,最好的学习结果通常出现在中等学习速率和λ值的情况下(我从 Sutton 的书中复制了图像,因为这张比我绘制的要清晰得多)。
这就是前视更新,请在这里查看完整的实现。在下一篇文章中,我们将学习向后更新,这是一种通过使用资格跟踪的更优雅的 TD(λ)方法。
参考:
- http://incompleteideas.net/book/the-book-2nd.html
- https://github . com/Shang tong Zhang/reinforcement-learning-an-introduction
强化学习:python 中的时差、SARSA、Q 学习和期望 SARSA
TD、SARSA、Q-Learning &预期的 SARSA 及其 python 实现和比较
如果一个人必须确定一个核心的和新颖的强化学习的想法,它无疑将是时间差异(TD)学习。——安德鲁·巴尔托和理查德·萨顿
先决条件
- 强化学习的基础
- 马尔可夫链,马尔可夫决策过程(MDPs)
- 贝尔曼方程
- 价值、策略功能和迭代
一些心理学
你可以跳过这一部分,这是可选的,不是这篇文章的先决条件。
我喜欢研究人工智能概念,同时将它们与心理学——人类行为和大脑——联系起来。强化学习也不例外。我们感兴趣的话题——时差是由理查德·萨顿创造的一个术语。这篇文章来源于他和安德鲁·巴尔托的书——《T4 强化学习导论》,可以在这里找到。为了理解时间差异的心理学方面,我们需要理解著名的实验——巴甫洛夫实验或经典条件反射。
伊凡·巴甫洛夫用狗做了一系列实验。一组狗接受了外科手术改造,这样它们的唾液可以被测量。这些狗被给予食物(非条件刺激——US ),在食物的反应中观察到唾液的排泄(非条件反应——UR)。这种刺激-反应对是自然的,因此是有条件的。现在,又增加了一个刺激因素。就在端上食物之前,铃响了。铃声是一种条件刺激(CS)。因为这个 CS 是在美国之前送给狗的,过了一会儿,人们发现狗听到铃声就开始流口水。这种反应被称为条件反应(CR)。实际上,帕沃洛夫成功地让狗在听到铃声时分泌唾液。情景喜剧《办公室》中展示了一个有趣的实验。
CS 和 US 发作之间的时间间隔称为刺激间隔(ISI ),是巴甫洛夫条件反射的一个非常重要的特征。基于 ISI,整个实验可分为以下类型:
Source: Introduction to Reinforcement learning by Sutton and Barto — Chapter 14
如上面容易理解的图表所示,在延迟条件作用中,CS 出现在我们之前,并且一直沿着我们。这就像铃响之前,一直呈现食物。而在痕迹条件作用中,CS 在 US 出现之前出现并终止。
在一系列实验中,观察到较低的 ISI 值显示更快和更明显的反应(狗流涎),而较长的 ISI 显示较弱的反应。由此,我们可以得出结论,为了加强刺激-反应对,条件刺激和非条件刺激之间的间隔应该更小。这形成了时间差异学习算法的基础。
依赖模型和无模型的强化学习
依赖于模型的 RL 算法(即值和策略迭代)在转换表的帮助下工作。一个转换表可以被认为是一本生活帮的书,它包含了代理在它所存在的世界中成功所需的所有知识。自然,写这样一本书是非常乏味的,并且在大多数情况下是不可能的,这就是为什么模型依赖的学习算法几乎没有实际用途。
时间差分是一种无模型的强化学习算法。这意味着代理通过实际经验学习,而不是通过现成的无所不知的手册(转换表)。这使我们能够引入随机元素和大量的状态-行为对序列。代理对奖励和转换系统一无所知。它不知道在任意状态下采取任意动作会发生什么。代理人必须与“世界”或“环境”互动,并自己找出答案。
时间差异学习
时间差分算法使代理能够通过它采取的每一个动作进行学习。TD 在每个时间步(动作)而不是在每个情节(达到目标或结束状态)更新代理的知识。
目标值称为目标误差。步长通常用表示,α 也称为学习速率。它的值介于 0 和 1 之间。
上面的等式通过在每个时间步长进行更新,帮助我们实现 目标 。目标是一种状态的效用。更高的效用意味着代理转换到更好的状态。为了这篇文章的简洁,我假设读者知道贝尔曼方程。根据它,一个国家的效用是贴现回报的期望值,如下所示:
通俗地说,我们让一个代理人自由地进入一个世界。代理不知道状态、奖励和转换。它与环境相互作用(做出随机或明智的行动),并通过在采取每一个行动后不断更新其现有知识来学习新的估计(状态-行动对的值)。
到目前为止的讨论将产生几个问题,例如——什么是环境?代理将如何与环境交互?代理将如何选择动作,即在特定状态(策略)下代理将采取什么动作?
这就是 SARSA 和 Q-Learning 的用武之地。这是两个控制策略,它们将在一个环境中指导我们的代理,并使它能够学习有趣的东西。但在此之前,我们将讨论什么是环境。
环境
一个环境可以被认为是一个微型世界,在这个世界中,一个主体可以观察离散的状态,采取行动,并通过采取这些行动来观察回报。把电子游戏想象成一个环境,把你自己想象成代理。在游戏《毁灭战士》中,你作为代理人将观察状态(画面)并采取行动(按下前进、后退、跳跃、射击等键)并观察奖励。杀死一个敌人会给你带来快乐(效用)和积极的回报,而向前移动不会给你带来太多的回报,但你仍然想这样做来获得未来的回报(找到并杀死敌人)。创建这样的环境可能是乏味而艰难的(一个 7 人团队工作了一年多才开发出《毁灭战士》】T1。
OpenAI 健身房前来救援!gym 是一个 python 库,它有几个内置环境,您可以在这些环境中测试各种强化学习算法。它已经成为分享、分析和比较结果的学术标准。健身房是非常好的记录和超级容易使用。在继续下一步之前,您必须阅读文档并熟悉它。
对于强化学习的新应用,你必须创造你自己的环境。建议总是参考和编写健身房兼容环境,并公开发布,以便每个人都可以使用它们。阅读健身房的源代码将帮助你做到这一点。这是乏味的,但很有趣!
萨尔萨
SARSA 是SState-Action-Reward-State-Action 的首字母缩写**
SARSA 是一种政策性 TD 控制方法。策略是状态-动作对元组。在 python 中,你可以把它想象成一个字典,以键作为状态,以值作为动作。策略映射了每个状态下要采取的操作。基于策略的控制方法通过遵循特定的策略(通常是它自己评估的策略,就像在策略迭代中一样)在学习期间为每个状态选择动作。我们的目的是估计出 Qπ(s,a) 对于当前策略**【π和所有状态-动作【s-a】**对。我们通过让代理从一个状态-动作对转换到另一个状态-动作对,使用在每个时间步长应用的 TD 更新规则来实现这一点(不像依赖于模型的 RL 技术,其中代理从一个状态转换到另一个状态)。
Q 值- 你一定已经熟悉了一个状态的效用值,Q 值是一样的,唯一的区别是定义在状态-动作对上,而不仅仅是状态。它是状态-动作对和表示其效用的实数之间的映射。Q-learning 和 SARSA 都是策略控制方法,用于评估所有动作-状态对的最优 Q 值。
SARSA 的更新规则是:
Source: Introduction to Reinforcement learning by Sutton and Barto — 6.7
如果一个状态 s 是终端(目标状态或结束状态)那么, Q(S,a)= 0ɐa∈a其中 A 是所有可能动作的集合
Source: Introduction to Reinforcement learning by Sutton and Barto —Chapter 6
上述算法中的动作**A’**是通过遵循相同的策略(ε-对 Q 值贪婪)给出的,因为 SARSA 是基于策略的方法。
ε-贪婪政策
ε-贪婪政策是这样的:
- 生成一个随机数r∈【0,1】**
- If r < ε 选择一个从 Q 值导出的动作(产生最大效用)
- 否则选择一个随机动作
在阅读 python 代码后,这一点会变得更加清楚。
请注意:在《萨顿与巴尔托的 RL》这本书里,如果 r > ε,则采取随机动作。 T 他们取了 ε =0.1 而对我来说 ε =0.9。这两个基本上是一回事。
ε的值决定了代理的探索-开采。
如果 ε 很大,则随机数 r 几乎不会大于ε,并且几乎不会采取随机行动(更少的勘探,更多的开采)
如果 ε 较小,则随机数 r 往往会大于ε,这将导致代理选择更多的随机动作。这种随机特性将允许智能体更多地探索环境。
根据经验, ε 通常选择为 0.9,但可以根据环境类型而变化。在某些情况下, ε 会随着时间的推移而退火,以允许更高的勘探程度和更高的开发程度。
下面是在 Taxi-v2 健身房环境中应用的 SARSA 的一个快速简单的 python 实现
q 学习
Q-Learning 是一种非策略 TD 控制策略。它与 SARSA 完全一样,唯一的区别是,它不遵循策略来寻找下一个动作,而是以贪婪的方式选择动作。类似于 SARSA,其目的是评估 Q 值,其更新规则是:**
Source: Introduction to Reinforcement learning by Sutton and Barto — 6.8
注意:与 SARSA 通过遵循某个策略来选择动作 、A’不同,这里的动作A’(在这种情况下为A**)是通过简单地取 Q 的最大值来贪婪地选择的。**
这是 Q 学习算法:
Source: Introduction to Reinforcement learning by Sutton and Barto — Chapter 6
下面是 Q-learning 的 python 实现:
预期 SARSA
预期 SARSA,顾名思义,取当前状态下每一个可能动作的 Q 值的期望值(均值)。目标更新规则应使事情更加清楚:
Source: Introduction to Reinforcement learning by Sutton and Barto —6.9
这是 python 的实现:
比较
我已经使用以下参数在 Taxi-v2 健身房环境中测试了三种算法
- 阿尔法= 0.4
- 伽玛= 0.999
- ε= 0.9
- 剧集= 2000
- max_steps = 2500(单集可能的最大时间步数)
以下图表展示了上述三种政策控制方法之间的比较:
收敛:
显然,通过下面的图,Q 学习(绿色)在 SARSA(橙色)和预期的 SARSA(蓝色)之前收敛
SARSA, Q-learning & Expected SARSA — Convergence comparison
性能:
对于我的三个算法的实现,Q-learning 似乎表现最好,而 Expected SARSA 表现最差。
SARSA, Q-learning & Expected SARSA — performance comparison
结论
时间差异学习是最重要的强化学习概念。它的进一步衍生,如 DQN 和双 DQN(我可能会在另一篇文章中讨论它们)已经取得了突破性的成果,在人工智能领域享有盛名。谷歌的 alpha go 使用 DQN 算法和 CNN 打败了围棋世界冠军。你现在已经具备了基本 TD 的理论和实践知识,出去探索吧!
如果我犯了一些错误,请在回复中提及。感谢阅读。
强化学习——瓦片编码实现
分块编码的逐步解释
我们已经走了这么远,并将我们的强化学习理论扩展到连续空间中(连续空间中的一般化)。如果你想更进一步,你需要知道瓦片编码,这可能是在连续空间,强化学习问题中使用的最实用和计算效率最高的工具。本质上,瓦片编码是连续状态空间中的特征表示,在本帖中,你将:
- 学习瓦片编码的思想
- 逐步实现图块编码
- 用 Q 函数整合并应用它
什么是瓷砖编码?
最简单的例子是我们在上一篇文章中学到的状态聚合。回想一下,在 1000 个状态的随机行走示例中,我们将 1000 个状态分成 10 组,每组 100 个状态,这样我们可以用二进制格式表示每个状态,也就是说,对于特定组内的状态,它是 1,否则是 0。其实这就是最简单形式的瓦片编码,只有 1 个状态分量和 1 个平铺(你可以把它想成一个表现层)。
毫无疑问,仅用 1 个分块来表示要素是有缺陷的(您可以将它想象成网格),因此这里出现了多个分块和多维要素:
Tile Coding
图中示出了在 2D 连续状态空间中使用瓦片编码的例子。在图的左边,状态空间由 1 个平铺显示表示,它本质上只是一个 2D 网格。注意灰色区域是特征空间,蓝色线条的 2D 网格是我们的平铺,它覆盖了整个状态空间区域(不一定要紧密贴合在特征空间中)。在这个表示中,白点,也就是我们的状态值,对于它所属的网格可以表示为 1,对于其余的网格可以表示为 0。
在右侧,该表示扩展到多个镶嵌,每个镶嵌具有不同的偏移。在此设置下,白点由 4 个不同的镶嵌表示,这 4 个不同的网格包括每个镶嵌中的白点。
从图中我们可以看到,只有一个切片的切片编码本质上是状态聚合,其中一个要素将只由它所属的切片来表示,而多个切片通过用属于每个切片的多个切片来表示一个要素来扩展这一思想。这种扩展更加强大,因为每个状态值可以共享一些瓦片,同时也属于不同的瓦片,这是一般化的本质。
逐步实施
如果你仍然对这个想法感到困惑,不要担心,在这个环节中,我们将一步一步地实现一个平铺编码。(全面实施)
让我们首先为 1 个要素创建 1 个切片:
我认为这个单行函数解决了您的大部分困惑。例如,给定一个范围为[0, 1]
的特征,该函数将它平均分成10
个箱,最后的格网加上一个0.2
的偏移量。测试结果显示在底部,范围从0.3
到1.1
,一个值的编码将是它所属的 bin 的顺序,例如给定一个特征值0.35
,它在0.3
到0.4
的范围内,它的编码将是1
,同样,小于0.3
的值编码为0
,大于1.1
的值编码为9
。
由于该函数能够为一个要素创建一个切片,让我们将其扩展到多个要素的多个切片:
现在输入feature_ranges
将是多个特征的特征范围列表。bins
是每个图块上设置的面元列表,offset
也是如此。例如,假设我们有 2 个要素,每个要素的范围分别为[-1, 1]
和[2, 5]
,我们想要创建3 tilings
,每个要素都有一个大小为10x10
的 2D 格网和不同的偏移,那么结果切片形状将为(3, 2, 9)
,代表n_tilings x n_features x (n_bins - 1)
(注意,箱数减 1,以确保大于范围的值得到 n _ 箱的编码)。
最好把它想象成一个立方体,正面是特征值的网格,第三维是镶嵌的数量。
现在我们已经准备好了镶嵌,让我们为每个输入特征值进行编码:
对于每个镶嵌和每个特征,这个函数得到它在那个维度上的编码,并最终连接结果。以我们上面设置的镶嵌为例,给出一个特征[0.1, 2.5]
,它的编码在第一个镶嵌(层)上是[5, 1]
,在第二个镶嵌上是[4, 0]
,在最后一个镶嵌上是[3, 0]
(注意这里偏移是如何起作用来区分不同镶嵌上的特征的)。
与 Q 函数集成
准备好平铺编码后,是时候将它用于 Q 值函数了。(点击查看完整实现)
这是将瓦片编码与 Q 函数结合的一般形式。在init
函数中,我们定义了一个self.q_tables
,其中每个q_table
都有一个大小为n_bins x n_bins x n_actions
的n_tilings
q 个表。想法是给定一个状态、动作和目标值,该动作将有助于对每个 q 表中的特定切片进行切片,并且该切片值将相应地更新。
value
函数获取状态、动作并返回其值。瓦片编码的主要优点之一是其计算效率。回想一下随机漫步中的状态聚集示例,给定状态的值就是该状态所属的 bin 的值,类似地,给定状态的值,这里的 action 等于每个平铺中平铺值的总和 ( 返回值被 num_tilings 除的原因是在更新过程中每个平铺都被未除的学习率更新。如果我们设置 self.lr = lr/num_tilings
,那么返回值就不需要除以)。
在update
函数中,由于这里的导数实际上是 1,所以用时间差乘以一个固定的学习率来更新每个图块,并且因为init
函数中的学习率没有除以图块的数量,所以加在一起的更新值近似于n_tilings*lr
,因此需要在value
函数中进一步除。
结论
在这篇文章中,我们一起实现了一个平铺编码,并学习了如何使用它的 Q 函数。与参数函数逼近相比,瓦片编码将连续空间离散化,通过获取活动瓦片的索引并进行一些简单的运算,使得学习过程在计算上更加高效。瓷砖编码是一个强大的工具,我们将在未来的帖子中使用它来解决一些更有趣的例子。
最后,感谢您的跟进,如果您有任何问题,请在下面留下您的评论。
参考:
- http://incompleteideas.net/book/the-book-2nd.html
- https://github . com/uda city/deep-enforcement-learning/tree/master/tile-coding
强化学习教程第 1 部分:Q-学习
这是关于强化学习的系列教程的第一部分。我们将从一些理论开始,然后在下一部分的中继续讨论更实际的东西。在这个系列中,您不仅将学习如何训练您的模型,还将学习使用 Valohai 深度学习管理平台在具有完全版本控制的云中训练它的最佳工作流程。
什么时候使用强化学习?
当你没有关于问题的训练数据或足够具体的专业知识时,强化学习是有用的。
在高层次上,你知道自己想要什么,但不知道如何去实现。毕竟,就连李·塞多尔也不知道如何在围棋中击败自己。
幸运的是,你所需要的只是一个奖励机制,如果你让它“玩”足够长的时间,强化学习模型会找出如何最大化奖励。这类似于教狗用零食坐下。起初,这只狗毫无头绪,在你的命令下尝试随机的事情。在某个时候,它意外地用屁股着地,得到了突然的奖励。随着时间的推移,并给予足够的迭代,它会找出专家的策略,坐在提示。
地牢中的会计师示例
这是强化学习的官僚版本。一个会计发现自己在一个黑暗的地牢里,他所能想到的就是走来走去填写电子表格。
会计知道的:
- 地牢有 5 块瓷砖长
- 可能的操作有向前和向后
- 向前总是一步,除了最后一个瓷砖碰到墙
- 后退总是带你回到起点
- 有时会有风把你的动作吹向相反的方向
- 您将在一些瓷砖上获得奖励
会计不知道的是:
- 进入最后一张牌会给你+10 奖励
- 进入第一个方块给你+2 奖励
- 其他瓷砖没有奖励
会计师,作为一名会计师,将遵循一个安全(但幼稚)的策略:
- 总是根据你的会计选择最有利可图的行动
- 如果会计显示所有选项都为零,请选择一个随机操作
让我们看看会发生什么:
会计师似乎总是喜欢向后走,即使我们知道最优策略可能总是向前走。最好的奖励(+10)毕竟在地下城的尽头。因为有一个随机因素有时会使我们的行动转向相反的方向,会计师实际上有时会不情愿地到达另一端,但根据电子表格仍然犹豫选择向前。这是为什么呢?
很简单,因为他选择了一个非常贪婪的策略。在非常短暂的初始随机性中,会计师可能愿意选择向前一次或两次,但一旦他选择向后一次,他就注定永远选择向后。玩这个地下城需要长期的计划,拒绝较小的直接奖励,以获得更大的奖励。
什么是 Q-learning?
q 学习是所有强化学习的核心。AlphaGO 战胜 Lee Sedol 或 DeepMind 击败老款 Atari 游戏从根本上来说都是在糖的基础上进行的 Q 学习。
Q-learning 的核心是像马尔可夫决策过程(MDP) 和贝尔曼方程这样的东西。虽然详细理解它们可能会有好处,但现在让我们将其简化为一种更简单的形式:
行动的价值=即时价值+所有最佳未来行动的总和
这就像估算一个大学学位相对于退学的经济价值。你需要考虑的不仅仅是你第一份薪水的直接价值,而是你一生中所有未来薪水的总和。一个行动总是导致更多的行动,你选择的道路总是由你的第一个行动决定。
也就是说,仅仅关注行动是不够的。执行的时候需要考虑自己所处的状态。当你 17 岁和 72 岁时进入大学是完全不同的。第一个可能是一个财务上积极的赌注,而后者可能不是。
那么你如何知道哪些未来行动是最优的呢?嗯——你不知道。你要做的是根据你当时掌握的信息做出最佳选择。
想象一下,你可以不止一次,而是一万次地重演你的人生。起初,你会很随意地去做,但是在几千次尝试之后,你会有越来越多的关于产生最佳回报的选择的信息。在 Q-learning 中,“你所拥有的信息”是从你以前的游戏中收集的信息,并编码到一个表格中。
所以从某种意义上说,你就像上一个例子中的会计,总是随身携带一个电子表格。不过,你将会以一种更微妙的方式更新和阅读你的电子表格。你也会把它叫做 Q 表而不是电子表格,因为它听起来更酷,对吗?
Q 学习算法
Q-learning 算法的形式如下:
它看起来有点吓人,但是它做的很简单。我们可以将其概括为:
根据我们得到的奖励和我们下一步期望的奖励,更新行动的价值评估。
这是我们正在做的根本事情。T2 学习率 T3 和 T4 折扣 T5 虽然是必需的,但只是用来调整行为。折扣将决定我们对未来预期行动价值与我们刚刚经历的行动价值的权衡程度。学习率是一个总的油门踏板。开得太快,你会错过最佳时机,开得太慢,你永远也到不了。
但是这个算法是不够的——它只是告诉我们如何更新我们的电子表格,但没有告诉我们如何使用电子表格在地牢中的行为!
地牢里的赌徒的例子
让我们看看我们将如何在一个地牢里用我们的花式 Q 表和一点赌博来行动。我们将选择一些更加细致入微的东西,而不是我们的会计师使用的照章办事的策略
我们的战略:
- 默认情况下,从我们的电子表格中选择最有利可图的行动
- 有时赌博并选择随机行动
- 如果会计显示所有选项都为零,请选择一个随机操作
- 从 100%赌博(探索)开始,慢慢向 0%移动
- 使用折扣= 0.95
- 使用 learning_rate = 0.1
为什么我们需要赌博和随机行动?原因和会计被困住了一样。因为我们的默认策略仍然是贪婪的,也就是说,我们默认选择最有利可图的选项,我们需要引入一些随机性来确保所有可能的对都被探索。
为什么我们需要停止赌博,降低我们的探索率?是因为达成最优策略的最佳方式是先积极探索,然后慢慢走向越来越保守。这个机制是所有机器学习的核心。
说够了。我们的赌徒正在进入地牢!
唷!那是一大堆东西。
注意,为了举例,我们做了很多赌博来证明一个观点。不仅仅是赌博,我们把硬币抛向右边,所以这通常是非常不寻常的前十几步!
与会计师的策略相比,我们可以看到明显的不同。这种策略收敛较慢,但我们可以看到顶行(向前)比底行(向后)得到的估值更高。
还要注意在最初的+10 奖励后,估价开始从右到左“泄漏”到顶行。这是允许 Q 表“预见未来”的基本机制。关于发生在最后一块瓷砖上的奖励丰厚的事情的消息慢慢流向左侧,最终到达我们电子表格的最左侧,这种方式允许我们的代理提前许多步预测好事情。
如果你被上面一步一步运行的信息过载搞糊涂了,就冥想这张图片,因为它是本文中最重要的一张。如果你理解了为什么信息会“泄露”以及为什么它是有益的,那么你就会理解整个算法是如何工作的以及为什么会工作。
就是这样!在的下一部分中,我们将提供一个教程,介绍如何使用 Valohai 深度学习管理平台在云中用代码实现这一点并运行它!
原载于blog.valohai.com。
强化学习教程第 2 部分:云 Q 学习
在第一部分中,我们用一个非常简单的地牢游戏研究了 Q-learning 背后的理论,这个游戏有两个策略:会计和赌徒。第二部分使用 Valohai 深度学习管理平台,将这些例子转化为 Python 代码,并在云中训练它们。
由于我们示例的简单性,我们不会故意使用任何像 TensorFlow 这样的库或像 OpenAI Gym 这样的模拟器。相反,我们将从头开始自己编写代码,以提供完整的画面。
所有的示例代码都可以在 https://github.com/valohai/qlearning-simple 的找到
代码布局
典型的强化学习代码库有三个部分:
- 模拟
- 代理人
- 管弦乐编曲
模拟是代理人操作的环境。它根据其内部规则和代理执行的动作更新状态并分发奖励。
Agent 是在模拟中操作、学习和执行策略的实体。它执行动作,接收带奖励的状态更新,并学习一种策略来最大化它们。
编排是所有剩余的样板代码。解析参数,初始化环境,在模拟和代理之间传递数据,最后关闭商店。
模拟
我们将使用第 1 部分中介绍的地牢游戏。这些是规则:
- 地牢有 5 块瓷砖长
- 可能的操作有向前和向后
- 向前总是一步,除了在最后一个瓷砖碰到墙
- 后退总是带你回到起点
- 有时会有风把你的动作吹向相反的方向
代理未知:
- 进入最后一张牌会给你+10 奖励
- 进入第一个方块给你+2 奖励
- 其他瓷砖没有奖励
代理人
在教程的第一部分,我们介绍了两种策略:会计和赌徒。会计只关心过去的业绩和保证的结果。赌徒更渴望探索风险更高的选项,以在未来获得更大的回报。也就是说,为了保持第一个版本的简单,引入了第三个策略:酒鬼。
酒鬼是我们的基本策略,有一个非常简单的启发:无论如何都要随机行动。
管弦乐编曲
现在我们已经有了模拟和代理,我们需要一些样板代码将它们粘在一起。
地牢模拟是回合制的,所以流程很简单:
- 向代理查询下一个动作,并将其传递给模拟
- 获取新的状态和奖励,并将其传递给代理
- 重复
基础设施
虽然有可能在本地运行这样的简单代码,但目标是提供一个如何正确编排更复杂项目的示例。
机器学习不等于软件开发。仅仅将代码推送到 Git 存储库是不够的。为了完全的再现性,您需要对数据、超参数、执行环境、输出日志和输出数据进行版本控制。
在本地运行也会让你慢下来。虽然玩具示例通常会给人一种快速迭代的错觉,但为真实问题训练真实模型并不适合您的笔记本电脑。毕竟,它一次只能运行一个训练执行,而基于云的环境让你可以同时启动几十个训练执行,同时拥有快速的 GPU、轻松的比较、版本控制和对同事更大的透明度。
瓦罗海设置
前往valohai.com并创建一个账户。默认情况下,您的帐户上有价值 10 美元的信用,足以在云实例上运行以下培训。
注册后,点击跳过教程或者打开右上角的项目下拉菜单,选择创建项目。
给你的项目起一个有意义的名字,然后点击下面的蓝色创建项目按钮。
在 https://github.com/valohai/qlearning-simple的示例 git 存储库中,我们已经有了我们的代码和 valohai.yaml。
我们只需要告诉瓦罗海他们在哪里。点击上面截图中的项目库设置链接或导航到设置>库选项卡。
将存储库 URL 粘贴到 URL 字段,确保获取引用为“主”,然后点击保存。
执行!
一切就绪,现在是我们第一次执行的时候了。
点击 Valohai 项目执行选项卡中的蓝色创建执行按钮。
Git 存储库中的 valohai.yaml 文件为我们提供了所有正确的默认值。如果你想了解更多关于 valohai.yaml 的信息,请查阅文档。
点击底部的蓝色创建执行按钮。
在 Valohai 中运行一个执行意味着大致会发生以下序列:
- 启动一个新的服务器实例
- 您的代码和配置(valohai.yaml)是从 git 存储库中获取的
- 下载训练数据
- 下载并实例化 Docker 映像
- 基于 valohai.yaml +您的参数执行脚本
- 所有标准输出都存储为 log + JSON 格式的元数据,并针对图表进行解析
- 为了以后的可再现性,整个环境是受版本控制的
- 脚本完成后,服务器实例会自动关闭
只需点击一下鼠标,你就能得到如此多的东西,这难道不令人惊奇吗?
如果您前往执行的元数据标签,您可以看到我们的酒鬼策略代理如何收集奖励。毫不奇怪,采取随机行动的策略会产生一条几乎有轻微抖动的直线,这告诉我们没有学习发生。
会计
在运行了基线随机策略之后,是时候带回在教程的第一部分中介绍的两个原始策略了:会计和赌徒。
会计师有以下策略:
- 总是选择基于会计的最有利可图的行动
- 如果所有选项都为零,则选择一个随机操作
要执行会计,记得更改执行的代理参数,然后再次单击蓝色的创建执行。
查看元数据选项卡,会计在学习方面也好不到哪里去。曲率甚至更直,因为在最初的几次迭代后,它将学会总是选择向后,以获得一致的+2 奖励,而不是像随机的醉汉一样摇摆。
不过,总奖励大约是+4000。至少有所改善!
赌徒
从我们的三个代理人,赌徒是唯一一个做真正的 Q 学习。还记得我们在第一部分中的算法吗:
该战略如下:
- 默认情况下,从我们的 Q 表中选择最有利可图的行动
- 有时赌博并选择随机行动
- 如果 Q 表显示两个选项都为零,选择一个随机动作
- 从 100%赌博(探索)开始,慢慢向 0%(剥削)移动
最后,我们可以看到一些真正的 Q 学习正在发生!
在以高探索率缓慢开始后,我们的 Q 表充满了正确的数据,与我们的其他代理相比,我们达到了几乎两倍的总回报。
并行执行
到目前为止,我们一次只运行一个执行,如果您想快速迭代您的模型探索,这并不能很好地扩展。在我们最后的努力中,我们将尝试运行 Valohai 任务,而不是一次性执行。在 Valohai 中,一个任务仅仅意味着执行一组具有不同超参数的执行。
切换到 Valohai 中的任务选项卡,然后点击蓝色创建任务按钮。
让我们看看 learning_rate 参数如何影响我们的性能。选择倍数,然后在不同行输入三个不同的选项(0.01,0.1,0.25)。最后,点击底部蓝色的创建任务开始执行。
Valohai 现在将并行启动不是一个而是三个服务器实例。每个带有数字的方框代表一个具有不同 learning_rate 的运行实例。一旦颜色变成绿色,就意味着执行已经完成。您还可以在执行过程中实时查看元数据图表!
下面是 learning_rate 三个不同值的奖励。看起来我们最初的 0.1 比 0.25 表现得好一点。使用 0.01 显然更糟,并且对于 10000 次迭代似乎根本学不到任何东西。
在我们的下一部分中,我们将更深入地研究并行执行,以加速我们的迭代,并看看如何有效地使用 Valohai 来搜索那些最优的超参数。敬请期待!
原载于blog.valohai.com。
强化学习教程第 3 部分:基本深度 Q 学习
在第 1 部分中,我们通过纸笔示例介绍了 Q-learning 的概念。
在第 2 部分中,我们用代码实现了这个例子,并演示了如何在云中执行它。
在第三部分中,我们将把我们的 Q 学习方法从 Q 表转移到深度神经网络。
使用 Q-table,你的内存需求是一个由状态 x 动作组成的数组。对于状态空间 5 和动作空间 2,总的内存消耗是 2 x 5=10。但是国际象棋的状态空间大约是 10 ⁰,这意味着这种严格的电子表格方法不能扩展到现实世界。幸运的是,你可以从媒体压缩的世界里偷到一个窍门:用一些准确性换取内存。
在无损压缩的情况下,以每秒 60 帧的速度存储 1080p 视频每秒大约需要 1gb。使用有损压缩的相同视频可以很容易地成为 1/10000 大小,而不会损失太多保真度。幸运的是,就像视频文件一样,用强化学习训练模型从来都不是 100%真实的,一些“足够好”或“比人类水平更好”的东西已经让数据科学家微笑了。因此,我们很乐意用准确性换取记忆。
我们不是从 Q 表中取一个“完美的”值,而是训练一个神经网络来估计这个表。毕竟,神经网络只不过是一个美化了的权重和偏好表而已!
我们的示例游戏是如此简单,以至于我们很可能用神经网络比用 Q 表使用更多的内存!任何真实世界的场景都比这复杂得多,所以这只是我们试图保持示例简单的一个假象,而不是一个普遍趋势。
培养
我们之前做 Q-learning 的时候,用的是上面的算法。用神经网络代替 Q 表,我们可以简化它。
不再需要学习率,因为我们的反向传播优化器已经有了。学习率只是一个全球油门踏板,你不需要两个。一旦去除了学习率,你意识到你也可以去除两个 Q(s,a)项,因为它们在去除学习率后相互抵消。
强化学习通常被描述为独立于监督学习和非监督学习的一个类别,然而这里我们将从我们的监督表亲那里借用一些东西。据说强化学习不需要训练数据,但这只是部分正确。事先不需要训练数据,但是在探索模拟时收集训练数据,并且使用非常类似。
当代理探索模拟时,它将记录体验。
单次体验=(旧状态,动作,奖励,新状态)
用单一体验训练我们的模型:
- 让模型估计旧状态的 Q 值
- 让模型估计新状态的 Q 值
- 使用已知的奖励,计算行动的新目标 Q 值
- 用输入=(旧状态),输出=(目标 Q 值)训练模型
注意:我们的网络不像 Q 学习函数 Q(s,a)那样得到(状态,动作)作为输入。这是因为我们没有复制 Q 学习作为一个整体,只是 Q 表。输入只是状态,输出是该状态下所有可能动作(向前、向后)的 Q 值。
代码
在上一部分中,我们足够聪明地将代理、模拟和编排作为单独的类分开。这意味着我们可以只引入一个新的代理,其余的代码基本保持不变。如果你想看剩下的代码,请看第二部分或者 GitHub repo。
定量
在我们的例子中,我们在模拟的每一步之后重新训练模型,一次只有一次体验。这是为了保持代码简单。这种方法通常被称为在线培训。
更常见的方法是将所有(或许多)经历收集到记忆日志中。然后,根据从日志中批量提取的多个随机经验来训练该模型。这被称为批量训练或小批量训练。它比强化学习更有效,并且通常提供更稳定的整体训练结果。将这个例子转化为批量训练是非常容易的,因为模型的输入和输出已经成形为支持批量训练。
结果
这里是一些使用 Valohai 贝叶斯优化器的不同学习率和折扣的训练运行。请注意,这里我们衡量的是绩效,而不是像前几部分那样衡量总薪酬。上升趋势是两件事的结果:学习和剥削。学习意味着模型像往常一样学习最小化损失和最大化回报。开发意味着,既然我们从赌博和探索开始,并越来越线性地转向开发,我们会在最后得到更好的结果,假设学习的策略已经开始在这个过程中有任何意义。
用深度神经网络训练这样的玩具模拟无论如何都不是最优的。模拟不是非常细致,奖励机制非常粗糙,深度网络通常在更复杂的场景中茁壮成长。通常在机器学习中,最简单的解决方案最终会成为最好的解决方案,所以在现实生活中不建议像我们这样用大锤砸坚果。
既然我们已经学会了如何用神经网络来取代 Q-table,我们就可以处理更复杂的模拟,并在下一部分中充分利用 Valohai 深度学习平台。回头见!
在 GitHub 开始这个 Q-learning 教程项目。
原载于blog.valohai.com。
使用单一演示的强化学习
从演示中学习
强化学习对未来有很大的希望;最近的成就显示了它在超级人类水平上解决问题的能力,像玩棋盘游戏,控制机械臂和在专业水平上玩实时策略游戏。这些成就展示了发现新策略的能力,这些新策略优于我们人类能够设计的策略,这是一个令人兴奋的前景。
RL 的另一个可能用途是在人的表现足够好的情况下,使人的决策自动化。在这个设置中,我们希望我们的代理模仿人类专家使用的策略,这为我们的代理提供了完成任务的“正确”方法的演示。这在几种情况下非常方便,例如:
a)当我们不能制定奖励函数,但是我们可以询问专家来指导学习过程,或者已经记录了专家的行为及其结果的数据时。这方面的一个实际例子可能是尝试学习“帮助台”风格的政策,其中我们的代理需要与客户互动并帮助解决他们的问题。由于我们不能很容易地对顾客的回报函数进行建模,我们不能采用标准的 RL 技术,但是我们可以利用人类专家的日志来学习策略。
b)当我们有一个“标准”类型的学习问题,但从头开始学习太难了,我们的算法完全失败了。专家的示范可以帮助我们的学习算法朝着正确的方向前进
需要注意的重要一点是,专家不一定必须是人类。也许我们有一个优化或搜索算法可以完成这项工作,但对于我们的实时应用程序来说,它太慢了,我们需要使用学习的神经网络策略来近似它。在这种设置下,搜索算法可以在整个过程中为学习算法提供专家演示。
在某种意义上,从人类演示中学习更具挑战性,因为让人类在整个学习过程中坐下来并在必要时提供建议通常是不实际的,不像我们的搜索算法那样。人类专家的时间很可能是昂贵的,因此我们通常只有少量的这种数据。
模仿学习
那么,我们如何利用专家的演示来学习政策呢?一个显而易见的和天真的方法是使用演示作为标记数据,并使用监督学习来尝试和预测专家在不同状态下采取的行动。监督学习比 RL 更容易理解,如果我们能够很好地预测行动,那么我们的代理就会表现得相对较好,或者至少在某种程度上接近专家。
然而,可悲的是,这种方法在许多情况下单独使用时非常失败。在大多数现实问题中,状态空间是非常大的,我们可能演示的状态的数量只是其中的一小部分。由于政策学习本质上处理多步骤过程,并且我们的天真的监督学习方法学习对单个状态的响应,所以一个事件开始时的小分歧可能会产生复合效应,将我们的代理带到它从未观察到并且不知道如何行动的状态。
这种行为克隆的另一个问题是,我们的学习过程没有优化我们想要的指标,即从剧集中累积的回报,而是最小化模型预测和专家行动之间的距离。显然,如果我们的模型完美地预测了走势,它也会产生相同的回报,但是预测误差如何转化为回报的差异呢?小错误可能会对代理在我们任务中的表现产生很大影响。
为了有希望成功地使用这种方法,我们必须有大量的数据,涵盖非常广泛的国家,这可能是我们所没有的。即便如此,行为克隆也经常被用作另一种强化学习算法的初始化,以加快学习基础知识的过程。例如,最初的 AlphaGo 使用从在线游戏中收集的 3000 万人类专家棋步数据集来训练其策略网络,最近的 AlphaStar 代理使用职业玩家游戏进行初始化,然后两者都使用 RL 算法进行进一步训练。
从一次演示中学习
近年来的几篇论文研究了使用人类演示来帮助代理学习困难问题的选项。经常被用作基准的一个众所周知的难题是 Montezuma 的复仇,这是一个 Atari 游戏,奖励极其稀疏和延迟,大多数标准 RL 算法都无法在其中取得哪怕是很小的进展。
谷歌 DeepMind 的研究人员发表了一篇关于这个主题的非常有趣的论文,名为“通过观看 YouTube 玩艰难的探索游戏”。在这篇论文中,研究人员收集了许多人类玩家玩游戏的 YouTube 视频,训练了一个神经网络来预测同一集不同帧之间的时间差。这产生了来自不同来源的游戏状态的有意义的嵌入,具有视觉变化,如略微不同的颜色和分辨率,这使得沿着嵌入轨迹“种植”虚拟奖励成为可能,代理人可以从嵌入轨迹中得知它在正确的轨道上。
虽然这种方法很好地利用了丰富的资源——YouTube 视频,但它可能不适用于许多数据很少的问题。OpenAI 的研究人员在最近一篇名为“从一次示威中学习蒙特祖马的复仇”的论文中解决了这个问题。解决方案非常简单:给定一个由专家提供的状态-动作轨迹,在轨迹的末端重新启动代理,并让它使用一些 RL 算法自行学习,然后在轨迹的早期逐步重新启动它,直到最终从头重新启动它,并让它从那里学习。
其背后的想法是,通过在轨迹的末端重新启动它,我们将它放置在奖励附近,事实上如此接近,以至于标准的 RL 算法将毫不费力地找到它。当代理已经学会满意地找到奖励时,我们在专家给出的状态-行动轨迹的更早部分重新启动它,并让它从那里学习。
为了直观地理解为什么这是一个好主意,让我们看看作者在论文中提供的一个简单的玩具问题;盲崖行走问题。在这个问题中,代理人必须使用两个动作中的任何一个,穿越一维悬崖回到安全的地方。第一个动作使它沿着悬崖前进,第二个动作使它坠落并死去。我们假设一个表格设置,其中代理不能在状态之间进行归纳,并且必须学习一个为每个状态指定一个动作的表格。
代理人只有在达到目标状态时才会收到奖励,因此必须首先使用随机动作来探索其环境。然而,期望达到回报所需的行动数量是悬崖长度的指数,这使得它在很短的长度之外不切实际。作者表明,通过一次成功的演示并使用所提出的方法,解决这一任务的时间与悬崖的长度成二次关系,这是一个巨大的进步。
作者指出,这非常像动态编程,在动态编程中,我们通常从最后开始向后解决问题,并引导我们的后期解决方案来帮助快速解决早期阶段。在动态编程中,我们实际上观察到对于诸如图中最短路径的问题,计算复杂性的非常相似的减少。
研究人员将这种方法用于臭名昭著的蒙特祖马的复仇,并获得了当时最先进的结果,以相当大的优势击败了 DeepMind 论文的分数,并使用了少得多的数据。
这种方法的一个明显的缺点是,它需要有能力在沿着规定轨迹的不同状态下重新启动我们的代理,这意味着我们必须自由控制环境,或者它是确定性的,以便采取相同的动作序列将总是导致相同的状态。但是,如果该方法适用,它有两个主要优点:
1)它需要很少的数据,正如论文中所证明的,甚至一个单独的轨迹就足以解决困难的问题。
2)它直接针对返回进行优化,因为轨迹仅用于初始化代理,并从那里开始使用标准 RL 进行学习。这使得原则上代理实际上比专家演示者表现得更好成为可能。
我总是喜欢简单的想法非常有效,这是一个很好的例子。检查纸。
强化学习——价值函数
利用价值函数的代理学习井字游戏的强化学习算法
直觉
在漫长的一天工作之后,你在两个选择之间做决定:回家写一篇中型文章或者和朋友去酒吧。如果你选择和朋友出去玩,你的朋友会让你感到快乐;然而,当你回家写文章时,在工作了一整天后,你会感到疲惫。在这个例子中,享受自己是一种奖励,感觉疲劳被视为一种消极的奖励,那么为什么要写文章呢?
因为在生活中,我们不会只考虑眼前的回报;我们计划了一系列的行动来决定未来可能的回报。也许写一篇文章会让你对某个特定的话题有更好的理解,得到认可,最终让你得到你梦寐以求的工作。在这个场景中,得到你梦想中的工作是从你采取的一系列行动中得到的延迟回报,然后我们想为处于这些状态的人分配一些值(例如“回家写一篇文章”)。为了确定一个状态的值,我们称之为“价值函数”。
那么我们如何从过去吸取教训呢?假设你做了一些伟大的决定,并且处于人生中最好的状态。现在回顾一下你为达到这个阶段所做的各种决定:你把你的成功归功于什么?之前让你走向这种成功的状态是什么?你过去做过的哪些行为让你达到这种收到这个奖励的状态?你现在正在做的事情和你将来可能得到的回报有什么关系?
奖励与价值函数
一个奖励立竿见影。它可以是在收集硬币的游戏中得分,赢得井字游戏或获得你梦想的工作。这个奖励就是你(或者代理)想要获取的。
为了获得奖励,价值函数是确定处于状态的价值的有效方法。用 V(s) 表示,这个价值函数衡量我们在这种状态 s 下可能获得的潜在未来回报。
定义价值函数
Fig 1: State A leads to state B or C
在图 1 中,我们如何确定状态 A 的值?有 50–50%的机会在下两个可能的状态中结束,状态 B 或 c。状态 A 的值就是所有下一个状态的概率乘以达到该状态的奖励。状态 A 的值为 0.5。
Fig 2: One-way future states
在图 2 中,您发现自己处于状态 D,只有一条可能的路径通往状态 E。由于状态 E 给出的奖励为 1,状态 D 的值也为 1,因为唯一的结果是获得奖励。
如果你处于状态 F(在图 2 中),这只能导致状态 G,接着是状态 H。由于状态 H 的负奖励为-1,状态 G 的值也将为-1,对于状态 F 也是如此
Fig 3: Being in state J brings you closer to state K
在这个井字游戏中,连续得到 2 个 X s(图 3 中的状态 J)并不能赢得游戏,因此没有奖励。但是处于状态 J 会使你离状态 K 更近一步,完成一行 X 就能赢得游戏,因此处于状态 J 会产生一个好的值。
Fig 4: State M has a higher value than state N
在图 4 中,您会发现自己处于状态 L,正在考虑将下一个 X 放在哪里。您可以将它放在顶部,这样就可以将您带到状态 M,在同一行中有 2 个 X s。另一种选择是将其放在最下面一行。与状态 N 相比,状态 M 应该具有更高的重要性和值,因为它导致更高的获胜可能性。
因此,在任何给定的状态下,我们可以执行动作,通过选择产生最高值的状态,使我们(或代理人)更接近获得奖励。
井字游戏—初始化值函数
井字游戏的价值函数 V(s) 是达到状态 s 的获胜概率。完成该初始化以定义获胜和失败状态。我们将状态初始化如下:
- V(s) = 1 —如果代理在状态 s 中赢得游戏,则为终止状态
- V(s) = 0 —如果代理在状态 s 中输掉或打平游戏,则为终止状态
- V(s)= 0.5——否则为非终止状态的 0.5,这将在训练期间进行微调
井字游戏—更新值函数
更新值函数是代理如何从过去的经验中学习,通过更新在训练过程中经历的那些状态的值。
Fig 5: Update the value of state s
状态s’是当前状态 s 的下一个状态。我们可以通过添加状态 s 和s’之间的值的差值来更新当前状态 s 的值。α是学习率。
由于在任何给定的状态下可以采取多种行动,所以在一个状态下经常只选择一种行动可能会导致错过其他更好的状态。在强化学习中,这就是探索-利用困境。
通过探索策略,代理采取随机行动来尝试未探索的状态,这可能会找到其他方法来赢得游戏。通过利用策略,代理能够增加那些在过去有效的行动的信心,以获得奖励。在探索和利用之间取得良好的平衡,并通过玩无限多的游戏,每个状态的值将接近其真实概率。探索和利用之间的良好平衡由ε贪婪参数决定。
当游戏结束时,在知道代理人是赢了(奖励= 1)还是输了/平了(奖励= 0)之后,我们只能更新代理人在该特定游戏中已经玩过的每个状态的值。终端状态只能是 0 或 1,我们确切地知道哪些是在初始化期间定义的终端状态。
代理的目标是在游戏结束后更新价值函数,以了解已执行的动作列表。当每个状态的值使用下一个状态的值更新时,在每个游戏结束时,更新过程向后读取该特定游戏的状态历史,并微调每个状态的值。
井字游戏—利用价值函数
Fig 6: Values of various next states
给定足够的训练,代理将会学习任何给定状态的值(或获胜概率)。因此,当我们与我们训练有素的代理人进行游戏时,代理人会使用利用策略来最大化胜率。看能不能打赢代理。
在游戏的每一个状态,代理循环通过每一种可能性,挑选具有最高值的下一个状态,从而选择最佳的行动过程。在图 6 中,代理将选择右下角来赢得游戏。
结论
在除了结束阶段(记录了赢、输或平)之外的任何进展状态,代理采取了导致下一个状态的行动,这可能不会产生任何奖励,但会导致代理向接收奖励靠近一步。
价值函数是确定处于一种状态的值的算法,即获得未来奖励的概率。
每个状态的值通过游戏的状态历史按时间顺序反向更新,通过使用探索和利用策略进行足够的训练,代理将能够确定游戏中每个状态的真实值。
有许多方法可以定义一个值函数,这只是一个适合井字游戏的方法。
40%的吸尘器,40%的看门人,20%的算命师。
towardsdatascience.com](/data-scientist-the-dirtiest-job-of-the-21st-century-7f0c8215e845)
嗨!,我是叮当。我喜欢构建机器学习项目/产品,我在迈向数据科学上写了它们。在 Medium 上关注我或者在 LinkedIn 上联系我。
用 AWS DeepRacer 进行强化学习
从玩具车到 AlphaGo 和自动特斯拉
2016 年 3 月,过去十年最伟大的围棋选手李·塞多尔(Lee Sedol)被 AlphaGo 以 4 比 1 击败。计算机以前在国际象棋上击败过最好的人类,但是围棋在复杂性上又上了一个台阶。你知道更疯狂的是什么吗*?这台机器在比赛前 8 小时才学会如何玩。*
今年 2019 年 1 月,谷歌 DeepMind 团队将 AlphaGo 带到了另一个高度,制作了 AlphaStar 。星际争霸是最复杂的视频游戏之一,它从来没有被电脑掌握过🤖以前,直到现在。AlphaStar 淘汰了两名世界级选手,以 5 比 0 击败了他们。
就在上个月,OpenAI(前 Elon Musk’s)发布了 多智能体捉迷藏 ,一个双方,寻找者和隐藏者之间的模拟。隐藏者必须避开视线👁在一个有墙、盒子和斜坡的世界里。出现了大量的策略,包括建造庇护所和箱子冲浪!查看下面的视频,了解更多信息👇
OpenAI’s video on their Multi-Agent Hide and Seek Simulation
最后但同样重要的是,就在两周前,OpenAI 发布了另一个惊人的结果,它训练了一只成功的机器人手解魔方。它不仅能在 60%的时间里用一只手解决不同大小的 3x3 魔方,还能在有干扰的情况下解决问题(比如被一只毛绒长颈鹿推来推去)🦒 ).
所有这些惊人的突破有什么共同点?他们都使用目前超级热的强化学习(RL)* 🔥机器学习领域。在高层次上,RL 涉及到一个演员在某个环境中通过试错来学习做什么。它被机器人、自动驾驶汽车甚至股市预测者雇佣来安全驾驶并给出准确的预测!***
说到自动驾驶汽车,亚马逊网络服务(AWS)最近创建了一个名为AWS DeepRacer的挑战🚗,主要目的是向开发人员介绍 RL。通过训练一辆汽车在赛道上行驶,参赛者比赛以达到最快的时间。我决定参加他们的挑战以及相应的 Udacity 课程,以更深入地了解 RL,我愿意与你分享它们!😃
更深入地了解 RL
本质上,强化学习是模仿现实世界,在进化中,以及人们如何👦和动物🐶学习。通过经验,我们人类学会了在不同的情况下做什么和不做什么,并将其应用到我们自己的生活中。RL 以同样的方式通过模拟体验来帮助机器学习。
让我们以 AWS DeepRacer 为例,通过描述一些关键术语来描述这个问题:
- ****代理/参与者:在环境中执行动作的实体(AWS DeepRacer 和控制它的模型)
- ****动作:代理可以做什么(汽车可以转弯、加速等)
- ****环境:代理存在的地方(轨迹)
- ****状态:给定时间内的关键特征(轨道上的位置)
- ****奖励:根据代理在前一状态中的动作给予代理的反馈(做得好的奖励高,做得差的奖励低)
下面是一个基本的 RL 模型是如何学习的:一个环境中的代理在其给定的状态下执行一个动作。环境给了代理一个奖励💸这取决于其行动的质量。然后代理执行另一个操作,循环继续。一个训练集由一定数量动作的整个循环组成。****
让我们更深入地研究一下奖励吧!
奖励里有什么?
奖励函数是 RL 模型中非常重要的一部分。对于一个训练有素的代理人来说,拥有一个激励最佳行为并抑制不良行为的机制是至关重要的。
在 AWS DeepRacer 中,我们创建了奖励函数💰用输入参数。这些包括汽车的位置、离中心的距离等等。下面是一个基本奖励函数的例子:****
Image by author
在该函数中,我们使用输入参数 params[‘track_width’] 和params[’ distance _ from _ center ']。我们创建了三个标记,并将赛车与中心线的距离与这些标记进行比较。如果汽车与中心的距离在 10%以内,它会得到 1 的奖励😊。如果在 25%以内,则给予 0.5 的奖励。如果在轨道上,它得到 0.1。如果偏离了轨道,我们给它 0.001,基本上等于零😢
Image by author
这个奖励功能会给坚持在赛道中间的车很高的奖励。知道了这一点,就会避免脱轨,这就是我们想要的!虽然这个奖励函数没有针对速度进行优化,但至少我们可以放心,我们可能会完成比赛。😅
调谐超参数
让我们讨论超参数:我们可以调整或“调整”的模型设置。通过在训练前调整超参数,我们可以尝试提高模型的性能💯。以下是我们可以调整的一些超参数的示例:
- 学习速率:模型学习的速度。如果学习率高,它学得快但可能达不到最佳状态。如果太低,可能需要很长时间训练。
- ****贴现因子:模型考虑未来的程度。如果更高,DeepRacer 就越看重未来,对考虑到未来的行动给予更高的奖励。如果低,DeepRacer 会以短期的方式思考。
- ****熵:不确定的程度。较高的值允许模型更彻底地探索环境,而较低的值允许模型利用它已经知道的东西。
- 还有更多!
有很多方法可以调整超参数,但没有正确的方法,只能通过实验来实现🔬🧪and 试错法。
培训和评估我们的模型
现在你已经知道了 AWS DeepRacer 的强化学习,让我们来训练和评估我们的虚拟模型吧!以下是步骤(注意,您可以通过创建一个 AWS 帐户来遵循这里的和):
- 在 AWS DeepRacer 控制台中创建一个模型。
- 设置名称、描述和轨道。
- 设置您的行动空间(模型可能采取的行动)。
- 创建你的奖励函数。
- 设置你的超参数。
- 开始训练!
在训练过程中,您的模型将按照您指定的时间⌚在虚拟赛道上进行训练,从一个状态转换到另一个状态,并在途中获得奖励。
The training dashboard for AWS DeepRacer, including training stats and a video stream; image by author
训练结束后,在任何赛道上对模型进行评估,看看效果如何。如果它表现良好,提交到排行榜🥇!如果没有,试着改变你的奖励函数和超参数,看看你能如何改进。毕竟,这是一个反复的过程😁
我们能从 AWS DeepRacer 身上学到什么?
我希望你在训练你的模型和在赛道上比赛时玩得开心!尽管与我们在 OpenAI 或谷歌的 DeepMind 上看到的相比,这是一个简单得多的模型,但我们仍然可以得出一些有价值的结论🔑
- 训练一个好的模型需要大量的时间、资源和实验。想想 DeepMind 花了多少时间训练 AlphaStar!这是一个真正的迭代过程。
- 设定一个最优的奖励函数至关重要。没有一个好的奖励函数,模型就不能正确地学习它的任务。如果一辆车没有动力留在赛道上,你可以指望它会很快崩溃。
- 强化学习正在掀起波澜。 AWS 让任何有资源的人都可以非常容易地拥有一个真正好的 RL 模型。我们已经看到了过去几个月的疯狂进步;想象一下我们将来会看到什么!
在 RL 领域有超级有趣的工作正在进行,你应该兴奋!不知不觉中,你就再也不能开自己的车了😏****
Photo by Bram Van Oost on Unsplash
希望你喜欢阅读 RL!我也将很快在 NLP 中做更深入的探索,所以一定要关注我并在 LinkedIn 上联系我!如果你想联系我,在 albertlai631@outlook.com 给我发信息。很想聊聊:)
祝您愉快,敬请期待更多精彩!👋
基于随机网络提取的探索式强化学习
自从 2013 年 DeepMind 的开创性 DQN 工作(其中一个代理人成功地学会了以高于人类平均水平的水平玩 Atari 游戏)以来,强化学习(RL)就经常成为头条新闻。从雅达利游戏到机器人技术,以及 AlphaGo 击败世界围棋冠军李世石,RL 似乎即将席卷世界。
事实上,虽然大多数 Atari 游戏现在都可以很好地学习,但有些游戏直到最近才取得相对较小的进展。这些游戏包括臭名昭著的蒙特祖马的复仇,陷阱!和冒险,其共同点是回报极其稀少。
为了理解为什么这是一个主要问题,让我们看看大多数强化学习算法的基本结构。
强化学习代理在与环境交互的同时通过试错来学习,并为自己的行为获得奖励。使用这些奖励信号,代理更新它的行为,并希望学会在未来做出更好的决定。在许多情况下,为了帮助代理探索环境并偶然发现导致更高回报的状态动作,我们通过从代理的当前策略中取样动作,或者通过随机选择具有某种概率的动作(ε-贪婪)来将随机性引入代理的行为。这些简单策略的基本假设是,随机行为最终会导致代理人获得某种回报。
在奖励很少的环境中,情况非常不同,因为代理可能大部分时间都没有收到任何奖励,因此可能很难学习。在极端的情况下,为了获得任何奖励,代理可能需要表现得非常聪明,并采用长而复杂的动作序列来获得第一次反馈。在一些艰难的探索游戏中就是这种情况,例如蒙特祖马的复仇,在这种游戏中,代理人必须避开敌人和致命的障碍,并在看到积极的奖励之前聪明地行动数百步。使用普通探索策略的标准 RL 算法在这些游戏中经常不能实现任何回报,并且这种情况一直持续到最近。
那么,你如何着手解决这样的问题呢?一个看起来很吸引人的方法是以某种方式鼓励代理去探索那些它到目前为止还没有看到的状态。如果我们能让它变得“好奇”,甚至在没有任何回报的情况下寻找新奇的状态,也许它最终会探索得足够多,找到一些。在某种程度上,这让我们想起了儿童学习的方式,好奇心是一种内在奖励。
我们想要做的是,计算代理访问每个州的次数,并向稀疏的外部奖励(来自环境)添加另一个元素,以到达访问次数较低的州的内在奖励的形式。如果我们能做到这一点,那么代理人将不断发现它以前没有见过的新状态,并最终达到一个具有积极外部奖励的状态。显然,为了得到想要的行为,必须在外在和内在奖励之间保持谨慎的平衡。
然而,在所有这些游戏中,状态的数量太大,无法一一列举,因此我们必须找到一种方法来近似计算访问次数。解决这个问题的早期建议是这样的:在训练代理人玩游戏的同时,训练另一个神经网络来预测代理人在玩游戏时遇到的状态转换和奖励。其思想是,最初,神经网络对这些转变和奖励的预测很差,但最终对于网络被训练的那些状态以及与它们相似的状态(由于 NNs 的泛化能力),预测和实际情况之间的距离减小。这意味着我们可以将这个神经网络的预测误差视为访问计数的近似值;如果给定状态的误差很高,则这表明该状态是新的,如果预测误差很低,则我们可以假设与此类似的状态已经被足够频繁地访问过。
这似乎是一个非常优雅的解决方案,但不幸的是,它有一个严重的缺点;在某些州,模型预测误差可能会更高,这是由于不经常访问之外的另一个原因。如果环境具有随机转变,我们的解决方案可能会导致代理被具有高随机性的转变所吸引,因为这些将不可避免地导致更高的预测误差。在实践中已经观察到这种现象,并且这种现象是这种方法通用性的主要缺点。
另一个缺点与模型容量有关;我们正试图使神经网络适应环境的动态,但在某些情况下,这对我们的模型来说可能是一项太难的任务,损害了它充分减少许多状态的预测误差的能力。具有渐近高误差的状态导致代理的探索行为中的偏差,并且可能使它“停留”在状态空间的这些区域中。
2018 年底,OpenAI 的研究人员前来救援,并发表了一篇题为“通过随机网络蒸馏进行探索”的论文,我从现在开始将他们的方法称为 RND 。作者回顾了这种近似访问计数的几种现有方法,并从识别预测误差的来源开始:
-
训练数据量 :预测误差在未被充分访问过的州较高(这是我们所希望的)。
-
随机性 :动态变化大的状态下预测误差大。
-
模型设定错误 :如果我们的模型缺乏近似环境动态的能力,则预测误差较高。
-
学习动态 :如果学习环境动态的过程不稳定且不能收敛,预测误差可能很高。
来源 2-4 是不可取的,因为我们希望预测误差仅反映大致的访问次数。作者随后提出了一个简单而优雅的解决方案:不预测环境动态,而是尝试预测随机神经网络的输出,因此得名“随机网络蒸馏”。
那么到底是什么意思呢?我们随机初始化一个目标网络,它将在整个学习过程中保持固定,并初始化另一个神经网络,它将试图预测目标网络的输出,我将把它称为预测网络。这些网络都以状态作为输入,并输出一个向量。目标网络的输出与转移无关,只是游戏状态的随机函数。最初,目标网络和预测网络是不相关的,并且预测误差将会很高。然而,在学习过程中,对于代理经常访问的状态,该误差将减少,就像我们之前讨论的动态预测方法一样。
通过尝试预测固定目标网络的输出,我们避免了误差源 2–4 中的问题:
-
训练数据量 :我们还是保留这个想要的误差源。
-
随机性 :目标网络是确定性的,所以这个误差源就消失了。
-
模型误设定 :目标网络和预测网络属于同一个模型类,因此具有相同的能力,所以这个误差源消失。
-
这与环境动态学习任务相反,环境动态学习任务是不稳定的(当代理发现新的状态时,它也可能遇到新的转换现象)。
现在,我们准备看看算法的伪代码,如论文中所示:
作者将 RND 方法与一种叫做近似策略优化(PPO)的普通 RL 算法结合使用。从这个伪代码中要得到的重要的东西是,内在的回报是预测网络的损失,并且它在由代理收集的用于更新策略的相同样本上被优化。
其余的细节在很大程度上是针对本文中使用的 RL 算法的,但事实上,RND 是一种完全通用的方法,原则上可以应用于任何 RL 算法,无论是 on 还是 off 策略,因为 RND 只通过奖励与 RL 算法进行交互。
在其出版时,RND 提供了蒙特祖马对纯 RL 算法的报复的最先进的结果(使用各种形式的人类演示获得了一些不错的结果),考虑到这种方法的通用目的,这是令人印象深刻的。
我为登山车问题实现了一个 RND 的极简版本,以演示如何在没有通常的奖励工程的情况下解决它。请随意查看:https://github.com/orrivlin/MountainCar_DQN_RND
后知后觉的强化学习经验回放
稀疏和二进制奖励
近年来,由于一些引人注目的成功,如击败围棋世界冠军和(最近)在流行的实时战略游戏《星际争霸 2》中击败顶级职业选手,强化学习获得了很大的人气。AlphaZero(最新的围棋代理)等成就令人印象深刻的一个方面是,它从稀疏的二进制奖励中学习,要么赢得比赛,要么输掉比赛。在大多数情况下,没有中间奖励会使学习变得非常困难,因为代理人可能永远不会真正获胜,因此没有关于如何改进其表现的反馈。显然,像围棋和星际争霸 2 这样的游戏(至少在比赛中是这样玩的)有一些独特的品质,使得用这些二进制奖励学习成为可能:它们是对称零和游戏。我现在不打算深入探讨这个问题,但我可能会在未来的一篇文章中专门讨论 AlphaZero 背后的算法。
问题是,大多数问题都不是对称的零和游戏,让我们再次没有反馈,没有学习。作为一个例子,我们可以看看一个经典的 RL 问题称为山地汽车。在这个问题中,一辆汽车试图到达山顶的旗帜,但由于它缺乏足够的加速度直接开车上山,它必须来回摆动以获得速度并最终到达目标。
只要汽车没有到达旗帜,它每走一步就获得-1 的奖励,直到该集在固定的步数后终止。一个经常使用的实用方法是使用领域知识来增加奖励,这被称为奖励工程或奖励形成。在我们的山地车示例中,因为我们知道汽车必须加快速度才能爬山,所以一个合理的方法是将汽车的速度添加到奖励中,鼓励它加快速度。如果我们足够仔细地设计奖励,我们的代理人将会加快速度,最终偶然发现这面旗帜,并避免一些本来会得到的负面奖励。
这种方法的问题是它并不总是容易做到。在某些情况下,我们可能不知道如何塑造奖励来帮助学习;换句话说,我们必须知道一些如何解决问题的知识,以便恰当地塑造奖励。这方面的知识并不总是有的,尤其是对于难题。另一个危险是,一旦我们设计了奖励,我们就不再直接优化我们真正感兴趣的指标,而是优化一个代理,我们希望它能使学习过程更容易。这可能会导致相对于真正目标的绩效妥协,有时甚至会导致意想不到和不想要的行为,这可能需要频繁微调设计的奖励,以使其正确。
多目标 RL
许多著名 RL 成就的另一个明显方面是,这些游戏与一个非常具体的目标有关,例如“在突围中尽可能多地得分”。在这些问题中,代理观察到一个状态,选择一个动作,并获得一个奖励。在这种情况下,我们的政策可以表述为:
其中“a”是候选动作,“s”是当前状态。
但许多现实世界的问题并不像这样,我们必须执行一个单一的全球任务。在许多情况下,我们希望我们的代理能够实现许多不同的目标,如“获取红色的球”,但也“获取绿色的立方体”。我的意思不是说代理需要以某种方式立即执行这些目标,而是我们希望它能够根据请求执行这些任务中的任何一个。在这种情况下,我们可以将我们的政策表述为:
其中“g”是期望的目标。在本文中,我们将把目标视为我们希望代理达到的状态。这是一个多目标学习问题。如果我们将多目标问题与稀疏二元奖励的额外困难结合起来,我们就会陷入一些真正的困难。
OpenAI 的研究人员在他们的论文“后见之明体验回放”中给出了这样一个问题的简单例子。假设我们有一个由二进制数(0–1)的向量组成的状态,我们希望训练一个代理到达给定的二进制目标向量的任何一个。可能的行动是每次切换一位,未达到目标的每个时间步长奖励-1。显然,如果我们将状态和目标向量的大小设置得足够大,我们就没有希望用传统的方法解决这个问题。随机交换比特和偶然发现想要的目标向量的机会是极不可能的,即使使用专门的探索方法(就像我在以前的文章中写的方法)我们也很可能失败,因为每个目标向量对这些方法来说就像是一个完全不同的问题。状态-目标空间太大了。作者证明了 DQN 的最大可解向量大小是 13,之后成功率急剧下降到零。
后知后觉的经历回放——从失败中学习
政策外学习
但是人类如何处理这样的问题呢?有时当我们未能完成某项任务时,我们会意识到我们所做的在另一种情况下或另一项任务中是有用的。这篇论文(这是我最喜欢的 RL 论文之一)的作者正是利用这种直觉来开发他们的方法。
即使我们最终失败了,为了转化检查过去行为并从中推断有用信息的能力,我们将转向一种称为非策略学习的学习范式。
在 RL 中,我们试图学习一种策略,在给定初始状态分布的情况下,使期望的累积回报最大化。我们通过反复试验与环境互动来学习政策,并使用在此过程中收集的数据来改进我们的政策。但是一些 RL 算法可以从由另一个策略收集的数据中学习一个策略。这另一个策略记录了它与环境的相互作用,我们的学习算法可以使用它来推断一个潜在的更好的策略。从现在起,我将把我们试图学习的政策简称为政策,而把另一个政策称为探索政策。探索策略的目的是探索足够多的状态-动作空间,以便我们的学习算法可以从中推断出在不同状态下应该采取什么动作。非策略学习算法的经典例子是 DQN(深度 Q 网络)和 DDPG(深度确定性策略梯度),这些算法可以在给定由探索策略收集的数据的情况下学习状态-动作对的值。
相比之下, On-Policy 学习算法必须只依赖于被学习的同一个策略收集的数据,这意味着它们不能使用另一个策略收集的历史数据,包括它们自己的旧版本(例如,在 SGD 更新到神经网络之前)。基于策略的学习算法的典型例子是各种策略梯度方法,例如加强和 A3C(异步优势行动者-批评家)。
后知后觉的经历回放
在著名的 DQN 算法中,通过对用于更新神经网络的每一批中的训练样本去相关,使用过去经验的缓冲区来稳定训练。这个缓冲区记录了过去的状态、在这些状态下采取的行动、收到的奖励以及观察到的下一个状态。如果我们希望将此扩展到我们的多目标设置中,除了状态之外,我们还必须保存目标,并了解状态-目标-行动三元组的价值。
正如我们已经看到的,体验重放缓冲区中的数据可以源自探索策略,这提出了一种有趣的可能性;如果我们可以通过想象如果情况不同会发生什么来添加虚拟数据,会怎么样?这正是后见之明经验回放(她)事实上做的。
在她的文章中,作者提出了以下策略:假设我们的智能体执行了一集,试图从初始状态 S 到达目标状态 G,但未能成功,并在该集结束时到达某个状态 S’。我们将轨迹缓存到重放缓冲区中:
其中带下标 k 的 r 是该集第 k 步收到的奖励,带下标 k 的 a 是该集第 k 步采取的动作。她的想法是想象我们的目标实际上一直都是‘S’,在这个替代现实中我们的代理人已经成功地达到了目标,并因此获得了积极的回报。因此,除了缓存之前看到的真实轨迹,我们还缓存以下轨迹:
这个轨迹是想象出来的,是由人类从失败的尝试中学到有用的东西的能力所驱动的。还需要注意的是,在想象的轨迹中,在这一集的最后一步得到的奖励现在是达到想象的目标所获得的积极奖励。
通过将想象的轨迹引入我们的重放缓冲区,我们确保了无论我们的策略有多糟糕,它总会从中获得一些积极的回报。在这个阶段,我们可能会问自己,学习去实现我们不感兴趣的目标有什么用?很明显,在训练的开始,那些想象的目标将只是我们糟糕的随机初始化策略可以达到的状态,没有实际用途。然而,神经网络函数逼近的魔力将确保我们的政策也能达到类似于它以前看到的那些状态;这是泛化属性,是成功深度学习的标志。起初,代理将能够到达初始状态周围相对小的区域中的状态,但是它逐渐地扩展状态空间的这个可到达区域,直到最后它学会到达我们实际上感兴趣的那些目标状态。
这个过程与深度学习中的另一种常见做法有很多相似之处;课程学习。在课程学习中,我们希望我们的神经网络学习一些困难的东西,但如果我们让它在真正的任务上训练,它很可能会失败。我们能做的是让它开始在更小的问题实例上进行训练,这要容易得多,并逐渐增加实例的难度,直到我们的模型学会在我们着手解决的任务上表现良好。课程学习通常在实践中运行良好,但需要设计者手动设计课程,并产生更简单的任务实例。这并不总是容易做到的,因为有时我们可能无法产生一个更简单的问题,并且成功地设计课程可能是困难和耗时的。
与此相反,她给了我们一个非常相似的结果,而不需要我们修改问题或设计课程。我们可以把她看作是一个隐性的课程学习过程,在这个过程中,我们总是向我们的代理提供它确实能够解决的问题,并逐渐增加这些问题的范围。
作者在几个机器人操纵任务上测试了她,在这些任务中,代理人必须从初始状态实现不同的目标,例如捡起物体或将其滑动到某个目标位置。在这些任务中,如果代理人按时完成了任务,就会得到奖励,如果没有按时完成,就没有奖励。作者使用 DDPG 作为基本算法对她进行了测试,并表明她在学习完成这些任务方面取得了成功,而其他算法无法学习。
作者还证明了,只要我们能为训练提供其他目标,即使在我们真正关心某个特定目标的任务中,她也能提高表现。
这是一个非常优雅和简单的方法来解决许多 RL 应用中的一个困难和重要的问题。检查纸。我已经用用她的实现了比特翻转实验,另外还用她训练了一个智能体在 2D 网格世界环境中导航,请随意看看。
无梯度强化学习:用遗传算法进化智能体
在假期里,我想提高我的强化学习技能。对这个领域一无所知,我上了一门课程,在那里我接触到了 Q-learning 和它的“深度”等价物(深度 Q 学习)。那是我接触 OpenAI 的健身房的地方,那里有几个环境供代理人玩耍和学习。
课程仅限于深度 Q 学习,所以我自己读了更多。我意识到现在有更好的算法,如政策梯度及其变体(如行动者-批评家方法)。如果这是你第一次参加强化学习,我推荐以下资源,它们对建立良好的直觉很有帮助:
- 安德烈·卡帕西的深度强化学习:来自像素的 Pong】。这是一个经典的教程,引发了人们对强化学习的广泛兴趣。必读。
- 通过 Q-Learning 深入强化学习。这篇文章对最基本的 RL 算法 : Q-learning 做了一个很好的、有插图的概述。
- 各种强化学习算法介绍。RL 算法世界的漫游。(有趣的是,我们在这篇文章中将要讨论的算法——遗传算法——不在列表中。
- 直觉 RL:优势介绍——演员——评论家(A2C) 。一个非常非常好的漫画(是的,你没听错)关于 RL 目前最先进的算法。
我感到很幸运,作为一个社区,我们分享了这么多,以至于在对强化学习一无所知的几天内,我能够复制仅仅 3 年前的艺术状态:使用像素数据玩雅达利游戏。这里有一个我的代理人(绿色)只用像素数据和 AI 玩 Pong 的快速视频。
This sort of feels like a personal achievement!
强化学习的问题是
我的代理使用策略梯度算法进行了很好的训练,但这需要在我的笔记本电脑上进行整整 2 天 2 夜的训练。即使在那之后,它也没有完美地播放。
我知道总的来说,两天并不算多,但我很好奇为什么强化学习的训练如此缓慢。通过阅读和思考,我意识到强化学习缓慢的原因是因为梯度(几乎)不存在,因此不是很有用。
梯度有助于监督学习任务,如图像分类,它提供了关于如何改变网络参数(权重、偏差)以获得更高精度的有用信息。
Imagine this surface representing error for different combinations of weights and biases (the lower the better). Starting from a randomly initialized point (of weights and biases), we want to find the values that minimize the error (the lowest point). Gradients at each point represent the direction of downhill, so finding the lowest point is equivalent to following the gradient. (Wait, did I just describe the stochastic gradient descent algo?)
在图像分类中,在每次小批量训练之后,反向传播为网络中的每个参数提供了清晰的梯度(方向)。然而,在强化学习中,梯度信息只是在环境给予奖励(或惩罚)时偶尔出现。大多数时候,我们的代理人在采取行动时并不知道这些行动是否有用。梯度信息的缺乏使得我们的误差范围看起来像这样:
Image via the excellent blog post Expressivity, Trainability, and Generalization in Machine Learning
奶酪的表面代表我们的代理人网络的参数,无论代理人做什么,环境都不会给予奖励,因此没有梯度(即,因为没有错误/奖励信号,我们不知道下一次在哪个方向改变参数以获得更好的性能)。表面上的几个孔代表对应于与表现良好的代理相对应的参数的低误差/高回报。
你现在看到政策梯度的问题了吗?一个随机初始化的代理很可能位于平面上(而不是一个洞)。如果一个随机初始化的代理在一个平坦的表面上,它很难达到更好的性能,因为没有梯度信息。因为(错误)表面是平的,一个随机初始化的代理或多或少做了一次随机游走,并在很长一段时间内被坏策略所困。(这就是为什么我花了几天时间来训练一个代理。提示:也许政策梯度法不比随机搜索好?)
正如标题为为什么 RL 有缺陷的文章明确指出的:
如果你想学的棋盘游戏是围棋,你会如何开始学习?你会阅读规则,学习一些高水平的策略,回忆你过去如何玩类似的游戏,得到一些建议…对吗?事实上,这至少部分是因为 AlphaGo Zero 和 OpenAI 的 Dota 机器人的从头学习限制,与人类学习相比,它并不真正令人印象深刻:它们依赖于比任何人都多得多的游戏数量级和使用更多的原始计算能力。
我认为这篇文章切中要害。RL 是低效的,因为它没有告诉代理它应该做什么。不知道该做什么的代理开始做随机的事情,只是偶尔环境会给出奖励,现在代理必须弄清楚它采取的数千种行动中的哪一种导致了环境给出奖励。人类不是这样学习的!我们被告知需要做什么,我们发展技能,奖励在我们的学习中扮演相对次要的角色。
If we trained children through policy gradients, they’ll always be confused about what they did wrong and never learn anything. (Photo via Pixabay)
强化学习的无梯度方法
当我在探索基于梯度的 RL 方法的替代方法时,我偶然发现了一篇题为深度神经进化:遗传算法是训练用于强化学习的深度神经网络的有竞争力的替代方法。这篇论文结合了我正在学习的东西(强化学习)和我一直很兴奋的东西(进化计算),所以我着手实现论文中的算法并进化出一个代理。
请注意,严格来说,我们甚至不必实现遗传算法。如上所述,同一篇论文发现甚至完全随机的搜索也能发现好的代理商。这意味着,即使你继续随机生成代理,最终,你会找到一个表现良好的代理(有时比策略梯度更快)。我知道,这很疯狂,但这只是说明了我们最初的观点,即 RL 从根本上是有缺陷的,因为它几乎没有什么信息可供我们用来训练算法。
什么是遗传算法?
这个名字听起来很花哨,但实际上,这可能是你能设计出的探索风景的最简单的算法。考虑一个通过神经网络实现的环境中的代理(如 Pong)。它获取输入层中的像素,并输出可用动作的概率(向上、向下或不做任何动作)。
Image via Deep Reinforcement Learning: Pong from Pixels
我们在强化学习中的任务是找到神经网络(权重和偏差)的参数(权重和偏差),这些参数使代理更经常获胜,从而获得更多奖励。到目前为止还好吗?
遗传算法的伪代码
- 简单地把代理想象成一个有机体,
- 参数将是指定其行为(策略)的基因
- 奖励将指示有机体的适应性(即,奖励越高,生存的可能性越高)
- 在第一次迭代中,您从带有随机初始化参数的 X 个代理开始
- 他们中的一些人可能会比其他人表现得更好
- 就像现实世界中的自然进化一样,你实现了*适者生存:*简单地选取最适的 10%的代理,并为下一次迭代复制它们,直到下一次迭代又有了 X 个代理。击杀最弱的 90%(如果这听起来很病态,可以把击杀功能改名为 give- 木沙!)
- 在复制前 10%最适合的代理的过程中,向其参数添加一个微小的随机高斯噪声,以便在下一次迭代中,您可以探索最佳代理参数周围的邻域
- 让表现最好的代理保持原样(不添加噪声),这样你就可以一直保留最好的,以防止高斯噪声导致性能下降
就是这样。你已经理解了遗传算法的核心。遗传算法有许多(奇特的)变种,其中两个代理之间有各种各样的(肮脏的)性(性重组),但关于深度神经进化的论文用上面的伪代码实现了香草遗传算法,这也是我在代码中实现的。(你可以在我的 Github 库上用代码访问Jupyter 笔记本)。
Yellower regions are regions with lower error (higher rewards/performance). Blue dots are all agents. Green ones are the top 10% and the red dot is the best of the best. Notice how gradually the entire population moves towards the region with the lowest error. (Image via Visual Guide to Evolutionary Strategies)
关于进化算法如何工作的更多可视化,我强烈推荐阅读这篇做得非常好的帖子:进化策略可视化指南。
用于实现强化学习的深度神经进化的代码
我 t̸r̸a̸i̸n̸e̸d̸进化出了一个移动小车上的代理平衡杆(又名 CartPole-v0 )。下面是完整的代码:https://github.com/paraschopra/deepneuroevolution
使用 PyTorch,我们通过 2 个隐藏层的神经网络(希望保留“深层”部分:)对代理进行参数化,对于 CartPole,一个层的网络也可以做得很好。
这是进化的主循环:
这段代码基本上是不言自明的,并且遵循了我在本文前面写的伪代码。将细节映射到伪代码:
- 我们的人口规模是 500 ( num_agents ),我们在第一次迭代中随机生成代理( return_random_agents )
- 从 500 个中,我们只选择前 20 个作为父代( top_limit )
- 我们想要运行循环的最大迭代次数是 1000 次(代)。尽管通常对于 CartPole 来说,在几次迭代中就能找到一个表现良好的代理。
- 在每一代中,我们首先运行所有随机生成的代理,并在 3 次运行中获得它们的平均性能(曾经可能是幸运的,所以我们想要平均)。这是通过 run_agents_n_times 函数完成的。
- 我们按照奖励(绩效)的降序对代理进行排序。排序后的索引存储在 sorted_parent_indexes 中。
- 然后,我们选择前 20 名代理,并在其中随机选择,为下一次迭代生成子代理。这发生在 return_children 函数中(见下文)。该函数在复制代理时向所有参数添加一个小的高斯噪声,但保留一个最佳的精英代理(不添加任何噪声)。
- 现在将子代理作为父代理,我们再次迭代并运行整个循环,直到完成所有 1000 代或者我们找到具有良好性能的代理(在 Jupyter 笔记本中,我打印了前 5 名代理的平均性能。当它足够好时,我手动中断循环)
return_children 函数是这样的:
您可以看到,首先,它从前 20 个代理中选择一个随机代理(索引包含在 sorted_parents_indexes 中),然后调用 mutate 函数添加随机高斯噪声,然后将其添加到 children_agents 列表中。在第二部分中,它调用 add_elite 函数将最佳代理添加到 children_agents 列表中。
下面是 变异 的功能:
你可以看到,我们迭代所有参数,并简单地添加高斯噪声(通过 np.random.randn() )乘以一个常数( mutation_power )。乘法因子是一个超参数,大致类似于梯度下降中的学习速率。(顺便说一下,这种遍历所有参数的方法速度慢,效率低。如果你知道 PyTorch 中更快的方法,请在评论中告诉我)。
最后,函数 add_elite 如下:
这段代码简单地选取前 10 名代理并运行 5 次,以根据平均表现双重确定哪一个是精英(通过 return_average_score )。然后它通过 copy.deepcopy 复制精英,并原样返回(无突变)。如前所述,精英确保我们总是有一个我们以前最好的副本,它防止我们随机漂移(通过突变)到一个没有好代理的区域。
就是这样!让我们看看进化后的钢管舞特工的表现。
You, Sir, are a product of evolution.
遗传算法并不完美。例如,在添加高斯噪声时,没有关于如何选择乘法因子的指导。你只需要尝试一堆数字,看看哪一个有效。而且,在很多情况下,可能会彻底失败。我多次尝试为 Pong 开发一个代理,但它非常慢,我放弃了。
我联系了深度神经进化论文的作者,费利佩这样的。他提到,对于一些游戏(包括 Pong)来说,神经进化失败了,但对于其他游戏(如 Venture )来说,它比政策梯度要快得多。
你会进化成什么样?
我的知识库中用于深度神经进化的代码足够通用,可以与 PyTorch 中实现的任何神经网络一起工作。我鼓励你尝试各种不同的任务和架构。如果你成功了,失败了或者卡住了,请告诉我!
祝你好运进化你自己的世界。
PS:查看我以前的实践教程 a) 从小语料库中生成哲学 和 b) 贝叶斯神经网络
感谢 Nirant Kasliwal 和 Felipe 审阅这篇文章的草稿。
在 Twitter 上关注我
我定期发关于人工智能、深度学习、创业公司、科学和哲学的推特。跟着我上https://twitter.com/paraschopra
[## Paras Chopra (@paraschopra) |推特
Paras Chopra 的最新推文(@paraschopra)。@Wingify |的创始人兼董事长写道…
twitter.com](https://twitter.com/paraschopra)
为人工智能时代重塑商场
设置背景
全球每月只有几十亿人逛商场和购物中心。这不仅反映了购物中心在零售业中不可或缺的地位,也反映了等待利用的数据驱动洞察的巨大潜力。购物中心可以使用大数据、机器学习和人工智能来获得有意义的见解,以最大限度地降低运营成本,建立更好的客户参与,探索新的收入途径,使租户能够提高生产力,等等。然而,我们看到和读到的新闻预示着一个新时代的到来,更多的购物中心将停止营业(分析师估计,到 2022 年,美国每 4 个购物中心中就有 1 个可能停业)。
最近,欧洲一家超大型购物中心管理服务公司的资产管理负责人在一次私人讨论中告诉我们:
“我们在做决定时很慢,但在询问结果和指向别处时却很快……我们发现很难做出充满不确定性的决定,也很难少做我们应该做的实验。我们想知道哪些品牌创造了更多的流量,但我们没有衡量品牌的停留时间。世界各地的购物中心和购物中心都在快速变化——我们只有在受到重创时才会做出反应,而我们通常在利用新技术方面动作迟缓。”
今天,大多数大型全球购物中心运营商的资产管理和运营领导人都敏锐地意识到,技术推动的破坏性创新、受过教育的年轻人口的偏好变化以及在线购物正在迅速缩短传统购物中心的生命周期,并创造新的机会将购物中心改造成不同于现状的东西。这些领导人被迫重新思考支持商业战略的技术投资,以便在这个新的世界秩序中生存和发展。然而,许多这样的领导人和他们的组织也遭受着失败的恐惧,缺乏内部支持,和实践的责任,特别是当开始雄心勃勃的计划时。
领导人面前的挑战
购物中心/购物中心正处于一场完美风暴的中心,这场风暴是由不同的内部和外部力量造成的,这些力量逐渐迫使高管将稀缺资源投入到多个相互矛盾的方向。
“购物中心作为购物大厅的传统概念正在成为‘历史的错误’,迫切需要彻底改造。”
-零售开发商 Caruso 附属公司首席执行官 Rick Caruso
- 过去十年左右,在线/移动购物的迅速崛起导致大品牌零售商的客流量下降,这些零售商是许多购物中心的核心商店。由于一些商店因财务原因关闭,商场客流量减少。
Of all the things we do on our phones, the fastest-growing segment in 2017 was shopping, up 54% year-over-year. Source: Mary Meeker 2018 State of the Internet report
- 大衰退的打击降低了整体支出,大多数千禧一代现在更注重体验而非所有权。旅游业蓬勃发展,酒店入住率高得惊人,餐饮服务和饮酒场所增长迅速,而购物中心的核心店铺——服装支出却在下降。随着消费者开始寻找便宜货,快时尚商店和俱乐部商店从百货商店那里抢走了一些市场份额。
- **并非所有的商场都是平等的。**购物中心“可出租总面积”(GLA)——美国的人均购物面积比加拿大多 40%,比英国多 5 倍,比德国多 10 倍。这是一个数量过多的问题,许多分析师认为有必要对 T4 市场进行一次必要的调整,尤其是当购物中心不在市区范围内或者维护不善的时候。虽然目的地购物中心(如美国购物中心)将能够成功地创造出值得离开沙发开车去的体验,但其余的购物中心将在关注如此广阔空间中塑造人类体验的细节方面挣扎或死亡。
This report clearly highlights the excess GLA that many countries have Source: A study commissioned by the South African Council of Shopping Centres to understand the GLA relative to the world.
- 商场管理层对测量工具的有限投资一直是一个很少被提及的话题,但却是一个关键的内部挑战。大多数商场业主都不愿意和/或缓慢地采用新技术,并进行充分的测量,以了解在这个新世界中什么可行,什么不可行。*例如,虽然大多数购物中心资产经理总是在寻找下一个突破性品牌、新时代杂货连锁店和继续将流量带到他们家门口的活动,但这些领导者没有/只有有限的工具集来了解当前的基线数字,导致与零售商之间的相互不信任。*一级和二级商场的运营和营销团队充分意识到,他们正在与提供个性化、便利性和无缝体验的在线聚合商激烈竞争,但大多数人仍忙于按照过去 20 年左右的方式查看客流量。
可见的中奖趋势
“独自购物或主要购物不再是人们会来购物中心的原因。随着越来越多的空地、充足的停车位和通往主干道的通道,购物中心现在开始问‘这些地方还能用来做什么?’
- Peter Muoio,Ten-X 首席经济学家
商场业主和购物中心管理层有一个传统的剧本——现有的结构、古老的治理流程、集中的资本要求&投资战略、长期运行的技术创新周期、本地有限的营销 —这是过时的,不适合在这个新的变化环境中推动增长。应对压力已经迫使许多一级和二级商场走上战略弯路。我们见证的最大趋势是购物中心的重新定位,从购物交易场所到以顾客体验创新为核心的消费者参与中心。这已经反映在
- 不断变化的租户组合模式已经从纯粹的零售转变为餐饮、娱乐、健康和一系列多样化业务的结合,包括办公空间,有时甚至是公寓。这种类似微型城市的发展已经成为千禧一代的磁石,他们离开市中心前往郊区,但仍然希望生活在一个密集、可步行的社区,并靠近他们想要的一切。
- 也有一个明显的转变,从只有长期租赁到灵活的短期租赁和弹出窗口,并增加了营销投入,以获得全年正确的租户组合。GenZ 和千禧一代中的很大一部分人生活在 Insta 和其他社交媒体的潮流中,Westfield 通过推出有史以来第一个人工智能驱动的“潮流商店”来捕捉他们的兴趣,该商店实时显示社交媒体上的热门产品。
The Trending Store operated by Westfield London — a pop-up selling clothes which are trending online. Source: https://www.standard.co.uk/fashion/westfield-trending-store-ai-pop-up-save-the-children-a4154196.html
- 线上和线下模式的日益融合导致前者在受欢迎的购物中心开设实体店,而购物中心大量投资数字界面,以实现混合购物体验。现在,在购物中心看到过多的数字信息亭和显示器并不罕见,它们超越了正常的“在购物中心找到你的路”——技术可能是实体商店重生的关键。
- 此外,由于购物中心在价格或其他便利选项上无法击败在线玩家,许多一级购物中心提供差异化服务,如忠诚客户的 VIP 待遇,举办产品学习会、音乐表演等。科威特的 Gate Mall 推出了一项为顾客提购物袋的礼宾服务,以帮助他们舒适地购物。事实证明,这是一项非常受顾客欢迎的服务,增加了购物时间,提高了转化率。
Listing of special concierge services at the Gate Mall in Kuwait: Source: http://www.thegatemall.com.kw/The-Gatemall/Services
前进前进策略
“我们将继续与品牌紧密合作,提供创新的零售空间,为他们和我们的访客创造理想的环境,包括开发融合数字和实体购物的技术,以增强在一流环境中的额外体验。”
-Myf Ryan,Westfield 英国和欧洲首席营销官
追逐商业房地产,尤其是购物中心的资本数量惊人,其核心信念是,实体环境具有更接近客户的根本优势,可以提供在线不可能提供的令人愉快的服务。我们看到,在全球范围内运营商业房地产服务业务的客户驱动型运营模式正在逐步但肯定地演变。基于上述趋势以及我们与众多领导者的闭门讨论,我们将以下内容确定为购物中心房地产开发商繁荣发展的三大赌注。
#1 为租户创造相互价值&商城开发商
我们预计将会出现一股采用新的灵活租赁模式的强劲浪潮,这种模式强调了实体店在更广泛的全渠道零售中的作用,为零售商和购物中心物业经理创造了双赢的机会。这将有助于从商场所有者到零售商的相对自由的度量和见解流动,反之亦然,创造一个信任的环境,这是今天所缺少的。
Next-gen rental models are on the rise and forward-looking malls are going to adopt them. Source: ICSC Research Envision 2020
新兴的混合购物模式,如展厅和网络空间,将被纳入租金公式,尊重开发商和零售商的需求和利益,并定义对双方公平公正的商业结果。与绩效相关的指标将成为这种共同价值创造的关键,并取决于净购物时间(停留时间)、顾客量、转换率和购物篮大小。根据零售商之间的剥离计算率,通过确定任何单个零售商的净客流量贡献,这将得到进一步完善。
#2 将购物中心重新定位为目的地,而不是购物中心
为了保持相关性,大型购物中心必须不仅仅是“商品集散地”,而是要发展成为社区中心和文化中心。一级和二级玩家正在认真考虑他们的投资组合,以确定将公寓、酒店、电影院、健身俱乐部、餐厅、活动区和其他类型的用途纳入其中的机会,从而增加宝贵的密度、客流量和活力。受过良好教育的年轻千禧一代和 Zs 一代不断涌入大城市,导致某些市中心市场的零售、公寓和写字楼需求增加,为重新定位现有城市中心和进行有限的开发创造了机会。
#3 投资人工智能技术
计算机视觉(AI)等数字跟踪技术的快速发展实现了准确的计算(而不是容易出错的基于 wifi 的估计或传统的人数计算),并为生物识别驱动的营销、运营效率和潜在的新收入渠道创造了机会。
这里有几个关键领域,这种技术可以推动针,我们希望领导人迅速实施它们。
Computer Vision is used to securely analyze the visitor flow and related demographics and mood index of areas inside and outside the malls without compromising on individual privacy. Source: RealValue.ai
作战
- ****保护场所和资产:面部识别可以通过防止潜在威胁和快速管理情况,为商场提供一种强大的安全和监控机制。
- ****提高运营效率:通过准确估计访客流量和管理相关资源和资产,管理电梯、洗手间、停车场的排队时间或自动扶梯和入口的拥挤情况。这使我们能够预测交通模式,并相应地提前计划人员需求。这可以非常有效地减少人员过剩的成本,避免在拥挤时期出现人员不足的情况。
- ****优化布局和标志:通过性别、年龄和情绪分析精心制作的热图可以帮助跟踪消费者的旅程,识别热点和瓶颈。这可用于设计布局变化,以提供最佳的客户购物路径,衡量数字标牌板和邻近营销的影响。
新收入
- ****广告收入:根据热图分析,确定针对特定受众创建新广告空间的最佳位置和时间。将现有的数字内容货币化,如开店视频、活动、产品发布等。将它们与产品/品牌发现 KPI 联系起来。
- 从互动信息亭中获取更多:信息亭在很大程度上仍未得到充分利用,仅仅作为方向提供者。智能信息亭可以快速分析客户人口统计数据,以提供量身定制的产品推荐、个性化促销,帮助发现商店、特色、设施等。这可以通过手势和情绪分析增强内容的相关性来进一步参与。
- ****让弹出式商店更赚钱:不仅仅是出租你的空间给弹出式商店。从访客分析中获得洞察,为参与的品牌带来显著价值。使用面部识别功能方便支付。
营销&品牌
- ****帮助租户确定他们的视觉营销:橱窗展示对品牌认知影响最大,在将路人转化为店内访客方面发挥着至关重要的作用。通过研究顾客对零售展示的反应,获得见解,帮助租户确定最有效的橱窗展示形式、产品组合和价格点,从而吸引顾客进店。
Simple dwell time, attention time analysis can help boost advertisement revenues inside and outside the malls. Source: RealValue.ai
- ****消除营销活动中的猜测:确定实施营销活动的最佳条件,并用真实数据衡量其有效性。芬兰赫尔辛基的 Kamppi 购物中心分析了步行交通模式,发现购物者聚集在午餐时间,而不是之前认为的下班后——他们能够通过调整时间来创造更有效的营销活动。
- ****创建能够转化的促销活动:利用能真正打动客户的内容,生成有针对性的信息。今天的顾客眼光更加敏锐,不会被折扣所左右或诱惑,只会受到价值的影响。
最终……
“如果我们有数据,你就可以进行智能对话。这真的很重要。想想伙伴关系,所有的关系都是如此,因为数据会让你有能力很好地分析关系,也会让你有能力真正了解如何改善。”
—行为分析学院(Behavior Analytics Academy)创始人罗尼·马克斯(Ronny Max)谈到数据在提高零售商和商场开发商之间的互信方面的重要性
勇气、雄心和毅力是所有三个建议奏效的先决条件:对当前商业模式施加压力的勇气、打破惯性的雄心和通过使用技术跟随变化的毅力。虽然多次访问硅谷和观看类似 TED 的视频启发了领导者,但现在是时候将这些战略迅速付诸行动,并接受数字化转型之旅中的不确定性。承诺是零售商和物业管理公司之间更好的合作,对终端消费者的透明度和便利性,以及快速响应市场变化的能力。
购物中心和购物中心已被证明是很好的生意,在那里有房地产开发商、零售商和其他供应商的利益汇合,当然还有像你我这样的消费者。我们正在见证这个行业为适应社会和技术变化而进行的缓慢但确定的演变。
Realflow 是来自 Calculai 的人工智能视觉智能平台,它对我们工作、娱乐和购物的物理空间产生了有意义的影响,从而提高了参与度、安全性和转化率。我们植根于硅谷、印度和法国,将前沿的人工智能和创新带给全球的本地企业。
来源
https://www . the verge . com/2019/5/24/18638782/Amazon-mall-kiosk-shopping-new-presented-by-stores
https://www . the guardian . com/us-news/2017/jul/22/mall-of-America-Minnesota-retail-周年庆
https://www . theatlantic . com/business/archive/2017/04/retail-meltdown-of-2017/522384/
https://www . Forbes . com/sites/geristengel/2018/02/21/6-ways-retailers-is-prospering-in-malls/# 3 dbdb 9 c 02 be 9
https://time.com/4865957/death-and-life-shopping-mall
重塑客户体验的个性化
为什么?什么?怎么会?
“记住,对一个人来说,他的名字是任何语言中最甜美、最重要的声音。”—戴尔·卡耐基,如何赢得朋友并影响他人
说到与客户建立良好的关系,记住他们的名字对于任何级别的企业都是必不可少的一步。当涉及到与他们做生意的品牌时,消费者希望被当作个体对待。记住一个人的名字,并在适当的时候使用它,这是赢得那个人接受你的思维方式的关键。这一事实得到了科学的支持,科学认为听到自己的名字会对听者的大脑产生强大的影响。因此,合乎逻辑的做法是,不仅要记住并使用客户的名字,还要记住并使用他们的好恶,让他们感到受到重视——换句话说,为消费者提供个性化的客户体验可以让他们立刻成为品牌的忠实客户。
Personalizing the customer experience across all touch points
客户时代标志着一刀切的信息时代的结束。如今,一条信息无法完成工作,除非它能与每个客户完美契合。在这个时代,消费者比以往任何时候都更有权力,更能控制他们与品牌的关系。这些消费者在整个购买过程中不断要求个性化。
生活在一个喧嚣的即时满足的世界,一家企业如何在一个已经过度拥挤的领域留下印象?实际上很简单——利用所谓的“鸡尾酒会”效应。鸡尾酒会效应是这样的:当你在一个鸡尾酒会上,有几十个人围着你聊天,你会发现你很容易模糊掉那些对话。对你来说,它们只是背景噪音。但是,一旦有人说了你的名字或你特别感兴趣的事情,你的耳朵就会竖起来,进入那个特定的对话。这个信息会超越噪音,因为它对你来说很重要*。*
同样,在客户体验中加入个人风格,例如,在电子邮件中使用动态收件人姓名标签,可以让企业发出自己的声音,从而在过度拥挤的市场中脱颖而出。
个性化——制胜策略
公司不能再依赖他们的产品和服务作为他们的主要竞争优势;如今,他们只能在提供卓越体验的基础上竞争。
据 Janrain 称,48%的消费者在他们的体验个性化时会花更多的钱,而 74%的人讨厌看到与 T2 无关的内容。那么,这说明了什么是个性化?在客户体验中,个性化是一种成功的策略,可以帮助公司增进与客户的关系。88%的营销人员声称,在实施客户体验个性化策略后,他们的业务有了明显的改善。
然而,只有 33%的企业对他们拥有的适当个性化客户体验的工具有信心。因此,企业如何利用数字化转型赢得客户体验竞赛,而不是因为这个事实而气馁?
这里的指南可以帮助企业为他们的客户创造更个性化的体验,不管他们目前的情况如何。
- 鼓励客户创建用户档案
创建完美个性化公式的基本要素之一是准确和完整的信息。为了获取这些信息,企业鼓励客户在他们的平台上创建用户档案是至关重要的。客户非常乐意让公司跟踪他们的行为,只要这只是用来提升他们的体验。顾客现在希望公司通过他们的个人资料来监控他们的行为,因为超过一半的顾客承认他们希望品牌能预测他们的需求,这样他们就能收到相关的建议。
因此,这个年龄段的客户希望公司:
- 为他们提供更个性化的体验
- 在多个频道上增强 CX
- 给他们有效的建议
据咨询公司麦肯锡估计,高达 35%的亚马逊购买来自推荐。网飞关于个性化的咒语很好地从顾客的角度总结了重要性:个性化=享受最大化+搜索时间最小化。
记住,激励客户建立个人资料的最好方法是让这个过程变得非常简单——不需要在注册表格中有数百个不相关的字段。
2。细分是成功的关键
无论是收集电子邮件还是在社交媒体上制作广告,细分都是关键。对于电子邮件,对电子邮件订户进行细分至关重要,因此只有相关内容才会发送给每个订户。尽管每个注册公司时事通讯的人都可能对该品牌感兴趣,但这并不一定意味着他们有相同的需求。例如,女装打五折与男性电子邮件收件人没有任何关系;对他来说,这是普通的垃圾邮件,没有人喜欢被垃圾邮件。因此,将用户分组或划分到不同的列表中有助于确保没有人被“垃圾邮件”
同样,细分受众可以帮助企业通过广告锁定潜在客户。
3。为未来保存信息—使用基于云的技术实现个性化
同样,用户配置文件在这里是最重要的。公司需要确保他们只要求相关信息来完成一次购买。之后,可以存储这些信息,以便通过任何渠道、在任何设备上、在任何时间加速未来的购买过程。
4。实施地理定位实践
客户的位置可以在几个方面有助于提升来自同一地区的所有潜在客户的客户体验。例如,一家公司可以通过允许网站访问者选择他们的国家来为他们提供定制的 CX。因此,如果它是一个零售电子商店,巴基斯坦人将看到公制计量,而美国人将看到 USCS 的公制计量。位置信息还可以以其他方式使用,如向电子邮件订户发送与天气或特殊场合相关联的报价。
5。听取客户反馈
所有伟大的公司都把客户放在第一位。根据研究,68%的消费者放弃一项业务,因为他们觉得这个品牌不关心他们。
向客户寻求反馈是对的,倾听反馈更好,但是仅仅为了反馈而实施改变并不是一个好主意,因为这不会带来投资回报。然而,如果大部分客户给出了类似的反馈,明智的做法是实施变革,不仅改善流程,还改善客户-品牌关系。
6。让顾客成为个性化过程的一部分
互动过程与个性化策略的融合有助于为顾客创造难忘的体验。即使一些客户没有个人资料,企业仍然可以使用交互工具为他们提供卓越的个性化体验。美宝莲的虚拟“试戴”功能就是一个很好的例子,它允许人们在购买前虚拟试戴化妆品。
Maybelline’s virtual ‘Try It On’ feature
7。不要一直拘谨
保持正式总是好的,但正式往往会使品牌难以与人们联系起来。为了与客户建立个人关系,在撰写内容时使用第一个词的视角极其重要。通过这样做,一个品牌能让它的顾客感觉更舒服,就像他们在和朋友交谈一样。
8。个性化电子邮件
个性化电子邮件内容与分割电子邮件列表一样重要。精心设计完美的主题是成功的电子邮件营销策略的第一步。毕竟,如果没有人打开那封邮件,它很可能是垃圾邮件。在 Inqline,我们使用电子邮件作为渠道,向客户提供个性化和周到的回复,这有助于改善客户体验。我们鼓励我们的团队使用客户的名字,以及感同身受的词语和写作风格,以便我们在保持专业的同时营造一种友爱感。一个很好的例子是,当我们的一位客户以歌曲的形式向我们发送他们的关注时,我们用一首歌来回复,为他创造了一个难忘的客户体验。
定论
我们知道,客户正在迅速转变为聪明的买家,这使得客户体验成为品牌之间唯一的竞争优势。面对激烈的竞争,品牌不断寻找不同的策略来保持客户的忠诚度和参与度。如果执行得当,客户体验的个性化可能是在让客户满意的同时获得更高回报的最可靠方法之一。
(拒绝)来自我的第一次数据科学面试
这一篇写起来有点有趣,可能看起来有点夸张,但我想涉及一个你在媒体上不会遇到的数据科学和机器学习领域。这不是编码教程或另一篇关于人工智能将如何取代你的工作的文章。是我们的老朋友拒绝。
Photo by Raj Eiamworakul on Unsplash
媒体描绘了这样一种看法,即数据科学家和机器学习工程师到处都在被雇佣,以至于有人声称人才短缺。但在现实中,公司正在寻找 1%的高技能数据科学家,你知道,有八年经验的 10 倍工程师,本质上是独角兽。
所以我被一个数据科学面试拒绝了,我正在媒体上写这个。但是这不是一篇令人遗憾的文章,相反,这是一篇有抱负的数据科学家和机器学习工程师有望从中获得一些价值的文章。
提供价值有多种形式;在这种情况下,这是通过我的第一次数据科学面试的经验。因此,我将提供以下一些信息:
- 数据科学/机器学习面试流程的结构
- 某人闯入数据科学/机器学习市场的学术和职业背景(剧透一下,是我)
- 一些资源有助于面试的各个阶段
- 为什么拒绝只是开始
在我们继续之前,我的学术和职业背景是有益的,因为它提供了对进入数据科学行业的个人素质的洞察。主要是,你下一个角色的竞争会是什么样的。
对于机器学习和数据科学相关的职位来说,硕士或博士学位是非常普遍的要求,所以我获得了计算机视觉、机器学习和机器人学的硕士学位。在攻读硕士学位之前,我在软件开发(Web)领域有三年的商业经验,并获得了软件工程本科学位。我在公司和创业公司工作过,也在软件工程(Web)领域担任过一些合同角色。而现在,我目前正在闯入数据科学/机器学习领域。
并非所有的面试都是一样的,但以下是我第一次面试的概要结构:
- 第一阶段 : 30 分钟的电话交谈(大概是检查我是否能沟通并知道一些角色需要的东西)。
- 第二阶段:3-4 小时的技术测试(趣味点,数据科学相关任务,以衡量您的编程能力和机器学习库知识)。
- 第三阶段 : 1 小时的技术测试解决方案演示,之后是一些问答。
前两个阶段很常见,我对此并不陌生,但最后一个阶段让我措手不及。这让我措手不及,因为人们希望我详细说明我将如何度过头三个月。除此之外,我还整理了一份我引以为豪的时髦简报。
我将提供一些见解和技巧,告诉你我是如何度过所有阶段的。希望提供的一些建议对你有所帮助,也许在你的下一次面试中。
第一阶段:电话交谈
电话交谈是我和这家初创公司的一位创始人进行的。这是一次持续约 30 分钟的谈话,内容涉及公司的背景、我的技能和经验,以及双方对未来的期望。
在申请大多数职位时,你和雇主之间的电话交谈是家常便饭。电话交谈的目的是让雇主评估你和你的技能,同时,这也是一个机会让你问一些关于这个职位的问题。谁知道呢,你可能会发现一些你不喜欢的职位的信息。
我为这个阶段准备的最好方法是做以下事情:
- 仔细阅读工作说明书,确保我具备了这个职位所需的所有基本技能
- 研究公司和他们从事的行业。还有,我通过 LinkedIn 对公司内部的团队进行了一些调研。
- 围绕之前的工作和展示该角色所需技能的项目准备谈话要点。
- 我准备了五个在电话交谈中要问的问题,但最后只问了三个。
第二阶段:技术测试(带回家编码作业)
我不会分享太多技术测试的细节,但它有两个任务要完成。
第一项任务是分析 excel 表格中的一些虚拟客户数据,并从这些数据中获得一些见解和发现。我利用标准的数据科学工具和库,如 Pandas、Numpy、Matplotlib 和 Jupyter Notebook 来完成第一个任务。
第二个任务更侧重于使用 Python 和 Flask 的后端实现,伴随着 API 集成任务。
我为技术测试准备的最好方法是做以下事情:
- 没事
你可能会有点困惑,但老实说,我几乎没有什么可以确保我通过技术测试。嗯,除了我每天都在做的事情。就像外面的许多数据科学家一样,我在我的笔记本电脑上花了几个小时在黑暗主题的 Jupyter 笔记本上,试验机器学习库,在 StackOverflow 上搜索答案,从事个人项目,并尝试各种深度学习模型。事实上,这是我通过技术测试所需要的。
如果你没有做我提到的任何事情,那么开始做一些个人项目和探索机器学习库。竞争对手做到了这一点,甚至更多。
第三阶段:演示和问答
最后一个阶段包括讨论用于解决技术测试的方法,讨论您从第二阶段进行的分析中发现了哪些见解,以及您将如何应对前三个月的数据科学角色。所有这些都将在两天内提交给公司的创始人和一位常驻数据科学家。
我讨厌承认这一点,但是一天 8 小时不与他人交流或联系的编码似乎会降低你的社交技能。我的演讲技巧大受影响。
那么一个开发者如何在一夜之间成为 5%的 TED 演讲主持人呢?
嗯,我只是做了以下的事情:
- 我看了这个关于史蒂夫工作介绍的视频
- 然后我看了这个视频,这个视频,还有这个视频(请不要带着烟去面试,而是带着幽默感)
- 最后,我使用 Prezi 创建了一个有望从标准 powerpoint 幻灯片中脱颖而出的演示文稿。
要点:找到一种不同于常规的方法,要么在展示时提供卓越的质量,要么描绘出一种可能不一定被期望的创造力。
仅此而已。
我在准备过程中采取的所有行动和步骤让我通过了面试的所有阶段,并让我处于被考虑担任该角色的位置。
你们中的一些人可能想知道为什么我被这个角色拒绝了,简单的答案是我对需要开发的算法没有直接的经验。这个职位有几个候选人,有些在第一阶段就被淘汰了,有些在技术测试阶段就被淘汰了。最后一个阶段是在我和另一个候选人之间,这个候选人有开发机器算法的经验,可能比我更适合这个角色。
拒绝不是结束,而是开始。拒绝让你知道你的知识、技能和经验有什么差距。所以当你被拒绝时,你要做的就是寻找一个有效的方法来填补这个空缺,这样做,你就离下一个角色更近了一步。
向前看,我将通过探索更多的机器学习算法并在正在进行的项目中利用它们来填补我的空白。请随意评论你的拒绝经历以及你是如何处理的。
面向数据专业人员的关系数据库管理(RDBMS)基础
数据专业人员权威指南
使用 Python SQLite3 和 SQLAlchemy 的基本 RDBMS
Source from Unsplash
数据科学家需要每天与数据库打交道。作为数据分析师和工程师,我们需要精通 SQL 和数据库管理。了解 RDBMS 将有助于我们访问、交流和处理数据。它将允许我们更快、更稳健地存储和过滤替代数据。
在本教程中,我们将学习如何:
- 设置 SQLite 磁盘连接
- 创建具有结构的表
- 将数据框值插入表中
在本教程中,我们将学习在 Python 中执行的两种方法。第一个是使用 SQLite 3,这里我们将使用 Python 和 SQL 来执行每个学习点。但是,我们也将简要讨论一下 SQL 炼金术,它允许我们仅用 4 行代码就能执行这些学习要点。(不开玩笑!)
在此之前,我们先来谈谈 RDBMS
什么是 RDBMS?
一个关系数据库是一种数据库。它使用的结构允许我们识别和访问数据库中与另一条数据相关的数据*。通常,关系数据库中的数据被组织成表。法典编纂*
关系数据库使用被称为记录的表。这些记录拥有多个列,这些列具有不同的名称和数据类型。然后,我们可以通过使用主键和外键来识别表模式关系,从而在记录之间建立连接。
Data Schema Sample for RDBMS
为什么不只是?csv 或。xlsx 对比 RDBMS (SQL)?
如今,Excel 和 csv 在存储我们的数据需求方面存在许多限制,而 RDBMS 可以解决这些限制:
容量
数据生态系统每天都在变化,今天被认为是大而快的东西,明天可能就不是了。这意味着我们需要一个能够灵活承载大量数据的专用存储。我们需要比 Excel 和 csv 更具可扩展性的存储。RDBMS 是解决方案—它允许基于服务器分布的可伸缩性,而不是基于行数和列数有限的 Excel,048,576 行乘以 16,384 列)。
具有已定义关系的依赖性
RDBMS 允许用户在表之间建立定义的关系。这将给用户一个完整的数据定义画面。例如,在您的购物收据中,您可能有几个实体,如产品描述、商品价格、商店分店位置等。所有这些都可以根据需要进行分离和合并。
分析没有从数据中分离出来
我们现在可以将数据与分析分开存储。在 Excel 中,我们需要管理不同的版本来与您的团队成员协作。每个文件都需要结合不同版本的数据和分析。但是,在 RDBMS 中,我们现在可以使用 SQL 指令分别重现和分析数据。这样,我们可以确保您的团队从中央数据服务器生成更新的数据和分析。
如果您想了解更多信息,请参考这篇 Codecademy 文章。
如果您在工作中使用 Excel 或 Google Sheets 等电子表格应用程序,这些问题可能对您来说很熟悉:它…
news.codecademy.com](https://news.codecademy.com/excel-to-sql-why-switch/)
对于数据专业人员来说,这项技能很有价值。它创建了一个一站式数据存储,每个人都可以从他们的 SQL 指令中获得相同的更新数据。
为什么我们选择 SQLite 而不是 PostgreSQL?
SQLite 为基于磁盘的数据库提供了一个轻量级的 C 库,允许 SQL 处理 CRUD 进程。这意味着我们可以在许多小型应用程序/用例中依赖 SQLite:
- SQLite 用于快速方便的内部数据存储
- SQLite 快速开发小型原型
- 在通过 PostgreSQL 或 Oracle 迁移到更大的数据库之前,SQLite 托管概念证明(POC)。
PostgreSQL 是一个非常先进的开源数据库,提供专用的数据服务器来运行其数据库。但是,SQLite 提供了不需要专用数据服务器的轻量级设置。
如果我们的数据需求包括适当的管理和安全性,那么 PostgreSQL 将是合适的选择。否则 SQLite 也行。
[## SQLite 与 PostgreSQL——使用哪个数据库,为什么?
SQLite 和 PostgreSQL 是最广泛使用的关系数据库管理系统(RDMS)。他们都是…
tableplus.io](https://tableplus.io/blog/2018/08/sqlite-vs-postgresql-which-database-to-use-and-why.html)
为了构建本文的 POC,我们将使用 SQLite。但是可以尝试使用 PostgreSQL。
将来自 Lazada 的数据提取插入 SQLite
问题陈述
我们将重用从 Lazada 中提取关键产品信息的问题。我们将把它导出到 SQLite 数据库,而不是导出到 csv。
product_df to store scraped information at Lazada Website
如果你对此不熟悉,请随意浏览我下面的文章。
[## 10 分钟内:为数据专业人员提供美味汤和硒的网络刮擦
使用 BS4 和 Selenium 快速提取关键信息
towardsdatascience.com](/in-10-minutes-web-scraping-with-beautiful-soup-and-selenium-for-data-professionals-8de169d36319)
对于本教程,我们将首先使用 SQLite3 来生成到 SQLite 引擎的连接。这将允许我们执行 SQL 命令来插入值。之后,我们将研究 SQLAlchemy 来缩短和简化这个过程,而不需要创建任何 SQL 命令。
Python SQLite3
连接到 SQLite 磁盘
我们首先建立到磁盘文件 lazada.db 的连接,这是 SQLite 引擎用来存储数据的磁盘。如果 lazada.db 不存在,它将创建一个新的,下次我们可以连接它。
import sqlite3
conn = sqlite3.connect("lazada.db")
c = conn.cursor()
注意,当我们打开连接时,我们也建立了一个游标。数据库游标是一种遍历数据库记录的工具。使用这个游标,我们可以创建表并在数据库磁盘中执行 SQL 命令。
创建 lazada_product 表
在将我们的 SQLite3 连接到 lazada.db 之后,我们将使用游标执行 SQL 查询并创建 lazada_product 表。我们将我们的元数据标识如下。
c.execute('''
CREATE TABLE lazada_product (
time date_time ,
id **INTEGER** ,
link **TEXT** NOT NULL,
product_title **TEXT** NOT NULL,
product_price **DOUBLE** NOT NULL,
category **TEXT** NOT NULL,
PRIMARY KEY (time, id)
);
''')
注意我们是如何将 time 和 id 指定为主键的。这意味着每一行都有唯一的 id 和日期时间。如果我们插入具有相同 id 和日期时间的行;SQLite 会抱怨并返回一个重复的错误。这种验证有助于防止不干净的冗余数据进入数据库。
将 df 行插入 lazada_product 表
让我们将提取的 product_df 插入到 lazada_product 表中。
def write_from_df_with_sqlite3(df):
for index, row in df.iterrows():
c.execute(
'''
INSERT INTO lazada_product VALUES
(*CURRENT_TIMESTAMP*,?,?,?,?,?)
''',
(row['id'], row['link'],row['product_title'],row['product_price'],
row['category'])
)
一旦运行这个方法,您将成功地将每个值转储到您的 lazada_product 表中。
祝贺您,您已经创建了 RDBMS 表并向其中插入了数据
注意,SQLite3 Python 有一个限制。当您将 SQL 命令和 Python 代码组合在一个文件中时,代码可能很难阅读。它看起来也很冗长。
因此,我们将看看如何使用 SQLAlchemy 以一种更短的、无 SQL 的方法来执行表和数据插入。
Python 对象关系映射器(ORM) SQLAlchemy
SQLAlchemy 是一个激活数据库引擎的 Python ORM。它在 SQLite 的 SQL 执行之上创建了一个 pythonic 包装器。这允许您在不接触任何 SQL 命令代码的情况下对表运行逻辑。
什么是对象关系映射器(ORM)?
ORM 提供了一个高级抽象,允许开发人员编写 Python 代码来调用数据库中 CRUD 和模式的 SQL。每个开发人员都可以使用他们熟悉的编程语言,而不是处理 SQL 语句或存储过程
连接到 SQLite 引擎
from sqlalchemy import create_engine
disk_engine = create_engine('sqlite:///lazada_alchemy.db')
创建 lazada_product 表并插入 df 行
def write_from_df_with_alchemy(df):
df.to_sql('lazada_product', disk_engine, if_exists='append')
看看这段代码有多简洁。运行这个方法后,我们立即根据 df 数据类型创建带有默认设置的表。同时,我们将把值追加到 lazada_product 表中,而不涉及任何 SQL。
因此,SQLAlchemy 最大的优点是促进 SQL 命令的高级抽象,以帮助 Python 开发人员使用同一种语言提取数据。
执行 SQL 而不运行 SQL 查询。— SQLAlchemy
当然,这不应该取代懂 SQL 语言的重要性。我们可以用 SQL 更好地处理更多的复杂性。然而,要对数据表的设置和插入进行编码,SQLAlchemy 将为您节省大量时间和精力。
访问我们的 SQLite 磁盘
为了检查我们磁盘的内容,我们可以使用下面的 Web Dashboard 工具。
[## SQLite 浏览器- SQL Online
JavaScript 上的 SQL 在线。用户友好的界面。不下载,不安装。在线测试 SQL 脚本…
sqliteonline.com](https://sqliteonline.com/)
从这里,您可以将磁盘作为文件插入,并编写一个简单的 SQL select 语句。
SELECT * from lazada_product
单击 run,这将显示您在 lazada_product 中的所有数据。
The results after inserting lazada_product inside the table. In total there are 108 products appended
恭喜你,你已经学会了 RDBMS 和使用 Python SQLite3 和 SQLAlchemy 插入值
结论
- RDBMS 为 csv 或 excelsheet 提供了许多好处,因为它具有更大的容量、依赖性检查以及分析和数据的分离
- 创建一个简单的 RDBMS 并不需要太多时间,我们可以使用 SQLAlchemy 来创建模式,只需用的 4 行代码。
- 我们可以通过使用 SQLite 浏览器在线或下载 Linux 或微软 SQLite 浏览器来恢复读取和 CRUD 操作。
目的、Github 代码和您的贡献
美汤硒网刮。为 VincentTatan/Web 抓取开发做出贡献,创建一个…
github.com](https://github.com/VincentTatan/Web-Scraping/tree/master/Selenium%20Web%20Scraping)
请随意克隆存储库并做出贡献。
最后…
我真的希望这是一本很棒的读物,是你发展和创新的灵感来源。
请在下面评论出来建议和反馈。
快乐编码:)
关于作者
Vincent Tatan 是一名数据和技术爱好者,拥有在 Visa Inc .和 Lazada 实施微服务架构、商业智能和分析管道项目的相关工作经验。
Vincent 是土生土长的印度尼西亚人,在解决问题方面成绩斐然,擅长全栈开发、数据分析和战略规划。
他一直积极咨询 SMU BI & Analytics Club,指导来自不同背景的有抱负的数据科学家和工程师,并为企业开发他们的产品开放他的专业知识。
请通过LinkedIn、Medium或 Youtube 频道 联系文森特