YOLO-World:实时开放词汇目标检测
paper:https://arxiv.org/pdf/2401.17270.pdf
Github:GitHub - AILab-CVC/YOLO-World: Real-Time Open-Vocabulary Object Detection
online demo:https://huggingface.co/spaces/stevengrove/YOLO-World
目录
0. 摘要
1. 引言
2. 相关工作
2.1. 传统目标检测
2.2. 开放词汇目标检测
3. 方法
3.1. 预训练范式:区域-文本对
3.2. 模型架构
3.3. 重参数化视觉-语言 PAN
3.4. 预训练方案
4. 实验
5. 结论
0. 摘要
YOLO系列检测器以其高效、实用而著称。不过,其需要预定义目标类别,这大大限制了其在开放场景的适用性。为了解决这个问题,我们提出了YOLO-World——一个创新的、通过视觉-语言建模和大规模数据预训练的方法,其强化了YOLO的开放词汇检测能力。具体的,提出了一个新的可重参数化的视觉-语言路径聚合网络(RepVL-PAN),以及一个能够促进视觉和语言信息之间交互的区域-文本对比损失。提出的方法能够以零样本方式,在宽范围目标检测方面表现优异,且十分高效。在LVIS挑战赛数据集上,YOLO-World使用V100可达到35.4 AP、52FPS的效果,这在速度和精度上都超过了很多SOTA。此外,微调后的YOLO-World在很多下游任务(如:目标检测、开放词汇实例分割)上也能达到不错的效果。
1. 引言
目标检测是一个长期研究的基础CV任务,在诸多领域,如图像理解、机器人、自动驾驶,都有涉及。已有大量相关研究[15, 26, 40, 42]使用深度神经网络在该领域取得了突破。尽管他们都取得了成功,但都是在有限的类别(如coco里面是80个类)上进行的,一旦类别定义好且标注完毕,训练的检测器就只能检测指定的类别,这大大限制了他们在开放场景中的能力和应用。
最近的工作 [7, 12, 49, 54]。 ] 探索了流行的视觉语言模型 [18, 36],通过从语言编码器(例如 BERT [5])中提取词汇知识来解决开放词汇检测 [54]。然而,由于训练数据缺乏、词汇多样性有限,基于蒸馏的方法的使用大大受限了。部分方法[23,29,52,53,55]将目标检测训练重新定义为区域级视觉语言预训练,并大规模训练开放词汇对象检测器。然而,这些方法在现实场景中仍然难以应用,有两个方面的原因:(1)较高的计算负担;(2)边缘设备部署的复杂性。先前的一些工作[23,29,52,53,55]已经证实了预训练大检测器的性能,而为预训练小检测器赋予开发词汇检测能力方面尚未被证实。
本文提出了YOLO-World来进行高效开放词汇对象检测,并探索大规模预训练方案,将传统的 YOLO 检测器升级为开放词汇检测方法。与以前的方法相比,所提出的 YOLO-World 推理速度高且易于部署到下游应用程序中,非常的有效。具体来说,YOLO-World 遵循标准的 YOLO 架构 [19],并利用预训练的 CLIP [36] 文本编码器对输入文本进行编码。我们进一步提出了可重新参数化的视觉语言路径聚合网络(RepVL-PAN)来连接文本特征和图像特征以获得更好的视觉语义表示。在推理过程中,可以去掉文本编码器,并将文本嵌入重新参数化为 RepVL-PAN 的权重以实现高效部署。我们通过大规模数据集上的区域-文本对比学习进一步研究了YOLO检测器的开放词汇预训练方案,将检测数据、标注数据和图像-文本数据统一为区域-文本对。具有丰富区域-文本对的预训练 YOLO-World 在大规模词汇检测和训练更多数据方面表现出强大的能力,可以显着提高开放词汇能力。
此外,我们探索了一种“提示然后检测”(prompt-then-detect)的范式,以进一步提高现实场景中开放词汇对象检测的效率。如图 2 所示,传统的目标检测器 [15, 19, 22, 38-40, 48] 专注于具有预定义和训练类别的固定词汇表(闭集)检测。而以前的开放词汇检测器[23,29,52,55]则使用文本编码器对用户的提示进行编码,并检测对象进行在线词汇表。不过,这些方法倾向于使用大主干的大型检测器,例如 Swin-L [31],以增加开放词汇容量。相比之下,prompt-then-detect 范式(图 2 (c))首先对用户的提示进行编码以构建离线词汇表,词汇表因不同需求而异。然后,高效的检测器可以动态推断离线词汇表,而无需重新编码提示。对于实际应用,一旦我们训练好了检测器,就可以预先编码提示或类别以构建离线词汇表,然后将其无缝集成到检测器中。
主要贡献有以下几点:
- 介绍了YOLO-World,其属于一种高端的开放词汇目标检测器,在实际使用中比较高效;
- 提出了可重参数化的视觉-语言PAN,将视觉和语言特征与YOLO-World的开放词汇区域-文本对比预训练方案结合了起来;
- 所提出的在大规模数据集上训练的 YOLO-World 表现出强大的零样本性能,并在 LVIS 上以 52.0 FPS 实现了 35.4 AP。预训练的 YOLO-World 可以轻松适应下游任务,例如开放词汇实例分割和参考对象检测。
2. 相关工作
2.1. 传统目标检测
流行的对象检测研究集中于固定词汇表(闭集)检测,其中对象检测器在具有预定义类别的数据集上进行训练,例如COCO数据集[25]和Objects365数据集[43],然后检测固定类别集合中的对象。在过去的几十年里,传统的目标检测方法可以简单地分为三组,即基于区域的方法、基于像素的方法和基于查询的方法。基于区域的方法 [10, 11, 15, 26, 41],例如 Faster R-CNN [41],采用两阶段框架进行提案生成 [41] 和 RoI-wise(感兴趣区域)分类和回归。基于像素的方法[27,30,39,45,57]往往是一级检测器,它对预定义的锚点或像素进行分类和回归。DETR[1]首先通过transformer[46]探索目标检测,并启发了广泛的基于查询的方法[60]。在推理速度方面,Redmon等人提出了YOLOs[37-39],它利用简单的卷积架构进行实时目标检测。一些工作[9,22,32,48,51]提出了YOLO的各种架构或设计,包括路径聚合网络[28]、跨阶段部分网络[47]和重新参数化[6],进一步提高了速度和准确性。与之前的 YOLO 相比,本文中的 YOLOWorld 旨在以强大的泛化能力检测固定词汇表之外的对象。
2.2. 开放词汇目标检测
开放词汇对象检测 (OVD) [54] 已成为现代目标检测的新趋势,旨在检测预定义类别之外的对象。早期的工作[12]通过在基类上训练检测器并评估新的(未知)类,遵循标准的OVD设置[54]。然而,这种开放词汇设置可以评估检测器检测和识别新对象的能力,对于开放场景仍然受到限制,并且由于在有限的数据集和词汇上进行训练,缺乏对其他领域的泛化能力。
受视觉语言预训练[18,36]的启发,最近的研究[7,21,49,58,59]将开放词汇对象检测表述为图像-文本匹配,并利用大规模图像-文本数据大规模增加训练词汇。GLIP [23] 提出了一种基于短语接地的开放词汇检测预训练框架,并在零样本设置中进行评估。接地DINO[29]将接地的预训练[23]合并到具有跨模态融合的检测transformer[56]中。
几种方法[24,52,53,55]通过区域-文本匹配和大规模图像-文本对的预训练检测器统一检测数据集和图像-文本数据集,取得了良好的性能和泛化能力。然而,这些方法通常使用 ATSS [57] 或 DINO [56] 等重检测器和 Swin-L [31] 作为主干,导致高计算需求和部署挑战。相比之下,我们提出了 YOLO-World,旨在通过实时推理和更容易的下游应用程序部署进行有效的开放词汇对象检测。我们的方法与 ZSD-YOLO [50] 不同,ZSD-YOLO [50] 还通过语言模型对齐探索了 YOLO 的开放词汇检测 [54],而YOLO-World 引入了一种新颖的 YOLO 框架,具有有效的预训练策略,提高了开放词汇性能和泛化能力。
3. 方法
3.1. 预训练范式:区域-文本对
传统的目标检测方法,包括YOLO系列[19],使用实例注释,由边界框{Bi}和类别标签{ci}组成。在本文中,我们将实例注释重新表述为区域-文本对
,其中 ti 是区域 Bi 的相应文本。具体来说,文本 ti 可以是类别名称、名词短语或对象描述。此外,YOLO-World 采用图像 I 和文本 T(一组名词)作为输入并输出预测框
和对应的目标嵌入
。
3.2. 模型架构
所提出的 YOLO-World 的整体架构如图 3 所示,它由一个 YOLO 检测器、一个文本编码器和一个可重新参数化的视觉语言路径聚合网络 (RepVL-PAN) 组成。给定输入文本,YOLO-World 中的文本编码器将文本编码为文本嵌入。YOLO检测器中的图像编码器从输入图像中提取多尺度特征。然后我们使用 RepVL-PAN 通过利用图像特征和文本嵌入之间的跨模态融合来增强文本和图像表示。
YOLO Detector:YOLO-World主要基于YOLOv8[19]开发,YOLOv8[19]包含一个Darknet骨干[19,40]作为图像编码器,一个用于多尺度特征金字塔的路径聚合网络(PAN),一个用于边界框回归和对象嵌入的head。
Text Encoder:给定文本 T,我们采用 CLIP [36] 预训练的 Transformer 文本编码器来提取相应的文本嵌入,其中 C 是名词的数量,D 是嵌入维度。与纯文本语言编码器 [5] 相比,CLIP 文本编码器为将视觉对象与文本连接起来提供了更好的视觉语义能力。当输入文本是一个标题或引用表达式时,我们采用简单的 n-gram 算法来提取名词短语,然后将它们输入文本编码器。
Text Contrastive Head:继之前的工作 [19] 之后,我们采用具有两个 3×3 convs 的解耦头来回归边界框 和对象嵌入
,其中 K 表示对象的数量。我们提出了一个文本对比头来获得对象-文本相似度
:
其中 L2-Norm(·) 是 L2 归一化,是第 j 个文本嵌入。此外,我们添加了具有可学习比例因子α和移位因子β的仿射变换。L2 范数和仿射变换对于稳定区域文本训练都很重要。
Training with Online Vocabulary:在训练期间,我们为每个包含 4 张图像的马赛克样本构建了一个在线词汇表 T。具体来说,我们对马赛克图像中涉及的所有正名词进行采样,并从相应的数据集中随机采样一些负名词。每个马赛克样本的词汇表最多包含 M个,M 默认设置为 80。
Inference with Offline Vocabulary:在推理阶段,我们提出了一种带有离线词汇表的prompt-then-detect 策略,以提高效率。如图3所示,用户可以定义一系列自定义提示,可能包括标题或类别。然后,我们利用文本编码器对这些提示进行编码并获得离线词汇嵌入。离线词汇表避免了每个输入都计算一遍,并能根据需要灵活调整词汇表。
3.3. 重参数化视觉-语言 PAN
图 4 显示了所提出的 RepVL-PAN 的结构,它遵循 [19, 28] 中的自上而下和自下而上的路径,以使用多尺度图像特征 {C3, C4, C5} 建立特征金字塔 {P3, P4, P5}。此外,我们提出了文本引导的CSPLayer (T-CSPLayer)和图像池注意(I-Pooling Attention),进一步增强了图像特征和文本特征之间的交互,提高了开放词汇能力的视觉语义表示。在推理过程中,离线词汇嵌入可以重新参数化为卷积或线性层的权重以进行部署。
Text-guided CSPLayer:如图4所示,自顶向下或自底向上融合后利用跨阶段部分层(CSPLayer)。我们通过将文本引导合并到多尺度图像特征中来扩展[19]的CSPLayer(也称为C2f),以形成文本引导的CSPLayer。具体来说,给定文本嵌入 W 和图像特征,我们在最后一个dark bottleneck块之后采用 max-sigmoid attention 将文本特征聚合为图像特征:
其中更新后的 与跨阶段特征连接作为输出。δ 表示 sigmoid 函数。
Image-Pooling Attention:为了用图像感知信息增强文本嵌入,我们提出 Image-Pooling Attention来聚合图像特征以更新文本嵌入。我们没有直接在图像特征上使用交叉注意,而是利用多尺度特征上的最大池化来获得3 × 3区域,总共有27个patch tokens。然后文本嵌入通过以下方式更新:
3.4. 预训练方案
在本节中,我们将介绍在大规模检测、grounding和图像文本数据集上进行YOLO-World 预训练的方案。
Learning from Region-Text Contrastive Loss:给定马赛克样本 I 和文本 T,YOLO-World 输出 K 个对象预测 以及注释
。我们遵循 [19] 并利用任务对齐的标签分配 [8] 将预测与基本事实注释进行匹配,并将每个正预测与文本索引分配为分类标签。基于这个词汇表,我们通过对象-文本(区域-文本)相似性和对象-文本分配之间的交叉熵构建区域-文本对比损失 Lcon。此外,我们采用 IoU 损失和分布式焦点损失进行边界框回归,总训练损失定义为:
,其中 λI 是一个指标因子,当输入图像 I 来自检测或grounding数据时设置为 1,当它来自图像文本数据时设置为 0。考虑到图像-文本数据集有噪声框,我们只计算具有精确边界框的样本的回归损失。
Pseudo Labeling with Image-Text Data:我们提出了一种自动标记方法来生成区域-文本对,而不是直接使用图像-文本对进行预训练。具体来说,标记方法包括三个步骤:(1)提取名词短语:我们首先利用 n-gram 算法从文本中提取名词短语; (2) 伪标记:我们采用预训练的开放词汇检测器,例如 GLIP [23],为每个图像生成给定名词短语的伪框,从而提供粗略的区域-文本对。(3)过滤:我们使用预训练的 CLIP [36] 来评估图像-文本对和区域-文本对的相关性,并过滤低相关性的伪注释和图像。我们通过结合非最大抑制 (NMS) 等方法进一步过滤冗余边界框。我们建议读者参阅附录以获得详细的方法。通过上述方法,我们使用 821k 伪注释从 CC3M [44] 中采样和标记 246k 图像。
4. 实验
5. 结论
我们提出了 YOLO-World,这是一种尖端的实时开放词汇检测器,旨在提高实际应用中的效率和开放词汇能力。在本文中,我们将流行的 YOLO 重塑为视觉语言 YOLO 架构,用于开放词汇预训练和检测,并提出了 RepVL-PAN,它将视觉和语言信息与网络连接起来,并且可以重新参数化以实现高效的部署。我们进一步提出了检测、接地和图像文本数据的有效预训练方案,使YOLOWorld具有较强的开放词汇检测能力。实验证明了 YOLO-World 在速度和开放词汇性能方面的优越性,并表明视觉语言预训练在小模型的有效性,这对未来的研究有见地。我们希望 YOLO-World 可以作为解决现实世界开放词汇检测的新基准。
相关文章:

YOLO-World:实时开放词汇目标检测
paper:https://arxiv.org/pdf/2401.17270.pdf Github:GitHub - AILab-CVC/YOLO-World: Real-Time Open-Vocabulary Object Detection online demo:https://huggingface.co/spaces/stevengrove/YOLO-World 目录 0. 摘要 1. 引言 2. 相关工…...
Unity中关于群组的一些组件
前言 在游戏开发环境中,UI组件是构建玩家交互界面的基础。以下是一些常见UI组件的详细解释和它们适用的场景,方便我们更好地理解和使用这些工具。 1. Graphic Raycaster Graphic Raycaster组件是游戏UI交互的核心。在Unity等游戏引擎中,当玩…...

面向对象详解,面向对象的三大特征:封装、继承、多态
文章目录 一、面向对象与面向过程1、什么是面向过程?2、什么是面向对象? 二、类与对象1. 初识对象2. 类的成员方法2.1 类的定义和使用2.2 成员方法 3. 类和对象4. 魔法方法1. _ _ inint _ _ 构造方法2. _ _ str _ _ 字符串方法3. _ _ lt _ _ 小于符号比较…...

【阿里云服务器的一些使用坑】都是无知的泪水呀
发生了什么? 我想学习一下关于Java的MySQL、Nginx 相关的知识。然后就用首次优惠注册的阿里云,都没有搞清楚实例,镜像,带宽,磁盘。然后。因为一不小心——我想去换一个Ubuntu的镜像而不是CentOS。就把实例给释放啊。之…...
Docker的常用命令||Docker是个流行的容器化平台,它允许你打包、分发和运行应用程序。
Docker是一个流行的容器化平台,它允许你打包、分发和运行应用程序。以下是一些常用的Docker命令及其示例用法: 1. **docker run**: 用于运行一个新的容器实例。 docker run <image_name> 例如,运行一个Nginx容器: docker ru…...

汽车电子论文学习--电动汽车电机驱动系统动力学特性分析
关键重点: 1. 汽车的低速转矩存在最大限制,受附着力限制,因路面不同而变化。 2. 起步加速至规定转速的时间可以计算得到: 3. 电机额定功率的计算方式: 可以采取最高设计车速90%或120km/h匀速行驶的功率作为电机额定功…...

c++的一些陌生用法记录
c的一些陌生用法记录 1. 完美转发std::forward<decltype(PH1)>(PH1)static的用法 1. 完美转发std::forward<decltype(PH1)>(PH1) static的用法 static函数与普通函数的区别: 用static修饰的函数,本限定在本源码文件中,不能被本源…...

Vue | (三)使用Vue脚手架(中)| 尚硅谷Vue2.0+Vue3.0全套教程
文章目录 📚Todo-list 案例🐇组件化编码流程(通用)🐇实现静态组件🐇展示动态数据🐇交互⭐️添加一个todo⭐️todo勾选实现⭐️删除功能实现⭐️底部统计功能实现⭐️底部全选功能实现⭐️底部一…...

TenorFlow多层感知机识别手写体
文章目录 数据准备建立模型建立输入层 x建立隐藏层h1建立隐藏层h2建立输出层 定义训练方式建立训练数据label真实值 placeholder定义loss function选择optimizer 定义评估模型的准确率计算每一项数据是否正确预测将计算预测正确结果,加总平均 开始训练画出误差执行结…...

Java基础(二十六):Java8 Stream流及Optional类
Java基础系列文章 Java基础(一):语言概述 Java基础(二):原码、反码、补码及进制之间的运算 Java基础(三):数据类型与进制 Java基础(四):逻辑运算符和位运算符 Java基础(五):流程控制语句 Java基础(六)࿱…...

qt - 19种精美软件样式
qt - 19种精美软件样式 一、效果演示二、核心程序三、下载链接 一、效果演示 二、核心程序 #include "mainwindow.h"#include <QtAdvancedStylesheet.h> #include <QmlStyleUrlInterceptor.h>#include "ui_mainwindow.h" #include <QDir&g…...
vue 使用docx库生成word表格文档
在Vue.js中生成Word表格文档,可以通过前端库来实现。这些库可以帮助我们轻松地将HTML表格转换为Word文档(通常是.docx格式)。以下是一些流行的前端库,它们可以用于在Vue项目中生成Word表格文档: docx…...

ElementUI table表格组件实现双击编辑单元格失去焦点还原,支持多单元格
在使用ElementUI table表格组件时有时需要双击单元格显示编辑状态,失去焦点时还原表格显示。 实现思路: 在数据中增加isFocus:false.控制是否显示在table中用cell-dblclick双击方法 先看效果: 上源码:在表格模板中用scope.row…...

Java基于SpringBoot+Vue的图书管理系统
博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…...
【云安全】Hypervisor与虚拟机
Hypervisor 也被称为虚拟机监视器(Virtual Machine Monitor,VMM),主要作用是让多个操作系统可以在同一台物理机上运行。 Type-1 Hypervisor 与 Typer-2 Hypervisor Type-1 Hypervisor 直接安装在物理服务器上,不依赖…...

JS文本加密方法探究
在前端开发中,有时候我们需要对敏感文本进行简单的加密,以提高安全性。本文将介绍一种基于 JavaScript 实现的文本加密方法,使用了 Base64、Unicode 和 ROT13 编码。 示例代码 function encodeText(text) {// Base64编码var base64Encoded …...

推荐彩虹知识付费商城免授权7.0源码
彩虹知识付费商城免授权7.0源码,最低配置环境 PHP7.2 1、上传源码到网站根目录,导入数据库文件:xydai.sql 2、修改数据库配置文件:/config.php 3、后台:/admin 账号:admin 密码:123456 4、前…...

【天衍系列 04】深入理解Flink的ElasticsearchSink组件:实时数据流如何无缝地流向Elasticsearch
文章目录 01 Elasticsearch Sink 基础概念02 Elasticsearch Sink 工作原理03 Elasticsearch Sink 核心组件04 Elasticsearch Sink 配置参数05 Elasticsearch Sink 依赖管理06 Elasticsearch Sink 初阶实战07 Elasticsearch Sink 进阶实战7.1 包结构 & 项目配置项目配置appl…...

一、ActiveMQ介绍
ActiveMQ介绍 一、JMS1.jms介绍2.jms消息传递模式3.JMS编码总体架构 二、消息中间件三、ActiveMQ介绍1.引入的原因1.1 原因1.2 遇到的问题1.3 解决思路 2.定义3.特点3.1 异步处理3.2 应用系统之间解耦3.3 实际-整体架构 4.作用 一、JMS 1.jms介绍 jms是java消息服务接口规范&…...
【牛客】寒假训练营1 I-It‘s bertrand paradox. Again! 题解
传送门:It’s bertrand paradox. Again! 标签:随机 题目大意 有两个人分别用两种方式在二维平面上随机生成1e5个圆,每个圆上的每一个点(x,y)都满足-100<x<100且-100<y<100,现在将某个人生成的1e5个圆的圆心和半径告…...

无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

算法打卡第18天
从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...
信息系统分析与设计复习
2024试卷 单选题(20) 1、在一个聊天系统(类似ChatGPT)中,属于控制类的是()。 A. 话语者类 B.聊天文字输入界面类 C. 聊天主题辨别类 D. 聊天历史类 解析 B-C-E备选架构中分析类分为边界类、控制类和实体类。 边界…...

分布式光纤声振传感技术原理与瑞利散射机制解析
分布式光纤传感技术(Distributed Fiber Optic Sensing,简称DFOS)作为近年来迅速发展的新型感知手段,已广泛应用于边界安防、油气管道监测、结构健康诊断、地震探测等领域。其子类技术——分布式光纤声振传感(Distribut…...

Electron通信流程
前言 今天讲Electron框架的通信流程,首先我们需要知道为什么需要通信。这得益于Electron的多进程模型,它主要模仿chrome的多进程模型如下图: 作为应用开发者,我们将控制两种类型的进程:主进程和渲染器进程 。 …...

Kotlin REPL初探
文章目录 1. Kotlin REPL 简介2. 在命令行中玩Kotlin REPL2.1 下载Kotlin编译器压缩包2.2 安装配置Kotlin编译器2.3 启动Kotlin交互式环境2.4 在命令行玩Kotlin REPL 3. 在IDEA里玩Kotlin REPL3.1 打开Kotlin REPL窗口3.2 在Kotlin REPL窗口玩代码 4. Kotlin REPL 的优势 1. Ko…...
css | class中 ‘.‘ 和 ‘:‘ 的使用 | 如,何时用 .is-selected{ ... } 何时用 :hover{...}?
省流总结:交互时的短暂视觉反馈 → 用 :hover,状态需要记录或切换 → 用类名如 .is-selected。 🧠 本质区别: 写法触发方式用途&.is-selected依赖 class 切换需要 JavaScript 控制状态,如选中、激活&:hover鼠…...