CNN的训练图像与测试图像不一致的多尺度问题
1. 传统检测和定位方法
对于检测和定位问题,最自然(也是最常用的方法)就是采用滑窗对每一个图像块进行检测,从而确定目标物体的位置。以上解决分类、检测和定位的方法有一个共同的地方,就是需要一个滑窗对整幅图像进行密集采样,然后处理每一个采样得到的图像块。传统的处理这些图像块的方法是一个接一个处理。但是,CNN有更便捷的做法。
2. CNN检测和定位方法
2.1 密集采样(滑窗)支持
对于一个训练好的CNN来说,CNN的结构(如CNN的层数、每一层feature map的个数,卷积层的kernel size等等)是固定的,但是,每一层的feature map的大小是可以改变的。
1)当测试样本和训练样本大小相同时,CNN最后一层的每一个节点分别输出一个0~1的实数,代表测试样本属于某一类的概率;
2)当测试样本比训练样本大时,CNN最后一层每一个节点的输出为一个矩阵,矩阵中的每一个元素表示对应的图像块属于某一类的概率,其结果相当于通过滑窗从图像中进行采样,然后分别对采样到的图像块进行操作:
如上图所示,当输入图像为16x16时,output层的每一个节点输出为一个2x2的矩阵,相当于在原图像上的四个角分别采样了一个14x14的图像块,然后分别对每一个图像块进行处理。
2.2 多尺度支持
传统的检测/定位算法是固定输入图像不变,采用不同大小的滑窗来支持不同尺度的物体。对于CNN来说,滑窗的大小就是训练时输入图像的大小,是不可以改变的。那么,CNN支持多尺度的办法就是,固定滑窗的大小,改变输入图像的大小。具体来说,对于一幅给定的待处理的图像,将图像分别resize到对应的尺度上,然后,在每一个尺度上执行上述的密集采样的算法,最后,将所有尺度上的结果combine起来,得到最终的结果。
然而,对于上面所述的密集采样算法来说,采样的间隔(也就是滑窗的stride)等于执行所有卷积和pooling操作后图像缩小的倍数,也就是所有卷积层和pooling层的stride的乘积。如果这个值较大的话,采样就显得sparse,图像中的某些位置就无法采样得到。这时,或者减小卷积层和pooling层的stride,或者干脆去掉某个pooling层,或者采用某种方法替代某个pooling层。
2.3 分类问题测试过程
训练一个CNN并确定图像的六个尺度。给定一幅待识别的图像,先将图像resize到这六个不同的尺度,然后,将这六种尺度的图像以及对它们进行水平翻转后的图像(总共12幅图像)送到CNN中,产生12个CNN输出的结果。然后,对每一个CNN输出的结果进行空间域的非极大值抑制。(例如,对于一个类别数为1000的CNN来说,其输出为1000个矩阵。第m个矩阵的位于(x, y)位置的元素表示点(x, y)对应的图像块属于类别m的概率。对这个输出结果进行非极大值抑制,即对矩阵中所有元素求最大值。)然后,对于所有的非极大值抑制的结果(总共12个)按类别求平均值,然后取均值的Top-1或者Top-5。
2.4 定位问题的模型和测试过程
定位问题的模型也是一个CNN,1-5层作为特征提取层和分类问题完全一样,后面接两个全连接层,组成regressor network。训练时,前面5层的参数由classification network给定,只需要训练后面的两个全连接层。这个regressor network的输出就是一个bounding box,也就是说,如果将一幅图像或者一个图像块送到这个regressornet work中,那么,这个regressor network输出一个相对于这个图像或者图像块的区域,这个区域中包含感兴趣的物体。这个regressor network的最后一层是class specific的,也就是说,对于每一个class,都需要训练单独最后一层。这样,假设类别数有1000,则这个regressor network输出1000个bounding box,每一个bounding box对应一类。
对于定位问题,测试时,在每一个尺度上同时运行classification network和regressor network。这样,对于每一个尺度来说,classification network给出了图像块的类别的概率分布,regressor network进一步为每一类给出了一个bounding box,这样,对于每一个bounding box,就有一个置信度与之对应。最后,综合这些信息,给出定位结果。