这篇文章本应放在第五个读,而我查阅资料后临时改变了顺序。因为之前的几篇是two-stage方法,如R-CNN系算法,其主要思路是先通过启发式方法(selective search)或者CNN网络(RPN)产生一系列稀疏的候选框,然后对这些候选框进行分类与回归;而SegLink,Textboxes/Textboxes++都是基于SSD,也就是one-stage方法,如Yolo和SSD,其主要思路是均匀地在图片的不同位置进行密集抽样,抽样时可以采用不同尺度和长宽比,然后利用CNN提取特征后直接进行分类与回归,整个过程只需要一步。因此对阅读顺序进行了调整,为保持思路了连贯性,把SegLink,Textboxes/Textboxes++放后面读。
言归正传,什么叫SegLink呢?因为本文提出了将文本分割成两个局部可检测的元素:Segment和Link。
Segment:带有方向的小文字块
Link:把小文字块用邻近连接给link成单词
Seglink提出了基于SSD的改进版网络结构(全卷积网络结构)同时预测不同尺度的segments和link,提出层内link、跨层link两种link,可以检测任意长度、任意方向的文本。
SSD全称Single Shot MultiBox Detector,Single代表是one-stage方法,multibox表示会有多个预测框。
对于Faster R-CNN,其先通过CNN得到候选框,然后再进行分类与回归,而Yolo与SSD可以一步到位完成检测。相比Yolo,SSD采用CNN来直接进行检测,而不是像Yolo那样在全连接层之后做检测。其实采用卷积直接做检测只是SSD相比Yolo的其中一个不同点,另外还有两个重要的改变,一是SSD提取了不同尺度的特征图来做检测,大尺度特征图(较靠前的特征图)可以用来检测小物体,而小尺度特征图(较靠后的特征图)用来检测大物体;二是SSD采用了不同尺度和长宽比的先验框(Prior boxes, Default boxes,在Faster R-CNN中叫做锚,Anchors)。Yolo算法缺点是难以检测小目标,而且定位不准,但是这几点重要改进使得SSD在一定程度上克服这些缺点。
上图为不同尺度的特征图。SSD采用不同尺度的特征图,大的特征图(如上图的8x8)可划分更小尺度的检测单元,检测相对较小的目标,而小的特征图(如上图的4x4)检测的是相对较大的目标。
与Yolo最后采用全连接层不同,SSD直接采用卷积对不同的特征图来进行提取检测结果。对于形状为 m × n × p m\times n \times p m×n×p 的特征图,只需要采用 3 × 3 × p 3\times 3 \times p 3×3×p 这样比较小的卷积核得到检测值。
在Yolo中,每个单元预测多个边界框,但是其都是相对这个单元本身(正方块),但是真实目标的形状是多变的,Yolo需要在训练过程中自适应目标的形状。而SSD借鉴了Faster R-CNN中anchor的理念,每个单元设置尺度或者长宽比不同的先验框,预测的边界框(bounding boxes)是以这些先验框为基准的,在一定程度上减少训练难度。一般情况下,每个单元会设置多个先验框,其尺度和长宽比存在差异,如下图所示,可以看到每个单元使用了4个不同的先验框,图片中猫和狗分别采用最适合它们形状的先验框来进行训练。
上图中上面的是SSD,下面的是YOLO。对比可得,SSD利用了多尺度的特征图做检测。
SSD采用VGG16作为基础模型,然后在VGG16的基础上新增了卷积层来获得更多的特征图以用于检测。分别将VGG16的全连接层fc6和fc7转换成 3 × 3 3\times3 3×3 卷积层 conv6和 1 × 1 1\times1 1×1 卷积层conv7,同时将池化层pool5由原来的stride=2的 2 × 2 2\times 2 2×2 变成stride=1的 3 × 3 3\times 3 3×3,为了配合这种变化,采用了一种Atrous Algorithm,其实就是conv6采用扩展卷积或带孔卷积(Dilation Conv),其在不增加参数与模型复杂度的条件下指数级扩大卷积的视野,其使用扩张率(dilation rate)参数,来表示扩张的大小,如下图所示,(a)是普通的 3 × 3 3\times3 3×3 卷积,其视野就是 3 × 3 3\times3 3×3 ,(b)是扩张率为1,此时视野变成 7 × 7 7\times7 7×7 ,( c ) 扩张率为3时,视野扩大为 15 × 15 15\times15 15×15 ,但是视野的特征更稀疏了。Conv6采用 3 × 3 3\times3 3×3 大小但dilation rate=6的扩展卷积。
然后移除dropout层和fc8层,并新增一系列卷积层,在检测数据集上做finetuing。
在训练过程中,首先要确定训练图片中的ground truth(真实目标)与哪个先验框来进行匹配,与之匹配的先验框所对应的边界框将负责预测它。SSD的先验框与ground truth的匹配原则主要有两点:
一个图片中ground truth是非常少的, 而先验框却很多,如果仅按第一个原则匹配,很多先验框会是负样本,正负样本极其不平衡,所以需要第二个原则。
这意味着某个ground truth可能与多个先验框匹配,这是可以的。但是反过来却不可以,因为一个先验框只能匹配一个ground truth,如果多个ground truth与某个先验框IOU大于阈值,那么先验框只与IOU最大的那个先验框进行匹配。第二个原则一定在第一个原则之后进行。
上图是一个例子,绿色的是Ground Truth,红色的是先验框。TP(Truth Positive)正样本,FP(False Positive)是负样本。
尽管一个ground truth可以与多个先验框匹配,但是ground truth相对先验框还是太少了,所以负样本相对正样本会很多。为了保证正负样本尽量平衡,SSD采用了hard negative mining,就是对负样本进行抽样,抽样时按照置信度误差(预测背景的置信度越小,误差越大)进行降序排列,选取误差的较大的top-k作为训练的负样本,以保证正负样本比例接近1:3。
训练样本确定了,然后就是损失函数了。损失函数定义为位置误差(locatization loss, loc)与置信度误差(confidence loss, conf)的加权和:
( x , c , l , g ) = 1 N ( L c o n f ( x , c ) + α L l o c ( x , l , g ) ) (x, c, l, g) = \frac{1}{N}(L_{conf}(x,c) + \alpha L_{loc}(x,l,g)) (x,c,l,g)=N1(Lconf(x,c)+αLloc(x,l,g))
其中 N 是先验框的正样本数量。这里 x i j p ∈ { 1 , 0 } x^p_{ij}\in \{ 1,0 \} xijp∈{1,0} 为一个指示参数,当 x i j p = 1 x^p_{ij}= 1 xijp=1 时表示第 i 个先验框与第 j 个ground truth匹配,并且ground truth的类别为 p 。 c 为类别置信度预测值。 l 为先验框的所对应边界框的位置预测值,而 g 是ground truth的位置参数。对于位置误差,其采用Smooth L1 loss,定义如下:
由于 x i j p x^p_{ij} xijp 的存在,所以位置误差仅针对正样本进行计算。值得注意的是,要先对ground truth的 g 进行编码得到 g ^ \hat{g} g^ ,因为预测值 l 也是编码值,若设置variance_encoded_in_target=True,编码时要加上variance:
g ^ j c x = ( g j c x − d i c x ) / d i w / v a r i a n c e [ 0 ] , g ^ j c y = ( g j c y − d i c y ) / d i h / v a r i a n c e [ 1 ] \hat{g}^{cx}_j = (g^{cx}_j - d^{cx}_i)/d^w_i/variance[0], \hat{g}^{cy}_j = (g^{cy}_j - d^{cy}_i)/d^h_i/variance[1] g^jcx=(gjcx−dicx)/diw/variance[0],g^jcy=(gjcy−dicy)/dih/variance[1]
g ^ j w = log ( g j w / d i w ) / v a r i a n c e [ 2 ] , g ^ j h = log ( g j h / d i h ) / v a r i a n c e [ 3 ] \hat{g}^{w}_j = \log(g^{w}_j/d^w_i)/variance[2], \space \hat{g}^{h}_j = \log(g^{h}_j/d^h_i)/variance[3] g^jw=log(gjw/diw)/variance[2], g^jh=log(gjh/dih)/variance[3]
对于置信度误差,其采用softmax loss:
权重系数 α \alpha α 通过交叉验证设置为1。
采用数据扩增(Data Augmentation)可以提升SSD的性能,主要采用的技术有水平翻转(horizontal flip),随机裁剪加颜色扭曲(random crop & color distortion),随机采集块域(Randomly sample a patch)(获取小目标训练样本),如下图所示:
预测过程比较简单,对于每个预测框,首先根据类别置信度确定其类别(置信度最大者)与置信度值,并过滤掉属于背景的预测框。然后根据置信度阈值(如0.5)过滤掉阈值较低的预测框。对于留下的预测框进行解码,根据先验框得到其真实的位置参数(解码后一般还需要做clip,防止预测框位置超出图片)。解码之后,一般需要根据置信度进行降序排列,然后仅保留top-k(如400)个预测框。最后就是进行NMS算法,过滤掉那些重叠度较大的预测框。最后剩余的预测框就是检测结果了。
SSD结合了YOLO中的回归思想和Faster R-CNN中的anchor机制,使用全图各个位置的多尺度区域特征进行回归,既保持了YOLO速度快的特性,也保证了窗口预测的跟Faster R-CNN一样比较精准。SSD在VOC2007上mAP可以达到72.1%,速度在GPU上达到58帧每秒。
Segment也是box,表达形式如下:
它相比SSD来说增加了角度信息。
关于default box的个数,本文每个feature map的每个位置只采用了一个aspect ratio=1的default box,而SSD中是一系列(1, 2, 3, 1/2, 1/3),这也是Seglink速度很快的原因。关于default box的scale size,本文的是根据当前层的感受野来进行设置scale size,而SSD是通过人工设定的,具体的设置公式如下:
其中分子分母分别表示输入图像的宽度和当前feature map的宽度。
Segment计算公式:
总结来说,对于segments的预测包括:2个segment score和5个geometric offsets为 ( x s , y s , w s , h s , θ s ) (x_{s},y_{s},w_s,h_s,\theta_s) (xs,ys,ws,hs,θs)。
link主要是用于连接上述segment,对于link detection部分,主要分成层内link检测(within-layer)和跨层link检测(cross-layer)。
上面的是层内Link,连接的是同层的8个邻域;下面的是跨层Link,连接连续两层的Link。
在同一个feature map层,由于文中对feature map中每个位置只预测一个segment,所以对于层内的link,我们只需要考虑当前segment的8邻域:即判断每个segment与它周围的8连通邻域的segment的连接情况,每个link有两个分数,一个用是正分,一个是负分,正分用来表示二者是否属于同一个单词;负分表示二者是否属于不同单词,应该断开连接。所以,每个segment的link应该是8*2=16维的向量。具体公式如下:
由于采用不同feature map,所以segment可能会被不同的feature map检测到,为了解决这种重复检测的冗余问题,文中提出了cross-layer Link。它主要是用于连续两层(注意这里前一层是后一层的邻居,但后一层不是前一层的邻居),所以只需要对conv7, conv8_2, conv9_2, conv10_2, conv11进行cross-layer link检测。
论文中说这些feature map中是前一层特征图的size是后一层的特征图的size的两倍(因为有pooling或者是步长为2的卷积层),这些特性需要保证feature map的size是偶数,所以输入图像的宽和高必须是128的倍数。
对于cross-layer link,对于feature map的每个位置需要预测2*4=8,这里4表示的是与上一层的4个邻域,就是对应前一层的感受野,具体公式如下:
总结来说:对于conv4_3层,其link输出的维度为2x8=16;对于conv7, conv8_2, conv9_2, conv10_2, conv11其输出的link维度为2x8+2x4=24。
上图中2表示是或不是字的二类分类分数,5表示位置信息x, y, w, h, θ,16表示8个同层的neighbor的连接或者不连接2种情况,8表示前一层的4个neighbor的连接与不连接情况。
对于conv4_3:其预测输出维度为: 2 + 5 + 2 × 8 = 23 2+5+2\times8=23 2+5+2×8=23 ,因为该层没有cross-layer link
对于conv7, conv8_2, conv9_2, conv10_2, conv11,其预测输出维度为: 2 + 5 + 2 × 8 + 2 × 4 = 31 2+5+2\times8+2\times4=31 2+5+2×8+2×4=31。
Seglink的Ground Truth包括defaut box的label、offset、层内Link和跨层Link的label。
网络的损失函数包括三部分:segment classification损失(softmax),offsets regression损失(L1 regression),link classification损失(softmax),具体公式如下:
其中控制全中因子λ1 和 λ2设置为1。
与SSD做法一致。
Seglink可以检测多方向文本(这是相对于SSD的一个创新点,因为在Segment中加入了角度信息);
Seglink将Link也放入了神经网络中学习,而不是像常规方法一样在后处理步骤中将多个bounding box通过合并算法合并,这也是Seglink的第二个创新点;
Seglink不涉及到感受野的问题,所以可以处理长文本;而且由于link的特性,Seglink可以很好地处理弯曲文本(看了这么多模型只有Seglink可以处理弯曲文本!!!)
1.《Detecting Oriented Text in Natural Images by Linking Segments》
2.https://zhuanlan.zhihu.com/p/33544892
3.SSD的tensorflow实现
4.https://blog.csdn.net/v_JULY_v/article/details/80170182
5.https://www.cnblogs.com/lillylin/p/6596731.html
6.https://zhuanlan.zhihu.com/p/37781277
7.Seglink的tensorflow实现