算法集锦(34) | 强化学习| 出租车载客问题

时间:2022-07-22
本文章向大家介绍算法集锦(34) | 强化学习| 出租车载客问题,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

强化学习(Reinforcement Learning)是一种重要的机器学习方法,在智能机器人及分析预测等领域有许多应用。强化学习是智能体(Agent)以"试错"的方式进行学习,通过与环境进行交互获得的奖赏指导行为,目标是使智能体获得最大的奖赏。

2016年,Deepmind公司的AlphaGo击败了韩国世界级围棋选手李世石,引起了巨大轰动。

如果你是个游戏爱好者,那么你可能听说过OpenAI研发的Dota2 AI战队。AI已能像人类一样“组队”,在5v5对战中完虐Dota 2人类玩家,并且平均天梯分数超过4200分(超过将近90%的Dota2玩家,去年中国平均天梯分为3274分)。

这些成就都是强化学习所带来的。此外,强化学习还在自动驾驶汽车、机器人、推荐系统和广告系统中得到了广泛的应用。

对于初学者,通常会关心这些问题:为什么我们需要强化学习?它是不是只能应用于游戏领域?或者它该如何应用到现实场景中呢?本文将为你解答这些问题,并介绍如何在Python环境中设计并解决强化学习项目。

强化学习简介

强化学习从何而来呢?它是Rich Sutton和Andrew Barto发明的,后者是前者的博士论文导师。它在20世纪80年代就形成,但当时并未引起足够的重视。但Rich坚信该技术有着很高的实用性,并最终将大放异彩。

强化学习通过从它所处的环境中学习来支实现自动化,机器学习和深度学习也是如此,它们采取的策略不同,但都可以实现自动化运行。

强化学习很像自然的学习过程,过程/模型会收到关于它是否表现良好的反馈。深度学习和机器学习也是学习过程,但它们最关注的是在现有数据中发现模式,其本质是基于统计学的。而强化学习通过“试错”的方法进行学习,最终得到正确的行为或全局最优。强化学习的另一个显著优点是,我们不需要像监督学习那样依赖大数据。

强化学习原理

想象你正在教你的猫一些新把戏,但不幸的是,猫不懂我们的语言,所以我们不能告诉它们我们想让它们做什么。相反,模拟一个场景,你的猫会尝试以许多不同的方式做出反应。如果猫的反应是你想要的,我们就用牛奶奖励它们。现在你猜怎么着,下次猫再遇到同样的情况时,它会以更大的热情做出类似的动作,期望得到更多的食物。这就是从积极的反应中学习,如果他们面对的是消极的反应,比如愤怒的脸,他们不会从这些反应中学习。

类似地,这就是强化学习的工作原理,我们给机器一些输入和动作,然后根据输出对它们进行奖励。奖励最大化将是我们的最终目标。现在我们来看看如何把上面的问题解释为强化学习问题。

  • 猫将是暴露在“环境”中的“代理(agent)”。
  • 环境可以是一个房子或游戏区,这取决于你想教它什么。
  • 遇到的情况称为“状态”,类似于你的猫在床下爬行或奔跑。
  • 代理会对“状态”的改变作出反应,并执行相应的操作。
  • 在状态更改之后,我们根据执行的操作给予代理“奖励”或“惩罚”。
  • “政策”是选择行动以寻求更好结果的战略。

强化学习术语

代理和环境在强化学习算法中起着至关重要的作用。环境是主体生存的世界。代理还会从环境中感知到一个奖励信号,这个信号是一个数字,告诉它当前世界状态是好是坏。代理的目标是最大化其累积的报酬,称为回报。在我们编写第一个强化学习算法之前,我们需要理解以下“术语”。

状态:状态是对世界的完整描述,它不隐藏世界上存在的任何信息。它可以是一个位置,一个常数或一个动态。我们通常用数组、矩阵或更高阶张量来记录这些状态。

动作:动作通常是基于环境的,不同的环境导致不同的动作。代理的一组有效操作记录在称为操作空间的空间中,它们的数量通常是有限的。

环境:这是代理存在和交互的地方。对于不同类型的环境,我们使用不同的奖励、策略等。

奖励与回报:奖励函数R是强化学习中必须时刻跟踪的函数。它对算法的优化、优化和停止算法的训练起着至关重要的作用。这取决于当前的全局状况、刚刚采取的行动以及下一个全局状况。

策略:策略是代理用于选择下一个动作的规则,这些规则也称为代理大脑。

出租车问题

既然我们已经看到了所有的强化术语,现在让我们用强化算法来解决一个问题。在此之前,我们需要理解如何设计问题,并在解决问题时指定这个强化学习术语。

假设我们有一个出租车培训区,我们教它在停车场把人送到四个不同的地方(R,G,Y,B)。该游戏的规则是:在一个地点接乘客,然后送至指定的另一个地点。完成一次成功载客,可以得到20分;但出租车每移动一步,则会扣点1分;此外,将乘客送至错误地点会被扣10分。

黄色方块代表出租车,(“|”)表示一堵墙,蓝色字母代表接乘客的位置,紫色字母是乘客下车的位置,出租车上有乘客时就会变绿。

在此之前,我们需要了解并设置python所适用的环境。通常,可以使用OpenAi的Gym设置出租车问题的环境,它是解决强化学习问题最常用的库之一。在使用它之前,需要安装gym库,可以用pip操作实现。

pip install gym

下图展示了出租车问题的运行环境,这个问题的所有模型和接口已经在gym中进行了配置,并命名为Taxi - v2

Taxi V2环境

让我们更深入的分析这个问题。首先,出租车是停车场中唯一的一辆车。其次,我们可以把停车场分成一个5x5的网格,这给了我们25个可能的出租车位置,这25个位置是状态空间的一部分。注意,出租车的当前位置状态是坐标(3,1)。

我们将上述运行环境抽象为一个坐标轴,那么就可以在(row, col)坐标中选择R、G、Y、B或[(0,0)、(0,4)、(4,0)、(4,3)]四个位置接送乘客。

我们可以将乘客位置和目的地位置的所有组合考虑为出租车环境的总状态数。可知,有4个目的地和5个可能的乘客位置。所以,我们的出租车环境5×5×5×4 = 500种可能状态,所有可能的状态都用一个从0到499的整数表示。代理遇到500个状态中的一个,然后采取行动。在我们的案例中,行动可以是向某个方向移动,或者决定接送乘客。

换句话说,我们有6种可能的行为:接乘客、放下乘客、北、东、南、西(这四个方向是出租车移动的方向)。这就是操作空间:代理在给定状态下可以采取的所有操作的集合。

由于墙壁的原因,出租车无法在某些状态下执行某些操作。在环境的代码中,我们将为每撞墙一次提供-1的惩罚,并且出租车不会移动到任何地方。这只会增加惩罚,导致出租车考虑绕过墙。

奖励表:出租车环境初始化时,一个初始奖励表p也同时被创建。我们可以把它设计为一个矩阵,其行数等于状态数,列数等于行为数。初始的奖励表可以设置为:

>>> import gym
>>> env = gym.make("Taxi-v2").env
>>> env.P[328]
{0: [(1.0, 433, -1, False)], 
 1: [(1.0, 233, -1, False)],
 2: [(1.0, 353, -1, False)],
 3: [(1.0, 333, -1, False)],
 4: [(1.0, 333, -10, False)],
 5: [(1.0, 333, -10, False)]
}

这个字典的结构为:{action: [(probability, nextstate, reward, done)]}

  • 0-5对应出租车在当前状态下的动作:(南,北,东,西,接乘客,放下乘客)。
  • done用来指示何时成功地将乘客送到了正确的位置。

首先,让我们看一下不采用强化学习,这个问题会如何解决。

因为每个状态下都有默认的奖励表p,所以可以尝试使用它来导航出租车。

我们将创建一个无限循环,一直运行到一个乘客到达一个目的地,也就是我们收到20的奖励时。env.action_space.sample()方法自动从所有可能的操作中选择一个随机操作。

虽然问题解决了,但明显不是最优解,或者这个算法难以一直正常工作。我们需要一个合适的交互代理,以减小算法的迭代次数,并获得最优解。

Q-Learning算法

下面采用强化学习中的Q-Learning算法来解决出租车问题。

这种算法用环境的奖励来学习,在给定的状态下采取最佳的行动。在上面的实现中,我们有一个奖励表p,代理将从中学习。使用奖励表,它会选择下一个是否有益的行为,然后更新一个名为Q-Value的新值。创建的这个新表称为q表,它们映射到一个名为(State, Action)的组合。如果q值较高,我们给予更多的优化奖励。

例如,如果出租车在当前位置遇到一个包括乘客的状态,那么与其他动作(如放下乘客或向北)相比,“接乘客”的q值很可能更高。

q值初始化为任意值,当代理将自身暴露于环境中,通过执行不同的动作获得相应的奖励时,q值根据以下公式进行更新:

这里有一个问题,如何初始化这个q值以及如何计算它们。因为我们使用任意常数初始化q值。,当代理向环境公开时,它通过执行不同的操作获得各种奖励。一旦执行了这些操作,q值就由方程执行。

这里的ar是Q-Learning算法的参数,被称为学习率和折现系数。其取值范围在0和1之间,有时等于1。不能设为0,因为损失函数应该以一定的学习率更新。

这里的a表示与监督学习中使用的相同。r决定了我们对未来奖励的重视程度。

以下是Q-Learning算法的主要步骤:

步骤1: 初始化q表,将所有0和q值初始化为任意常数。

步骤2: 让代理对环境作出反应并探索这些操作。对于状态中的每个更改,在当前状态的所有可能操作中选择任意一个。

步骤3: 作为该操作(a)的结果,移动到下一个状态(S)。

步骤4:对于来自状态(S)的所有可能操作,选择q值最高的操作。

步骤5: 使用公式更新q表值。

状态6: 将下一个状态更改为当前状态。

步骤7: 如果达到目标状态,则结束并重复该过程。

具体代码如下。

import gym
import numpy as np
import random
from IPython.display import clear_output

# Init Taxi-V2 Env
env = gym.make("Taxi-v2").env

# Init arbitary values
q_table = np.zeros([env.observation_space.n, env.action_space.n])

# Hyperparameters
alpha = 0.1
gamma = 0.6
epsilon = 0.1


all_epochs = []
all_penalties = []

for i in range(1, 100001):
    state = env.reset()

    # Init Vars
    epochs, penalties, reward, = 0, 0, 0
    done = False

    while not done:
        if random.uniform(0, 1) < epsilon:
            # Check the action space
            action = env.action_space.sample()
        else:
            # Check the learned values
            action = np.argmax(q_table[state])

        next_state, reward, done, info = env.step(action)

        old_value = q_table[state, action]
        next_max = np.max(q_table[next_state])

        # Update the new value
        new_value = (1 - alpha) * old_value + alpha * 
            (reward + gamma * next_max)
        q_table[state, action] = new_value

        if reward == -10:
            penalties += 1

        state = next_state
        epochs += 1

    if i % 100 == 0:
        clear_output(wait=True)
        print("Episode: {i}")

print("Training finished.")

经过训练,模型可确保出租车更准确地接送乘客。

原文地址:

https://towardsdatascience.com/reinforcement-learning-with-python-8ef0242a2fa2