一:背景
在上一篇博客中,贴上了卷积层滑动窗口的实现效果和提了一下卷积滑动明显的速度优势
卷积滑动窗口,其实也和全卷积网络息息相关,我看了一下网上对全卷积网络的介绍主要集中于FCN的论文和某种领域的应用形式(医疗影像的U-NET网络),FCN其实有种编码和解码的思想在里面,生成的是端对端的网络,对数据集的要求也高,样本和标签必须都是图像,主要用于图像分割。本文的主题是目标检测,同时数据集并不适合作回归分类直接输出box,因为本文所用数据集是单类物体的图像。
问题来了:
1.用单类物体图像的数据集做目标检测(一般都只能在图像上用滑动窗口,一个个区域检测)
2.数据集均为20*20 的飞机及非飞机图像,相对于1700*900的机场图像太过于小,滑动窗口必须每个像素都遍历到。
二:用到的FCN知识
可以看到FCN用全卷积网络实现,不再被输入尺寸所限制。
三:本文网络与传统CNN的区别与联系
常用的cnn大体结构如下:
- 输入层
- 卷积层
- 激活层
- 池化层
- 全连接FC层(把提取的特征变为一行,输入简单的多分类神经网络(如:BP神经网络),通过softmax函数得到最终的输出)
划重点:保存了权重的卷积层其实不会限制输入尺寸,但最后的全连接层却对输入尺寸有限制!!!
所以全卷积网络用了多个卷积层,将输入的图像变为1*1大小的多通道的信息,最后输入softmax层中进行分类。
可能有同学会问:1*1的多通道??怎么能有效地代表原始图像的重要信息呢?
敲黑板:全卷积网络的重点其实是多通道
我们可以理解全卷积网络用多通道来代替了多分类神经网络的每层的神经元个数(仅效果而论,数学理论上肯定不对hhh)
例如:
cnn最后的全连接层是那样的:
-
model.Flatten()#将特征平铺为一行
-
model.add(Dense(1024))#1024个神经元
-
model.add(Activation('relu'))
-
model.add(Dense(10))#10种物体分类
-
model.add(Activation('softmax'))
我们的全卷积层是这样的:
-
model.add(Conv2D(256, (2, 2), activation='relu', name='conv5', padding='valid')) # 用2*2的卷积核把特征变为256维的1*1的向量,卷积核的大小看情况,反正要求就是可以把上一层的特征图变为1*1大小的多通道信息 ps:可以把这一层理解为cnn中的Flatten层
-
model.add(Conv2D(256, (1, 1), activation='relu', name='conv6', padding='valid')) # 实现的效果而言,可以理解为一个256神经元的FC层
-
model.add(Conv2D(2, (1, 1), activation='softmax', name='conv7')) #2个卷积核,代表了2种物体分类的概率
-
model.add(Flatten(name='flatten1'))#平铺输出的分类结果,好对应训练标签
只要把CNN最后的全连接层用适当的卷积层代替,一个既可以训练图像分类和又可以执行目标检测的网络就搭建好了(无需任何更改)
四:训练图像分类的网络可以用来进行目标检测的原理
本网络训练图像分类和传统cnn一样,在第三部分已经说得很明白了。
可能有同学会疑问不经过任何更改,怎么可能进行目标检测?
这就是全卷积网络的精髓所在了
以本文为例子:我们的网络在最后几层,把训练图像用卷积层压缩到256通道的1*1特征图。这样一个网络用来接受更大尺寸的输入(比如包含很多飞机的机场图像)时,会出现怎样的惊喜呢?
此时,我们网络的输出会是一个比起原图略微缩小的特征图(缩小的部分就是训练图片缩小至1*1的差值)。
例如训练图片是20*20,我们的网络在训练时,将20*20缩小至1*1;
同理可得,此时的机场图像,我们网络的输出结果是(1700-20)*(900-20)的特征图
而这个特征图,其实已经代表了机场图像的所有目标检测结果。(一次性输出所有结果)
这个特征图的每一个1*1通道,代表着它这个坐标在原图的点的周围20*20的区域的分类结果。
(没明白的同学可以多看看上一幅图)
这就是基于卷积层的滑动窗口检测法。
五:缺陷
1.一次只能检测一张图上的固定尺寸的所有滑动窗口区域(本文将20*20的训练图片变为1*1的多通道特征向量,故此只能检测机场图片中20*20 的所有滑动窗口区域),可以考虑应用空间金字塔的形式来进行多尺度滑动窗口检测
2.速度可能还不够快(不过航空图像的目标检测,20s一次应该够吧。。)(应用在视频上时,滑动窗口应该比检测飞机大很多,计算量应该会小,速度会有所提升)。