【实例分割】论文阅读:YOLACT Real-time Instance Segmentation

论文:YOLACT Real-time Instance Segmentation (ICCV2019)
作者:Daniel Bolya Chong Zhou

Abstract

我们为实时实例分割提供了一个简单的全卷积模型,该模型在单个Titan Xp上以33.5 fps的速度在MS COCO上达到了==29.8 mAP,==这比以前的任何竞争方法都快得多。此外,我们仅在一个GPU上训练后即可获得此结果。我们通过将实例分割分为两个并行的子任务来完成此任务:(1)生成一组原型Mask,以及(2)预测每个实例的Mask系数。然后,我们通过将原型与Mask系数线性组合来生成实例Mask。我们发现,由于此过程不依赖于repooling,因此此方法可产生非常高质量的Mask并显示出了时间稳定性。此外,我们分析了原型的涌现行为,并展现出了他们能够以翻译变体的方式自行定位实例,尽管是全卷积。最后,我们还提出了快速NMS,这是对标准NMS的12毫秒快速替代,但只对性能有轻微的影响。

1. Introduction

创建实时实例分割算法需要什么? 在过去的几年中,视觉社区在实例分割方面取得了长足的进步,部分是通过利用来自完善的对象检测领域的强大相似之处。 诸如Mask RCNN [18]和FCIS [24]等最先进的实例分割方法直接建立在Faster R-CNN [37]和R-FCN [8]等对象检测技术的基础上。然而,这些方法主要关注在性能与速度之间的关系上。场景中的实时实例分割工作并没有像实时对象检测器(如SSD [30]和YOLO [35,36])一样并行。 在这项工作中,我们的目标是以一种快速的一级实例分割模型填补这一空白,就像SSD和YOLO填补该空白以进行对象检测一样。

但是,实例分割很困难-比对象检测困难得多。 诸如SSD和YOLO之类的一级对象检测器能够通过简单地移除第二级并以其他方式弥补性能损失来加快诸如Faster R-CNN之类的现有两级检测器。 但是,同一方法不易扩展到实例分割。 最新的两阶段实例分割方法在很大程度上依赖于特征定位来生成Mask。 也就是说,这些方法(例如,通过RoIpool / align)在某些边界框区域中“repool”特征,然后将这些现在局部化的特征馈送到Mask predictor中。 这种方法本质上是顺序的,因此很难加速。 确实存在像FCIS一样并行执行这些步骤的一阶段方法,但是它们在定位之后需要大量的后处理,因此仍然远远不够实时。
在这里插入图片描述
为了解决这些问题,我们提出了YOLACT1,这是一个实时实例分割框架,它无需进行明确的本地化步骤。 相反,YOLACT将实例分割分解为两个并行的任务:(1)在整个图像上生成非局部原型Mask的字典,以及(2)预测每个实例的一组线性组合系数。 然后,从这两个组件产生全图像实例分割很简单:对于每种实例,使用相应的预测系数线性组合原型,然后使用预测的边界框进行裁剪。 我们展示了通过以这种方式进行分割,网络学会了如何自行定位实例Mask,在视觉,空间和语义上相似的实例在原型中看起来是不同的。

此外,由于原型Mask的数量与类别的数量无关(例如,可以有比原型更多的类别),因此YOLACT学习了一种分布式表示形式,其中每个实例都通过在类别之间共享的原型组合进行了细分。 分布式表示会在原型空间中引起有趣的紧急行为:一些原型在空间上对图像进行分区,一些定位实例,一些检测实例轮廓,一些编码位置敏感的方向图(类似于在FCIS中对位置敏感模块进行硬编码[ 24]),并且大多数都将这些任务组合在一起(请参见图5)。

这种方法还具有一些实际优势。 首先,它是快速的:由于其并行的结构和极其轻巧的组装过程,YOLACT仅向一级backbone检测器增加了少量的计算开销,即使使用ResNet-101时也很容易达到30fps [19] ; 实际上,整个Mask分支只需5毫秒即可评估。 其次,Mask是高质量的:由于Mask会使用整个图像空间,而不会因反复池化而损失像素,因此我们用于大型物体的Mask的质量明显高于其他方法(参见图7)。 最后,一般的:生成原型和Mask系数的想法几乎可以添加到任何现代物体检测器中。

我们的主要贡献是第一个实时(> 30 fps)实例分割算法,在具有挑战性的MS COCO数据集上[28]具有竞争性结果(见图1)。 此外,我们分析了YOLACT原型的新兴行为,并提供了实验来研究在不同主干架构,原型数量和图像分辨率下获得的速度与性能之间的权衡。 我们还提供了一种新颖的快速NMS方法,其性能比传统NMS快12ms。

2. Related Work

Instance Segmentation 鉴于其重要性,已进行了大量研究工作以提高实例分割的准确性。 Mask-RCNN [18]是一种代表性的两阶段实例分割方法,该方法首先生成候选感兴趣区域(ROI),然后在第二阶段对这些ROI进行分类和分段。 后续工作试图通过例如增加FPN功能[29]或解掩码的置信度得分与其定位精度之间的不兼容性[20]来提高其准确性。 这两个阶段的方法需要为每个ROI反复池化,并通过后续计算对其进行处理,这使得即使减小图像大小,它们也无法获得实时速度(30 fps)(请参见表2c)。

一阶段实例分割方法生成位置敏感图,并通过位置敏感池将其组装成最终掩码[6,24]或结合语义分割logit和方向预测logits [4]。尽管从概念上讲,它比两阶段方法要快, 但仍然需要进行repooling或其他 non-trivial 计算(例如,掩码投票)。 这严重限制了它们的速度,使它们远离实时。 相比之下,我们的组装步骤要轻得多(仅是线性组合),并且可以实现为GPU加速的矩阵矩阵乘法,从而使我们的方法非常快速。

最后,一些方法首先执行语义分割,然后进行边界检测[22],像素聚类[3、25],或学习嵌入以形成实例掩码[32、17、9、13]。 同样,这些方法具有多个阶段和/或涉及昂贵的聚类过程,这限制了它们在实时应用中的可行性。

Real-time Instance Segmentation 尽管存在实时对象检测[30、34、35、36]和语义分割[2、41、33、11、47]方法,但很少有工作专注于实时实例分割。 Straight to Shapes [21]和Box2Pix [42]可以实时执行实例分割(对于Pascal SBD 2012 [12,16],Straight to Shapes可以实时执行实例分割,在Cityscapes [5]上可以达到10.9 fps,在KITTI [15]上可以达到35fps。 ](适用于Box2Pix),但其精度远非现代基准。 实际上,Mask R-CNN [18]仍然是语义上具有挑战性的数据集(如COCO [28])的最快实例分割方法之一(在550x550 px图像上为13.5fps;请参见表2c)。

Prototypes 学习原型(又称词汇表或密码本)已在计算机视觉中得到了广泛探索。 古典的表现形式包括文本[23]和视觉单词[40],并通过稀疏性和局部性先验[44、43、46]取得了进步。 其他人则设计了用于物体检测的原型[1,45,38]。 尽管相关,但这些作品使用原型来表示特征,而我们使用它们来组装掩码以进行实例分割。 此外,我们学习特定于每个图像的原型,而不是在整个数据集中共享的全局原型。

3. YOLACT

我们的目标是按照与Mask R-CNN [18]和Faster R-CNN [37]相同的方式,向现有的一阶段对象检测模型添加mask分支,但没有明确的特征定位步骤(例如,feature repooling)。 为此,我们将实例分割的复杂任务分解为两个更简单的并行任务,可以将它们组合起来以形成最终的Mask。 第一分支使用FCN [31]来生成一组图像大小的“原型Mask”,这些Mask不依赖于任何一个实例。 第二种方法向对象检测分支添加了一个额外的头部,以预测每个锚的“Mask系数”矢量,这些锚对原型空间中的实例表示进行编码。 最后,对于在NMS中幸存的每个实例,我们通过线性组合这两个分支的工作为该实例构造一个Mask。
在这里插入图片描述
Rationale 我们以这种方式执行实例分割主要是因为Masks在空间上是连贯的。 也就是说,彼此靠近的像素可能是同一实例的一部分。 卷积(conv)层自然地利用了这种一致性,而全连接(fc)层却没有,这是一个问题,因为一级目标检测器会为每个锚点生成类和盒系数作为fc的输出。 二阶方法如掩模R-CNN的两步方法通过使用定位步骤(例如RoIAlign)解决了此问题,该步骤保留了特征的空间连贯性,同时还允许将Mask作为转换层输出。 但是,这样做需要模型的很大一部分等待第一阶段的RPN提出定位候选对象,从而导致明显的速度损失。

因此,我们将问题分为两个平行的部分,即利用fc层和conv层,其中fc层善于产生语义矢量,而conv层善于产生空间一致的Mask,从而产生“mask coefficients”和“prototype masks” , 分别。 然后,由于原型和掩膜系数可以独立计算,因此,骨干检测器的计算开销主要来自于组装步骤,可以将其实现为单个矩阵乘法。 这样,我们可以保持特征空间的空间连贯性,同时仍然保持一个阶段且快速。

3.1. Prototype Generation

原型生成分支(protonet)为整个图像预测一组k个原型Mask。 我们将pronet实施为FCN,其最后一层具有k个通道(每个原型一个),并将其附加到主干特征层(请参见图3)。 尽管此表述与标准语义分段相似,但不同之处在于我们在原型上没有表现出明显的损失。 取而代之的是,对这些原型的所有监督都来自组装后的最终掩模损失。

我们注意到两个重要的设计选择:从更深的主干特征中获取Protonet会产生更健壮的Mask,而更高分辨率的原型会同时带来更高质量的Mask和更小的物体性能。 因此,我们使用FPN [26],因为它的最大特征层(在我们的情况下为P3;见图2)最深。 然后,我们将其上采样到输入图像尺寸的四分之一,以提高在小物体上的性能。
在这里插入图片描述
最后,我们发现无限制的Protonet输出非常重要,因为这可以使网络为它充满信心的原型(例如,明显的背景)产生大型的,强大的激活。 因此,我们可以选择遵循带有ReLU或不具有非线性的原型。我们选择ReLU以获得更具解释性的原型。

3.2. Mask Coefficients

典型的基于锚的对象检测器在其预测头中有两个分支:一个分支预测c类置信度,另一个分支预测4个边界框回归器。 对于掩膜系数预测,我们只需并行添加第三分支即可预测k个掩膜系数,每个分支对应一个原型。 因此,我们不会产生每个锚点4 + c的系数,而是会产生4 + c + k的系数。

然后对于非线性,我们发现能够从最终Mask中减去原型很重要。 因此,我们将tanh应用于k个掩码系数,从而在没有非线性的情况下产生更稳定的输出。 这种设计选择的相关性在图2中显而易见,因为在不允许扣除的情况下,两种掩模都无法构建。

3.3. Mask Assembly

为了产生实例Mask,我们将原型分支和Mask系数分支的工作结合在一起,使用前者和后者作为系数的线性组合。 然后,我们通过S型非线性来生成最终的Mask。 使用单矩阵乘法和S形可以有效地实现这些运算: M = S ( P C T ) , S 为 s i g m o i d 激 活 函 数 M=S(PC^{T}),S为sigmoid激活函数 M=S(PCT),Ssigmoid。其中P是原型掩模的h x w x k矩阵,C是n个幸存的NMS和得分阈值实例的掩模系数的n x k矩阵。 其他更复杂的组合步骤也是可能的。 但是,我们通过基本的线性组合使其保持简单(快速)。

LOSS 我们使用三种损失来训练模型:分类损失Lcls,框回归损失Lbox和Mask Loss(Lmask),权重分别为1、1.5和6.125的。 Lcls和Lbox的定义方法与[30]中相同。 然后,要计算Mask Loss,我们只需简单地获取已组装mask M与真实Mask M g t M_{gt} Mgt之间的像素级二进制交叉熵: L m a s k = B C E ( M , M g t ) L_{mask} = BCE(M,M_{gt}) Lmask=BCEM,Mgt

Cropping Masks 我们在评估过程中使用预测的边界框裁剪最终Mask。 在训练过程中,我们改用地面实况边界框进行裁剪,然后将Lmask除以真实边界框区域,以保留原型中的小对象。

3.4. Emergent Behavior

我们的方法似乎令人惊讶,因为围绕实例分割的普遍共识是,由于FCN是平移不变的,因此该任务需要在[24]中添加平移差异。 因此,诸如FCIS [24]和Mask R-CNN [18]之类的方法尝试显式添加平移方差,无论是通过方向图和位置敏感的重现,还是通过将mask分支置于第二阶段,因此都不必 处理本地化实例。 在我们的方法中,我们添加的唯一平移方差是使用预测的边界框裁剪最终的Mask。 但是,我们发现我们的方法也无需裁剪就可以处理大中型对象,因此这不是裁剪的结果。 相反,YOLACT学习如何通过其原型中的不同激活来自行对实例进行本地化。
在这里插入图片描述

4. Backbone Detector

对于我们的骨干检测器,我们优先考虑速度和功能丰富性,因为预测这些原型和系数是一项艰巨的任务,需要良好的功能才能做好。 因此,我们的骨干探测器的设计紧跟RetinaNet [27],并着重于速度。

YOLACTDetector **我们使用ResNet-101 [19]和FPN [26]作为默认特征主干,并且基本图像尺寸为550x550。**为了获得一致的评估时间,我们不保留纵横比。像RetinaNet一样,我们通过不生成P2以及不生成P6和P7来修改FPN,从P5(不是C5)开始连续3x3,步长为2转换层,并放置3个宽高比为[1,1/2 , 2]。 P3的锚点的面积为24像素平方,并且每个后续层的大小都是前一个的两倍(结果为[24; 48; 96; 192; 384])。对于每个Pi附加的预测头,我们三个分支共享一个3x3 conv,然后每个分支并行获得自己的3x3 conv。与RetinaNet相比,我们的预测头设计(参见图4)更轻巧,更快。我们将平滑L1损失应用于训练盒回归器,并以与SSD [30]相同的方式对盒回归坐标进行编码。为了训练班级预测,我们使用带有c个正标记和1个背景标记的softmax交叉熵,使用OHEM [39]以3:1 neg:pos的比率选择训练示例。因此,与RetinaNet不同,我们不使用Focal loss,我们发现这种在我们的情况下不可行。

通过这些设计选择,我们发现该主干网比具有相同镜像大小的修改为使用ResNet-101 [19]的SSD [30]更好和更快。

5. Other Improvements

我们还将讨论其他改进,这些改进要么提高速度而对性能几乎没有影响,要么提高性能而没有速度损失。

快速NMS在为每个锚点生成边界框回归系数和类置信度之后,像大多数对象检测器一样,我们执行NMS来抑制重复检测。 在许多先前的工作[35、36、30、37、18、27]中,NMS是按顺序执行的。 也就是说,对于数据集中的每个c类,对检测到的框按置信度降序进行排序,然后对于每个检测,删除所有置信度比其低且IoU重叠大于某个阈值的框。 尽管此顺序方法在大约5 fps的速度下足够快,但它却成为获取30 fps的障碍。例如,以5 fps的速度提高10毫秒可提高0.26 fps,而以30 fps的速度提高10毫秒则可提高12.9 fps。

为了解决传统NMS的顺序性问题,我们引入了Fast NMS,它是NMS的一种版本,可以确定每个实例并行保留还是丢弃。 为此,我们只允许已经删除的检测来抑制其他检测,这在传统NMS中是不可能的。 这种放松使我们能够完全在标准GPU加速矩阵操作中实施Fast NMS。
在这里插入图片描述
由于放松,快速NMS的作用是删除过多的盒子。 但是,与速度的急剧提高相比,由此造成的性能下降可以忽略不计(参见表2a)。 在我们的代码库中,快速NMS比传统NMS的Cython实现快11.8毫秒,而性能仅降低0.1mAP。 在Mask R-CNN基准套件[18]中,快速NMS比其传统NMS的CUDA实施快15.0 ms,而性能损失仅为0.3 mAP。
在这里插入图片描述
Semantic Segmentation Loss 尽管Fast NMS牺牲了少量的性能以提高速度,但仍有许多方法可以提高性能而不会降低速度。 其中一种方法是在训练期间使用未在测试时执行的模块对模型施加额外的损失。 这有效地增加了功能丰富性,而没有速度损失。

因此,我们使用仅在训练期间评估的图层将语义分割损失应用于特征空间。 请注意,由于我们是通过实例注释来构造这种损失的基本事实,因此这不能严格捕获语义分段(即,我们不对每个像素强制执行标准的一类)。 要在训练期间创建预测,我们只需将带有c个输出通道的1x1转换层直接附加到骨干网中最大的特征图(P3)。 由于每个像素可以分配给多个类别,因此我们使用S形和c通道,而不是softmax和c +1。此损耗的权重为1,导致+0:4 mAP增强。

6. Results

我们使用标准指标在MS COCO [28]和Pascal 2012 SBD [16]上报告实例分割结果。对于MS COCO,我们在train2017上进行训练,并在val2017和test-dev上进行评估。
在这里插入图片描述
Implementation Details 我们使用ImageNet [10]预训练权重在一个GPU上训练了批处理大小为8的所有模型。我们发现这是足够的批处理大小,可以使用批处理规范,因此我们不冻结预训练的批处理规范,但不添加任何额外的bn 层。 我们使用SGD进行了800k迭代训练,初始学习率为10e-3,然后在280k,600k,700k和750k迭代中除以10,使用了5x10e-4的权重衰减,0.9的动量以及所有 SSD中使用的数据增强[30]。 对于Pascal,我们训练了12万次迭代,并将学习率除以60k和100k。 随着目标趋于更大,我们还将锚定比例乘以4/3。 一台Titan Xp在COCO数据集上训练需要4-6天(取决于配置),而在Pascal上则需要不到1天的。

我们还在表1中其他可选模型。除了基本的550 x 550图像尺寸模型之外,我们还训练了400 x 400(YOLACT-400)和700 x 700(YOLACT-700)模型,并相应地调整了锚点比例 (sx = s550 / 550 x)。 减小图像大小会导致性能大幅下降,这表明实例分割自然需要更大的图像。 然后,如预期的那样,增大图像大小会显着降低速度,但也会提高性能。
在这里插入图片描述
Mask Results 我们首先将YOLACT与表1中MS COCO的测试开发集上的最新方法进行比较。由于我们的主要目标是速度,因此我们将其与没有测试时间增加的其他单个模型结果进行了比较。 我们报告所有在单个Titan Xp上计算的速度,因此列出的某些速度可能比原始论文中的速度更快。

除了ResNet-101 [19]的基本骨干之外,我们还测试了ResNet-50和DarkNet-53 [36],以获得更快的结果。 如果更高的速度是可取的,我们建议使用ResNet-50或DarkNet-53而不是减小图像图像的大小,因为这些配置的性能比YOLACT-400好得多,而速度却稍慢一些。 最后,我们还在表3中针对Pascal 2012 SBD训练和评估了ResNet-50模型。YOLACT明显优于报告SBD性能的流行方法,而且速度明显更快。
在这里插入图片描述
Mask Quality 因为我们生成的最终Mask的尺寸为138 x 138,并且因为我们直接从原始特征创建了Mask(没有进行重新合并以转换和潜在地错位特征),所以用于大型目标的Mask的质量明显高于Mask R-CNN [18]和FCIS [24]。 例如,在图7中,YOLACT产生了一个清晰地沿着手臂边界的Mask,而FCIS和Mask R-CNN都具有更多的噪音。 此外,尽管总体情况下差了5.9 mAP,但在95%IoU阈值的情况下,我们的基本模型仍达到了1.6 AP,而Mask R-CNN获得了1.3 AP。 这表明repooling确实会导致掩模质量的量化下降。\

Temporal Stability 尽管我们仅使用静态图像进行训练,而未应用任何时间平滑,但我们发现,与Mask R-CNN相比,即使对象静止不动,其模型也会在帧之间抖动,因此我们的模型在视频上产生的时间稳定性更高。 我们认为我们的掩码更稳定,部分是因为它们的质量更高(因此帧之间的误差空间较小),但主要是因为我们的模型是单阶段的。 采用两阶段方法生产的掩码在第一阶段高度依赖于其区域建议。 与我们的方法相反,即使模型在帧中预测不同的盒子,原型也不会受到影响,从而产生了时间上更稳定的掩码。
在这里插入图片描述

7. Discussion

尽管我们的掩码质量更高,并且具有诸如时间稳定性之类的良好属性,但我们在整体性能方面仍落后于最新的实例分割方法,尽管速度要快得多。 大多数错误是由检测器中的错误引起的:分类错误,盒子未对准等。但是,我们已经确定了两种典型的错误,这些错误是由YOLACT的掩模生成算法引起的。

Localization Failure 如果场景中一个点的对象太多,则网络可能无法在其自己的原型中定位每个对象。 在这些情况下,网络将输出比组中某些对象的实例分割更接近前景Mask的内容。 例如,在图6的第一张图片(第1行第1列)中,红色飞机下方的蓝色卡车未正确定位。

Leakage 我们的网络利用了在组装后对掩码进行裁剪的事实,并且没有试图抑制裁剪区域之外的噪声。 当边界框准确时,此方法效果很好,但如果边界框不正确,则噪声可能会渗入实例掩码中,从而从裁剪区域的外部产生一些“泄漏”。 当两个实例彼此相距很远时,也会发生这种情况,因为网络已了解到它不需要对很远的实例进行定位-裁剪会照顾好它。 但是,如果预测的边界框太大,则掩码也将包含某些远处实例的掩码。 例如,图6(第2行第4列)显示了这种泄漏,因为面罩分支认为这三个滑雪者的距离足够远,不必将它们分开。

Understanding the AP Gap仅定位失败和泄漏不足以解释YOLACT基本模型与Mask R-CNN之间的近6 mAP差距。 确实,我们基于COCO的基础模型的测试开发掩码与框mAP(29.8蒙版,32.3框)之间只有2.5 mAP的差异,这意味着即使使用完美的Mask,我们的基础模型也只能获得几分mAP。 此外,Mask R-CNN具有相同的mAP差异(35.7 mask,38.2 box),这表明这两种方法之间的差距在于检测器性能相对较差,而不是我们生成mask的方法。
在这里插入图片描述

### 回答1: Deep Snake是一种用于实时实例分割的算法。它基于深度学习技术,通过对图像中的每个像素进行分类,实现对目标物体的精确分割。Deep Snake算法具有高效性和准确性,可以应用于许多领域,如自动驾驶、医学影像分析等。 ### 回答2: DeepSnake是一个用于实时实例分割的新型神经网络模型。与传统的基于卷积神经网络(CNN)的实例分割方法不同,DeepSnake使用自适应的密集曲线组件,来更好地关注目标对象的形状特征,从而实现更精确的分割结果。 DeepSnake的设计基于一种称为“变形回归”的曲线回归方法。该方法使用两个CNN分支,来分别处理图像区域和曲线参数,然后将它们组合起来进行端到端的训练。其中,图像分支出自用于目标检测任务的ResNet,而曲线分支则采用了U-Net结构。 DeepSnake的优点在于可以克服目标形状多样性和大小变化等问题,能够适应各种不同的数据集,并且在计算效率上具有很高的实时性。与一些竞争的实例分割算法相比,DeepSnake在准确率和速度上都有不错的表现。在PASCAL VOC 2012和COCO 2017数据集上测试,DeepSnake的性能超过了相同条件下的大多数算法,同时具有更低的计算成本。 总之,DeepSnake为实时实例分割任务提供了一种创新的方法,可以应用于许多领域,如智能监控、自动驾驶和机器人导航等。 ### 回答3: Deep Snake是一种用于实时实例分割的新型神经网络架构,由来自华盛顿大学的研究团队开发。与目前主流的神经网络架构Mask R-CNN相比,Deep Snake的优势在于能够更加准确地分割物体,同时在速度和计算资源消耗方面表现更好。 具体来说,Deep Snake使用了一种名为“蛇形控制器”的新型机制来协调具有各自目标的多个神经元。这种机制使得网络在提取图像中物体的轮廓信息时更加准确。Deep Snake还采用了特殊的分组卷积层,用于在不同的尺度上提取特征,以更好地分割物体。 此外,Deep Snake还可以使用相对较少的内存和计算资源,快速运行实例分割任务。研究者使用COCO数据集进行了实验,结果表明Deep Snake在准确率和速度方面都优于Mask R-CNN。在单个Nvidia 1080Ti GPU上,Deep Snake可以实现每秒5.7帧的实时实例分割,准确率高达33.6%。 总的来说,Deep Snake是一种非常有潜力的神经网络架构,可用于实时实例分割。它不仅可以提高准确性,还可以节省计算资源和实现更快的运行速度。未来,深度学习的研究者将继续探索和改进这种架构,以满足不断发展的实时实例分割需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值