当前位置:   article > 正文

RAM - 识别一切,强大的图像标记模型_recognize anything: a strong image tagging model

recognize anything: a strong image tagging model

Recognize Anything: A Strong Image Tagging Model

https://arxiv.org/abs/2306.03514

CVPR 2023, OPPO Research

在这里插入图片描述

是啥


RAM 是一个 Image Tagging 模型,定义如下:

Image Tagging: 图像标注(Image Tagging)是一种识别和描述图像内容的技术。它通过自动化标注或标记图像中的对象、场景、情感等元素,以便于图像的管理、分类、搜索和检索。
一般来说,图像标注可以分为两个主要的步骤:目标检测和目标识别。目标检测是指在图像中检测出所有的对象或场景,而目标识别则是指对这些对象或场景进行识别和描述。
图像标注可以应用于许多应用领域,例如图像搜索引擎、图像分类、自然语言处理、人机交互等。在图像搜索引擎中,用户可以使用文本或者图像来搜索相似的图像。在图像分类中,可以使用图像标注来自动分类图像。在自然语言处理中,可以将图像标注作为输入,用于生成自然语言描述。在人机交互中,可以使用图像标注来帮助计算机理解人类的需求和意图。
最近,随着深度学习技术的发展,图像标注技术已经取得了重大进展。许多深度学习模型已经被用于目标检测和目标识别,并取得了很好的效果。

RAM 包含四个步骤

  1. 通过自动文本语义解析获得无注释图像的标签
  2. 基于第一步获得的数据训练一个初版模型
  3. 清洗错误数据,生成图像的额外信息
  4. 最后使用高质量小规模数据集进行微调

在 zero-shot 任务上超过现有的 CLIP 和 BLIP,且比 Google Tagging API 效果还好

算法&模型架构


在这里插入图片描述

整体架构

上图为整体的架构图,包含了三个模块

Image Encoder: 为 SwinTransformer,用来提取图像的特征

Image-Tag Recognition Decoder: 为 Bert 模型,接收图像特征和 Label 特征,输出图像 Tags

Image-Tag-Text Encoder-Decoder: 为 Bert 模型,接受图像特征和 Tag,输出图像描述 Caption, Text

整个架构在运行的时候,用到了图片的 tag 和 text,不同的模型之间通过 embedding 建立起了关联关系。

此外图上还有一个预训练的 CLIP 模型,它只作为外部模块,提供 label 的 embedding 信息,这样做带来了 zero-shot 的能力,接下来会讲到

Open-Vocabulary Recognition

关键的改进在于将语义信息嵌入到了 Recognition Decoder 中,从而有助于在训练过程中泛化到之前没有见过的类别。

嵌入语义信息的方法则是使用了预训练 CLIP 来编码标签列表中的每个标签,从而为文本标签的查询提供丰富的上下文语义。而之前的方法使用的是随机编码,从而缺少泛化性,这样描述可能比较抽象,来看看代码

假设我要识别 [”dog”, “cat”] 两个没见过的类别,在 openset_utils.py 中的代码就会变成如下

# 伪代码
def build_openset_label_embedding():
    categories = ["dog", "cat"]
    model, _ = clip.load("ViT-B/16")
    templates = multiple_templates
    
    template = "a photo of {}"
    openset_label_embedding = []
    for category in categories:
        texts = [template.format(category)]
        texts = clip.tokenize(texts)
        text_embeddings = model.encode_text(texts)
        ......
        openset_label_embedding.append(text_embeddings)
     openset_label_embedding = torch.stack(openset_label_embedding, dim=1)
     return openset_label_embedding, categories
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

随后在推断中就会利用这两个 embedding 特征并输出分类或其他下游任务的结果

训练


训练环节: RAM 在分辨率 224 的大规模数据集上进行预训练,然后使用小型且高质量的数据集在 384 分辨率模型上进行微调,实验表明 RAM 收敛迅速,通常只需要 5 个 epoch 便可收敛,这种收敛特性有助于提高计算资源限制下复现 RAM 的可能性,例如,在400w图片上预训练模型耗时一天,最大的 RAM 模型在 1400w 图片预训练耗时 3 天,GPU 用的是 8 快 A100。

推断环节: 轻量级的 image-tag 识别解码器能够有效的提升 RAM 的推断效率,并且识别解码器中还去除了自监督模块,运行速度又有进一步的提升。

数据集


训练集

筛选训练时使用的标签,遵循下面三个指导原则

  1. 频繁出现的 Image-Tag 比图像描述更有价值
  2. 应该在 Tag 中表示各种领域和上下文,如对象,场景,属性和动作
  3. 标签的数量需要适度,否则标注成本会很高

先用 SceneGraphParser 对 1400w 句子处理后转换成标签,从出现频率最高的前 1w 标签中手动进行筛选,选择有意覆盖了分类,检测和分割等许多流行数据集中存在的标签,如下图所示

在这里插入图片描述

部分标签是使用商用 API 在开源的图片上获得,最终 RAM 可以识别高达 6449 固定标签,比 Tag2Text 多的多,为减少冗余,通过各种方法收集同义词(参考 WordNet 的方法),整理后标签系统中包含 4585 个标签 ID

因为大部分数据都爬取自互联网,所以会存在很多缺失和错误的标签,为了环节这个问题,作者做了以下工作。

**生成:**用上面初筛的数据,先训练一个基础模型,然后使用这个基础模型对数据进行打标,并把原标注和模型标注组合在一起,这一步操作后,在 400W 这个数据集上,标签数量从 1200w 扩展到 3980w 个。

**清理:**为了解决不正确标签的问题,先使用目标检测模型(DINO)识别出类别的区域,然后对类别区域进行聚类,删除重合区间小于 90% 的标签(这段话没看明白,原文是 To address the issue of incorrect tags, we initially employ Grounding-Dino [29] to identify and crop regions corresponding to a specific category within all images. Subsequently, we cluster the regions from this category based on K-Means++ [4] and eliminate the tags associated with the outlier 10%.)同时还使用分类模型识别图像区域的类别,删除不存在的类别。

测试集:

OpenImages-common:从原 OpenImages V6 数据集中筛选到的高质量子数据集,有 214 个标签

OpenImages-rare: 同上,但是 200 个标签在 RAM 训练时不存在

OPPO-common: 内部高质量的测试集

ADE20k-clean: 清除了 ADE20k 上小目标和类别模糊的数据

在这里插入图片描述

效果评估


目的:验证 Zero Shot 的性能
评估指标

使用 mAP,对于没有 mAP 的模型,则使用 Precision/Recall 指标,并且会调整获得最佳阈值
在这里插入图片描述
绿色底是监督学习,蓝色底是 zero-shot,黄色底训练时见过图片但没见过标签,指标为 mAP

与分类模型比较,RAM 在多个任务和指标上都超过 ML-Decoder 和 Tag2Text,例如,RAM 在 OpenImages-common 上的 Zero Shot 的指标是超过监督训练获得 ML-Decoder 模型。

在这里插入图片描述

与检测和分割任务比较,指标为 Precision / Recall,这里我没太明白计算 PR 的逻辑,但从给出的指标来看,RAM 也表现出了良好的泛化性。

与视觉语言模型比较,RAM 比 CLIP, BLIP 在 OPPO-common,OpenImages-common 两个数据集上指标都要高出 20% 左右。但在 OpenImages-rare 上是不如 CLIP, BLIP 的,一个可能的原因是因为训练数据集没他们的大而且并没有专门针对不常见的数据集进行优化。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/709358
推荐阅读
相关标签
  

闽ICP备14008679号