文章目录
- 1 DINO(ICCV2021, Meta)
- 1.1 数据增强
- 1.2 损失函数
- 2 DINOv2(CVPR2023, Meta)
- 2.1 数据采集方式
- 2.2 训练方法
- 3 Grounding DINO
- 3.1 Grounding DINO设计思路
- 3.2 网络结构
- 3.2.1 Feature Extraction and Enhancer
- 3.2.2 Language-Guided Query Selection
- 3.2.3 Cross-Modality Decoder
- 3.2.4 Sub-Sentence Level Text Feature
- 3.2.5 Loss function
- 3.3 完整流程
1 DINO(ICCV2021, Meta)
- Paper:DINO_ICCV2021_paper.pdf
- Github:https://github.com/facebookresearch/dino
- 参考博客:https://juejin.cn/post/7224738994825789496
DINO:可以理解为由DIstillation和NO labels的缩写,表示为一种没有标签的自蒸馏方法,重塑子监督学习。是2021年Facebook AI发表在CVPR上的方法(Emerging Properties in Self-Supervised Vision Transformer) 。DINO是最早探讨基于Transformer架构的子监督学习代表作之一,其通过在无标签的图像上进行子监督训练来学习视觉特征表示。在这个方法中,模型使用自身的输出来生成“伪标签”,然后使用这些伪标签来重新训练模型,从而进一步提高模型的性能和泛化能力。以下是DINO的伪代码:
伪代码解析DINO训练流程:
- Step1:创建2个完全一样的网络,命名为教师teacher网络和学生student网络
- Step2:对同一个输入x,进行不同的数据增强,得到student和teacher网络的输入x1,和x2
- Step3:交叉计算对比损失,再求均值得到loss
- Step4:只对student网络进行反向传播和梯度更新
- **Step5:基于student网络的参数更新teacher的参数: θ t = λ θ t + ( 1 − λ ) θ s \theta_t = \lambda\theta_t+(1-\lambda)\theta_s θt=λθt+(1−λ)θs **
- *Step6:更新teacher网络输出的中心点:C = m*C + (1 - m)mean(t1, t2)
正如我们上面提到过的,DINO 是采用自蒸馏(self-distillation)的方法学习的,其整体框架包含两个相同的架构,分别为教师网络和学生网络,具体的架构可以是 ViT 等 vision transformer 或者诸如 ResNet 等 CNNs 特征提取器,非常灵活方便。当然,通过下述消融实验也知道还是 ViT 的潜力更大。
然而,这种学生和教师网络均输出相同 embeddings 的情况容易出现模式崩塌(mode collapse)的现象。在《Momentum Contrast for Unsupervised Visual Representation Learning》一文中提出了一种解决方案,即应用“动量教师”(momentum tearcher)模型,可以简单地理解为就是教师的模型不是基于反向传播更新的,而是再对学生模型进行梯度回传后,在通过指数移动平均(Exponentially Weighted Average, EWA),直接将学生网络学习到的模型参数更新给教师网络,**换句话就是教师网络的权重更新自学生网络。**DINO 中便是沿用这种方式。具体地,我们可以简单看下教师权重的更新公式:
θ
t
=
λ
θ
t
+
(
1
−
λ
)
θ
s
\theta_t = \lambda\theta_t+(1-\lambda)\theta_s
θt=λθt+(1−λ)θs
t和s分别代表教师网络和学生网络。
1.1 数据增强
一句话总结:teacher用大图,student用小图+大图
DINO 中最核心的数据采样策略便是图像裁剪,这也是自监督学习领域应用非常广泛的主策略之一。一般来说,我们可以将裁剪后的图像分为两种:
- Local views: 即局部视角,也称为 small crops,指的是抠图面积小于原始图像的 50%;
- Global views: 即全局视角,也称为 large crops,指的是抠图面积大于原始图像的 50%;
在 DINO 中,学生模型接收所有预处理过的 crops 图,而教师模型仅接收来自 global views 的裁剪图。据作者称,这是为了鼓励从局部到全局的响应,从而训练学生模型从一个小的裁剪画面中推断出更广泛的上下文信息。**简单来说,就是把局部特征和全局特征分别交给不同的模型来学习,以便在处理整个图像时,能够更好地对局部细节和上下文进行综合判断。**此外,为了使网络更加鲁棒,DINO 中也采用一些其它的随机增强,包括:
- 颜色扰动(color jittering)
- 高斯模糊(Gaussian blur)
- 曝光增强(solarization)
1.2 损失函数
在 DINO 中,教师和学生网络分别预测一个一维的嵌入。为了训练学生模型,我们需要选取一个损失函数,不断地让学生的输出向教师的输出靠近。softmax 结合交叉熵损失函数是一种常用的做法,来让学生模型的输出与教师模型的输出匹配。具体地,通过 softmax 函数把教师和学生的嵌入向量尺度压缩到 0 到 1 之间,并计算两个向量的交叉熵损失。这样,在训练过程中,学生模型可以通过模仿教师模型的输出来学习更好的特征表示,从而提高模型的性能和泛化能力。当然,这也可以看作是一个分类问题,以便网络可以从局部视图中学习更有意义的全局表示。
核心特点:
- 两完全一样的教师和学生网络(vit/cnn均可)
- 教师网络通过centering和sharpening正则化避免训练崩塌
- centering:教师模型的输出也经过EMA操作,从原始激活值中减去一个平均值
- sharpening:在softmax中加入一个temperature桉树,强制让概率分布更加尖锐
- 两个网络的输出都通过softmax层归一化处理
- 通过cross entropy loss计算损失。
- 学生网络通过SGD更新参数,并通过EMA更新教师网络参数
2 DINOv2(CVPR2023, Meta)
- Paper:https://arxiv.org/abs/2304.07193
- Github:https://github.com/facebookresearch/dinov2
- Demo:https://dinov2.metademolab.com/
DINOv2:是Meta在2023年CVPR上公开的一种在大型图像数据集上训练图像编码器,以获得具有通用语义的视觉特征(DINOv2: Learning Robust Visual Features without Supervision)。可以看作是DINO的增强版,其核心特点:
- 通过无监督的学习方法,构建了一个自动化数据管道,创建了一个包含公开/网络数据的大规模数据集(LVD-142M高质量数据集);
- 训练一个10亿参数的ViT模型,通过无监督蒸馏方法,可以将其压缩成一系列能够用于不同任务的小模型;
可以应用的下游任务:https://cloud.tencent.com/developer/article/2314807
- 深度估计
- 语义分割
- 实例检索
2.1 数据采集方式
参考资料:
- https://zhuanlan.zhihu.com/p/623274167
- https://cloud.tencent.com/developer/article/2314807
数据集LVD-142M构造流程:
- 数据采集:包含公开数据集(ImageNet-22k、ImageNet-1K、Google Landmarks等)和网络爬取的数据;
- 数据去重:利用(A self-supervised descriptor for image copy detection , cvpr2022, meta)中提到的方法进行数据去重;
- 自监督图像检索::使用一个在ImageNet-22k上预训练的ViT-H/16用于计算每个图像的image embedding,再使用kmeans聚类,从未标注数据中检索出与精心整理过的数据集中存在相似度很高的那部分样本。最后,给定一个查询图像,DINOv2从查询图像所在的聚类中检索出N个最相似的图像用于网络训练。
在数据去重和图像检索阶段,DINOv2依赖于Faiss的库进行高效最近的N个embeddings。
2.2 训练方法
DINOv2 采用了一种判别式自监督方法(Discriminative Self-supervised Pre-training)来学习特征,这种方法可以看作是以SwAV为中心的DINO和iBOT 损失的组合。具体而言,作者们实现了以下几种方法:
-
**图像级损失(Image-level objective):**利用一种交叉熵损失函数来比较从学生和教师网络中提取出的特征。这些特征都来自于ViT的cls token,通过对同一图像的不同裁剪图像进行提取得到。作者们使用指数移动平均法(EMA)来构建教师模型,学生模型的参数则通过训练得到(DINO的方法)。
-
**Patch级损失(Patch-level objective):**随机遮盖一些patch输入给student,teacher不遮盖,计算在遮盖的 patch上特征的交叉熵损失函数。
-
**解耦上述的两个优化目标(Untying head weights between both objectives):**作者们发现,将两种目标的权重绑定在一起会导致模型在 Patch-level 欠拟合,在 Image-level 过拟合。于是不复用权重,使用不同的head就可以避免这个问题。
-
Sinkhorn-Knopp centering: 使用SwAV中提到的Sinkhorn-Knopp(SK) Batch Normalization来代替DINO和IBot中的teacher网络中的softmax-centering步骤;对student进行3次Sinkhorn-Knopp算法迭代,再使用softmax进行normalization。可参考:Sinkhorn-Knopp算法,SINKHORN-KNOPP ALGORITHM,Unsupervised Learning of Visual Features
by Contrasting Cluster Assignments。
对于相似度矩阵,分别对行、列进行加权,权重来自于每个元素与每行(列)元素和的比值。
-
KoLeo regularizer: KoLeo regularizer 是一种正则化方法,它通过计算特征向量之间的差异来确保它们在批次内均匀分布,其源自于 Kozachenko-Leonenko 微分熵估计器,可以使得一个batch内的特征具有统一跨度。具体见:Spreading vectors for similarity search (arxiv.org)
L k o l e o = − 1 n Σ i = 1 n l o g ( d n , i ) d n , i = min j ≠ i ∣ ∣ x i − x j ∣ ∣ 2 \mathcal{L}_{koleo} = -\frac{1}{n}\Sigma_{i=1}^{n}log(d_{n,i}) \\ d_{n, i} = \min_{j \neq i}||x_i - x_j||_2 Lkoleo=−n1Σi=1nlog(dn,i)dn,i=j=imin∣∣xi−xj∣∣2其中 d n , j d_{n,j} dn,j表示 x i x_i xi与batch中其他向量的最小距离,距离计算使用L2范数。
-
调整分辨率(Adapting the resolution): 这一步主要是涉及在预训练的最后一段时间内,将图像的分辨率提高到(224x224->416x416->) 518×518 ,便在下游任务中更好地处理像素级别的信息,例如分割或检测任务。高分辨率的图像通常需要更多的计算资源和存储空间,因此只在预训练的最后阶段使用这种方法,以减少时间和资源成本。
3 Grounding DINO
参考资料:
- Paper:https://arxiv.org/pdf/2303.05499.pdf
- Github:https://github.com/IDEA-Research/GroundingDINO
- Blog:
- https://zhuanlan.zhihu.com/p/627646794
- https://blog.roboflow.com/grounding-dino-zero-shot-object-detection/
Grounding DINO可以用来干什么:根据输入文字描述检测图像中的指定目标
传统目标检测:将范围限定在特定的类别集合之中;
开放集目标检测:指根据文本检测任意目标,即为开集目标检测;
关于开集目标的检测的两种思路:
- Referring:表示学习的思路,对region特征进行分类。即为先提取目标region再,再判断类别;
- Grounding:将Detection文件转化为Grounding问题,如将图像类别名称(描述)作为prompt,然后将图像与prompt一同输入模型,从而获得对应的类别和bbox;
3.1 Grounding DINO设计思路
- 特征提取主干Backbone;
- 特性增强模块Neck;
- 区域细化(或边界框预测)Head;
让一个close-set detector在文字引导下识别新类别的关键是利用contrastive loss建立图像特征和文字特征的关联。为了帮助模型获得跨模态的能力,特征融合可能发生在以下三个阶段中:neck (phase A), query initialization (phase B), 和 head (phase C)。举例来说,GLIP选择了phase A,而OV-SETR选择在phase B进行模型融合。Grounding DINO认为融合的越多越好,所在在A、B、C三个阶段都有文本与图像特征的交互。
3.2 网络结构
Grounding DINO的整体结构如上图所示。Grounding DINO是一个双encoder单decoder结构,它包含了:
- image backbone用于提取image feature(Swin transformer)
- text backbone用于提取text feature(BERT)
- feature enhancer用于融合image和text feature
- language-guide query selection模块用于query初始化
- cross-modality decoder用于bbox预测。
3.2.1 Feature Extraction and Enhancer
特征提取,image encoder使用SWIM Transformer作为backbone,BERT作为text encoder的backbone。提完特征之后送入到如下的网络结构中:
Source: Piotr Skalski.
先分别进行self-attention,再利用GLIP中image-to-text和text-to-image cross-attention来实现特征融合。
3.2.2 Language-Guided Query Selection
为了让文字信息更好地指导目标检测,作者设计了一个language-guide query selection模块,用以筛选与输入文字特征相似更高的图像特征用作decoder的qureies。该模块的PyTroch伪代码如下图所示,其中num_query是用作decoder的query数量,设置为900;num_img_tokens和num_text_tokens是image和text的token数量。
计算流程:
- image features和text features进行矩阵乘法得到logits(nxm,其中n是image token的数量,m是text token的数量)
- 取出每个image对应的最大logits(nx1)
- 从最大logits(nx1)中取出num_query个最大logit所在的index
language-guide query selection输出了num_query个indices,其实就是在text指导下选择最佳的num_query个queries。
3.2.3 Cross-Modality Decoder
每个跨模态查询都输入到一个self-attention、一个用于组合图像特征的图像交叉注意力层、一个用于组合文本特征的文本交叉注意力层以及每个跨模态解码器层中的 FFN 层。与 DINO 解码器层相比,每个解码器层都有一个额外的文本交叉注意力层,因为需要将文本信息注入queries中以获得更好的模态对齐。
Source: Piotr Skalski.
3.2.4 Sub-Sentence Level Text Feature
以往的工作中主要采用两种text prompt,分别为sentence level和word level的表达,如下图所示。
- sentence level的方式将整句话编码为一个特征,但是它只保留与GT相关的短语。例如上图(a)所示,“A cat is sleeping on a table"只保留"A cat"和"a table”,这种方式忽视了句子中某些更细粒度的信息。
- word level的方式能够同时编码多个类别的名字,但是却引入了类别之间很多不必要的依赖。如图(b)所示,很多没有关系的类别也产生了交互。
- 字句级:为了避免上述问题,作者引入了attention mask来屏蔽不相关类别名之间的联系,称作sub-sentence level的方式,如上图©所示。
说人话就是:作者引入了一个新的分割符号.
用于区分文本中的不同类别,因此建议在实际使用时,使用符号.
来分割句子。
Source: Grounding DINO Github
3.2.5 Loss function
- 回归损失:继承DETR的L1 loss和GIOU-loss作为box regression
- 分类损失:借鉴GLIP,预测对象tokens和语言tokens之间的对比损失进行分类,的带Focal-ce-loss
网络输出有cls和box,其中:
- box通过匈牙利算法匹配gt,可计算L1 loss、GIOUloss和box regression
- 预测box对应的tokens与text tokens之间计算contrastive loss
3.3 完整流程
- 输入:(Image, Text)对;
- 默认输出900个目标框,每个框都与所有输入的单词计算相似度;
- 通过
box_threshhold
来过滤一部分框; - 通过
text_threshold
来选择相似度较高的单词作为标签;
注意:
- 句子中的单词数可能不等于最终标签的数量;
- 为了更好的区分类别,句子中的不同类别建议使用
.
分开。