深度学习论文: Real-time Scene Text Detection with Differentiable Binarization及其PyTorch实现
深度学习论文: Real-time Scene Text Detection with Differentiable Binarization及其PyTorch实现
Real-time Scene Text Detection with Differentiable Binarization
PDF: https://arxiv.org/pdf/1911.08947.pdf
PyTorch代码: https://github.com/shanglianlm0525/CvPytorch
PyTorch代码: https://github.com/shanglianlm0525/PyTorch-Networks
1 概述
传统的文本检测算法流程是先通过网络输出文本分割的概率图,然后使用预先设定好的阈值将概率图转换为二值图,最后使用后处理操作将像素级的结果转换为检测结果。然而,这样就会使得算法性能很大程度上取决于二值化时阈值的选择。

DBNet对这个流程进行了优化,对每个像素点进行自适应二值化,二值化的阈值由网络学习得到,彻底将二值化这一步骤加入到网络里一起训练,这样最终的输出图对于阈值就会非常鲁棒。
2 DBNet
DBNet网络结构如下:

整个流程如下
- 图像经过FPN网络结构,得到四个特征图,分别为1/4,1/8,1/16,1/32大小;
- 将四个特征图分别上采样为1/4大小,再concat,得到特征图F
- 由F得到 probability map ( P) 和 threshold map (T)
- 通过P、T使用可微分二值化DB计算 approximate binary map( 近似binary map )
**训练阶段:**对P、T、B进行监督训练,P和B是用的相同的监督信号(label);
**推理阶段:**通过P或B就可以得到文本框 (为了速度,一般使用P)。
2-1 Differentiable binarization
标准二值化(Standard binarization)如下,其中 t 为预先设定的固定阈值

为解决不可微的问题,引入了Differentiable Binarization,公式如下,

其中

Differentiable binarization 相较 Differentiable Binarization 的优势:

可以看出,DB曲线与标准二值化曲线具有很高的相似度,并且DB曲线是可微分的,从而达到了二值化的目的,也可加入分割网络联合优化。由于有了增强因子k,错误预测对梯度的影响也就被放大了,从而可以促进模型的优化过程并产生更为清晰的预测结果。
2-2 Deformable convolution
可变形卷积可以为模型提供灵活的感受野,这对极端长宽比的文本实例特别有利。 在 ResNet-18 或 ResNet-50 主干中的 conv3,conv4和conv5阶段的所有3×3卷积层中应用了可调节的可变形卷积。
2-3 Label generation
label生成的流程图如下所示,

probability map(预测图) 计算过程如下:
- F(shape:(batch,256,1/4W,1/4H))先经过卷积层,将通道压缩为输入的1/4,然后经过BN和relu,得到的特征图shape为(batch,64,1/4W,1/4H);
- 将得到的特征图进行反卷积操作,卷积核为(2,2),得到的特征图shape为(batch,256,1/2W,1/2H),此时为原图的1/2大小;
- 再进行反卷积操作,同第二步,不同的是输出的特征图通道为1,得到的特征图shape为(batch,W,H),此时为原图大小。
- 最后经过sigmoid函数,输出概率图,probability map。
PyTorch代码如下:
self.binarize = nn.Sequential(
nn.Conv2d(inner_channels, inner_channels //4, 3, padding=1, bias=bias), #shape:(batch,256,1/4W,1/4H)
BatchNorm2d(inner_channels//4),
nn.ReLU(inplace=True),
nn.ConvTranspose2d(inner_channels//4, inner_channels//4, 2, 2), #shape:(batch,256,1/2W,1/2H)
BatchNorm2d(inner_channels//4),
nn.ReLU(inplace=True),
nn.ConvTranspose2d(inner_channels//4, 1, 2, 2), #shape:(batch, W, H)
nn.Sigmoid())
代码解读
**threshold map(阈值图)**计算过程如下:
具体实现如 probability map 一样
PyTorch代码如下:
self.thresh = nn.Sequential(
nn.Conv2d(in_channels, inner_channels //4, 3, padding=1, bias=bias),
BatchNorm2d(inner_channels//4),
nn.ReLU(inplace=True),
nn.ConvTranspose2d(inner_channels // 4, inner_channels//4, 2, 2)
nn.ConvTranspose2d(in_channels, out_channels, 2, 2)
BatchNorm2d(inner_channels//4),
nn.ReLU(inplace=True),
nn.ConvTranspose2d(inner_channels // 4, 1, 2, 2)
nn.Sigmoid())
代码解读
approximate binary map 计算过程如下:
torch.reciprocal(1 + torch.exp(-self.k * (binary - thresh)))
代码解读
因此最后得到的标签
| - | 蓝线以内区域 | 绿线和蓝线中间的区域 | 其他区域 |
|---|---|---|---|
| threshold map | 0.3 | 越靠近红线越接近0.7,越远离红线越接近0.3 | 0.3 |
| probability map | 1 | 0 | 0 |
| binary map | 1 | 0 | 0 |
3 Experiments

