【论文阅读--实时语义分割】PIDNet: A Real-time Semantic Segmentation Network Inspired from PID Controller

论文链接https://arxiv.org/pdf/2206.02066.pdf
githubhttps://github.com/XuJiacong/PIDNet

摘要

双分支网络结构已显示出其对实时语义分割任务的效率性和有效性。然而,低级细节和高级语义的直接融合将导致细节特征容易被周围上下文信息淹没,即本文中的超调 (overshoot),这限制了现有两个分支模型的准确性的提高。
在本文中,我们在卷积神经网络(CNN)和比例积分微分(PID)控制器之间架起了桥梁,并揭示了双分支网络只是一个比例积分(PI)控制器,当然也会存在类似的超调问题。为了解决这个问题,我们提出了一种新的三分支网络架构:PIDNet,它具有三个分支来分别解析细节、上下文和边界信息(语义的派生),并在最后阶段使用边界注意来指导细节和上下文分支的融合
PIDNets系列在推理速度和准确性之间实现了最佳平衡,其测试精度超过了Cityscapes、CamVid和COCO Stuff数据集上具有相似推理速度的所有现有模型。特别是,PIDNet-S在Cityscapes测试集上以93.2 FPS的推理速度实现了78.6%的mIOU,在CamVid测试集上则以153.7 FPS的速度实现了80.1%的mIOO。

1 Introduction

【PID概念引入网络结构】
比例积分微分(PID)控制器是上个世纪提出的传统概念,已广泛应用于现代动态系统或过程,如机器人操纵、化学过程、电力系统。尽管近年来已经开发了许多具有更好控制性能的先进控制策略,但由于其简单但鲁棒的特性,PID控制器仍然是大多数工业应用的首选。一个科学领域的经典概念可以扩展到许多其他领域。例如,PID控制器的基本方法被引入到图像去噪、随机梯度下降和数值优化中,并实现了对原始方法的极大改进。在本文中,我们通过采用PID控制器的基本概念,为实时语义分割任务设计了一个深度神经网络架构,该新模型的性能超过了所有先前的网络,从而实现了推理速度和准确性之间的最佳权衡,如图1所示。
在这里插入图片描述
【语义分割的现状】
语义分割是视觉场景分析的基本任务,其目标是为给定图像中的每个像素分配特定的类标签。随着智能需求的逐渐增加,准确的语义分割已成为许多应用的基本感知组件,如自动驾驶、医学图像诊断和遥感图像。从FCN开始,深度学习方法在语义分割领域逐渐占据主导地位,并提出了许多具有代表性的模型。这些学习模型的发展表明,具有不错分割性能的网络架构必须具有在不丢失重要细节信息的情同时具有大规模学习像素之间的上下文相关性的能力。尽管这些模型实现了令人惊喜的分割精度,但牺牲了太多的空间和时间复杂性,这严重限制了它们在实时情况下的应用,如自动驾驶汽车和机器人辅助手术。

【实时语义分割的方法】
为了满足实时或移动需求,研究人员提出了许多高效和有效的模型。

  • ENet 通过采用轻量级解码器并在早期阶段对特征图进行下采样,大大提高了推理速度。
    ICNet 在复杂而深的路径中对小尺寸输入进行编码,以解析语义,并利用简单而浅的路径对大尺寸输入的细节进行编码。
    MobileNetv2 用深度可分离卷积代替了传统卷积,以降低整体模型复杂度,并提出了一种反向残差块来缓解正则化效应;
  • 这些早期的工作对减少分割模型的延迟和内存使用做出了巨大贡献,但它们的低精度显著限制了它们的实际应用。
    最近,提出了一些 基于双分支网络的出色模型,并在速度和准确性方面取得了最先进的性能。
  • 本文提出 三分支网络 。在本文中,我们从PID控制器的角度深入分析了两分支网络的基本架构,并指出两分支网络只是一个PI控制器,并且固有的存在超调问题,如图2所示。为了解决这个问题,我们建立了一种新的三分支网络结构,即比例积分微分网络(PIDNet),它具有一个用于边界检测的分支。然后,我们在Cityscape[13]、CamVid[5]和COCOStuf[6]基准上比较了PIDNet与其他最先进模型的性能,以证明其优越性。此外,还提供了消融研究和特征可视化,以更好地理解每个详细模块的功能。可通过以下方式访问代码和预训练模型:https://github.com/XuJiacong/PIDNet
    在这里插入图片描述
    图2. 动态系统(左|)和图像分割(右|)的超调问题。左|:二阶系统的PI和PID控制器的阶跃响应;|右:第一行为标签,第二行为DDRNet-23输出,第三行为ADB-Bag-DDRNet-23(我们的)的输出。

本文的主要贡献有三个方面:

  • 我们在深度学习模型与PID控制器之间架起了桥梁,并提出了一个基于PID控制器架构的三分支网络家族。
  • 提出了基于选择性学习的连接、快速上下文聚合模块和边界引导融合模块,以提高PIDNets的性能
  • 我们的模型在所有现有模型中实现了推理速度和准确性之间的最佳权衡。特别是,在没有加速工具的Cityscapes测试集上,PIDNet-S以93.2 FPS的速度实现了78.6%的mIOU,PIDNet-L以31.1 FPS的速度达到了80.6%的mIOU(实时域最高)。

2 Related Work

由于实时和普通情况下的网络设计理念截然不同,因此我们简要介绍了这两种情况下的一些代表性架构。


2.1 高精度语义分割

用于语义分割的大多数早期深度学习方法基于编码器-解码器架构,其中编码器通过级联跨步卷积或池化操作逐渐扩大其感受野,解码器使用反卷积或上采样从高级语义中恢复详细信息。然而,在编码器-解码器网络的下采样过程中,空间细节很容易被忽略。针对这个问题,提出了扩张卷积,它可以在不降低空间分辨率的情况下扩大视野。基于此,

  • DeepLab系列通过在网络中集成具有不同膨胀率的扩张卷积,实现了对先前工作的巨大改进。DeepLabs的一个关键问题是,由于其大量非连续内存访问,扩展卷积不适合当前硬件。为了缓解这个问题,后续的方法做了改进
  • PSPNet 引入了金字塔池模块(PPM)来解析多尺度上下文信息,
  • HRNet 采用多路径和双边连接来学习和融合不同的尺度表示。
  • 受机器翻译中自我注意机制[46]的上下文聚合能力的启发,非局部操作[48]被引入到计算机视觉中,并引发了许多有意义的语义分割工作[18,24,54]。

2.2 实时语义分割

为了实现推理速度和准确性之间的最佳权衡,研究人员付出了大量努力来重新设计网络架构,可以概括为:轻量级编码器和解码器(卷积因子分解或群卷积)、多尺度输入和双分支网络。具体而言,

  • SwiftNet 使用一个低分辨率输入来获得高级语义,使用另一个高分辨率输入来为其轻量级解码器提供足够的细节。
  • DFANet 通过修改Xception的架构引入了一种轻量级主干,该架构基于深度方向可分离卷积,并减小了输入大小以加快推理速度。
  • ShuffleSeg 采用了ShuffleNet作为其主干,其结合了信道混洗和组卷积,以降低计算成本。

然后以上的方式存在的问题:

  • 1 这些网络中的大多数仍然是编码器-解码器架构的形式,需要信息流通过深度编码器,然后反向返回以通过解码器,这为这些模型引入了很多延迟。
  • 2 由于GPU上深度可分离卷积的优化尚不成熟,因此传统卷积呈现出更快的速度,即使它具有更多FLOP和参数。

2.3 双分支网络结构

正如前几节所讨论的,上下文依赖性可以通过大的感受野来提取,空间细节对于精确的边界描绘和小范围物体识别至关重要。于是

  • BiSeNet 提出了一种双分支网络架构,该架构包含两个具有不同深度的分支,用于【上下文嵌入】和【细节解析】,以及用于融合上下文和细节信息的【特征融合模块(FFM)】。然后,基于该架构的一些方法被提出,以提高其表示能力或降低模型复杂性。
  • DDRNet 引入了双边连接,以增强上下文和细节分支之间的信息交换,并达到了实时语义分割的优秀的结果。

然而,在DDRNet中,细节分支的输出大小是上下文分支的8倍(BiSeNet中的4倍),它们的直接融合将不可避免地导致一种现象:对象边界很容易被周围像素腐蚀,小规模对象可能被其相邻的大对象淹没,即本文中的超调,如图2所示。为了缓解超调问题,我们借鉴了自动化工程领域的PID概念,并提出了一种三分支网络架构:PIDNet,它这简单地补充了用于边界提取的附加分支,并利用边界来监督上下文和详细特征的融合。

3 Method

PID控制器包含三个具有互补功能的组件:比例(P)控制器表示当前误差,积分(I)控制器累积先前误差,微分(D)控制器预测未来误差变化,如图3所示。因此,PID控制器的输出是基于整个时域中的误差产生的。通常,PI控制器可以满足大多数设定点控制场景,但它固有地存在超调问题。为了获得更好的动态响应,研究人员引入了微分控制器,在超调发生之前进行预测并调整控制输出。
在双分支网络中,上下文分支通过级联跨步卷积或池化层不断地从局部到全局聚集语义信息,以解析像素之间的长距离依赖关系,而细节分支保持高分辨率特征图,以保存每个单独像素的语义和定位信息。因此,细节和上下文分支可以被视为空间域中的比例和积分控制器,这解释了分割超调问题的根本原因。
在这里插入图片描述
图3。PID控制器与双支路网络结构的相似性。TBN表示双分支网络,ADB是我们建议的辅助衍生分支。P\I\D 分别指 细节分支、上下文分支和边界分支


3.1 PIDNet:一种新型的三分支网络

【辅助微分分支(ADB)】
为了缓解超调问题,我们建议为两分支网络提供辅助微分分支(ADB),并在空间域中完全模拟PID控制器。每个对象内部像素的语义是一致的,并且仅在相邻对象的边界上变得不一致,因此语义的微分仅在对象边界处是非零的,ADB的功能应是边界检测。因此,我们建立了一个新的三分支实时语义分割架构,即比例积分微分网络(PIDNet),如图4所示。PIDNet拥有三个具有互补职责的分支:

  • 比例(P)分支解析并保存其高分辨率特征图中的详细信息;
  • 积分(I)分支本地和全局聚合上下文信息以解析长程依赖关系;
  • 微分(D)分支提取高频特征以预测边界区域。

整个网络按照[22]进行开发,采用级联残差作为主干,以实现硬件友好的架构。此外,考虑到相应任务的复杂性,P\I\D分支的深度被安排为中等、深和浅,以便高效运行。此外,通过加深和扩展模型,生成了一系列PIDNets(PIDNet-S、PIDNet-M和PIDNet-L)。
在这里插入图片描述
图4。我们提出的比例积分微分网络(PIDNet)的基本架构概述。S和B表示语义和边界,Add和Up分别表示按元素求和和双线性上采样操作;BAS损失表示边界感知CE损失。虚线和关联块将在推理阶段被忽略。

【辅助微分分支(ADB)】
与[22, 29, 50]相似,与我们在第一个Pag模块的输出处放置一个语义头,以生成额外的语义损失 l 0 l_0 l0,从而更好地优化整个网络。采用加权二元交叉熵损失 l 1 l_1 l1 代替dice loss[14], 来处理边界检测的不平衡问题,因为粗糙边界更适合突出边界区域并增强小对象的特征。 l 2 l_2 l2 l 3 l_3 l3 表示CE损失,而我们利用边界头的输出来协调语义分割和边界检测任务,并增强Bag模块的功能,将边界感知CE损失[45]用于 l 3 l_3 l3 l 3 = − ∑ i , c { 1 : b i > t } ( s i , c l o g s i , c ^ ) l_{3}= -\sum_{i,c}\{1:b_i>t\}(s_{i,c}log\hat{s_{i,c}}) l3=i,c{1:bi>t}(si,clogsi,c^) 其中 t t t表示预定义阈值, b i b_i bi s i , c s_{i,c} si,c s i , c s_{i,c} si,c 分别是 c c c 类第 i i i 个像素的边界头、语义分割真实标签和预测结果的输出。因此,PIDNet的最终损失可概括为: L o s s = λ 0 l 0 + λ 1 l 1 + λ 2 l 2 + λ 3 l 3 Loss=\lambda_{0} l_0+\lambda_{1} l_1+\lambda_{2} l_2+\lambda_{3} l_3 Loss=λ0l0+λ1l1+λ2l2+λ3l3根据经验,我们把PIDNet训练损失的参数设置为 λ 0 λ_0 λ0=0.4、 λ 1 λ_1 λ1=20、 λ 2 λ_2 λ2=1、 λ 3 λ_3 λ3=1和 t t t=0.8。


3.2 Pag: 选择性学习高级语义

在这里插入图片描述
图5. 侧面连接的Pag模块图示。Sum是指沿通道的元素总和;σ表示Sigmoid函数的输出;Up用于双线性上采样。

[22,34,47]中使用的横向连接 增强了不同特征图之间的信息传输,并提高了其模型的表示能力。在PIDNet中,I分支 提供的丰富而准确的语义信息,对于包含相对较少的层和通道的 P分支 的细节解析至关重要。因此,我们可以将 I分支视为其他两个分支的备份,并使其能够向它们提供所需的信息。与直接添加所提供的特征图的 D分支不同,我们为P分支引入了像素注意力引导融合模块(Pag),如图5所示,以选择性地从I分支学习有用的语义特征,而不会被淹没。基本上,Pag的基本概念借鉴自注意力机制。将P分支和I分支提供的特征图中对应像素的矢量分别定义为 v p → \overrightarrow{v_p} vp v i → \overrightarrow{v_i} vi ,则Sigmoid函数的输出将变为: σ = S i g m o i d ( f p ( v p → ) ⋅ f i ( v i → ) ) \sigma =Sigmoid(f_p(\overrightarrow{v_p} )\cdot f_i(\overrightarrow{v_i})) σ=Sigmoid(fp(vp )fi(vi ))其中 σ σ σ表示这两个像素来自同一对象的可能性。如果σ较高,我们更信任 v i → \overrightarrow{v_i} vi ,因为I分支在语义上是准确的,反之亦然。因此,Pag模块的输出可以写成: O u t P a g = σ v i → + ( 1 − σ ) v p → Out_{Pag}=\sigma \overrightarrow{v_{i}}+(1-\sigma)\overrightarrow{v_{p}} OutPag=σvi +(1σ)vp


3.3 PAPPM:上下文的快速聚合

为了更好地构建全局场景:

  • SwiftNet[34]中采用了空间金字塔池(SPP)[20]来解析全局相关性。
  • PSPNet[57]引入了金字塔池模块(PPM),它在卷积层之前连接多尺度池映射,以形成局部和全局上下文表示。
  • [22]提出的深度聚合PPM(DAPPM)进一步提高了PPM的上下文嵌入能力,并显示出优异的性能。
    然而,DAPPM的计算不能就其深度进行并行化,这非常耗时,并且每个尺度的DAPPM包含太多通道,这超过了轻量级模型的表示能力。

因此我们提出PAPPM。稍微改变了DAPPM中的连接使其并行化,如图6下图所示,并将每个比例的通道数从128个减少到96个。这个新的上下文获取模块被称为并行聚合PPM(PAPPM),并应用于PIDNet-M和PIDNet-S以提高其速度。对于我们的深度模型:PIDNet-L,我们仍然选择考虑深度的DAPPM,但将每个比例的通道数从128更改为112。
在这里插入图片描述


3.4. Bag:平衡细节和上下文

在这里插入图片描述
图7. Bag(a) 和Light-Bag(b) 的结构。P/I/D 分别指细节分支、上下文分支和边界分支的输出。 σ σ σ 表示Sigmoid函数的输出

考虑到 ADB 提取的边界特征,我们的建议是利用边界注意力来指导 [详细§] 和 [上下文(I)] 表示的融合。因此,我们设计了一个边界注意力引导融合模块(Bag)来融合三个分支提供的特征。注意,上下文分支语义丰富,可以提供更准确的语义,但它丢失了太多的空间和几何细节,特别是对于边界区域和小对象。由于细节分支更好地保留了空间细节,我们迫使模型沿着边界区域更加信任细节分支,并利用上下文特征填充对象内部的区域,这可以通过图7中的Bag实现。将P、I和D分支输出中对应像素的矢量分别定义为 v p → \overrightarrow{v_p} vp v i → \overrightarrow{v_i} vi v d → \overrightarrow{v_d} vd ,然后Sigmoid、Bag 和 Light-Bag 的输出可以表示为: σ = S i g m o i d ( v d → ) \sigma =Sigmoid(\overrightarrow{v_d}) σ=Sigmoid(vd ) O u t b a g = f o u t ( ( 1 − σ ) ⊗ v i → + σ ⊗ v p → ) Out_{bag}=f_{out}((1-\sigma )\otimes \overrightarrow{v_i}+\sigma \otimes \overrightarrow{v_p}) Outbag=fout((1σ)vi +σvp ) O u t l i g h t = f p ( ( 1 − σ ) ⊗ v i → + v p → ) + f i ( σ ⊗ v p → + v i → ) Out_{light}=f_{p}((1-\sigma )\otimes \overrightarrow{v_i} + \overrightarrow{v_p}) + f_{i}(\sigma \otimes \overrightarrow{v_p}+\overrightarrow{v_i}) Outlight=fp((1σ)vi +vp )+fi(σvp +vi )
其中 f f f表示卷积、批归一化和ReLU的组成。尽管我们将Bag中的3×3卷积替换为LightBag中两个1×1卷积,但Bag和LightBag的功能是相似的,即当 σ σ σ>0.5时,模型更依赖于细节特征,否则优先考虑上下文信息。

4 Experiment

为了验证我们提出的方法的优越性,我们在Cityscapes、CamVid和COCO Stuff基准数据集上训练我们的模型,并将其测试精度和推理速度与其他最先进的实时网络进行比较。


4.1 数据集

  • Cityscapes。Cityscapes是最知名的城市场景解析数据集之一,其中包含从不同城市的汽车视角收集的5000幅精细注释图像。这些图像被分成2975、500和1525个组,用于训练、验证和测试。注释包含30个类,但只有19个用于语义分割。所有数据的图像大小为2048×1024,这对于实时分割来说具有挑战性。在这里,我们只使用精细注释的数据集来训练我们的模型,以便与其他网络进行公平比较。
  • CamVid。CamVid提供了701张驾驶场景的图像,这些图像被划分为367、101和233张,用于训练、验证和测试。图像分辨率为960×720,注释类别数为32,其中11个类别用于语义分割。为了与其他像素进行公平比较,忽略了这11个类以外的像素。
  • COCO-Stuff。我们选择了COCOStuff 数据集的10K版本,该数据集也在[22,50]中被利用。该数据集由10K张密集注释图像组成,分为9K张用于训练,1K张用于测试。COCO Stuff的复杂类别对于每个分割模型都是挑战性的,其中包括91个事物和91个Stuff类。

4.2 实施细节

  • 预训练。在三个数据集上训练我们的模型之前,我们首先通过ImageNet对这些模型进行预处理,因为预处理对于[22,34]中的横向连接至关重要。我们删除了D分支,并在最后阶段遵循与DDRNet[22]相同的合并方法来构建分类模型。训练轮次是90,初始学习率设置为0.1,并在第30轮和第60轮乘以0.1。CE损失、动量为0.9、权重衰减为1e−4的SGD用于优化网络。图像被随机裁剪成224×224,并水平翻转以进行数据增强。
  • 训练。为了公平比较,我们的训练方案与之前的工作几乎相同[16,22,50,51]。具体来说,
    • 我们采用多学习率策略来更新每次迭代中的学习率。
    • 随机裁剪、随机水平翻转和[0.5,2.0]范围内的随机缩放用于数据增强。
    • 每个数据集的训练周期数、初始学习率、权重衰减、裁剪大小和批量大小可分别设置为
      Cityscapes:[484、1e−2、5e−4、1024×1024、12]
      CamVid:[200、1e–3、5e–4、960×720、12]
      COCO Stuff:[180、5e-3、1e-4、640×640、16]
      在[22,50]之后,我们对Cityscapes为CamVid预训练的模型进行微调,并提前停止训练过程,以避免过度拟合。
  • 推理。在测试集上进行评估之前,我们的模型由Cityscapes和CamVid的训练集和验证集进行训练。我们在由单个RTX 3090、PyTorch 1.8、CUDA 11.2、cuDNN 8.0和Anaconda环境组成的平台上测量推理速度。使用[11]和[22,34,44]提出的速度测量协议,我们将批次归一化集成到卷积层中,并分别将Cityscapes、CamVid和COCO Stuff的批次大小设置为1,输入图像大小设置为2048×1024、960×720和640×640。

4.3 消融实验

  • ADB的两个分支网络。为了证明ADB的有效性,我们从PIDNet借用了ADB和Bag,并将其与现有模型相结合。这里,实现了两个具有代表性的两个分支网络:具有ADB和Bag的 BiSeNet 和 DDRNet,与它们的原始模型相比,它们在Cityscapes数据集上实现了更高的精度,如表1所示。然而,额外的计算大大降低了它们的推理速度,从而引发我们建立PIDNet。
    在这里插入图片描述
  • Pag和Bag的配合使用。按元素求和是在横向连接中合并特征的传统方法。我们为P分支提供了Pag模块,以帮助它从I分支学习有用的信息,而不是直接将特征图相加。此外,引入了Bag模块,以指导在最后阶段使用边界关注融合细节和上下文特征。如表2所示,横向连接可以显著提高模型精度,预训练可以进一步提高其性能。在我们的场景中,Add横向连接和Bag融合模块或Pag横向连接和Add融合模块的组合意义不大,因为整个网络中的细节保存应该一致。因此,我们只需比较Add-Add和Pag-Bag的性能,表2和表3中的实验结果证明了Pag和Bag(或Light Bag)协作的优越性。图8中的特征图可视化显示,与第二个Pag的Sigmoid图中的大对象相比,小对象变得更暗,其中I分支丢失了更详细的信息。此外,Bag模块的输出大大增强了边界区域和小物体的特征,如图9所示,并解释了我们选择粗边界检测的原因。
    在这里插入图片描述
    在这里插入图片描述
  • PAPPM的效率。对于实时模型,沉重的上下文聚合模块可能会大大降低推理速度,并可能超过网络的表示能力。因此,我们提出了由并行结构和少量参数构成的PAPPM。表3中的实验结果表明,PAPPM实现了与DAPPM相同的精度,但对于我们的轻量级模型,其速度提高了9.5FPS。
  • 额外损失的有效性。PIDNet引入了三个额外的损失,以促进整个网络的优化,并强调每个组件的功能。根据表4,边界损失l1和边界感知损失l3是PIDNet更好性能所必需的,尤其是边界损失(.1%mIOU),这有力地证明了D分支的必要性,在线硬示例挖掘(OHEM)[42]进一步提高了准确性
    在这里插入图片描述

4.4. 对比

  • CamVid。 对于CamVid数据集,只有DDRNet的精度可以与我们的模型相媲美,如表5所示,以进行公平比较,我们在我们的平台上使用相同的设置测试其速度,因为我们的平台比他们的平台更先进。实验结果表明,我们的轻量级模型的准确度超过了80%mIOU,PIDNet-M实现了最高的准确度,大大领先于以前的模型,这有力地证明了我们的模型的优越性。此外,PIDNetS的精度超过了以前的最先进模型:DDRNet-23-S的精度为1.5%mIOU,延迟仅增加约1ms
    在这里插入图片描述
  • Cityscapes。以前的实时工作将Cityscapes[13]作为标准基准。如表6所示,只有SFNet和DDRNet与我们的模型具有相似的精度,因此我们在与PIDNet相同的平台上测试它们的速度,以进行公平比较。实验结果表明,PIDNets在推理速度和准确性之间实现了最佳平衡。具体而言:
    • PIDNet-L在速度和精度方面超过SFNet(ResNet18)和DDRNet-39,通过将测试精度从80.4%mIOU提高到80.6%mIOU,成为实时领域中最准确的模型。
    • 与具有相似推理速度的模型相比,PIDNet-M和PIDNet-S也提供了高得多的精度。特别是,PIDNet-S成为所有模型中速度最快的一个,精度高于77.5%mIOU,这将满足大多数具有严格延迟和精度要求的应用。实际性能见图10。
      在这里插入图片描述
      在这里插入图片描述
  • COCO-Stuff。PAPPM中的 (17,8)-Avg池化路径被删除,因为COCO Stuff中的图像尺寸太小。尽管沿边界区域的COCO Stuff注释不如前两个数据集精确,但与其他模型相比,我们的模型在效率方面仍具有竞争力,如表7所示
    在这里插入图片描述

5 Conclusion

本文提出了一系列三个分支网络:用于实时语义分割任务的PIDNets。PIDNets实现了推理时间和准确性之间的最佳权衡,这一点通过大量实验得到了证明。然而,由于PIDNets利用边界预测来平衡详细信息和上下文信息,因此需要围绕边界进行精确的注释以获得更好的性能。

  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值