RAM(recognize anything)—— 论文详解

news/2024/7/21 6:32:16 标签: 图像处理, transformer, 人工智能, 深度学习

一、概述

1、是什么

    RAM 论文全称 Recognize Anything: A Strong Image Tagging Model。区别于图像领域常见的分类、检测、分割,他是标记任务——即多标签分类任务(一张图片命中一个类别),区分于分类(一张图片命中一个类别)。然后他这里提到的anything,需要注意,模型本身原始支持6449个标签(去掉同义词后4585个标签),但是可以通过后面提到的一些方法实现未知的标签(6449以外)识别。

    如下是原生支持的6449个标签(去掉同义词后4585个标签)的官方地址,需要注意其中英文和中文是一一对应的,都是4585组。

    原生支持的中文标签:https://github.com/xinyu1205/recognize-anything/blob/main/ram/data/ram_tag_list_chinese.txt

    原生支持的英文标签:https://github.com/xinyu1205/recognize-anything/blob/main/ram/data/ram_tag_list.txt

2、亮点

1)强大的图片标记能力和zero-shot泛化识别能力;

2)可较低成本复现,使用的都是开源和免人工标记的数据集,最强版本的RAM也只需要8卡A100训练3天;

3)灵活并且可以满足各种应用场景:可以单独使用作为标记系统;也可以结合Grounding DINO 和SAM 多标签分割。

3、对比Tag2Text的提升

准确性更高。RAM利用数据引擎生成额外的注释并清除不正确的标记,与Tag2Text相比具有更高的准确性。(详见后面的数据处理部分。)

标记类别数更多。RAM将固定标签的数量从3,400个升级到6,400个(同义减少到4,500个不同的语义标签),涵盖了更有价值的类别。此外,RAM具有开集能力,可以识别训练中未看到的标签。

PS

这篇来自OPPO的论文,写的相对真的很详细,有任何细节疑问可以参考论文,论文中不含的细节也在本博客末尾写到作为后续待解决项。

二、模型

    1、模型结构

    PS:关于模型,由于官方没有释放训练的代码,对比推理代码和论文,也发现了有不一致的地方(后面描述),所以这里只是描述目前能看到的和推测到的,不一定准确。

    论文中提到,SAM 只保留了(Tag2Text )的 Tagging 和 Generation 两个:

    *主干的image Encoder 使用了swin-transformer, 有两个版本,swin-b 和 swin-l ;

    *Tagging 分支用来多tags推理,完成识别任务;使用的是BIRT(代码里是BIRT,论文里说是2 层的transformer);

    *Generation分支用来做 image caption任务encoder-decoder使用的是12 层的transformer

    *Alignment 分支是做 Visual-Language Features学习的,在这里被移除了。

    *这里还涉及两个离线模型:一个是CLIP(又涉及到image encoder 和 Text encoder,后面介绍),一个是SceneGraphParser (OPPO 官方修改过)。

    2、训练过程

    PS:这里抛开数据处理过程的训练细节,主要将住进程;这里的更多细节目前官方并未开源,所以也只能大概。

    注意:

    1)训练过程没有上图右侧的CLIP Text Encoder。N个类别对应N个textual label queries——也就是可学习的参数,假设论文4585个类,每个类768维度表示,那么就是4585*768。

    2)训练输入是三个元素:图片-Tag-文本构成,对应网络的一个输入(图像,文本输入不算,是网络自己的可学习参数)+ 2个输出(文本描述和多标签分类)。损失也就是常见的文本生成损失+多标签ASL损失。

    3)image-Tag-interaction encoder 的文本输入是label 解析的Tag,不是模型的输出(推理时是模型的输出)

    4)训练过程的某个节点(论文没有详细说)使用了CLIP image encoder 的输出进行蒸馏(distill)RAM 自己的image encoder。(这个我的理解是潜在对齐了CLIP Text encoder ,才更好的实现了后面推理阶段的open set 的识别。)

    3、推理过程

    分为两种,第一种就是模型本身支持的类别的推理;第二种是模型不支持(当然支持的类别也可以使用这种方式)的open set 的推理。推理过程是开源了的。

    第一种,模型支持的类别。

    * 这里不需要文本输入,只需要输入图片即可。

    * 对应的代码为:https://github.com/xinyu1205/recognize-anything/blob/main/inference_ram.py

    * 需要先查看是否有自己的类目,

        中文:https://github.com/xinyu1205/recognize-anything/blob/main/ram/data/ram_tag_list_chinese.txt 

        英文:https://github.com/xinyu1205/recognize-anything/blob/main/ram/data/ram_tag_list.txt

        对应的阈值:https://github.com/xinyu1205/recognize-anything/blob/main/ram/data/ram_tag_list_threshold.txt

    * 当前版本231020,如果大量调用建议修改源代码,因为会重复的读取模型权重:https://github.com/xinyu1205/recognize-anything/blob/main/ram/models/ram.py#L170

    

    第二种,模型不支持的类别(open set)。

    * 这里需要提前输入自己想要的类别+图片。自己想要的类别参考这个进行填充:https://github.com/xinyu1205/recognize-anything/blob/main/ram/utils/openset_utils.py#L91 

    * 原理:这里其实是模型里的queries 可学习输入给换掉了,换成了CLIP 的编码。CLIP 的编码方式是使用了一组模板:https://github.com/xinyu1205/recognize-anything/blob/main/ram/utils/openset_utils.py#L24 把自己想要的单词编码成了句子,然后离线的算出每个模板的CLIP Text encoder 的输出特征向量,然后进行求平均来当做这个单词的特征表示,然后其他地方不变得到这个类别的得分。这里说一下另一点就是在训练过程中作者也特别实用了CLIP 的image encoder 进行蒸馏 RAM 的image encoder ,这其实相当于为这里的open set 使用CLIP Text encoder 作了文本和图片的特征对齐,作者的实验也显示提高了模型的性能。

    

    4、消融经验

    1)两个分支训练提升了模型的Tag分之的能力。

    2)开发集合识别主要依靠CLIP,并没有提升闭集的能力(???跟训练本来就无关啊)

    3)提升标签的类别对已有类影响较小(有影响,因为提升了训练难度),但是可以提升开放识别的能力,增强了模型的覆盖范围。

三、数据

    1、数据标签

    参考来源:

    1)开源的学术数据集(分类、检测、分割)。

    2)商业已有的API(谷歌、微软、苹果)

    指导原则:

    1)高频出现,代表更有价值。

    2)标签包括:对象、场景、属性、动作(行为),这提升了模型的泛化能力(复杂、未知场景)。

    3)标签的数量需要适中,过多会导致严重的标注成本。

    数量:

    1)使用修改后的SceneGraph-Parser 解析1400W预训练句子。

    2)手工从top-1W 高频Tag 中选取6449个Tag。

    3)通过多种手段(手工检查、参考WordNet、翻译等)合并同义词汇到同一个ID,最后变为4585个Tag。

    PS:RAM 覆盖 OpenImages 和 ImageNet 较少,原因是里面很多Tag比较不常见,比如ImageNet 很多鸟的细类。

    

    2、数据构成

    一共两个版本的数据4 Millon和14 Millon,分别对应训练了两个参数量的模型swin-b和swin-l。

    1)4M:2个人工标注数据集,COCO(113K 图像、557K 描述)、Visual Genome(101K 图像、822K 描述);2个大规模互联网数据集 Conceptual Captions  (3M 图像, 3M 描述) and SBU

Captions (849K 图像, 849K 描述)。

    2)14M:4M 基础上增加 Conceptual 12M  (10M 图像, 10M 描述)

    3、数据清洗

    原因:来自网络的图像文本对本质上是嘈杂的,通常包含缺失或不正确的标签。为了提高注释的质量,我们设计了一个标记数据引擎。

    解决丢失的标签。使用一部分数据训练一个base model,然后使用这个model将剩余数据进行打标,然后混合原始标注和生成的标注进行扩充,本文4M image 的tag 12M -> 39.8M。

    解决多余的标签。我们首先使用Grounding-Dino定位与图像中不同标签对应的特定区域,随后:

    1)我们采用区域聚类技术( K-Means++)来识别和消除同一类中的异常值(最外部的10%)(使用的特征来源和聚类数未做说明);

    2)我们过滤掉在整个图像及其相应区域之间表现出相反预测的标签(使用base model 对裁切区域进行推理,如果没有预测出对应的tag 进行删除)(整图有的标签、裁切区域更应该被识别到),确保更清晰和更准确的注释。

    预估平均一个tag 也有1W图片。

    4、消融结果

    1)在12.0M到41.7M范围内添加更多的标签,可以显著提高所有测试集的模型性能,说明原始数据集存在严重的标签缺失问题。

    2)进一步清理某些类别的标签会导致OPPO-common和OpenImages-common测试集上的性能略有提高。受GroundingDino推理速度的限制,我们只对534个类别进行清洗处理。

    3)将训练图像从4M扩展到14M,在所有测试集上都有显著的改进。

    4)使用更大的骨干网络会导致openimages的性能略有改善——在常见类别上的性能很少甚至略差。我们将这种现象归因于我们进行超参数搜索的可用资源不足。

    5)对从COCO Caption数据集解析的标签进行微调,在OPPO-common和7OpenImages-common测试集上显示出显著的性能提高。(COCOCaption数据集为每个图像提供了五个描述性句子,提供了一个全面的描述,近似于一组完整的标签标签。)

四、策略

1、训练过程

参考数据清洗流程,整个训练过程如下

1)通过自动文本语义解析在大规模数据上获得无标注的图像标签。

2)使用原始文本和解析后的标记训练第一版模型。

3)一个数据引擎用于生成额外的注释和清理不正确的(参考数据清洗小结)。

4)使用更小但更高质量的数据集处理数据并进行模型微调。

五、结果

1、多维度对比。

对比分割模型SAM,标记模型Tag2Text等,多模态模型CLIP、BLIP等,主要从定位能力和识别精度和类别数上如下

2、标记能力对比。

RAM提供更精确(精度)、更多(召回&覆盖范围)的结果。

    *RAM展示了令人印象深刻的zero-shot性能,明显优于CLIP和BLIP。

    *RAM甚至超过了完全监督的方式(ML-Decoder)。

    *RAM表现出与Google标签API相当的性能。

3、测试集对比

六、使用方法

TRANSFORMERS_OFFLINE=1 python inference_ram.py --image images/1641173_2291260800.jpg --pretrained pretrained/ram_swin_large_14m.pth

七、待解决

1、聚类的内容是什么?图像特征?

2、训练代码,描述分支网络的结果。

八、参考链接

GitHub - xinyu1205/recognize-anything: Code for the Recognize Anything Model (RAM) and Tag2Text Model

Recognize Anything: A Strong Image Tagging Model

识别一切模型RAM(Recognize Anything Model)及其前身 Tag2Text 论文解读 - 知乎

https://arxiv.org/pdf/2306.03514.pdf

https://github.com/xinyu1205/recognize-anything/blob/main/ram/utils/openset_utils.py#L293

ASL: 多标签分类之非对称损失-Asymmetric Loss_asl loss-CSDN博客


http://www.niftyadmin.cn/n/5114940.html

相关文章

主从复制1

第一章: xtrabackup安装包下载 第二章: 全量备份主库数据在从库还原主库的数据 第三章: 主从复制关系配置 3.1、 my.cnf配置文件(标准文档生产可直接用) 第一章:xtrabackup安装包下载 使用背景&#xf…

让小脚本成为自己高效测试的工具

测试中会遇到的工具 软件测试如果仅仅靠手工去执行会发现在很多地方力不从心,虽然市面上已经有大牛开源了一些测试工具可以供我们使用但是在一些公司特有的业务方面则需要我们借助开源或重新做一个自己的测试工具。 测试常用的开源工具 死链接检测工具 Xenu home…

数据类型与SQL语句

针对记录的SQL语句 记录:表中的一行一行的数据称之为是一条记录 # 需要先有库、在有表、最后操作记录 id name age gender 1 kevin 20 male 1、查看记录 select * from t1; # 查所有 2、增加数据 insert into t1 values(1, kevin, 20); # 第一种方式&#xf…

k8s-----14、controller-Job和Cronjob

Job和Cronjob 1、Job(一次性任务)2、CronJob(定时任务) 1、Job(一次性任务) [rootmaster controlleryaml]# cat job.yaml apiVersion: batch/v1 kind: Job metadata:name: pi spec:template:spec:contain…

JVM工具使用(jstat + jmap)

命令格式 jstat -gcutil pid interval(ms) 举例: jstat -gcutil 16361 1000 线上服务器的GC情况如下: 参数说明如下: S0: 新生代中Survivor space 0区已使用空间的百分比S1: 新生代中Survivor space 1区已使用空间的百分比E: 新生代已使用空…

通义千问-7B-Chat-8-9 离线整合包 使用 4bit 运行的代码

通义千问-7B-Chat-8-9 离线整合包 使用 4bit 运行的代码;离线包自己去下载,把app.py 文件改成下面的,然后记得安装一个 bitsandbytes 的window 版本, 安装命令放在最后了 import os #os.system(pip install tiktoken) #os.system(pip install "modelscope" --upg…

深度学习模型不确定性方法对比

©PaperWeekly 原创 作者|崔克楠 学校|上海交通大学博士生 研究方向|异构信息网络、推荐系统 本文以 NeurIPS 2019 的 Can You Trust Your Model’s Uncertainty? Evaluating Predictive Uncertainty Under Dataset Shift 论文为主线…

Kotlin中的Set集合

在Kotlin中,Set集合用于存储一组唯一的元素,它们是无序的,不可重复的。Set集合分为可变集合(MutableSet)和不可变集合(Set)。本篇博客将分别介绍可变集合和不可变集合,并提供相关的A…