RAM(recognize anything)—— 论文详解

一、概述

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.mzph.cn/news/116164.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

读书笔记:Effective C++ 2.0 版,条款43(多继承)、条款44(概念明确)、条款45-50(杂项)

条款43: 明智地使用多继承 并没有禁止,从概念上讲,多继承可能更符合真实世界。 条款44: 说你想说的;理解你所说的 概念明确 条款45: 弄清C在幕后为你所写、所调用的函数 隐性成本,看下编译后的c、asm源码。 条款46: 宁可编译和…

Java基础(第一期):IDEA的下载和安装(步骤图) 项目结构的介绍 项目、模块、类的创建。第一个代码的实现

文章目录 IDEA1.1 IDEA概述1.2 IDEA的下载和安装1.2.1 下载1.2.2 安装 1.3 IDEA中层级结构介绍1.3.1 结构分类1.3.2 结构介绍project(项目、工程)module(模块)package(包)class(类) …

安全渗透测试之信息收集

一、什么需要收集? 1.1 whois 得到域名注册人的信息(邮箱、电话、姓名) 1.2子域名 可以扩大攻击范围,子域名一定是有关联的,很多时候基本上都同属一个公司 1.3端口探测 危险端口能直接爆破入侵,一个IP能搭建多个网站,分布在不同端口 1.4目录扫描 目录扫描有时能…

【Javascript】等于与全等于

var a1;if(a1){console.log(你好!!);} 如果a赋值为 1 的时候 var a1;if(a1){console.log(你好!!);}仍然会执行 console.log(你好!!); 所以在开发中如果if语句里要使用等于的时候使用 var a1;if(a1)…

基于Java的疫苗接种管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding) 代码参考数据库参考源码获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…

图像分割 人脸分割CVPR2023笔记

目录 cvpr2023的分割 轻量级语义分割 DFNet ICNet BiSeNets 人脸分割: M2SNet创新点 损失函数: LossN

AM@麦克劳林公式逼近以及误差分析

abstract 麦克劳林公式及其近似表示的应用误差估计和分析 Lagrange型泰勒公式的估计误差 由Lagrange型余项泰勒公式可知,多项式 p n ( x ) p_n(x) pn​(x)近似表达函数 f ( x ) f(x) f(x)时,其误差为 ∣ R n ( x ) ∣ |R_{n}(x)| ∣Rn​(x)∣ R n ( x ) R_{n}(x) Rn​(x) f …

windows服务器和linux服务器的ssh免密登录失败的解决方案

1. windows服务器的ssh免密登录失效的解决方法 原因: 1. 去掉了C:\ProgramData\ssh\sshd_config文件中的两行配置,也就是注释掉: #Match Group administrators #AuthorizedKeysFile PROGRAMDATA/ssh/administrators_authorized_keys 2. aut…

LeetCode 11. 盛最多水的容器

盛水最多的容器 题目链接 11. 盛最多水的容器 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。…

2023 uniapp( vue3)使用canvas生成海报并保存,taro/微信小程序也适用

有段时间没写vue了&#xff0c;有点生疏了...... 1、代码有注释&#xff0c;完整代码如下 <template><view class"page"><canvas class"canvas" v-if"isShow" :style"{width:${canvasWidth}px,height:${canvasHeight}px}&…

spring cloud Eureka集群模式搭建(IDEA中运行)《二》

上一篇集群配置文件完善 上一篇博客&#xff0c;想必大家都学会了Eureka集群模式的搭建和运行&#xff0c;针对上一篇的配置文件进行了优化&#xff0c;在这里分享给大家。上一篇主要有3个配置文件&#xff0c;分别对应3个不同的服务&#xff0c;这种形式配置文件分别写在了不…

uni-app 小宠物 - 会说话的小鸟

在 template 中 <view class"container"><view class"external-shape"><view class"face-box"><view class"eye-box eye-left"><view class"eyeball-box eyeball-left"><span class"…

Learning Open-World Object Proposals without Learning to Classify(论文解析)

Learning Open-World Object Proposals without Learning to Classify 摘要1 介绍2 相关工作3 方法3.1 基线3.2 基于纯定位的对象性3.3. 对象定位网络 (OLN)4 实验4.1跨类泛化4.2.开放世界类不可知检测4.3更多的跨数据集泛化4.3.1 Objects365 泛化4.3.2 EpicKitchens 的泛化4.4…

LeetCode LCR 179. 查找总价格为目标值的两个商品

和为 s 的两个数字 题目链接 LCR 179. 查找总价格为目标值的两个商品 购物车内的商品价格按照升序记录于数组 price。请在购物车中找到两个商品的价格总和刚好是 target。若存在多种情况&#xff0c;返回任一结果即可。 示例 1&#xff1a; 输入&#xff1a;price [3, 9, 12, …

Hadoop3教程(三十六):(生产调优篇)企业开发场景中的参数调优案例概述

文章目录 &#xff08;170&#xff09;企业开发场景案例HDFS参数调优MapReduce参数调优YARN参数调优执行程序 参考文献 &#xff08;170&#xff09;企业开发场景案例 这章仅做兴趣了解即可。 需求&#xff1a;从1G数据中&#xff0c;统计每个单词出现次数。服务器3台&#x…

【通览一百个大模型】Baize(UCSD)

【通览一百个大模型】Baize&#xff08;UCSD&#xff09; 作者&#xff1a;王嘉宁&#xff0c;本文章内容为原创&#xff0c;仓库链接&#xff1a;https://github.com/wjn1996/LLMs-NLP-Algo 订阅专栏【大模型&NLP&算法】可获得博主多年积累的全部NLP、大模型和算法干货…

Delphi 编程实现拖动排序并输出到文档

介绍&#xff1a;实现拖动排序功能&#xff0c;并将排序后的内容输出到文档中。我们将使用 Delphi 的组件来创建一个界面&#xff0c;其中包括一个 Memo 控件用于输入内容&#xff0c;一个 ListBox 控件用于显示排序后的内容&#xff0c;并且提供按钮来触发排序和输出操作。 代…

常用Win32 API的简单介绍

目录 前言&#xff1a; 控制控制台程序窗口的指令&#xff1a; system函数&#xff1a; COORD函数&#xff1a; GetStdHandle函数&#xff1a; GetConsoleCursorInfo函数&#xff1a; CONSOLE_CURSOR_INFO函数&#xff1a; SetConsoleCursorInfo函数&#xff1a; SetC…

docker自动构建jar镜像,自动发布最新镜像的简单shell脚本

使用docker自动构建spring boot jar&#xff0c;自动发布最新镜像的简单shell脚本。一般在docker上部署流程问为&#xff1a; 构建docker镜像 -> 停止旧版本 -> 杀掉旧版本 -> 部署最新镜像。 1、maven/mvd/gradle 打包spring boot jar 2、编写Dockerfile&#xff0c…

读书笔记:Effective C++ 2.0 版,条款37(不要重新定义继承而来的非虚函数)、条款38(不重新定义继承而来的缺省参数值)

条款37: 决不要重新定义继承而来的非虚函数 非虚函数在编译期静态绑定&#xff0c;容易出错。 概念上也不合适。 任何条件下都要禁止重新定义继承而来的非虚函数。 条款38: 决不要重新定义继承而来的缺省参数值 继承一个有缺省参数值的虚函数。 虚函数是动态绑定而缺省参数值是…