作者:王江,吴双,刘少山
本文为《程序员》原创文章,未经允许不得转载,更多精彩文章请订阅2016年《程序员》
本文是无人驾驶技术系列的第六篇,着重介绍增强学习在无人驾驶中的应用。增强学习的目的是通过和环境交互,学习如何在相应观测中采取最优行为。相比传统的机器学习,它有以下优势:首先,由于不需要标注的过程,可以更有效地解决环境中存在的特殊情况。其次,可以把整个系统作为一个整体,从而对其中的一些模块更加鲁棒。最后,增强学习可以比较容易地学习到一系列行为。这些特性十分适用于自动驾驶决策过程,我们在本文深入探讨增强学习如何在无人驾驶决策过程中发挥作用。
增强学习是最近几年中机器学习领域的最新进展。增强学习的目的是通过和环境交互学习到如何在相应的观测中采取最优行为。行为的好坏可以通过环境给的奖励来确定。不同的环境有不同的观测和奖励。例如,驾驶中环境观测是摄像头和激光雷达采集到的周围环境的图像和点云,以及其他的传感器的输出,例如行驶速度、GPS定位、行驶方向。驾驶中的环境的奖励根据任务的不同,可以通过到达终点的速度、舒适度和安全性等指标确定。
增强学习和传统机器学习的最大区别是增强学习是一个闭环学习的系统,增强学习算法选取的行为会直接影响到环境,进而影响到该算法之后从环境中得到的观测。传统的机器学习通过把收集训练数据和模型学习作为两个独立的过程。例如,如果我们需要学习一个人脸分类的模型。传统机器学习方法首先需要雇佣标注者标注一批人脸图像数据,然后在这些数据中学习模型,最后我们可以把训练出来的人脸识别模型在现实的应用中进行测试。 如果发现测试结果不理想,那么我们需要分析模型中存在问题,并且试着从数据收集或者模型训练中寻找原因,然后从这些步骤中解决这些问题。对于同样的问题,增强学习采用的方法是通过在人脸识别的系统中尝试进行预测,并且通过用户反馈的满意程度来调整自己的预测,从而统一收集训练数据和模型学习的过程。增强学习和环境交互过程的框图如图1所示。
增强学习存在着很多传统机器学习所不具备的挑战。首先,因为在增强学习中没有确定在每一时刻应该采取哪个行为的信息,增强学习算法必须通过探索各种可能的行为才能判断出最优的行为。如何有效地在可能行为数量较多的情况下有效探索,是增强学习中最重要的问题之一。其次,在增强学习中一个行为不仅可能会影响当前时刻的奖励,而且还可能会影响之后所有时刻的奖励。在最坏的情况下,一个好行为不会在当前时刻获得奖励,而会在很多步都执行正确后才能得到奖励。在这种情况下,增强学习需要判断出奖励和很多步之前的行为有关非常有难度。
虽然增强学习存在很多挑战,它也能够解决很多传统的机器学习不能解决的问题。首先,由于不需要标注的过程, 增强学习可以更有效地解决环境中所存在着的特殊情况。比如,无人车环境中可能会出现行人和动物乱穿马路的特殊情况。只要我们的模拟器能够模拟出这些特殊情况,增强学习就可以学习到怎么在这些特殊情况中做出正确的行为。其次,增强学习可以把整个系统作为一个整体的系统,从而对其中的一些模块更加鲁棒。例如,自动驾驶中的感知模块不可能做到完全可靠。前一段时间,Tesla无人驾驶的事故就是因为在强光环境中感知模块失效导致的。增强学习可以做到,即使在某些模块失效的情况下也能做出稳妥的行为。最后,增强学习可以比较容易学习到一系列行为。自动驾驶中需要执行一系列正确的行为才能成功的驾驶。如果只有标注数据,学习到的模型如果每个时刻偏移了一点,到最后可能就会偏移非常多,产生毁灭性的后果。而增强学习能够学会自动修正偏移。
综上所述,增强学习在自动驾驶中有广阔的前景。本文会介绍增强学习的常用算法以及其在自动驾驶中的应用。希望能够激发这个领域的探索性工作。
增强学习中的每个时刻t∈{0,1,2,…}中,我们的算法和环境通过执行行为at进行交互,可以得到观测st和奖励rt。一般情况中,我们假设环境是存在马尔科夫性质的,即环境的变化完全可以通过状态转移概率Pass′=Pr{st+1=s′|st=s,at=a}刻画出来。也就是说,环境的下一时刻观测只和当前时刻的观测和行为有关,和之前所有时刻的观测和行为都没有关系。而环境在t+1时刻返回的奖励在当前状态和行为确定下的期望可以表示为:Ras=E{rt+1|st=s,at=a}. 增强学习算法在每一个时刻执行行为的策略可以通过概率π(s,a,θ)=Pr{at=a|st=s;θ}来表示。其中θ是需要学习的策略参数。我们需要学习到最优的增强学习策略,也就是学习到能够取得最高奖励的策略。
其中γ是增强学习中的折扣系数,用来表示在之后时刻得到的奖励折扣。同样的奖励,获得的时刻越早,增强学习系统所感受到的奖励越高。
同时,我们可以按照如下方式定义Q函数。Q函数Qpi(s,a)表示的是在状态为s,执行行为a之后的时刻都使用策略π选择行为能够得到的奖励。我们能够学习到准确的Q函数,那么使Q函数最高的行为就是最优行为。
增强学习的目的,就是在给定的任意环境,通过对环境进行探索学习到最佳的策略函数π最大化rho(π)。下面的章节中我们会简单介绍常用的增强学习算法。包括REINFORCE算法和Deep Q-learning算法。
REINFORCE
REINFORCE是最简单的reinforcement learning算法。其基本思想是通过在环境里面执行当前的策略直到一个回合结束(比如游戏结束),根据得到的奖励可以计算出当前策略的梯度。我们可以用这个梯度更新当前的策略得到新策略。在下面的回合,我们再用新的策略重复这个过程,一直到计算出的梯度足够小为止。最后得到的策略就是最优策略。
假设我们当前的策略概率是πθ(x)=Pr{at=a|st=s;θ} (θ是策略参数)。每个回合,算法实际执行的行为at是按照概率π(x)采样所得到的。算法在当前回合时刻t获得的奖励用rt表示。那么,策略梯度可以通过以下的公式计算。
其中π(at|st;θ)是策略在观测到st时选择at的概率。Rt=∑Tt′=tγt′-trt′是算法在采取了当前策略之后所获得的总的折扣后的奖励。为了减少预测出梯度的方差。我们一般会使用(Rt-bt)来代替Rt。bt一般等于Eπ[Rt],也就是当前t时刻的环境下使用策略π之后能获得的折扣后奖励的期望。
计算出方差之后,我们可以使用θ=θ+▽θρ(π)更新参数得到新的策略。
REINFORCE的核心思想是通过从环境中获得的奖励判断执行行为的好坏。如果一个行为执行之后获得的奖励比较高,那么算出的梯度也会比较高,这样在更新后的策略中该行为被采样到的概率也会比较高。反之,对于执行之后获得奖励比较低的行为,因为计算出的梯度低,更新后的策略中该行为被采样到的概率也会比较低。通过在这个环境中反复执行各种行为,REIFORCE可以大致准确地估计出各个行为的正确梯度,从而对策略中各个行为的采样概率做出相应调整。
作为最简单的采样算法,REINFORCE得到了广泛应用,例如学习视觉的注意力机制和学习序列模型的预测策略都用到了REINFORCE算法。事实证明,在模型相对简单,环境随机性不强的环境下,REINFORCE算法可以达到很好的效果。
但是,REINFORCE算法也存在着它的问题。首先,REINFORCE算法中,执行了一个行为之后的所有奖励都被认为是因为这个行为产生的,这显然不合理。虽然在执行了策略足够多的次数然后对计算出的梯度进行平均之后,REINFORCE以很大概率计算出正确的梯度。但是在实际实现中,处于效率考虑,同一个策略在更新之前不可能在环境中执行太多次。在这种情况下,REINFORCE计算出的梯度有可能会有比较大的误差。其次,REINFROCE算法有可能会收敛到一个局部最优点。如果我们已经学到了一个策略,这个策略中大部分的行为都以近似1的概率采样到。那么,即使这个策略不是最优的,REINFORCE算法也很难学习到如何改进这个策略。因为我们完全没有执行其他采样概率为0的行为,无法知道这些行为的好坏。最后,REINFORCE算法之后在环境存在回合的概念的时候才能够使用。如果不存在环境的概念,REINFORCE算法也无法使用。
最近,DeepMind提出了使用Deep Q-learning算法学习策略,克服了REINFORCE算法的缺点,在Atari游戏学习这样的复杂的任务中取得了令人惊喜的效果。
Deep Q-learning
Deep Q-learning是一种基于Q函数的增强学习算法。该算法对于复杂的每步行为之间存在较强的相关性环境有很好的效果。Deep Q-learning学习算法的基础是Bellman公式。我们在前面的章节已经介绍了Q函数的定义,如下所示。
如果我们学习到了最优行为对应的Q函数Q*(s,a),那么这个函数应该满足下面的Bellman公式。
另外,如果学习到了最优行为对应的Q函数Q*(s,a),那么我们在每一时刻得到了观察st之后,选择使得Q*(s,a)最高的行为做为执行的行为at。
我们可以用一个神经网络来计算Q函数,用Q(s,a;w)来表示。其中w是神经网络的参数。我们希望学习出来的Q函数满足Bellman公式。因此可以定义下面的损失函数。这个函数的Bellman公式的L2误差如下。
其中r是在s的观测执行行为a后得到的奖励,s′是执行行为a之后下一个时刻的观测。这个公式的前半部分r+γmaxa′Q*(s′,a′,w)也被称为目标函数。我们希望预测出的Q函数能够和通过这个时刻得到的奖励及下个时刻状态得到的目标函数尽可能接近。通过这个损失函数,我们可以计算出如下梯度。
可以通过计算出的梯度,使用梯度下降算法更新参数w。
使用深度神经网络来逼近Q函数存在很多问题。首先,在一个回合内采集到的各个时刻的数据是存在着相关性的。因此,如果我们使用了一个回合内的全部数据,那么我们计算出的梯度是有偏的。其次,由于取出使Q函数最大的行为这个操作是离散的,即使Q函数变化很小,我们所得到的行为也可能差别很大。这个问题会导致训练时策略出现震荡。最后,Q函数的动态范围有可能会很大,并且我们很难预先知道Q函数的动态范围。因为,我们对一个环境没有足够的了解的时候,很难计算出这个环境中可能得到的最大奖励。这个问题会使Q-learning工程梯度可能会很大,导致训练不稳定。
首先,Deep Q-learning算法使用了经验回放算法。其基本思想是记住算法在这个环境中执行的历史信息。这个过程和人类的学习过程类似。人类在学习执行行为的策略时,不会只通过当前执行的策略结果进行学习,而还会利用之前的历史执行策略经验进行学习。因此,经验回放算法将之前算法在一个环境中的所有经验都存放起来。在学习的时候,可以从经验中采样出一定数量的跳转信息(st,at,rt+1,st+1),也就是当处于环境,然后利用这些信息计算出梯度学习模型。因为不同的跳转信息是从不同回合中采样出来的,所以它们之间不存在强相关性。这个采样过程还可以解决同一个回合中的各个时刻的数据相关性问题。
而且,Deep Q-learning算法使用了目标Q网络来解决学习过程中的震荡问题。我们可以定义一个目标Q网络Q(s,a;w-)。这个网络的结构和用来执行的Q网络结构完全相同,唯一不同就是使用的参数w-。我们的目标函数可以通过目标Q网络计算。
目标Q网络参数在很长时间内保持不变,每当在Q网络学习了一定时间之后,可以Q网络的参数w替换目标Q网络的参数w-。这样目标函数在很长的时间里保持稳定。可以解决学习过程中的震荡问题。
最后,为了防止Q函数的值太大导致梯度不稳定。Deep Q-learning的算法对奖励设置了最大和最小值(一般设置为[-1, +1])。我们会把所有奖励缩放到这个范围。这样算法计算出的梯度更加稳定。
Q-learning算法的框图如图2所示。
因为使用了深度神经网络来学习Q函数,Deep Q-learning算可以直接以图像作为输入学习复杂的策略。其中一个例子是学习Atari游戏。这是计算机游戏的早期形式,一般图像比较粗糙,但要玩好需要对图像进行理解,并且执行复杂的策略,例如躲避,发射子弹,走迷宫等。一些Atari游戏的例子如图3所示,其中包含了一个简单的赛车游戏。
Deep Q-learning算法在没有任何额外知识的情况下,完全以图像和获得的奖励进行输入。在大部分Atari游戏中都大大超过了人类性能。这是深度学习或者增强学习出现前完全不可能完成的任务。Atari游戏是第一个Deep Q-learning解决了用其他算法都无法解决的问题,充分显示了将深度学习和增强学习结合的优越性和前景。
现有的深度增强学习解决的问题中,我们执行的行为一般只对环境有短期影响。例如,在Atari赛车游戏中,我们只需要控制赛车的方向和速度让赛车沿着跑道行驶,并且躲避其他赛车就可以获得最优的策略。但是对于更复杂决策的情景,我们无法只通过短期奖励得到最优策略。一个典型的例子是走迷宫。在走迷宫这个任务中,判断一个行为是否是最优无法从短期的奖励来得到。只有当走到终点时,才能得到奖励。在这种情况下,直接学习出正确的Q函数非常困难。我们只有把基于搜索的和基于增强学习的算法结合,才能有效解决这类问题。
基于搜索算法一般是通过搜索树来实现的。搜索树既可以解决一个玩家在环境中探索的问题(例如走迷宫),也可以解决多个玩家竞争的问题(例如围棋)。我们以围棋为例,讲解搜索树的基本概念。围棋游戏有两个玩家,分别由白子和黑子代表。围棋棋盘中线的交叉点是可以下子的地方。两个玩家分别在棋盘下白子和黑子。一旦一片白子或黑子被相反颜色的子包围,那么这片子就会被提掉,重新成为空白的区域。游戏的最后,所有的空白区域都被占领或是包围。占领和包围区域比较大的一方获胜。
在围棋这个游戏中,我们从环境中得到的观测st是棋盘的状态,也就是白子和黑子的分布。我们执行的行为是所下白子或者黑子的位置。而我们最后得到的奖励可以根据游戏是否取胜得到。取胜的一方+1,失败的一方-1。游戏进程可以通过如下搜索树来表示:搜索树中的每个节点对应着一种棋盘状态,每一条边对应着一个可能的行为。在如图4所示的搜索树中,黑棋先行,树的根节点对应着棋盘的初始状态s0。a1和a2对应着黑棋两种可能的下子位置(实际的围棋中,可能的行为远比两种多)。每个行为ai对应着一个新的棋盘的状态si1。接下来该白棋走,白棋同样有两种走法b1和b2,对于每个棋盘的状态si1,两种不同的走法又会生成两种不同状态。如此往复,一直到游戏结束,我们就可以在叶子节点中获得游戏结束时黑棋获得的奖励。我们可以通过这些奖励获得最佳的状态。
通过这个搜索树,如果给定黑棋和白棋的策略π=[π1,π2],我们可以定义黑棋的值函数为黑棋在双方分别执行策略π1和π2时,最后黑棋能获得奖励的期望。
黑棋需要寻找的最优策略需要最优化最坏的情况下,黑棋所能得到的奖励。我们定义这个值函数为最小最大值函数。黑棋的最优策略就是能够达到这个值函数的策略π1。
如果我们能够穷举搜索树的每个节点,那么我们可以很容易地用递归方式计算出最小最大值函数和黑棋的最优策略。但在实际的围棋中,每一步黑棋和白棋可以采用的行为个数非常多,而搜索树的节点数目随着树的深度指数增长。因此,我们无法枚举所有节点计算出准确的最小最大值函数,而只能通过学习v(s;w)~v*(s)作为近似最小最大值函数。我们可以通过两种方法使用这个近似函数。首先,我们可以使用这个近似函数确定搜索的优先级。对于一个节点,白棋或者黑棋可能有多种走法,我们应该优先搜索产生最小最大值函数比较高节点的行为,因为在实际游戏中,真实玩家一般会选择这些相对比较好的行为。其次,我们可以使用这个近似函数来估计非叶子节点的最小最大值。如果这些节点的最小最大值非常低,那么这些节点几乎不可能对应着最优策略。我们再搜索的时候也不用考虑这些节点。
因此主要问题是如何学习到近似最小最大值函数v(s;w)。我们可以使用两个学习到的围棋算法自己和自己玩围棋游戏。然后通过增强学习算法更新近似最小最大值函数的参数w。在玩完了一局游戏之后,我们可以使用类似REINFORCE算法的更新方式:
在这个式子中Gt表示的是在t时刻之后获得的奖励。因为在围棋这个游戏中,我们只在最后时刻获得奖励。所以Gt对应的是最后获得的奖励。我们也可以使用类似Q-learning的方式用TD误差来更新参数。
因为围棋这个游戏中,我们只在最后时刻获得奖励。一般使用REINFORCE算法的更新方式效果比较好。在学习出一个好的近似最小最大值函数之后,可以大大加快搜索效率。这和人学习围棋的过程类似,人在学习围棋的过程中,会对特定的棋行形成感觉,能一眼就判断出棋行的好坏,而不用对棋的发展进行推理。这就是通过学习近似最小最大值函数加速搜索的过程。
通过学习近似最小最大值函数,Google DeepMind在围棋领域取得了突飞猛进。在今年三月进行的比赛中,AlphaGo以四比一战胜了围棋世界冠军李世石。AlphaGo的核心算法就是通过历史棋局和自己对弈学习近似最小最大值函数。AlphaGo的成功充分的显示了增强学习和搜索结合在需要长期规划问题上的潜力。不过,需要注意的是,现有将增强学习和搜索结合的算法只能用于确定性的环境中。确定性的环境中给定一个观测和一个行为,下一个观测是确定的,并且这个转移函数是已知的。在环境非确定,并且转移函数未知的情况下,如何把增强学习和搜索结合还是增强学习领域中没有解决的问题。
自动驾驶的人工智能包含了感知、决策和控制三个方面。感知指的是如何通过摄像头和其他传感器输入解析出周围环境的信息,例如有哪些障碍物,障碍物的速度和距离,道路的宽度和曲率等。这个部分是自动驾驶的基础,是当前自动驾驶研究的重要方向,在前文我们已经有讲解。控制是指当我们有了一个目标,例如右转30度,如何通过调整汽车的机械参数达到这个目标。这个部分已经有相对比较成熟的算法能够解决,不在本文的讨论范围之内。本节,我们着重讲解自动驾驶的决策部分。
自动驾驶的决策是指给定感知模块解析出的环境信息如何控制汽车的行为来达到驾驶目标。例如,汽车加速、减速、左转、右转、换道、超车都是决策模块的输出。决策模块不仅需要考虑到汽车的安全和舒适性,保证尽快到达目标地点,还需要在旁边车辆恶意驾驶的情况下保证乘客安全。因此,决策模块一方面需要对行车计划进行长期规划,另一方面还需要对周围车辆和行人的行为进行预测。而且,自动驾驶中的决策模块对安全和可靠性有着严格要求。现有自动驾驶的决策模块一般根据规则构建,虽然可以应付大部分驾驶情况,对于驾驶中可能出现的各种突发情况,基于规则的决策系统不可能枚举到所有突发情况。我们需要一种自适应系统来应对驾驶环境中出现的各种突发情况。
现有自动驾驶的决策系统大部分基于规则,该系统大部分可以用有限状态机表示。例如,自动驾驶的高层行为可以分为向左换道、向右换道、跟随、紧急停车。决策系统根据目标可以决定执行高层行为。根据需要执行的高层行为,决策系统可以用相应的规则生成出底层行为。基于规则决策系统的主要缺点是缺乏灵活性。对于所有的突发情况,都需要写一个决策。这种方式很难对所有的突发系统面面俱到。
自动驾驶模拟器
自动驾驶的决策过程中,模拟器起着非常重要的作用。决策模拟器负责对环境中常见的场景进行模拟,例如车道情况、路面情况、障碍物分布和行为、天气等。同时还可以将真实场景中采集到的数据进行回放。决策模拟器的接口和真车的接口保持一致,这样可以保证在真车上使用的决策算法可以直接在模拟器上运行。除了决策模拟器之外,自动驾驶的模拟器还包含了感知模拟器和控制模拟器,用来验证感知和控制模块。这些模拟器不在本文的讨论氛围之内 (详细请见CSDN《程序员》2016年8月《基于Spark与ROS的分布式无人驾驶模拟平台》)。
自动驾驶模拟器的第一个重要功能是验证。在迭代决策算法的过程中,我们需要比较容易地衡量算法性能。比如,需要确保新决策算法在之前能够正确运行和常见的场景都能够安全运行。我们还需要根据新决策算法对常见场景的安全性、快捷性、舒适性打分。我们不可能每次在更新算法时都在实际场景中测试,这时有一个能可靠反映真实场景的无人驾驶模拟器是非常重要的。
模拟器的另一个重要的功能是进行增强学习。可以模拟出各种突发情况,然后增强学习算法利用其在这些突发情况中获得的奖励,学习如何应对。这样,只要能够模拟出足够的突发情况,增强学习算法就可以学习到对应的处理方法,而不用每种突发情况都单独写规则处理。而且,模拟器也可以根据之前增强学习对于突发情况的处理结果,尽量产生出当前的增强学习算法无法解决的突发,从而增强学习效率。
综上所述,自动驾驶模拟器对决策模块的验证和学习都有着至关重要的作用,是无人驾驶领域的核心技术。如何创建出能够模拟出真实场景、覆盖大部分突发情况、并且和真实的汽车接口兼容的模拟器,是自动驾驶研发的难点之一。
增强学习在自动驾驶中的应用和展望
增强学习在自动驾驶中很有前景。我们在TORCS模拟器中使用增强学习进行了探索性的工作。TORCS是一个赛车模拟器。玩家的任务是超过其他AI车,以最快速度达到终点。虽然TORCS中的任务和真实的自动驾驶任务还有很大区别。但其中算法的性能非常容易评估。TORCS模拟器如图5所示。增强学习算法一般可以以前方和后方看到的图像作为输入,也可以环境状态作为输入(例如速度,离赛道边缘的距离和跟其他车的距离)。
我们这里使用了环境状态作为输入。使用Deep Q-learning做为学习算法学习。环境奖励定义为在单位时刻车辆沿跑道的前进距离。另外,如果车出了跑道或者和其他的车辆相撞,会得到额外惩罚。环境状态包括车辆的速度、加速度、离跑道的左右边缘的距离,以及跑道的切线夹角,在各个方向上最近的车的距离等等。车的行为包括向上换挡、向下换挡、加速、减速、向左打方向盘、向右打方向盘等等。
与普通的Deep Q-learning相比,我们做了以下的改进。首先,使用了多步TD算法进行更新。多步TD算法能比单步算法每次学习时看到更多的执行部数,因此也能更快地收敛。其次,我们使用了Actor-Critic的架构。它把算法的策略函数和值函数分别使用两个网络表示。这样的表示有两个优点:1. 策略函数可以使用监督学习的方式进行初始化学习。2. 在环境比较复杂的时候,学习值函数非常的困难。把策略函数和值函数分开学习可以降低策略函数学习的难度。
使用了改进后的Deep Q-learning算法,我们学习到的策略在TORCS中可以实现沿跑到行走,换道,超车等行为。基本达到了TORCS环境中的基本驾驶的需要。Google DeepMind直接使用图像作为输入,也获得了很好的效果,但训练的过程要慢很多。
现有的增强学习算法在自动驾驶模拟环境中获得了很有希望的结果。但是可以看到,如果需要增强学习真正能够在自动驾驶的场景下应用,还需要有很多改进。第一个改进方向是增强学习的自适应能力。现有的增强学习算法在环境性质发生改变时,需要试错很多次才能学习到正确的行为。而人在环境发生改变的情况下,只需要很少次试错就可以学习到正确的行为。如何只用非常少量样本学习到正确的行为是增强学习能够实用的重要条件。
第二个重要的改进方向是模型的可解释性。现在增强学习中的策略函数和值函数都是由深度神经网络表示的,其可解释性比较差,在实际的使用中出了问题,很难找到原因,也比较难以排查。在自动驾驶这种人命关天的任务中,无法找到原因是完全无法接受的。
第三个重要的改进方向是推理和想象能力。人在学习的过程中很多时候需要有一定的推理和想象能力。比如,在驾驶时,不用亲身尝试,也知道危险的行为会带来毁灭性的后果。 这是因为人类对这个世界有一个足够好的模型来推理和想象做出相应行为可能会发生的后果。这种能力不仅对于存在危险行为的环境下下非常重要,在安全的环境中也可以大大加快收敛速度。
只有在这些方向做出了实质突破,增强学习才能真正使用到自动驾驶或是机器人这种重要的任务场景中。希望更多有志之士能投身这项研究,为人工智能的发展贡献出自己的力量。
作者简介
点击阅读无人驾驶技术系列文章:
订阅2016年程序员(含iOS、Android及印刷版)请访问 http://dingyue.programmer.com.cn
订阅咨询:
• 在线咨询(QQ):2251809102
• 电话咨询:010-64351436
• 更多消息,欢迎关注“程序员编辑部”