雷锋网按:本文作者夏飞,清华大学计算机软件学士,卡内基梅隆大学人工智能硕士。现为谷歌软件工程师。雷锋网首发文章。
视频结果:无人车以 30m/h (~ 50km/h) 在Simulator中行驶。这应该是最有趣的部分:
技术要点:
Simulator安装与使用
数据收集和处理
深度卷积网络 (CNN) 训练端到端 (end-to-end) 模型
代码:Github链接
所谓 end-to-end 无人驾驶模型,指的是由传感器的输入,直接决定车的行为,例如油门,刹车,方向等。简单来讲,可以利用机器学习的算法直接学习人类司机的驾驶行为:首先,人类司机驾驶安装有各种传感器 (例如摄像头) 的汽车来收集数据;然后,用传感器收集的数据作为输入,相应的人类行为数据作为输出label,训练一个机器学习模型,例如,如果摄像头发现前方有行人,司机行为应当是刹车;最后,将训练好的模型应用于无人车上。这种方法又叫做行为复制,其原理直观,避免了无人车系统中各种复杂的问题,是无人车中很有趣的一个topic。
在这篇文章中,我们来一起动手做一个在 Simulator 中的 end-to-end 模型!和在真实世界中类似,我们需要:
在 Simulator 中驾驶无人车收集数据,像玩赛车游戏一样!
处理数据并训练模型
将模型应用于 Simulator 中看效果
先把Simulator搭好 --- 这里使用Udacity的Self-Driving Simulator Platform,下载链接:
建议直接从上面的链接下载,如果对源代码感兴趣,这里是Github链接。
运行Simulator程序,选择Screen Resolution和Graphics Quality,建议开始时先选择最低分辨率和对应最快的图片质量。点击OK进入主界面。
Controls:在Simulator中的按键指南
Training Mode:人为控制车辆模式,用来收集数据
Autonomous Mode:全自动模式,使用训练好的模型进行无人驾驶
进入Training Mode开始玩游戏,熟练一下按键和操作!在Simulator中,这辆车的传感器是三个前置摄像头,分别放置在左、中、右三个方向,对周围的环境进行拍摄录制,结果之后会以图片形式保存到电脑上。
开始收集数据:
首先按下R键 (Record),选择数据保存目录,确认
再次按下R键,进入录制模式
驾驶车辆在车道中行驶
行驶完毕后第三次按下R键,数据会被保存到硬盘上
这时,在相应目录下会生成两个文件: driving_log.csv和IMG文件夹。顾名思义,driving_log.csv中保存了用户开车时的log,IMG文件夹中保存了摄像头的照片。driving_log.csv基本结构如下图。
前三列分别表示在当时左中右摄像头的照片路径
D列表示车的方向盘角度
E列表示油门力度
F列表示刹车力度
G列表示当前速度
为了简洁明了,在本文中我们只采用A,B,C,D列数据,即利用摄像头照片预测方向盘角度。另外,收集数据时有几个tips:
首先大概收集两圈比较完美的数据,尽量保持车在道路中间行驶;
在转弯或模型训练之后比较容易出错的地方多收集几次数据。
数据在机器学习中地位至关重要,保证数据质量是模型是否有效的关键因素。以下是我们遇到的几个问题,在model.py中均有相应的代码。
观察一:D列Steering Angle大部分都是0,这很正常,因为大部分情况下在拐弯的地方我们才会转动方向盘。然而这对模型却是致命的,因为会造成严重的数据不平衡。
解决方案:随机抽样,尽量使数据平衡。在实际操作中,可以将整个Steering Angle范围划分成n个bucket,保证每个bucket中数据样本不超过m个。
观察二:在同一个位置,不同摄像头的内容差距很大,但是车子的转向角度只有一个。下图给出了同一位置左中右摄像头的照片。
解决方案:以中间摄像头照片为主训练数据,对左右两边照片的转向角度进行修正。最简单的修正方法是对左边图片的转向角度+0.2,对右边图片的转向角度-0.2。
观察三:数据量可能不够大。
解决方案:将图片进行左右反转,同时将转向角度取相反数,这样就生成了新的数据。
观察四:地面是影响车子转向角度的决定性因素,照片的上半部分信息冗余,不利于模型的generalization。
解决方案:将上半部分图片裁掉。
观察五:图片RGB值均在0-255之间,范围太大。
解决方案:进行normalization,使其值在[0, 1]之间或[-0.5, 0.5]之间。
深度卷积神经网络 (Deep Covolutional Neural Networks, DCNN)!
DCNN及其衍生模型是目前对图片处理最先进的方法,主要应用有图片分类,物体检测及定位,自动生成图片标题等。DCNN的一个最大特点是能够抓取local pattern --- 例如:人类识别一张图片上的猫并不取决于这张图片还有什么其他动物,也不取决于这只猫位于图片的什么位置,甚至只露出半只猫的身子我们也可以将其识别,这就是基于local pattern。DCNN的这一特点还被用于AlphaGo中抓取围棋的local pattern,我在这篇文章中有简述AlphaGo的算法。
关于DCNN的技术细节就不在这里介绍了,有兴趣的可以参考Stanford的同学们做的一个tutorial (我第一次接触Deep Learning时的学习网站) 或这篇文章。
我们在这里可以采用最常用的DCNN架构:三个Convolutional layer + 两个Fully Connected layer:
三个covolutional layer的filter size均为3x3,filter depth分别是8,16,32,使用ReLU activation function,dropout rate设为0.2
两个fully connected layer的size分别为512,256,同样使用ReLU activation function,dropout rate 0.2。
最后输出层size为1,使用linear activation对steering angle做regression。
具体代码也在model.py中,使用Keras实现,我采用的是Tensorflow的后端。现在就可以直接运行model.py文件进行模型训练了!如果对配置Tensorflow和Keras环境有疑问,最后的附录给出了一个简单步骤。
在我的Github中我已经给出了一个用GPU训练好的模型model.h5,本文开始中的视频就是使用这个模型生成的。
(1)运行模型
python drive.py model.h5
(2)进入Autonomous Mode
(3)Enjoy the self-driving
关于环境配置,推荐使用Anaconda!我的操作系统是Ubuntu,基本步骤是
(希望下面的链接国内的朋友都可以访问)
(1)下载Anaconda最新版并安装
(2)创建conda environment
conda create -n my_env python=PYTHON_VERSION
(3)启用conda environment,在这个环境下安装的python或conda package会与系统及其他环境相互隔离
source activate my_env
(4)安装Tensorflow
(5)安装Keras
(6)使用pip或conda安装其他所需的package
【完】