搞懂了DBNet的二值化处理和标签制作就理解了DBNet网络。
DBNet提出可微分二值化(红色箭头部分)来解决这个缺点:
DBNet网络结构主要由3个模块构成,分别说明如下。
(1)模块1(FPN 结构):分为自底向上的卷积操作与自顶向下的上采样,以此来获取多尺度的特征
主干网络是ResNet,在stage2-4中使用Deformable convolution来更好地检测长文本;
1 图下半部分是 3 × 3 3 \times 3 3×3 的卷积操作,分别获取原图大小比例的 1/2、1/4、1/8、1/16、1/32 的特征图;
然后自顶向下进行上采样 × 2 \times 2 ×2,然后与自底向上生成的相同大小的特征图融合得到1图的上半部分;
融合之后再采用 3 × 3 3 \times 3 3×3 的卷积消除上采样的混叠效应;
将四个特征图分别上采样,统一为 1/4 大小的特征图;
最后将四个1/4大小的特征图concat,得到F。
问:如何进行concat?
答:我估计是四个特征图对应像素点进行平均,具体如何concat,建议去看源代码。
(2) 模块2(FCN 网络结构):获取概率图 P 和阈值图 T
1 binary = self.binarize(fuse) #由F得到P,输入fuse代表F
2 if self.training:
3 result = OrderedDict(binary=binary)
4 else:
5 return binary #如果在推理阶段,直接用P得到文本框
6 if self.adaptive and self.training: #如果在训练阶段且自适应阈值,则计算threshold map
7 if self.serial:
9 fuse = torch.cat(
10 (fuse, nn.functional.interpolate(
11 binary, fuse.shape[2:])), 1)
12 thresh = self.thresh(fuse) #由F得到T,self.thresh与self.binarize实现一样,只是训练得到的参数不同。
self.binarize函数具体实现如下:
1 self.binarize = nn.Sequential(
2 nn.Conv2d(inner_channels, inner_channels //
3 4, 3, padding=1, bias=bias), #shape:(batch,256,1/4W,1/4H)
4 BatchNorm2d(inner_channels//4),
5 nn.ReLU(inplace=True),
6 nn.ConvTranspose2d(inner_channels//4, inner_channels//4, 2, 2), #shape:(batch,256,1/2W,1/2H)
7 BatchNorm2d(inner_channels//4),
8 nn.ReLU(inplace=True),
9 nn.ConvTranspose2d(inner_channels//4, 1, 2, 2), #shape:(batch, W, H)
10 nn.Sigmoid())
流程如下:
(3)模块3(DB操作):获取近似二值图
thresh_binary = self.step_function(binary, thresh) #binary和thresh分别为P和T,thresh_binary为近似二值图
def step_function(self, x, y):
return torch.reciprocal(1 + torch.exp(-self.k * (x - y)))
利用上面三个模块,可以得到概率图、阈值图和近似二值图。
训练过程对这三个图进行监督学习,更新各个模块的参数。
推理过程直接使用概率图,然后使用固定阈值获取结果。
在传统的图像分割算法中,我们获取概率图后,会使用标准二值化(Standard Binarize)方法进行处理,将低于阈值 t t t的像素点置0,高于阈值 t t t的像素点置1:
B i , j = { 1 , if P i , j ≥ t , 0 , otherwise. B_{i,j}=\left\{\begin{matrix} 1, \textrm{if} \ P_{i,j} \ge t, \\ 0, \textrm{otherwise.} \end{matrix}\right. Bi,j={1,if Pi,j≥t,0,otherwise.
标准的二值化是不可微的,无法放入到网络中进行优化学习。
可微二值化就是将标准二值化中的阶跃函数进行了近似:
B ^ i , j = 1 1 + e − k ( P i , j − T i , j ) , \hat{B}_{i,j}= \frac{1}{1 + e^{-k(P_{i,j} - T_{i,j})}}, B^i,j=1+e−k(Pi,j−Ti,j)1,
k k k 是膨胀因子(经验型设置为50)。
可微二值化本质上是一个 带系数 k k k 的 sigmoid 函数,取值范围为(0,1); P i , j P_{i,j} Pi,j指概率图像素点, T i , j T_{i,j} Ti,j指阈值图像素点。
标准二值化和可微二值化的对比如图 (a) 所示, x > 0 x>0 x>0属于正样本(文字区域), x < 0 x<0 x<0属于负样本(非文字区域)。
SB 代表标准二值化曲线,DB 代表可微二值化曲线,可以看到曲线变得更为平滑,也就是可微:
除了可微之外,DB 方法也会改善算法的性能,在反向传播是梯度的计算上进行观察。当使用交叉熵损失( y = 1 y = 1 y=1代表文字区域)时,正负样本的 loss 分别为 l + l_+ l+ 和 l − l_- l−,公式如下:
对输入 x = P i , j − T i , j x = P_{i, j}-T_{i, j} x=Pi,j−Ti,j 求偏导,令 f ( x ) = 1 1 + e − k x f(x) = \frac{1}{1 + e^{-kx}} f(x)=1+e−kx1,则会得到:
δ l + δ x = − k f ( x ) e − k x δ l − δ x = − k f ( x ) , \begin{array}{c} \frac{\delta l_{+}}{\delta x}=-k f(x) e^{-k x} \\ \frac{\delta l_{-}}{\delta x}=-k f(x), \end{array} δxδl+=−kf(x)e−kxδxδl−=−kf(x),
分析图(b)和©,可以得到如下一些结论:
在训练DBNet的时候,需要概率图 G s G_{s} Gs、阈值图 G d G_{d} Gd及近似二值图作为监督信息(ground-truth):
因为近似二值图可以由概率图和阈值图计算得到,所以只需要构建阈值图和概率图两个标签。
阈值图和概率图:参考 PSENet 中的方法,使用扩张和收缩的方式;在该方法中,对于一幅文字图像,文本区域的每个多边形使用一组线段 G = { S k } k = 1 n G=\left\{S_{k}\right\}_{k=1}^{n} G={Sk}k=1n来进行描述, n n n为线段个数。
问题:原始的多边形文字区域 G G G(红线区域)是怎么得到的?
有了标签,就可以进行监督学习啦!!
损失函数为概率图的损失、二值化图的损失和阈值图的损失的和:
L = L s + α × L b + β × L t L=L_{s}+\alpha \times L_{b}+\beta \times L_{t} L=Ls+α×Lb+β×Lt
其中:
L s = L b = ∑ i ∈ S l y i log x i + ( 1 − y i ) log ( 1 − x i ) , L_{s}=L_{b}=\sum_{i \in S_{l}} y_{i} \log x_{i}+\left(1-y_{i}\right) \log \left(1-x_{i}\right), Ls=Lb=i∈Sl∑yilogxi+(1−yi)log(1−xi),
其中 S l S_{l} Sl表示使用OHEM进行采样,正负样本比例为1:3。
L t L_{t} Lt计算预测值和标签间的 1 _1 L1 距离:
L t = ∑ i ∈ R d ∣ y i ∗ − x i ∗ ∣ L_{t}=\sum_{i \in R_{d}}\left|y_{i}^{*}-x_{i}^{*}\right| Lt=i∈Rd∑∣yi∗−xi∗∣