这一年竟然没有任何更新,只能说,我堕落了。要说工作内容紧张了,显然没有,起码没有多么紧张。那么,一个很大概率的推断就是:女友是个吃时间的大怪物。
1 这一年的工作内容
这一年的主要工作内容就是开发一个运行在嵌入式平台上的ADAS系统,具体的方法是传统的cascade+hog,似乎也只有这条路能够满足嵌入式平台上的性能要求。后续我们也探索了使用DNN的方法进行Object Detection的方法。目前嵌入式平台的程序中已经有了一个很小的卷积网络辅助工作,当然,嵌入式平台的性能限制,不可能使用太大的网络,主要的工作还是依赖传统的方法。
整体过程自然是跌宕起伏,在我们开始这个项目的时候,公司内已经有一个一样的项目启动了一年了,真是搞不懂当时的老板是怎么想的。开始之后的将近4个月的扯皮就不表了,只想安心的写份代码,但是真的是因为各种扯皮和恶心没有这个心情。15年的9, 10月份更是被强行调入另外一组帮忙,理由竟然是,“你们都会写c”,当然,这些都是老板的要求,部门主管自然也没法说话,但是,之前和别的部门的经理商量好的是自愿先试一周再看,这到了老板那里就成了强制,可想而知抵触心理有多么严重。何况当时我们自己的工作也在一个重要的关头。
所以虽说总共一年多的时间,但是交给我们自己的时间自然是没有那么多的。由于我们对arm的cpu的性能过于乐观,程序使用了不少运算量来获得更加稳定的结果,手机上的性能也只能做到5fps左右。当然,目前做了很多取舍后的性能能够在10fps以上,甚至能到16fps,但是结果已经不符合我自己的预期了。一年前的效果,当时刚刚结束完扯皮。
后续又因为小米手机的性能问题,花了两个月时间,最后,还是没有结论,我们手上能找到的小米手机,程序性能上都比同硬件或者相近硬件的别的牌子的手机慢一倍。当然,我个人是有结论的,以后我是不会买小米的任何一部手机或者平板的(虽然我也从来没买过, --)。
回到DNN这一块来。两个月前,又因为其他原因我们全组又暂停了DNN这块的工作。 我们组简直就是一直在转换工作重心,而且是被迫的。考虑到我们高峰时期也没有超过三个人在实际工作,整个技术都是从零开始,目前的进度虽然不怎么满意吧,但是感觉还是勉强对得起自己的。吐完了草回头,好歹还是在DNN这个技术上做了不少尝试,主要是CNN,也有一些总结。
两个月前的技术原型可以在GTX Titan X上获得实时的性能,车道的识别速度可以达到95fps,车辆的也有50fps。我们正开始准备将两个任务合并到一个网络上并进一步优化的时候,工作重心又被变了。目前来看还有很多可以提高的空间,毕竟这只是刚出来的技术原型,车道的训练数据只不过几百帧视频,车辆的也只用了1000帧视频。
2 一些技术总结
2.1 卷积网络
2.1.1 卷积层与MLP的等价
虽然卷积层经常被人单独拿出来说明,但是实际上,卷积层就是很普通的MLP。只是,这个MLP考虑到了图片是有位置信息的这个特点,输入一般是[w * w]的方块(也就是卷积核的大小),当然卷积核的长宽是可以自己设置不同大小的,当你将卷积核大小设置为[w * 1]或者是[1 * h],那么你就会发现,这其实就是一个简单的感知机。所以,一个[w * w]的卷积核就等价于一个输入为w*w的感知机,如果你要将这个感知机直接应用于图片,可以有两个方法:
- 改变程序流程, 使用多层循环,将图片中的一个方块作为输入。
- 改变数据,将图片中的方块摊平,也就是二维的矩阵压为一维的向量。
改变数据就是caffe和nvidia提供的加速库采用的方法。显然,改变数据的优势还是比较明显的,从我看来是:
- 减少了程序实现逻辑,改变数据后卷积层的操作就和普通的全联通层一样
- 提高了缓存命中,将在一次循环中的数据都放在了一起,同时没有了多层循环和判断,也减少了缓存不命中的情况(但是改变数据过程中的操作带来的问题似乎也不少)
- 易于cuda的实现,毕竟多层循环变成单层,并发代码也容易实现
缺点应该是,需要多做数据转换的工作, 占用内存增加。
回到等价MLP这个问题上来,一个输入为三层的,有96个11x11的卷积核的卷积层,就等价于一个输入为11×11×3,输出为96的MLP的一层。当然,还会有更加复杂的情况,比如每个核只处理输入的某几层的情况,不多说。
2.1.2 feature map的意义与卷积核
feature map和卷积核都是调试网络时需要查看的东西。讨论feature map的意义离不开卷积核本身的意义。对于卷积核的理解存在一个非常直观的途径: Sobel边缘检测 ,如果自己手算一下sobel算子的一次计算过程就会明白卷积核的意义,因为一个典型的Sobel算子就是一个3×3的卷积核,而这样的一个卷积核可以用来提取图像的边缘信息。
一旦知道了卷积核的意义,我们就可以理解 feature map的意义了。我们假设让一张黑白图片通过一个人工设定的卷积层, 这一卷积层只包括两个 3×3的Sobel算子,分别用于提取x和y轴方向的边缘特征。通过这一卷积层后,会获得两个 feature map, 第一个feature map对应x轴的边缘特征,一旦黑白图片中某个像素位置上具有了x轴方向的边缘特征, 那么这个feature map中对应的位置的值就会偏高。通常我们会将feature map作为单通道的黑白图片显示出来,值越高,自然越亮, 所以作为我个人的习惯我会说,“这里亮了”, 也就是说图片的这里具有对应的卷积核提取的特征(在这个例子里面,就是具有x轴方向的边缘特征)。
所以,如果我们需要深入查看一个网络的训练,可以考虑查看卷积核+feature map,卷积核在学习成功后,一般会具有很明显的特征,而非一种随机的分布。而针对某一个图片的中间层中的feature map,可以让你知道网络在这一层中对图片中的那些部分有响应。虽然即使这样也无法定量,但是还是有利于理解网络的整体情况。
回到feature map, 随着层数的深入,其意义是否发生了改变?事实上, 每一层的feature map都是对上层的feature maps (注意这里是复数)的特征提取的结果。如果使用之前的sobel例子,第二层卷积层后的feature map就是不同的x轴和y轴的组合情况。当然,由于本身的上一层只有两个feature map,所有第二层的组合的可能性并不多。从我们组之前的实验来看,第一层的宽度还是有很重要的作用的。
我们可以看到随着深度的增加,每一层的卷积层都在提取越来越复杂的特征的组合。第一层可以提取基本的纹理/边缘特征,第二层就是这些特征的进一步组合,第三层就是更加复杂的组合,CNN的网络就是通过这样的一个方法,最终来实现对复杂物体的检测。这一过程实际上非常明显符合另外一个非常常用的算法的特点: Deformable Models。 所以,CNN可以看作是一种具有自学习能力的Deformable Models。
2.1.3 卷积网络的视界问题与全连通网络
典型的CNN的分类网络结构会是多层卷积层后增加一个全连通网络的。在我看来,全连通是一个整合全局信息的进行最终决策的分类器。为什么需要一个全连通网络?不仅仅是为了可以输出可以符合分类标准的格式,而是为了克服卷积层的视界问题。多层卷积+pooling,会提供一个类似锥形的视界,具体的大小可以从最后一层的卷积层逆推知道,已经知道卷积层与单层神经网络等价,每一个卷积核,其实就是一个神经元,将卷积核大小的前一层图片(比如5×5大小),转换为一个feature map上的像素,那么这层卷积的视界就是前一层的5×5,前一层的则可以以此类推,同时需要考虑pooling带来的视界的双倍扩大,以及卷积本身的步长带来的影响。
逆推可以让我们明白,卷积层的视界限制在多大。我们完全可以选择通过增加层数,获得更大的视界,甚至可以一直达到整个图片的大小,那么后续的全连通就不再需要(考虑到卷积层等价于全连通层)。如果限制了卷积层的数量,而网络的训练任务又需要获得全局信息,那么就可以利用全连通层来获得图像的全局信息。
从我们的经验来看,无论是传统方法还是使用DNN的方法,图像局部信息与上下文信息的结合是十分重要的(有些任务下上下文的信息的范围可能较少,附近的信息就可以,有些则可能需要整张图片的上下文信息)。
2.1.4 FCN与训练方法
全连通层带来的问题是输入图片大小被完全确定,同时增加了大量的模型参数(和计算量)。模型参数的增加有利有弊,但是一旦图片的尺寸变大,全连通的参数是几何级别的增长的,这就让全连通的CNN难以处理高清图片或者处理速度非常慢。所以FCN就出现以解决这个问题。(在Overfeat的论文中,有方法来处理图片尺寸变化后的卷积层结果与全连通层的链接,但是也只是小范围的浮动)
FCN就是去除了全连通的CNN,卷积层相对全连通层来说,模型参数是数量级的减少,同时也可以更加灵活的处理不同的图片大小。 Fully Convolutional Networks for Semantic Segmentation 这篇论文中使用了FCN进行图像分割的工作。
我们组由于任务的需求,也很早就开始考虑去除全连通层的可能性,当然,和学界比已经是相对落后一段时间了。之后也独立探索了自己训练FCN的方法,以及适应于我们自己任务的网络设计(FCN本身的问题还是卷积层的视界限制,造成缺少全局信息)。从两个月前的工作来看,我们的网络设计能够获得一定范围的上下文信息,而训练方法也起码能够满足我们的任务需求。进一步改进的空间依然很大,只是唯一可惜的是,我们在两个月前取得进展后被迫暂停这方面的工作。
FCN带来的网络性能提升是明显的(当然,网络能力由于失去了全连通也是大量下降的),我们在640p的视频上使用alexnet去除全连通复杂度的模型在Titan X都可以做到实时处理(50+ fps)。今年的CES 2016,NVdia的drive px2平台更是提供了Titan X六倍的计算能力,这就提供了更大的模型扩展的空间。从纸面上数据来看,这个50+fps的模型可以在drive px2上达到300+fps。
2.2 在CV任务中的其他经验
已经太长了,就一个提纲吧:
- 上下文信息与全局信息
- 预处理与normalize
- 边缘信息
- 与某一个CV任务相关的特点的考虑