下一代自主驾驶技术剖析:核心算法、车载客户端和云端平台系统
想更深入地学习本文和其他深度学习技术,可以查看《The Deep Learning Video Collection: 2016》来了解世界级专家介绍他们是如何实现深度神经网络、解决常见的挑战以及处理大规模场景下的分布式训练等内容。
我们正处在下一代自主驾驶时代的开端。自主驾驶的现状是什么?会怎么发展?在预测它的未来前,先让我们先回顾一下历史。
信息科技发端与上世纪60年代。由仙童半导体和因特尔开创出的硅基微处理器打下了这个行业的基石(也创立了硅谷)。微处理器技术极大地提升了工业界的生产力,但普通大众依然很难使用到它,并获得益处。到上世纪80年代,随着使用图形用户界面的施乐的Alto计算机、苹果的Lisa计算机以及后来的微软的视窗系统的出现,第二层基础被铺设好。“个人”电脑的设想变成可能。
到2000年,几乎每个人都能使用计算机的时候,Google铺下了第三层基础——通过信息间接地联接起了世界。
从2004年的FaceBook开始发端,社交网络铺下了信息科技的第四层基础,让人们直接通过网络联系起来。从而有效地把人类社会拓展到了万维网的空间。
伴随着熟悉互联网的人群逐渐成为主流,由Airbnb(2008年)和Uber(2009年)引领的互联网商务服务大潮又为信息科技铺下了第五层的基础。
每一层新的基础都为信息科技带来了新的改进,并促进了互联网的使用,同时也带来新的需求。需要注意的是,尽管大部分的互联网商务网站是通过互联网接受并建立的服务,但实际提供服务的还是人类。
图1 信息科技的历史。图片由Shaoshan Liu友情提供
现在,我们正在铺下这第六层——使用机器人而不是人类来提供服务。
这一趋势的一个例子就是自主驾驶汽车(AV)的出现。自主驾驶技术驱动的车辆可以把乘客送往目的地而无需人类驾驶员。它不是一项单纯的技术,而是一个由很多部分组成的系统。
在这篇博文里,我会遍历自主驾驶所涉及的技术,并探讨如何把这些技术集成在一起,形成一个安全、有效和高效的自主驾驶系统。
自主驾驶技术概览
自主驾驶技术是一个复杂的系统,由三个主要的子系统组成:核心算法、车载客户端系统和云端平台系统。核心算法包括感知、理解和决策部分;车载客户端系统包括机器人操作系统(ROS)和硬件平台;云端平台包括数据存储部分、模拟系统、高清晰度地图部分和深度学习模型训练部分。
图2 自主驾驶系统的架构总览。图片由Shaoshan Liu友情提供
算法子系统从传感器收集来的原始数据中抽取出有意义的信息,从而能理解周围的环境,并对于要采用什么行动做出决策。车载客户端子系统集成了这些算法,并保证满足实时和可靠性的需求(例如,如果传感摄像头以60Hz的频率生成数据,那么客户端子系统必须保证处理管道的最长时间必须少于16毫秒)。云端平台是为车辆提供离线的计算和存储能力。基于云平台,我们可以测试新的算法、升级高清晰度地图以及训练更好的识别、跟踪和决策模型。
自主驾驶算法
算法部分包括:从传感器采集的原始数据里感知和抽取有意义的信息;理解信息来定位车辆位置和了解当前的环境;决定采用什么行动来让车辆可靠安全地抵达目的地。
感知
通常,一辆自主驾驶汽车包括多个主要的传感器。因为每种类型的传感器都有自己的优缺点,所以必须组合使用来自多个传感器的数据。常见的传感器类型包括如下几种:
1. GPS/IMU(全球定位系统和惯性测量单元):
GPS和IMU系统通过高频(例如200Hz)收集惯性变化和地理位置估计来帮助自主驾驶汽车定位自身。尽管GPS是一个相当精确的定位传感器,但它的更新频率是10Hz,无法提供实时的信息。经管IMU的准确度随着时间变长而降低,从而导致不能长时间地依赖于它提供精确的位置信息。但它能提供更快的更新频率(200Hz或更高),这就能满足实时的需求。通过结合GPS与IMU,就可以提供实时且准确的车辆定位信息。
2. LIDAR(激光雷达):
LIDAR被用于绘图、定位以及避障。它的工作原理是通过发射激光,并测量反射回来的时间来测量自身与其他物体的距离。它的准确度很高。因此在大多数自主驾驶实现里,它都是主要的传感器。LIDAR可以被用于生成高清晰度地图、比对移动中的车辆和地图的位置以及探测前方的障碍物等。通常一个LIDAR单元(比如Velodyne的64束激光器)会以10Hz的频率扫描,每秒采集大约一千三百万的读数。
3.摄像头:
摄像头主要是用于物体识别和物体追踪的任务,比如车道探测、信号灯探测和行人探测等。为了增强自主驾驶车辆的安全性,通常的实现是在车身前后安装八个甚至更多的摄像头,用于探测、识别和追踪前后左右的物体。这些摄像头的工作频率一般是60Hz,总计会在一秒钟产生约1.8GB的原始数据。
4. 雷达和声呐:
雷达和声呐系统是规避障碍物的最后一道防线。由它们产生的数据显示了车辆与前方最近的物体间的距离。当检测到前方有物体并可能有碰撞的危险时,自主驾驶汽车可以通过刹车或是转向来进行规避。因此由雷达和声呐产生的数据并不要求多少处理,通常是直接输出给控制处理器(没有通过主要的计算管道)来完成紧急的任务,比如急转、刹车或是预先拉紧安全带等。
理解
第二步,传感器收集的数据被发送给理解子系统来了解车辆的周围环境。自主驾驶车辆的理解系统的三大主要任务就是定位、物体探测和物体跟踪。
定位
GPS和IMU都可以被用于定位。GPS提供相当精确的定位,但更新速度较慢;而IMU可以提供快速更新,但精度较差。我们可以使用卡尔曼滤波来组合这两者的优点,提供精确且及时的位置更新。如图3所示,IMU每5ms推测一次车辆的位置,但随着时间的流逝,错误逐渐累积。不过每100ms,我们就可以得到GPS提供的更新,从而能纠正IMU的错误。通过使用这个推测与更新模型,就能得到GPS和IMU共同产生的快速且精确的定位结果。
不过我们不能仅仅依赖于这个组合方法得到的定位结果。这主要是因为三个原因:1)定位结果的精度仅有1米;2)GPS的信号会有多路的问题,即GPS信号可能会被建筑物反射,从而引入很多的噪音;3)使用GPS要求车辆上方空间无遮拦,因此无法在封闭空间里工作,比如隧道。
图3 GPS和IMU定位。图片由Shaoshan Liu友情提供
摄像头也能被用于定位。基于视觉的定位过程遵循如下简化的管道:1)通过三角定位双目图像对,就可以获得一个视差图。它可以用来推导出图像里每个点的深度信息;2)通过比对连续两帧立体图像里的显著特征,就能够估算出两帧图片间的移动;3)通过比较视频图片里的显著特征和已知的地图,就推导出车辆的当前位置。然而,基于视频的定位方法对于光线非常敏感。因此这个方法单独使用时也不够可靠。
图4 双目图像测距法。图片由Shaoshan Liu友情提供
因此,严重依赖于粒子滤波的LIDAR(激光雷达)成为主要的定位传感器。由LIDAR产生的点云提供了对环境的“形状描述”,但它也很难来对单独的点进行差异化。通过使用粒子滤波,系统把一个特别的观测形状和已知的地图进行比对,从而提升确定性。
为了定位车辆与地图的相对位置,我们应用粒子滤波技术来把来自LIDAR的测量和地图关联。粒子滤波方法已经被证明能获得实时的定位,精度在10厘米,同时对于城市环境也有效。然而,LIDAR也有它自己的问题:当空气中有非常多的悬浮颗粒(如雨滴和灰尘)的时候,它的测量值可能会非常得混乱。
因此,为了能获得可靠且精确的定位,我们需要一个传感器融合的过程来合并这些传感器的优点,如图5所示。
图5 传感器融合定位管道。图片由Shaoshan Liu友情提供
物体识别与追踪
因为LIDAR提供了精确的关于深度的信息,所以它最初在自主驾驶汽车上是被用于物体识别和追踪的。但近年来,随着深度学习技术的飞速发展,它在物体识别和追踪的准确度上有了显著的提高。
深度神经网络之一的卷积神经网络(CNN)已经被广泛地用于物体识别。一个普通的CNN评估管道一般包括下述的几层:1)卷积层,使用不同的过滤器来从输入图像里抽取不同的特征。每个过滤器都包括一套在训练阶段结束后“可学习到”的参数;2)启动层,决定是否要启动目标神经元;3)pooling层,降低图像表征的空间尺寸,从而能降低参数的数量,以及随之带来的网络计算量的降低;最后4)全连接层,连接前一层所有的启动神经元到本层的所有的神经元。
一旦用CNN识别了一个物体,下一步就是自动地估计物体移动的轨迹了,或叫物体追踪。
物体追踪技术可以被用来跟踪附近行驶中的车辆,也能用来跟踪横穿马路的行人。从而保证车辆不会和其他移动的物体发生碰撞。近年来,深度学习技术已经展示出比传统的计算机视觉技术更好的跟踪能力。通过使用辅助的自然图片,一个堆栈化的自动编码器可以被离线的训练来学习常见的图片特征。这样获得的模型比从实际车辆的位置和视角上看到的震动的图片去训练的模型要更鲁邦。这个离线训练的模型就可以被用来做物体追踪。
决策
在决策阶段,行为预测、路径规划和避障机制被组合起来,实时地产生一个有效的操作计划。
行为预测
人类司机在行驶过程中所面对的一大挑战就是如何去应对其他司机可能的行为。因为其他司机的这些行为会直接影响他自己的驾驶策略。这在有多个车道的路面以及行驶改变点的时候尤其重要。为了保证自主驾驶汽车在这些情况下能安全行驶,决策单元会预测附近其他车辆的行为,并依据这些预测来做出自己的操作计划。
为了预测它车的行为,我们可以生成一个其他车辆可达的位置集合的统计模型,并给出这些集合的概率分布。
路径规划
在一个动态变化的环境里,规划一个自主驾驶、自主反应的汽车的路径是一个复杂的问题,尤其当要求车辆完全利用它自己的操控能力的时候。一种方法是使用确定性全局算法,即搜索全部可能的路径,并用一个损失函数来决定最佳路径。但是这个方法的计算量非常大,并有可能无法提供实时的导航计划。为了规避这个计算复杂度并提供有效的实时路径规划,一般使用概率性规划器。
避障
自主驾驶中,安全是极其重要的考虑因素,所以我们应该使用至少两级避障机制来保证车辆不会撞到其他东西。第一级是主动的,基于交通情况预测的。交通预测机制产生类似于预计碰撞时间或是预计最小距离的指标。基于这些指标,避障机制被触发来进行局部路径的再规划。如果主动机制失效,第二级使用雷达数据的被动机制就会接管控制。一旦雷达探测到路径前方有障碍,它就要获取车辆的控制权,并设法避障。
车载客户端系统
车载客户端子系统集成了上诉算法,来满足实时和可靠性的需求。客户端系统要应对三大主要的挑战:1)系统需要确保处理管道足够快,才能及时消化掉传感器产生的海量数据;2)如果系统的部分失效了,系统自己必须保证足够鲁棒,从而能从失效中恢复;3)系统需要在有限的供电和计算资源的情况下完成所有的运算。
机器人操作系统
机器人操作系统(ROS)是一个专门为机器人应用而设计的,被广泛使用的高性能分布式的计算框架(参见图6)。
每个机器人所要完成的任务(如自身定位)都由一个ROS的子节点处理。这些节点间是通过话题和服务进行相互连接的。它对于自主驾驶而言是一个合适的操作系统,但也有一些问题:
- 可靠性:ROS只有一个主节点而且对子节点没有监控,从而无法实现失效恢复。
- 性能:在发送广播消息的时候,ROS会把消息复制多份,这就导致性能的降低。
- 安全性:ROS没有认证和加密的机制。
虽然ROS 2.0版宣称要修复这些问题,但它还没有被广泛的测试过,并且很多特性也没有实现。
为了在自主驾驶车辆上使用ROS,我们需要先解决这几个问题。
图6 机器人操作系统(ROS)。图片由Shaoshan Liu友情提供
可靠性
现有版本的ROS的实现仅有一个主节点。因此当主节点崩溃时,整个系统就崩溃了。这一点并不能满足自主驾驶的安全性要求。为了解决这一问题,我们在ROS上实现了一个类似ZooKeeper的机制。如图7所示,这个设计包含一个主节点和一个备份主节点。当主节点失效时,备份节点就接替主节点,并确保系统能持续运行无间断。另外,ZooKeeper的机制还可以监控所有节点,并在节点失效时重启它们。从而可以确保整个系统的可靠性。
图7 ROS上使用ZooKeeper。图片由Shaoshan Liu友情提供
性能
性能问题是现有ROS实现的另外一个缺陷。ROS节点间通信很频繁,因此节点之间的通信就必须是非常高效的。首先,ROS客户端节点间的通信采用的是环回机制。每完成一次环回的管道,就会带来约20毫秒的开销。为了降低这个节点间通信的开销,我们可以使用共享内存的机制来避免消息传输必须经过TCP/IP的打包/拆包的过程。另外,ROS的节点在广播消息的时候,消息会被复制多次,极大地占用了系统带宽。改用多点传送机制就能够很好地提升系统吞吐量。
安全性
安全性问题是ROS的最大的死穴。设想两个场景:第一个,某个ROS的节点被“黑”了,随后操作系统内存被持续的占用并最终导致内存溢出,从而开始杀掉其他的ROS的节点。最终黑客成功地让整个系统崩溃。第二个场景,ROS的消息默认是不加密的。黑客可以很容易地监听节点间的通信,然后使用消息拦截机制发动攻击。
为了解决第一个安全问题,我们可以使用Linux容器机制(LXC)来限制每个节点可以使用的资源数量,并提供沙箱机制来防止一个节点被其他节点破坏。这样可以有效地防止资源溢出。对于第二个问题,可以通过加密消息来阻止消息被窃听。
硬件平台
为了能更好地理解为自主驾驶车辆设计硬件平台的挑战,让我们先看看某个行业领先的企业的计算平台的实现。这个计算平台包括两个计算系统,每个装备了Intel Xeon E5处理器,以及4到8个Nvidia Tesla K80 GPU加速处理器。第二个系统完成与第一个系统一模一样的任务,从而保证了可靠性。当第一个系统失效的时候,第二个系统可以立即接手工作。
最差的情况下,如果两套系统都工作在最大功耗,共计使用超过5000瓦的电量,同时产生非常多的热量。每套系统的价格在2万到3万美元之间,远远超出了一般消费者的承受能力。
这种设计所带来的高功耗、高散热以及高价格都让 自动驾驶 汽车(目前)还不能为广大消费所使用。为了探索技术的极限以及更好地理解在ARM的移动片上系统(SoC)里开发自主驾驶系统,我们基于ARM的移动片上系统实现了一个简化的、基于视觉的自主驾驶系统。它的最高功率只有15瓦。
令人惊讶的是,这个设计的性能根本不差。定位计算管道可以每秒处理25帧画面,几乎能跟上系统每秒产生30帧画面的速度。深度学习计算管道可以每秒识别两到三个物体。路径规划和控制管道可以在6毫秒内完成路径规划。使用这一系统,我们可以让车辆以每小时5英里的速度行驶并且没有丢失位置的情况发生。
云端平台
自主驾驶车辆是一个移动系统,因此需要一个云平台来提供支持。云端主要提供两大功能,包括分布式计算和分布式存储。这一系统还包括几个应用,即仿真(可以被用于验证新算法)、高分辨率地图的生成以及深度学习模型的训练。为了构建这样的一个系统,我们使用Spark来做分布式计算,OpenCL来做异构计算,并用Alluxio进行内存分布存储。
我们通过集成这三个框架,提供了一个可靠、低延时、高吞吐的自主驾驶云平台。
仿真
云平台的第一个应用就是仿真。当我们开发了一个新的算法,都需要在正式部署到车辆前进行测试。否则代价会很高且挽救时间会很长。
因此我们首先会在模拟器上测试新算法,例如在ROS节点上做数据重现。然而,如果只是在一个单机上测试新算法,要不会花费很长时间,要不就没有能做到全覆盖测试。
为了解决这个问题,我们可以使用一个分布式的模拟平台,如图8所示。
这里,Spark被用于管理分布式计算节点。每个节点上,我们可以运行一个ROS再播放实例。在一个单机服务器上做 自动驾驶 物体识别测试将会需要3个多小时。而使用分布式系统,水平扩展到8个服务器,整个测试在25分钟内完成。
图8 Spark和基于ROS的模拟平台。图片由Shaoshan Liu友情提供
高清晰度地图生成
如图9所示,高清晰度地图的生成是一个复杂的过程,涉及到很多步骤。包括原始数据处理,点云生成,点云对齐,2维反射地图生成,高精度地图标记以及最终地图生成。
使用Spark,我们可以把所有的这些步骤放入一个任务中完成。Spark的一大优点是它提供基于内存的运算机制。这样我们就可以不用存储中间数据到硬盘上,从而可以级大地提升地图生成的速度。
图9 基于云平台的高清晰度地图生成。图片由Shaoshan Liu友情提供
深度学习模型训练
因为我们为自主驾驶使用了多种不同的深度学习模型,所以持续更新模型来保证它们的有效性和高效性就非常重要。然而,由于原始数据的量非常的大,仅仅靠单机是很难快速地完成模型的训练的。
为了解决这个问题,我们使用Spark和Paddle(最近由百度开源的一个深度学习平台)开发了一个高可扩展的分布式深度学习系统。
在Spark驱动程序里,它可以管理Spark Context和Paddle Context。在每个节点里,Spark执行器容纳了一个Paddle的训练实例。在此架构之上,我们使用Alluxio作为这个系统的参数服务器。使用这一系统,我们可以实现线性的性能扩展(甚至在增加了更多资源后),从而证明它是高可扩展的。
这仅仅只是开端
如你所见到的,自主驾驶(以及人工智能)不是单一技术,它是多种技术的综合。它包括创新的算法、系统集成和云端平台。这还仅仅只是开端,机遇无限。我预计到2020年,我们会正式的开启人工智能(AI)时代,在市场上见到更多基于AI的产品。让我们做好准备吧!
作者介绍:Shaoshan Liu是Perceptln的联合创始人和主席,致力于开发下一代的机器人平台。在创立PerceptIn之前,他在百度(美国)的自主驾驶和深度学习基础设施(Autonomous Driving and Deep Learning Infrastructure)工作。Liu拥有加州大学欧文分校的计算机工程博士学位。