当前位置: 首页 > news >正文

DBNet学习笔记

1 概述

1.1 传统方法和DBNet的比较

在这里插入图片描述
传统分割算法流程(蓝色箭头部分):

  • 先通过网络输出文本分割的概率图;
  • 然后使用设定阈值将概率图转化为二值图;
  • 最后通过后处理得到检测结果(文本框坐标)。
  • 缺点:在于阈值的选取非常关键。

DBNet提出可微分二值化(红色箭头部分)来解决这个缺点:

  • 对每一个像素点进行自适应二值化;
  • 二值化阈值由网络学习得到,彻底将二值化这一步骤加入到网络里一起训练,这样最终输出的阈值图就非常鲁棒。

1.2 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 的卷积消除上采样的混叠效应;

  • 经过FPN后,得到了四个大小分别为原图的1/4,1/8,1/16,1/32的特征图;
    在这里插入图片描述

  • 将四个特征图分别上采样,统一为 1/4 大小的特征图;

  • 最后将四个1/4大小的特征图concat,得到F。

(2) 模块2(FCN 网络结构):获取概率图 P 和阈值图 T

  • 将 1/4 大小的特征图经过一系列卷积和转置卷积的操作后,生成与原图一样大小的概率图 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
6         if self.adaptive and self.training:
7             if self.serial:
9                 fuse = torch.cat(
10                        (fuse, nn.functional.interpolate(
11                            binary, fuse.shape[2:])), 1)
12            thresh = self.thresh(fuse)

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())

流程如下:

  • 1)F(shape:(batch,256,1/4W,1/4H))先经过卷积层,将通道压缩为输入的1/4,然后经过BN和relu,得到的特征图shape为(batch,64,1/4W,1/4H);(代码2至5行)
  • 2)将得到的特征图进行反卷积操作,卷积核为(2,2),得到的特征图shape为(batch,256,1/2W,1/2H),此时为原图的1/2大小;(代码第6行)
  • 3)再进行反卷积操作,同第二步,不同的是输出的特征图通道为1,得到的特征图shape为(batch,W,H),此时为原图大小。(代码第9行)
  • 4)最后经过sigmoid函数,输出概率图,probability map。(代码第10行)

(3)模块3(DB操作):获取近似二值图

  • 将概率图 P 和阈值图 T 经过 DB (可微二值化)操作,得到近似二值图。

利用上面三个模块,可以得到概率图、阈值图和近似二值图。
训练过程对这三个图进行监督学习,更新各个模块的参数。
推理过程直接使用概率图,然后使用固定阈值获取结果。

2 二值化

2.1 标准二值化

在传统的图像分割算法中,我们获取概率图后,会使用标准二值化(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,jt,0,otherwise.
标准的二值化是不可微的,无法放入到网络中进行优化学习。

2.2 可微二值化

可微二值化就是将标准二值化中的阶跃函数进行了近似:
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+ek(Pi,jTi,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指阈值图像素点。

2.3 SB和DB曲线

标准二值化和可微二值化的对比如图 (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,公式如下:

  • 交叉熵损失函数: L = − [ y log ⁡ B ^ + ( 1 − y ) log ⁡ ( 1 − B ^ ) ] L=-[y \log \hat{B}+(1-y) \log (1-\hat{B})] L=[ylogB^+(1y)log(1B^)]
  • 正样本 ( y = 1 y = 1 y=1) 损失: l + = − log ⁡ ( 1 1 + e − k ( P i , j − T i , j ) ) l_{+}=-\log \left(\frac{1}{1+e^{-k\left(P_{i, j}-T_{i, j}\right)}}\right) l+=log(1+ek(Pi,jTi,j)1)
  • 负样本 ( y = 0 y = 0 y=0) 损失: l − = − log ⁡ ( 1 − 1 1 + e − k ( P i , j − T i , j ) ) l_{-}=-\log \left(1-\frac{1}{1+e^{-k\left(P_{i, j}-T_{i, j}\right)}}\right) l=log(11+ek(Pi,jTi,j)1)

对输入 x = P i , j − T i , j x = P_{i, j}-T_{i, j} x=Pi,jTi,j 求偏导,令 f ( x ) = 1 1 + e − k x f(x) = \frac{1}{1 + e^{-kx}} f(x)=1+ekx1,则会得到:
δ 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)ekxδxδl=kf(x),
分析图(b)和©,可以得到如下一些结论:

  • 增强因子 k k k会使得错误预测对梯度的影响变大,从而促进模型的优化过程,产生更为清晰的预测结果;
  • 图(b)为 l + l_+ l+的导数曲线,如果发生误0报(正样本被预测为负样本 x < 0 x<0 x<0),图(b)小于 0 的部分导数非常大,证明损失也是非常大的,则更能清晰的进行梯度回传。
  • 图©为 l − l_- l的导数曲线,当发生误报(负样本被预测为正样本 x > 0 x>0 x>0),导数也是非常大的,损失也比较大。

3 构建真实标签

在训练DBNet的时候,需要概率图 G s G_{s} Gs、阈值图 G d G_{d} Gd及近似二值图作为监督信息(ground-truth):

  • 概率图:每个像素点的值表示该位置属于文本区域的概率;
  • 阈值图:每个像素点的值表示该位置的二值化阈值;
  • 近似二值图:每个像素点的值为 0 或 1,利用概率图和阈值图通过 DB 算法计算得到。

阈值图和概率图:参考 PSENet 中的方法,使用扩张和收缩的方式;在该方法中,对于一幅文字图像,文本区域的每个多边形使用一组线段 G = { S k } k = 1 n G=\left\{S_{k}\right\}_{k=1}^{n} G={Sk}k=1n来进行描述, n n n为线段个数。
在这里插入图片描述

3.1 概率图 G s G_{s} Gs和近似二值图的标签构建方法

  • 概率图和近似二值图:使用收缩的方式(Vatti clipping算法)构建标签;
  • 标签为:蓝线区域内为文字区域,蓝线区域外为非文字区域;
  • 将原始的多边形文字区域 G G G(红线区域)收缩到 G s G_s Gs(蓝线区域),收缩的偏移量 D D D按照如下公式计算:
    D = A ( 1 − r 2 ) L , D=\frac{A\left(1-r^{2}\right)}{L}, D=LA(1r2),
    其中:
    L L L:多边形的周长;
    A A A:多边形的面积;
    r r r:收缩因子,经验设置为 0.4。

问题:原始的多边形文字区域 G G G(红线区域)是怎么得到的?

3.2 阈值图 G d G_{d} Gd的标签构建方法

  • 类似于概率图 G s G_{s} Gs和近似二值图的标签构建过程,为阈值图生成标签;
  • 首先将原始的多边形文字区域 G G G扩张到 G d G_d Gd(绿线区域),偏移量 D D D同概率图中的 D D D
  • 将收缩框 G s G_s Gs(蓝线)和扩张框 G d G_d Gd(绿线)之间的间隙视为文本区域的边界,计算这个间隙里每个像素点到原始图像边界G(红线)的归一化距离(最近线段的距离)
  • 计算完之后可以发现,扩张框 G d G_d Gd上的像素点和收缩框 G s G_s Gs上的像素点的归一化距离的值是最大的,并且文字红线上的像素点的值最小,为0。呈现出以红线为基准,向 G s G_s Gs G d G_d Gd方向的值逐渐变大。
  • 所以再对计算完的这些值进行归一化,也就是除以偏移量 D D D,此时 G s G_s Gs G d G_d Gd上的值变为1,再用1减去这些值;
  • 最后得到,红线上的值为1, G s G_s Gs G d G_d Gd线上的值为0;
  • 呈现出以红线为基准,向 G s G_s Gs G d G_d Gd方向的值逐渐变小。此时 G s G_s Gs G d G_d Gd区域内的值取值范围为[0,1];
  • 最终再进行缩放,比如归一化到 [0.3,0.7],这就是最终的标签。

有了标签,就可以计算损失啦!!

相关文章:

  • 1、搭建环境
  • 基于Java+Spring+vue+element社区疫情服务平台设计和实现
  • 【Leetcode】剑指Offer 34:二叉树中和为某一值的路径
  • CockroachDB架构-复制层
  • Netty 入门学习(1)
  • Android手部检测和手势识别(含训练代码+Android源码+手势识别数据集)
  • 【NLP】第4章 从头开始预训练 RoBERTa 模型
  • 第3章 循环神经网络
  • 机器学习入门八
  • java毕业设计流浪动物救助公益平台源码+lw文档+mybatis+系统+mysql数据库+调试
  • 物联网IOT面临挑战
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • Intel汇编-奇偶标志位测试
  • CMSC5724-关于条件概率和朴素贝叶斯分类器
  • FFmpeg入门详解之50:SDL2键盘事件案例
  • Angular Elements 及其运作原理
  • js递归,无限分级树形折叠菜单
  • js学习笔记
  • python_bomb----数据类型总结
  • Terraform入门 - 3. 变更基础设施
  • vue自定义指令实现v-tap插件
  • 对超线程几个不同角度的解释
  • 分布式任务队列Celery
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 如何在 Tornado 中实现 Middleware
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • TPG领衔财团投资轻奢珠宝品牌APM Monaco
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • (C语言)逆序输出字符串
  • (笔试题)合法字符串
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • (论文阅读22/100)Learning a Deep Compact Image Representation for Visual Tracking
  • (一)Neo4j下载安装以及初次使用
  • (原創) 如何優化ThinkPad X61開機速度? (NB) (ThinkPad) (X61) (OS) (Windows)
  • (转)【Hibernate总结系列】使用举例
  • (转)Oracle存储过程编写经验和优化措施
  • .net 简单实现MD5
  • .NET/C# 使用反射调用含 ref 或 out 参数的方法
  • .Net6支持的操作系统版本(.net8已来,你还在用.netframework4.5吗)
  • /etc/fstab和/etc/mtab的区别
  • @Autowired标签与 @Resource标签 的区别
  • []error LNK2001: unresolved external symbol _m
  • [2018-01-08] Python强化周的第一天
  • [BJDCTF2020]The mystery of ip1
  • [DevEpxress]GridControl 显示Gif动画
  • [DNS网络] 网页无法打开、显示不全、加载卡顿缓慢 | 解决方案
  • [dts]Device Tree机制
  • [HTML]Web前端开发技术18(HTML5、CSS3、JavaScript )HTML5 基础与CSS3 应用——喵喵画网页
  • [HTML]Web前端开发技术30(HTML5、CSS3、JavaScript )JavaScript基础——喵喵画网页
  • [javaSE] GUI(事件监听机制)
  • [LeetCode]—Add Binary 两个字符串二进制相加