目标检测之DBnet(流程详解)

目标检测之DBnet模型


前言

  本文所介绍的模型DBnet是目前比较流行的文本检测模型。Real-time Scene Text Detection with Differentiable Binarization是发表在AAAI2020的一篇文章。文章地址:原文地址
  传统分割方法的后处理,设定一个固定的阈值,将分割网络生成的概率图转换为二值图像;然后,采用像素聚类等启发式技术将像素分组为文本实例。
缺点:由于是在pixel层面操作,比较复杂且时间消耗较大。
  DBNet后处理,DBNet的pipeline目的是将二值化操作插入到分割网络中进行联合优化,这样网络可以自适应的预测图像中每一个像素点的阈值(区别去传统方法的固定阈值),从而可完全区分前景和背景的像素。
DBnet中 二值化阈值由网络学习得到,彻底将二值化这一步骤加入到网络里一起训练,这样最终的输出图对于阈值就会具有非常强的鲁棒性,在简化了后处理的同时提高了文本检测的效果。基于分割的方法最关键的步骤是对二值化map的后处理过程,即将分割方法产生的概率图转化为文本框的过程。

  文章细节较多,请读者耐心观看!


一、DBnet模型的结构

结构如下图所示:
在这里插入图片描述

图1 DBnet模型结构图

  上图展示了DBnet整体的模型结构,可以看出DBnet的模型整体由三部分组成,Backbone,Neck,Head ,Backbone与Neck使用Resnet和FPN结构来完成对图片结构的特征信息提取,在我看来,FPN结构其实可以有待改进,读者可以学习并对之改进。Head部分如下图:
在这里插入图片描述

图2 Head部分

  Head部分是本文的创新点所在之处,本文对于Backbone部分就不作赘述,不懂得可以参考其他博客或者是Resnet的原文,下面我们分别对FPN和Head部分进行介绍。

二、FPN结构

在这里插入图片描述

图2 FPN结构
  浅层的特征图感受野小,比较适合检测小目标(要检测大目标,则其只“看”到了大目标的一部分,有效信息不够);深层的特征图感受野大,适合检测大目标(要检测小目标,则其”看“到了太多的背景噪音,冗余噪音太多),FPN就针对这两种尺度来综合浅层语义信息获得一个强语义信息。如果看不太懂图2,下图应该能使你比较清楚了解FPN的结构:

在这里插入图片描述

图3 FPN结构,图片源自(Backbone 之 FPN:特征金字塔)

  FPN的总体架构如图3所示,主要包含自下而上网络、自上而下网络、横向连接与卷积融合4个部分。

自下而上:
   默认ResNet结构用作提取语义信息。C1代表了ResNet的前几个卷积与池化层,而C2至C5分别为不同的ResNet卷积组,这些卷积组包含了多个Bottleneck结构,组内的特征图大小相同,组间大小递减。如图1所示,原图经过自下而上的Resnet结构,逐渐变为1/2,1/4,1/8,1/16,1/32,这分别对应C1,C2,C3,C4,C5。

自上而下:
   首先对C5进行1×1卷积降低通道数得到P5,然后依次进行上采样得到P4、P3和P2,目的是得到与C4、C3与C2尺度相同的特征,以方便下一步进行逐元素相加。这里上采样方法采用2倍最邻近上采样。

横向连接(Lateral Connection):
  目的是为了将上采样后的高语义特征与浅层的定位细节特征进行融合。高语义特征经过上采样后,其长宽与对应的浅层特征相同,而通道数固定为256,因此需要对底层特征C2至C4进行1×1卷积使得其通道数变为256,然后两者进行逐元素相加得到P4、P3与P2。由于C1的特征图尺寸较大且语义信息不足,因此没有把C1放到横向连接中。

卷积融合:
  在得到相加后的特征后,利用3×3卷积对生成的P2至P5再进行融合,融合时要保证各特征的尺寸相同,我们使用P2尺寸,所以P2不需要上采样,P3至P5分别上采样2倍、4倍、8倍,然后对P2、P3、P4、P5卷积融合。目的是消除上采样过程带来的重叠效应,以生成最终的特征图。

  FPN背后的思路是为了获得一个强语义信息,这样可以提高检测性能。使用更深的层来构造特征金字塔,这样做是为了使用更加鲁棒的信息;除此之外,将处理过的低层特征和处理过的高层特征进行累加,这样做是因为低层特征可以提供更加准确的位置信息,而多次的降采样和上采样操作使得深层网络的定位信息存在误差,因此将其结合使用,就构建一个更深的特征金字塔,融合了多层特征信息,并在不同的特征进行输出。

最后图像经过FPN网络结构得到特征图F,然后Head部分对这个特征图F进行处理。

三、Head部分

  Head部分由Backbone+FPN得到的特征图F计算得到 probability map( P) 和 threshold map (T)
通过P、T计算(通过可微分二值化DB,下文介绍) 得到approximate binary map(B)
该网络网络训练和推理阶段存在不同:
  训练阶段:对P、T、B进行监督训练。
  推理阶段:通过P或B就可以得到文本框。

1.训练阶段

(1)前向传播

我把图2放在这里,方便读者观看。
在这里插入图片描述
  由Backbone+FPN得到的特征图F,其尺寸大小为原图的1/4,然后计算得到,代码如下:


class DBHead(nn.Module):
    def __init__(self, in_channels):
        super().__init__()

        self.probability = nn.Sequential(
            nn.Conv2d(in_channels, in_channels // 4, 3, padding=1, bias=False),
            nn.BatchNorm2d(in_channels // 4),
            nn.ReLU(inplace=True),
            nn.ConvTranspose2d(in_channels // 4, in_channels // 4, 2, 2),
            nn.BatchNorm2d(in_channels // 4),
            nn.ReLU(inplace=True),
            nn.ConvTranspose2d(in_channels // 4, 1, 2, 2),
            nn.Sigmoid()
        )

        self.threshold = nn.Sequential(
            nn.Conv2d(in_channels, in_channels // 4, 3, padding=1, bias=False),
            nn.BatchNorm2d(in_channels // 4),
            nn.ReLU(inplace=True),
            nn.ConvTranspose2d(in_channels // 4, in_channels // 4, 2, 2),
            nn.BatchNorm2d(in_channels // 4),
            nn.ReLU(inplace=True),
            nn.ConvTranspose2d(in_channels // 4, 1, 2, 2),
            nn.Sigmoid())

    def forward(self, x):
        prob_maps = self.probability(x)
        thresh_maps = self.threshold(x)

        return prob_maps, thresh_maps 
        

  特征图F(shape:(batch,256,1/4W,1/4H))
1)先经过卷积层,将通道压缩为输入的1/4,然后经过BN和relu,得到的特征图shape为(batch,64,1/4W,1/4H);
2)将得到的特征图进行反卷积操作,卷积核为(2,2),得到的特征图shape为(batch,256,1/2W,1/2H),此时为原图的1/2大小;
3)再进行反卷积操作,同第二步,不同的是输出的特征图通道为1,得到的特征图shape为(batch,W,H),此时为原图大小。
4)最后经过sigmoid函数,输出概率图,probability map(P),threshold map (T)同理,不同点在于权重矩阵不同。
probability map(P),threshold map (T)

(2)损失分析

  训练数据集是图片中对文本区域的框架,框架是矩形框,DBnet是对于训练数据集是如何操作的呢?
首先我们对损失函数进行分析,论文中总损失函数是由P、T、B三种损失构成,B是什么?
    B是由P和T通过可微分二值化DB,下文介绍) 得到approximate binary map,故我们同样的要对训练数据集进行处理,通过训练集图片中的文本区域所对应标注的框架,计算得到与模型输出的P、T以及P,T计算得到的B对应的特征图P1、T1、B1,进而可以计算损失。
  所以有必要在数据处理前,我们要介绍本文的创新点DB(可微分二值化),这个可微分二值化是对前向推理的P、T进行计算,得到的B,在本模型中,B仅仅是用来监督训练的,但是也取得了很不错的效果。

(3)DB

标准二值化公式如下:
在这里插入图片描述

  以上的标准二值化公式可以看出,标准二值化操作会给训练带来梯度不可微的情况,如果将二值化操作加入到分割网络进行联合优化,是没法直接用优化算法梯度下降的,本文在此基础上进行创新,提出可微分二值化。

可微分二值化的公式如下:
在这里插入图片描述
  B是由P,T通过一个函数(可微分二值化)计算得到,计算过程看的话,这个函数其实就是一个带系数k的sigmoid函数,其取值范围为0-1,下图(a)是原文中标准二值化曲线与可微分二值化曲线的对比,可见DB曲线是可微分的,可以达到二值化的目的,也可加入分割网络联合优化。图(b)和图(c)是DB函数正负标签的导数曲线,DBNet性能提升的原因可以用梯度的反向传播来解释。首先对于该任务的分割网络,每个像素点都是二分类,即文字区域(正样本为1)和非文字区域(负样本为0),可以使用BCELoss。

B C E l o s s = − y l o g ( f ( x ) ) − ( 1 − y ) l o g ( 1 − f ( x ) ) BCEloss=-ylog(f(x))-(1-y)log(1-f(x)) BCEloss=ylog(f(x))(1y)log(1f(x))
y表示正样本1,那么1-y=0
所以正样本的BCELoss和负样本的BCELoss分别为:
在这里插入图片描述
那么链式法则求得偏导数为:
在这里插入图片描述
  所以可以由此来分析下图中的图(b)和图(c)
(1)梯度被放大 因子k增大;
(2)对比曲线中的黄线和蓝线,横轴为预测取值,故在错误预测的区域( l + l_+ l+的x<0区域, l − l_- l的x>0区域)这一放大效果更为显著,也就是loss更大,这可以促进模型的优化过程并产生更为清晰的预测结果。

在这里插入图片描述

(4)自适应阈值

  对于自适应阈值,论文中是这样介绍的:

The threshold map in Fig. 1 is similar to the text border map
 in (Xue, Lu, and Zhan 2018) from appearance. However, the
 motivation and usage of the threshold map are different from
 the text border map. The threshold map with/without super
vision is visualized in Fig. 6. The threshold map would high
light the text border region even without supervision for the
 threshold map. This indicates that the border-like threshold
 map is beneficial to the final results. Thus, we apply border
like supervision on the threshold map for better guidance.
 An ablation study about the supervision is discussed in the
 Experiments section. For the usage, the text border map in
 (Xue, Lu, and Zhan 2018) is used to split the text instances
 while our threshold map is served as thresholds for the bina
rization.

翻译一下:
  首先介绍下图各图:
图b为概率图,图c为没有监督的阈值图,图d为带监督的阈值图
图中的阈值图从外观上类似于文本边界图。但是,我们的阈值映射的用法与文本边界映射不同。有无视觉的阈值图如图所示。即使没有对阈值映射的监督,阈值映射也会对文本边界区域进行高亮显示。这表明类似边界阈值图对最终结果有利。因此,我们在阈值图上应用类似 边界的监督 以获得更好的指导。有关监督的消融研究在实验部分讨论。对于用法,文本边界映射通常用于拆分文本实例,而我们的阈值映射用作二值化的阈值。
在这里插入图片描述

所以我们对于阈值图进行的是边界的监督,这对于后面对于训练数据的处理的理解也很重要。

(5)训练数据处理

  由图片中文本区域所对应的矩形框坐标,是如何得到P、T、B呢?首先对于原图片进行尺寸变换,变换为模型输入的标准尺寸 640×640×3 对应的标注好的文本框也随比例进行缩放。然后得到输出图像image和标签contour。根据这个变换后的标签contou来计算P1和T1,P1对应下面图片中的蓝色框包含的区域,T1对应于下面的绿色和蓝色之间的区域,红黄色框为标签contour,B1由P1和T1根据DB算法计算得到,由此便得到了标签P1、T1、B1。如何由标签contour计算得到P1和T1呢?
在这里插入图片描述
对于概率图P的label的生成:
  基于PSEnet的启发,参考PSE网络,使用Vatti clipping算法,将原始的多边形文字区域G(红线区域)收缩到Gs(蓝线区域),收缩的偏移量D从原始多边形的周长和面积按照如下公式计算:


A是原始区域的面积,L是原始区域的周长,r是收缩系数,论文中依经验设置为r=0.4,实际情况按照自己的数据进行设置。最后生成的标签为: 整个蓝线区域内为文字区域,即标签为 1 ,蓝线区域外为非文字区域,即标签为 0 。 整个蓝线区域内为文字区域,即标签为1,蓝线区域外为非文字区域,即标签为0。 整个蓝线区域内为文字区域,即标签为1,蓝线区域外为非文字区域,即标签为0
  对于阈值图T的label的生成:
  通过类似的过程,为阈值图生成标签。首先将原始的多边形文字区域G(红线区域)扩张到Gd(绿线区域),收缩偏移量D同概率图中的D。将收缩框Gs(蓝线)和扩张框Gd(绿线)之间的区域 视为文本区域的边界,计算这个区域内每个像素点到原始图像边界G(红线)的归一化距离(最近线段的距离)。

  计算完之后可以发现,扩张框绿线上的像素点和收缩框蓝线上的像素点到红线的归一化距离的值是最大的,并且文字红线上的像素点的值最小,为0。呈现出以红线为基准,向蓝线和绿线方向的值逐渐变大。

  所以再对计算完的这些值进行归一化,也就是除以偏移量D,此时Gs(蓝线)和Gd(绿线区域)上的值变为1,再用1减去这些值最后得到红线上的值为1,Gs(蓝线)和Gd(绿线区域)线上的值为0。呈现出以红线为基准,向Gs和Gd方向的值逐渐变小。

  此时Gs(蓝线)和Gd(绿线区域)区域内的值取值范围为[0,1],此时非文字Gs(蓝线)和Gd(绿线区域)区域之外的取值也是0。我们再次全图进行归一化,取值为(0, 1),比如0.2, 0.8, 0.4等等,这些数值也就是阈值图T最终的标签。需要注意的是,经过最后的归一化,文字区域也就是Gs(蓝线)内的区域,也会存在标签,论文中设置的是0.3,而靠近红线附近出最大为0.7。这就对应上边的对于阈值图进行的是边界的监督。蓝线到绿线之间的区域相当于阈值图的边界,这和概率图的区域内二值化并不相同!

此时,标签就已经生成。

(6)损失函数

  有了前向传播的输出,有了标签,就可以计算损失了,损失函数为概率图的损失 L s L_s Ls、二值化图的损失 L b L_b Lb和阈值图的损失 L t L_t Lt 的和:
在这里插入图片描述
α和β分别设置为1和10,因为的 L t L_t Lt 结果会影响到 L b L_b Lb的结果,所以β设置为10。
L s L_s Ls采用BCE Loss, L b L_b Lb采用Dice Loss, L t L_t Lt使用Gd中预测值和标签间的L1距离。
BCE Loss上文已经提到,这里就不做赘述,下面介绍一下Diceloss,:
Diceloss是目标检测中常用的损失函数,Dice loss 来自文章VNet(V-Net: Fully Convolutional Neural Networks for Volumetric Medical Image Segmentation),旨在应对语义分割中正负样本强烈不平衡的场景。dice coefficient定义如下:
在这里插入图片描述
∣ X ⋂ Y ∣ | X \bigcap Y | XY代表标签与输出的交集的像素点的数量, ∣ X ∣ |X| X ∣ Y ∣ |Y| Y 分别代表标签与输出的像素点数量
Diceloss公式:
在这里插入图片描述
Gd中预测值和标签间的L1距离:
在这里插入图片描述
R d R_d Rd是Gd区域内的像素,注意是Gd区域内的所有像素点都要算,不仅仅是Gd和Gs区域内的;
y ∗ y^* y 是阈值图的标签, x ∗ x^* x 是模型对于阈值图的生成。

2.推理阶段


  在推理时,采用概率图或近似二值图便可计算出文本框,为了方便,作者选择了概率图,这部分也是读者比较有疑问的地方,为什么不用阈值图呢,应该在训练阶段,阈值图参与监督训练,效果已经达到了。论文中根据概率图P计算得到文本框的步骤
可分为三个方面:

(1)使用固定阈值(0.2)对概率图(或近似二值图)进行二值化,得到二值图;

(2)从二值图中得到连通区域(收缩的文字区域);

(3)将收缩文字区域按Vatti clipping算法的偏移系数D’进行扩张得到最终文本框,D’的计算公式如下:
在这里插入图片描述
A ′ A' A L ′ L' L收缩的文字区域的面积、周长,论文中, r ′ r' r依经验设置为1.5(对应收缩比例r=0.4)。
   
至此,DBnet模型介绍完毕!读者可以参考源码来看此文章。


参考

手把手教你学DBNet
Real-time Scene Text Detection with Differentiable Binarization

<think>好的,用户现在想用lqmm包来做面板数据的双固定效应分位数回归分析,因变量是income,核心解释变量是dig,还有五个控制变量x1到x5。我需要详细考虑如何回答这个问题。 首先,用户之前已经询问过使用fixest和quantreg进行双固定效应回归,现在转向lqmm。这说明用户可能遇到了quantreg处理高维固定效应的问题,或者需要更专业的包来处理面板分位数回归。我需要确认lqmm是否支持双固定效应,以及如何正确设置模型。 查阅lqmm文档后,我发现lqmm主要用于线性混合模型的分位数回归,支持随机效应,但固定效应可能需要手动处理。双固定效应通常指个体和时间效应,但在混合模型中,通常将个体作为随机效应,时间作为固定效应,或者反之。但用户明确要求双固定效应,可能需要将所有效应作为固定处理,但lqmm可能不支持。这时候可能需要用因子变量来引入固定效应,但需要注意自由度问题。 用户的数据结构可能有面板数据,比如个体(如公司)和时间(如年份)。在lqmm中,随机效应是通过random参数指定的,而固定效应则需要包含在模型公式中。因此,用户需要将个体和时间作为因子变量加入固定效应部分,但这样在个体或时间数量较大时会导致模型矩阵过大,计算困难。 接下来,我需要编写示例代码,展示如何用lqmm进行这样的分析。首先,安装并加载lqmm包。然后,生成示例数据,包括income、dig、x1-x5,以及个体id(如firm_id)和时间变量(year)。然后,将个体和时间转换为因子,并加入到固定效应中。 需要注意的是,lqmm的公式中固定效应部分需要显式加入,例如使用factor(firm_id)和factor(year)。但这样会导致模型参数过多,尤其是当个体或时间数目很大时,可能会遇到内存不足或计算时间过长的问题。因此,可能需要提醒用户在这种情况下的替代方案,如先去除固定效应再回归,或者使用其他包。 此外,分位数回归需要指定tau参数,用户可能需要分析不同分位数下的结果,比如中位数(tau=0.5)。在示例代码中,需要展示如何设置tau,并解释输出结果的含义,如固定效应和随机效应的区别。 另外,用户可能对结果的解读有疑问,比如如何提取固定效应的系数,以及如何验证模型是否收敛。需要提醒用户注意收敛警告,并可能调整优化方法或参数。 最后,还需要比较lqmm与其他方法(如之前的fixest+quantreg方法)的优缺点,帮助用户选择适合他们数据情况的方法。如果用户的数据具有大量个体或时间点,可能需要推荐其他方法,如先去除固定效应再进行分位数回归,或者使用更高效的包。 总结步骤: 1. 安装加载lqmm包。 2. 准备数据,生成示例变量。 3. 将个体和时间作为因子加入固定效应。 4. 编写lqmm模型代码,指定因变量、自变量、随机效应(如果有的话)。 5. 处理可能的高维问题,建议替代方法。 6. 解释结果,提取系数。 7. 注意事项和常见问题解决。 需要确保代码正确,并解释每个步骤的作用,特别是因子变量的处理和随机效应的设置。同时,提醒用户lqmm的限制,以及替代方案的存在。</think>--- ### **使用`lqmm`进行双固定效应面板分位数回归的R代码指南** 以下针对因变量`income`、核心解释变量`dig`、控制变量`x1-x5`,结合个体和时间双固定效应,详细说明如何利用`lqmm`包实现分位数回归分析。 --- #### **1. 准备工作** ```r # 安装与加载包 install.packages("lqmm") library(lqmm) # 分位数混合模型 library(dplyr) # 数据清洗 # 生成示例数据(假设面板数据结构) set.seed(123) n <- 1000 # 总观测数 df <- data.frame( firm_id = rep(1:50, each = 20), # 50个个体,每个20期 year = rep(2000:2019, times = 50),# 时间跨度20年 income = rnorm(n), dig = rnorm(n), x1 = rnorm(n), x2 = rnorm(n), x3 = rnorm(n), x4 = rnorm(n), x5 = rnorm(n) ) ``` --- #### **2. 模型设定与估计** `lqmm`通过`random`参数定义随机效应,但**双固定效应需手动处理**。以下提供两种方法: ##### **方法1:显式加入固定效应(适合小维度)** ```r # 将个体和时间转换为因子(固定效应) df <- df %>% mutate( firm_factor = as.factor(firm_id), year_factor = as.factor(year) ) # 分位数回归(以中位数τ=0.5为例) model_lqmm <- lqmm( income ~ dig + x1 + x2 + x3 + x4 + x5 + firm_factor + year_factor, random = ~1 | firm_id, # 若需添加随机效应(如个体随机效应) data = df, tau = 0.5, control = lqmmControl(method = "df") # 优化算法 ) # 查看结果 summary(model_lqmm) ``` ##### **方法2:预吸收固定效应(大维度推荐)** ```r # Step 1: 用fixest去除固定效应 library(fixest) # 对因变量和所有自变量去双固定效应 df$income_resid <- feols(income ~ 1 | firm_id + year, data = df)$residuals df$dig_resid <- feols(dig ~ 1 | firm_id + year, data = df)$residuals df$x1_resid <- feols(x1 ~ 1 | firm_id + year, data = df)$residuals # 同理处理x2-x5... # Step 2: 对残差进行分位数回归 model_resid <- lqmm( income_resid ~ dig_resid + x1_resid + x2_resid + x3_resid + x4_resid + x5_resid, random = ~1 | firm_id, # 若需添加随机效应 data = df, tau = 0.5 ) # 查看结果 summary(model_resid) ``` --- #### **3. 结果解释与提取** ##### **提取固定效应系数** ```r # 固定效应系数(方法1) fixed_effects <- coef(model_lqmm)[grepl("firm_factor|year_factor", names(coef(model_lqmm)))] head(fixed_effects) # 核心变量系数 main_coef <- coef(model_lqmm)["dig"] cat("核心变量dig的系数:", main_coef) ``` ##### **输出示例** ``` tau: 0.5 Fixed effects: Value Std. Error Lower bound Upper bound Pr(>|t|) dig_resid 0.1023 0.0284 0.0465 0.1581 0.0003 x1_resid -0.0071 0.0293 -0.0646 0.0504 0.8090 ... ``` --- #### **4. 注意事项与问题解决** | **关键问题** | **解决方案** | |----------------------------|-----------------------------------------------------------------------------| | 固定效应维度高导致计算崩溃 | 使用预吸收固定效应方法(方法2),或升级硬件内存 | | 模型不收敛 | 调整`control`参数:尝试`method = "gs"`(网格搜索)或增加`max_iter` | | 结果中固定效应系数过多 | 关注核心变量`dig`的系数,固定效应可通过`summary`中的分组效应整体检验 | | 随机效应与固定效应混淆 | 明确区分:固定效应通过因子变量加入,随机效应通过`random`参数指定 | --- #### **5. 替代方案对比** - **`lqmm`优势**:直接支持分位数混合模型,适合同时分析固定效应和随机效应。 - **`fixest`+`quantreg`优势**:更高效处理高维固定效应,适合大规模面板数据。 - **选择建议**: - 若需严格双固定效应+分位数回归,优先使用**预吸收固定效应**方法。 - 若需同时建模随机效应(如个体随机斜率),选择`lqmm`。 --- ### **总结** - **小规模数据**:直接使用`lqmm`显式加入固定效应因子,结果直观。 - **大规模数据**:先通过`fixest`去除固定效应,再使用`lqmm`或`quantreg`分析残差。 - **核心关注点**:比较不同分位数下`dig`的系数变化,观察数字化(`dig`)对收入分布不同位置的影响差异。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值