如何计算CLS

821801c099d94be4d92827741df2a397.png

如何计算CLS

累积布局偏移 (CLS,Cumulative Layout Shift) 是测量视觉稳定性的一个以用户为中心的重要指标,因为该项指标有助于量化用户经历意外布局偏移的频率,较低的 CLS 给用户呈现的效果是交互流程自然、没有延迟和卡顿。

指标说明

CLS 测量整个页面生命周期内发生的所有意外布局偏移量中最大一连串的布局偏移分数。每当一个可见元素的位置从一个已渲染帧变更到下一个已渲染帧时,就发生了布局偏移 。更多信息,请参见布局偏移分数。

CLS 分数如何计算?

浏览器在计算布局偏移分数时,会查看可视区域大小和两个已渲染帧之间的可视区域中不稳定元素的位移。CLS分数是该位移的两个度量的乘积:影响分数和距离分数(两者定义如下)。

CLS分数 = 影响分数 * 距离分数

影响分数

影响分数测量不稳定元素对两帧之间的可视区域产生的影响。前一帧和当前帧的所有不稳定元素的可见区域集合(占总可视区域的部分)就是当前帧的影响分数。51775af787e7d0e4e41f7372ae2b7fd5.png

在上图中,有一个元素在一帧中占据了一半的可视区域。接着,在下一帧中,元素下移了可视区域高度的 25%。红色虚线矩形框表示两帧中元素的可见区域集合,在本示例中,该集合占总可视区域的 75%,因此其影响分数为0.75 。

距离分数

CLS分数计算公式的另一部分测量不稳定元素相对于可视区域位移的距离。距离分数指的是任何不稳定元素在一帧中位移的最大距离(水平或垂直)除以可视区域的最大尺寸维度(宽度或高度,以较大者为准)。412029d20f8a6400dab64e481553e63c.png

在上方的示例中,最大的可视区域尺寸维度是高度,不稳定元素的位移距离为可视区域高度的 25%,因此距离分数为 0.25。所以,在这个示例中,影响分数是0.75 ,距离分数是0.25 ,所以CLS分数是0.75 * 0.25 = 0.1875 。

最初,CLS分数只根据影响分数进行计算。引入距离分数是为了避免在大元素发生微小位移的情况下进行过度惩罚的情况。

预期布局偏移 vs. 意外布局偏移

布局偏移并不总是坏事。事实上,许多动态网络应用程序经常更改页面元素的起始位置。

由用户发起的布局偏移

布局偏移只有在用户并不期望其发生时才算是坏事。换言之,对用户交互(单击链接、点选按钮、在搜索框中键入信息等)进行响应的布局偏移通常没有问题,前提是偏移发生的时机与交互时机足够接近,使用户对前后关系一目了然。

例如,如果某次用户交互触发了一个网络请求,而该请求可能需要一段时间才能完成,那么最好立即留出一些空间并显示加载指示器,避免在请求完成时出现令用户不快的布局偏移。如果用户没有意识到当前正在加载某些内容,或者不知道资源什么时候能够准备就绪,他们就可能会在等待期间尝试单击其他内容(来打破僵局)。在用户输入 500 毫秒内发生的布局偏移会带有hadRecentInput标志,便于在计算中排除这些偏移。

注意:hadRecentInput标志仅适用于不连续输入事件,如轻触、点击或按键操作。滚动、拖动或捏拉缩放手势等连续性交互操作不算作"最近输入"。详情请参见布局不稳定性规范。

怎样算是良好的 CLS 分数?

为了提供良好的用户体验,网站应该将 CLS 分数控制在0.1 或以下。为了确保您能够在大部分用户的访问期间达成建议目标值,一个良好的测量阈值为页面加载的第 75 个百分位数,且该阈值同时适用于移动和桌面设备。4143ccc3f5dc1b3b6eb78f86ccce708e.png

指标获取实现细节

Layout Shift 是由 Layout Instability API 定义的,当视图中可见的元素在两个帧之间改变其起始位置时,该API就会报告布局偏移项。这些元素被认为是不稳定元素。

创建一个 PerformanceObserver ,使用 Layout Instability API 来监听意外的布局变化。

let clsValue = 0;
let clsEntries = [];
let sessionValue = 0;
let sessionEntries = [];
new PerformanceObserver((entryList) => {
    for (const entry of entryList.getEntries()) {
        // Only count layout shifts without recent user input.
        if (!entry.hadRecentInput) {
            const firstSessionEntry = sessionEntries[0];
            const lastSessionEntry = sessionEntries[sessionEntries.length - 1];
        // If the entry occurred less than 1 second after the previous entry and      
        // less than 5 seconds after the first entry in the session, include the      
        // entry in the current session. Otherwise, start a new session.  
         if (sessionValue
         && entry.startTime - lastSessionEntry.startTime < 1000
         && entry.startTime - firstSessionEntry.startTime < 5000) {
             sessionValue += entry.value;
             sessionEntries.push(entry);
          } else {
              sessionValue = entry.value;
              sessionEntries = [entry];
           }
           // If the current session value is larger than the current CLS value
           // update CLS and the entries contributing to it.
           if (sessionValue > clsValue) {
               clsValue = sessionValue;
               clsEntries = sessionEntries;
               // Log the updated value (and its entries) to the console. 
               console.log('CLS:', clsValue, clsEntries)
           }
       }
}}).observe({type: 'layout-shift', buffered: true});javascript
<think>嗯,用户想了解Vision Transformer(ViT)中的CLS概念,特别是CLS token的用途和使用方法。首先,我需要回顾一下ViT的基本结构。ViT将图像分成多个patch,这些patch经过线性嵌入后加上位置编码,形成序列输入,类似于Transformer在NLP中的应用。在NLP中,通常会在序列开头添加一个特殊的分类token(如BERT的[CLS]),用于聚合整个序列的信息,最终用于分类任务。ViT借鉴了这一设计,所以CLS token应该也是类似的用途。 接下来,我需要详细说明CLS token的作用。首先,作为全局特征聚合器,因为自注意力机制可以让CLS token与其他所有patch token交互,从而捕获全局信息。其次,作为分类头输入,因为ViT通常将CLS token的输出作为最终的分类特征,后面接一个MLP头进行分类。另外,可能还需要提到位置无关的特性,因为CLS token本身没有位置信息,但通过位置编码学习到位置信息。 用户可能还关心CLS token的实现细节,比如如何初始化和训练。在ViT中,CLS token通常是一个可学习的向量,随机初始化后与patch embeddings一起输入到Transformer层中。通过多层的自注意力机制,CLS token逐步聚合全局信息。训练过程中,梯度通过分类损失反向传播,更新CLS token的参数,使其能够有效捕捉有用的特征。 另外,可能需要对比其他方法,比如使用全局平均池化(GAP)。ViT选择CLS token而不是GAP,可能是因为自注意力机制能更灵活地聚合信息,而GAP可能丢失空间结构信息。同时,CLS token的设计与NLP中的做法一致,保持了结构的一致性。 还要注意引用用户提供的参考资料。用户给出的引用[1]提到MobileViT在计算成本和性能上的优势,但其中也提到了ViT变体的比较。虽然CLS token的具体细节可能在原始ViT论文中,但可以结合引用中的内容,比如泛化能力和计算效率,来补充说明CLS token如何帮助模型保持高效和鲁棒。 最后,生成相关问题时要围绕ViT的结构、CLS token的作用、与其他方法的对比,以及实际应用中的考虑因素。比如,如何初始化CLS token,为什么不用GAP,训练中的注意事项,以及在不同任务中的应用等。</think>### Vision Transformer (ViT) 中CLS token的作用与设计原理 在Vision Transformer(ViT)中,**CLS token**(分类标记)是一个关键设计,用于全局特征聚合和分类任务。其核心作用与实现方式如下: --- #### 1. **CLS token的核心作用** - **全局特征聚合** CLS token作为输入序列的第一个标记(位于所有图像块patch token之前),通过多层自注意力机制与所有patch token交互,最终输出包含全局图像信息的表示。例如,在ViT中,输入序列为: $$ \text{[CLS], } x_1, x_2, \dots, x_N $$ 其中$x_i$为图像块嵌入,CLS token的输出向量将用于分类任务[^1]。 - **分类头输入** 训练时,**仅使用CLS token的输出向量**作为分类特征,后接多层感知机(MLP)完成分类。这一设计避免了传统CNN中全局平均池化(GAP)可能丢失空间信息的缺陷。 - **位置无关性** CLS token本身不携带图像块的位置信息,但通过与patch token的交互学习到全局上下文,同时依赖位置编码保留空间关系。 --- #### 2. **CLS token的实现细节** - **初始化与训练** CLS token是一个可学习的向量,随机初始化后与patch embeddings一起输入Transformer编码器。例如,在ViT-B/16模型中,CLS token的维度与其他patch token相同(如768维),通过梯度下降优化其参数。 - **自注意力机制中的角色** 在每一层Transformer中,CLS token通过多头自注意力(Multi-Head Self-Attention)与所有patch token交互,逐步整合局部与全局信息。计算过程可表示为: $$ \text{Attention}(Q_{\text{CLS}}, K, V) = \text{softmax}\left(\frac{Q_{\text{CLS}}K^T}{\sqrt{d}}\right)V $$ 其中$Q_{\text{CLS}}$是CLS token的查询向量,$K$和$V$为所有token的键和值矩阵。 - **对比全局平均池化(GAP)** ViT选择CLS token而非GAP,因为自注意力能更灵活地捕捉长程依赖,而GAP可能削弱重要区域的特征(如小目标或边缘)。 --- #### 3. **CLS token的实际效果** - **高效的特征表示** 实验表明,CLS token的输出向量在ImageNet-1k分类任务中优于GAP,例如ViT-B/16的top-1准确率达77.9%,而类似架构的CNN模型需更多参数才能达到相近性能。 - **迁移学习适应性** 在目标检测、分割等下游任务中,CLS token的全局特征可作为补充信息,与中间层patch特征结合使用。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值