Learning Globally Optimized Object Detector via Policy Gradient翻译

Yongming Rao1,2,3, Dahua Lin4, Jiwen Lu1,2,3, Jie Zhou1,2,3
1Department of Automation, Tsinghua University
2State Key Lab of Intelligent Technologies and Systems,Tsinghua University
3Beijing National Research Center for Information Science and Technology
4Department of Information Engineering, The Chinese University of Hong Kong
raoyongming95@gmail.com;dhlin@ie.cuhk.edu.hk{lujiwen,jzhou}@tsinghua.edu.cn
原文:http://openaccess.thecvf.com/content_cvpr_2018/CameraReady/2657.pdf


摘要:

本文提出了一种简单但有效的学习全局优化目标检测检测器的方法,该方法是对REINFORCE算法启发的标准交叉熵梯度的简单改进。在我们的方法中,根据每个检测候选的当前状态的总体平均精度(mAP)自适应地调整交叉熵梯度,这使得梯度和全局优化检测结果更有效,并且不带来计算开销。得益于全局优化方法产生的更精确的梯度,我们的框架显著改进了最先进的目标检测器。此外,由于该方法基于分数和边界框,无需修改目标检测器的体系结构,因此可以容易地应用于现成的现代目标检测框架。

1. 简介

目标检测是计算机视觉中最古老、最基本的任务之一。与目标识别任务相比,目标检测更具挑战性,因为它需要同时对多个目标进行准确的定位和分类。为了解决这个问题,大多数现代物体检测器[5,6,16,18,20,22]是通过一种简化来训练的,这种简化将物体检测转换为对象分类和每个物体定位的多任务学习。这种减少引入了学习和推理之间的鸿沟,其中学习的过程只需要评估每个可能的对象建议(在[5]中的RoIs,在[16,18,21,22]中的anchors)并反馈给检测器,但是推理过程应该执行冗余候选的最优选择,以获得准确的检测结果。这是一个全局优化问题,具有对检测量的约束(例如,用于COCO评估的100[17])。

在[5,6,16,18,20,22]中,使用了一种称为非最大抑制(NMS)的方法来缩小差距。NMS执行测试时后处理以合并可能属于同一对象的边界框。该方法选择得分较高的边界框,并消除得分较低的相邻边界框,因为它们很可能覆盖相同的对象。NMS是建立在假设更精确的检测候选具有更高的置信度分数的基础上的,这在以往的检测器训练目标中没有明确地进行设计。毫不奇怪,我们的调查和实验(参见第2和4.1节)都表明,在大多数情况下,这个假设并不成立,尤其是在一些具有挑战性的数据集,如COCO。学习与推理的不一致性会影响检测性能。因此,设计一个在训练阶段弥补差距的框架非常重要。
除了开发更丰富和层次化的特征以获得更好的性能[12,15,18]之外,在最近的工作[16,25]中,更好的目标函数也被证明对改善目标检测结果是有效的。 Focal Loss[16]和在线难样本挖掘(OHEM)[25]都集中在类不平衡上,这可能导致低效的训练,因为标准的交叉熵损失不能提供有用的监控信号。这两种方法都采用重加权方案来解决这个问题。然而,不适当分配的标签可能导致误导性的梯度,该梯度可能被梯度重新加权方案放大,并在训练期间导致崩溃。利用检测候选的全局信息,针对类不平衡和标签不适问题,提出了一种通用的解决方案,可以进一步提高检测性能。为了解决上述挑战,我们提出一个端到端的目标检测训练框架,它试图通过采用策略梯度方法来学习全局优化的目标检测器。我们的方法是有效且易于实现的,这是对增强学习中REINFORCE算法[31]启发的标准交叉熵梯度的简单修改,如图1所示。在我们的方法中,交叉熵对于每个目标建议,根据当前状态的总体平均精度(mAP)自适应地调整梯度,这使得更有效的梯度和对检测结果的全局优化。此外,没有引入计算开销。我们的框架得益于由我们的方法中的全局优化产生的更精确的梯度,显著改进了最先进的对象检测器,如Faster R-CNN[22]和带有特征金字塔网络的Faste R-CNN15。在没有技巧的情况下,我们的方法在Faste R-CNN的基线上提高了COCO数据集的mAP 2.0%,在Faste R-CNN(R-CNN与FPN结合)对COCO目标检测数据集上提高了1.8%。此外,由于该方法基于置信度评分和边界框回归,无需修改目标检测器的体系结构,因此可以很容易地应用于现成的现代目标检测框架。
图1.我们方法的关键思想。 我们提出了一种端到端框架,用于通过使用策略梯度方法来学习全局优化的对象检测器。 该图显示了现有对象检测框架(在顶部)和我们提出的框架(在底部)之间的差异。 现有对象检测框架将每个地面实况框分配给具有高IOU值的提议并独立地训练每个检测候选者。 通过采用政策梯度法,我们的框架通过使用全局信息监督框,并直接改进mAP。红框表示边界框的集合。

2. 相关工作

由于有了更好的特征,过去几年物体检测有了很大的发展[6,8,15,22]。与计算机视觉中的其他高级图像理解任务,如语义分割[19]相比,设计用于目标检测的端到端解决方案更加困难。因此,基于区域的方法被广泛地用于精确的目标检测,这将目标检测问题归结为许多独立的子问题,即评估密集或稀疏区域。然而,利用全局信息进行目标检测在最近的工作中很少被探索。

基于CNN的目标检测器:卷积神经网络(CNN)首次被Girshick等人引入到目标检测领域[6]。几乎使在PASCAL VOC数据集的检测性能增加一倍。该方法称为R-CNN,通过执行基于区域的识别操作来使用CNN进行定位,该识别操作将具有多个目标的图像分解成多个预先提取的感兴趣区域(RoIs)。 Fast R-CNN[5]和Faster R-CNN[22]分别通过共享CNN特征和组合基于CNN的区域建议网络来进一步发展和加速该方法。与通过区域建议网络来获得高精度检测结果的R-CNN型(two-stage)检测器不同,one-stage目标检测器[16,18,20]旨在实现实时检测应用。大多数one-stage检测器使用anchor,其中anchor固定在特征图的每个像素上。在所有上述对象检测器中,proposals在训练阶段被独立地处理。

目标检测的目标函数:在Fast R-CNN及其后代中,采用多任务损失分类和回归的方法进行区域识别。区域建议的标签是根据 固定阈值标准分配的。由于前景RoI和背景RoI的数量在训练过程中常常是不平衡和变化的,因此目标函数可能产生无用或误导性的学习信号,因此在大多数位置的训练是低效的。为了解决类别不平衡的问题,提出了在线难样本挖掘(OHEM)[25]和Focal Loss[16]来分别改进稀疏和密集目标检测的训练。已有的工作表明,目标函数越好,检测性能越好。

关于非极大抑制的修改:为了获得更好的检测结果,已经对NMS进行了一些修改。例如,Hosang等人提出了一种参数化辅助模型Gnet[10],用于在目标检测器的standard pipeline之后,将相邻边界框之间的信息进行集成,对边界框进行重新评分。Gnet专注于惩罚双重检测,这减少了冗余的box。相反,NMS上的另一个改进是soft-NMS[1],它试图保留在执行NMS期间被消除的框并rescore这些框。Gnet和soft-NMS均提高了检测结果,表明了该方法的有效性。NMS的检测是冗余的和不准确的,并且假设在大多数情况下不成立。不同于这些工作,我们的方法没有改变NMS方法,而是使用一个平滑和更精确的目标函数来训练目标检测器,它把NMS作为检测器的一部分。

目标检测器的端到端训练:自从CNN被引入到目标检测领域以来,设计用于目标检测的端到端学习框架引起了人们的极大兴趣。Faster R-CNN[22]将区域建议模块结合到目标检测的pipeline中,其中提出了可训练的区域建议网络(RPN),显著地提高了区域建议的质量。[10]和[9]将NMS合并到用于现代目标检测器的端到端学习框架中。然而,所有这些努力都集中在利用建议框的位置信息,试图解决双重检测和遮挡的问题。尽管已经对诸如[2,24]检测结果的post-processing作出了一些努力,但是对于现代目标检测器的检测结果的全局规划还没有被研究。

3. 方法

用于目标检测的全局优化的关键思想如图1所示。现有的学习框架以分类和定位的多任务损失来独立地训练每个检测候选。全局优化方法根据detection results set和ground truth bounding boxes set之间的差异,利用策略梯度对检测器进行监督,从而对象之间的全局信息能够被利用。

3.1 Faster R-CNN回顾

我们首先简单的回顾一下Faster R-CNN[22]检测器,我们的框架建立在这个检测器上。

Faster R-CNN分为两个阶段,即区域建议网络(RPN)和Fast R-CNN head。RPN由几个卷积层组成,为每个参考框(称为anchor)产生置信度分数和边界框。具有不同尺度和宽高比的anchors固定在特征图的每个位置,其中执行密集和类不可知的预测以找到object proposals。Fast R-CNN头部利用RoIPool操作对每个RoI进行特征提取,并进行分类和边界盒回归。这两个阶段对于快速推理具有相同的特征。
在训练期间,使用具有用于分类的交叉熵损失和用于定位的smooth L1 loss的多任务学习方案,其可以公式化为:

其中α是分类和定位损失之间的平衡权重。在将标签分配给每个RoI之后,并行地为每个RoI执行多任务学习过程。我们认为,Faster R-CNN中忽略的ROI之间的关联信息,其可以被进一步用于改进目标检测器。

3.2 提出问题

给定图像I,对象检测是一个映射的任务图像到一组具有类信息B={(bi,yi)}的边框,其中边框的数量等于感兴趣的对象的数量,边框是对应对象的最小包围矩形。在大多数现代对象检测器中,提供了冗余的检测候选集B′,这意味着

边界框检测任务的评估不要求目标检测器提供包含精确|B|检测的边界盒集合,相反,图像中的目标数量对于目标检测器是不可知的。因此,在COCO基准[17]和PASCAL VOC[3]中都使用了对检测量的约束。
目标检测的目标可以表述为

其中,F是以图像作为输入并产生一组检测候选的目标检测器,θ是F中的参数集,Nbb是最大检测候选的阈值。mAP是[17]和[3]中使用的评价函数,它计算具有固定阈值(PASCAL VOC为0.5)或阈值范围([0.5:0.95],对于COCO基准为0.05增量)的检测候选和ground truth boxes之间的平均精度)。

如前节所述,传统检测系统上使用多任务损失独立地优化每个检测候选来训练。为了在目标检测中利用全局信息,我们提出联合检测候选集的方法,其目的是使检测候选与ground truth boxes之间的mAP最大。因此,学习全局优化的目标检测器的目标可以写如下:

其中EI是对所有训练图像的期望,第二项是正则化因子λ的正则化项。

3.3 目标检测器的全局优化

由于非极大值抑制是对检测候选的hard选择操作,所以方程4中描述的优化问题不能用标准梯度下降算法解决。为了解决这个问题,我们提出了基于策略梯度的REINFORCE算法[31]来处理目标检测的全局优化问题。在我们的例子中,检测器,比如Faster R-CNN,可以被看作是图像与外部环境交互的媒介。agent(媒介)的目的是在所选择的检测候选和ground truth boxes之间获得最大可能的mAP,这可以看作是对agent的奖励。目标检测器的参数θ、定义一个策略pθ,它的结果用于选择检测的动作。在每个动作之后,agent提出一组检测候选,并观察来自评估系统的奖励。不同于基于诸如机器人控制和视频游戏等一系列决策的强化学习问题,在我们的例子中,图像的特征包括对环境的描述,这些描述不是由先前的状态或动作确定的。严格地说,上述公式并不是一个完整的强化学习框架,这超出了本文的范围。在此,我们致力于采用策略梯度法作为梯度逼近工具,利用全局信息,改进训练目标检测器的进程。
总之,端到端训练目标是最小化负期望评估度量,即平均精度(mAP)。

全局优化的策略梯度:对于目标检测任务,由于非极大值抑制,期望奖励r是不可微的。为了直接计算▽L(θ),可以使用策略梯度方法,该方法计算不可微奖励函数的期望梯度如下:

其中动作a可以被描述为“从所有候选者中选择一组边界框”。如果每次选择m个候选c类别和n个框,那么所有可能的操作的数量将达到#a=[m×c;n],这可能非常大(例如,如果m=1000,n=10和c=80,#a=3×1042)。探索这么大的活动空间是困难的,也是低效的。

为了将方程6中的目标应用于目标检测器的训练过程,我们采用了一些逼近技巧来减小动作空间的大小,获得更有效的梯度。由于我们所提出的方法被应用于预训练目标检测器,因此我们可以假设预训练检测器能够正确地生成输入区域的类别:

其中,P(b,l)是类别l中边界框的softmax输出,因此,每个边界框都能被分配到真值类别,并且在策略梯度训练期间将不作为其他类别进行采样。pb是检测器将b识别为ground truth class的概率,即b的分数。pa是动作a的概率,因此,pa =

我们可以进一步简化公式6:

我们可以定义r(b)=Σa[p(a)r(a)δ(a,b)]。注意,总结所有可能的操作是不切实际的,因此我们根据pa随机地采样k=10操作,以在我们的实现中计算r(b)。我们认为,在单个梯度计算过程中对多个动作进行采样,而不是像以往的策略梯度典型方法中的实现那样每次迭代采样一个动作,训练过程更有效、稳定。因此,预期的策略梯度可以写成:

具有基线的策略梯度:在基于策略梯度的算法中广泛使用基线以减少梯度估计的方差[23,27]:

其中,基线r′可以任意选择[31],只要它不依赖于动作a。添加基线项不会改变梯度的期望,因为基线与置信度分数pb无关。这里,我们选择通过执行NMS获得的检测结果的mAP作为基线。直观地,我们可以看到,具有较高IoU边界框的ground truth boxes将得到积极的奖励,而选择低IoU框的行为将受到惩罚。此外,我们将已经选择的框的奖励设置为零。

带交叉熵损失的联合训练:为了使方程7中的假设在训练期间成立,可以使用辅助交叉熵损失来进一步利用注释信息和稳定训练。我们可以将最终的梯度公式概括为:

其中γ是交叉熵损失的权重。我们可以计算如下导数:

其中x是softmax函数的输入。策略梯度可以看作是交叉熵损失的调整,根据每个检测候选的当前检测结果动态地调整最终梯度。可以观察到,本方法的关键元素包括:(1)确保更好的检测候选者具有较高的置信度分数,(2)在训练阶段使检测器意识到NMS,(3)放大传统检测器学习中遗漏的hard examples的梯度。figure2,提出的方法的总体框架。学习全局优化目标检测器的目的是最大化检测结果与ground truth boxes之间的mAP。目标检测器由两个监督信号进行训练:用于边界框回归的smooth L1损失函数和用于全局优化的策略梯度
我们提出的方法的总体框架概括在figure2中。算法1详细描述了该方法的训练过程。
算法1

4. 实验

4.1 实现

我们在具有挑战性的80类COCO检测数据集[17]上评估了我们提出的方法。我们所有的模型都是使用80k个训练图像和35k个val图像子集(trainval35k)的联合来训练的。我们报告了标准COCO度量,包括COCO-style的mAP、mAP50、mAP75、mAPs、mAPm和mAPl,它们位于val图像(minival)的5k子集上。

在[7,15,16]之后,我们使用在ImageNet1k分类数据集[13]上预训练的网络作为骨干网络,并在目标检测数据集上对我们的模型进行微调。我们所有的模型都是在[8]作者提供的ResNet-101模型的基础上训练的。

我们提出的方法是训练目标检测器的通用解决方案。在本节中,我们在最先进的目标检测器(如Faster R-CNN[22]和利用特征金字塔网络15的Faster R-CNN)进行评价我们的方法。为了证明该方法的有效性,我们对原始实现做了一些修改,以构建更强的目标检测基线。虽然我们的基线模型比之前的文献[15,22]中的原始模型性能要好,但是我们的方法可以进一步提高检测性能。

采用Faster R-CNN的目标检测:Faster R-CNN是基于区域的目标检测器(Fast R-CNN)和区域建议网络(RPN)的组合,可以端到端地训练输入图像去检测候选。卷积神经网络用于产生图像特征,目标检测器和区域建议网络共享图像特征,以便更快地进行推理。

原始的 Faster R-CNN模型建立在VGG类型的网络[28]上,与诸如ResNet[8]及其后代[30,32]等流行的更深层架构相比,这些网络相对浅且低效。在[8,15]之后,我们使用深度为101层的ResNet网络(ResNet-101)作为我们的实验中特征提取的骨干架构。在ImageNet1k数据集上预先训练基本ResNet-101模型作为目标检测任务的初始化模型。在训练阶段,ResNet-101前两个阶段中的层和所有批量归一化层被冻结,以便更稳定地训练。与原始利用ResNets[8]实现的Faster R-CNN不同,它从第四阶段的卷积层中提取特征,整个具有扩展卷积层的模型被用于更深和更大的特征,如[14]。在我们的实现中,从ResNet的最后一个卷积层,即第5阶段的最终卷积层中提取特征,并且第5阶段的卷积层被扩张的卷积层替换,以减少特征步长,同时保持感受野[19]。为了充分利用ImageNet预训练模型,利用相应的卷积层对扩展层的权重进行初始化。

区域建议网络以图像特征为输入,输出一组具有复杂得分的目标建议。我们使用核大小为3×3的卷积层将图像特征从ResNet映射到512维特征映射。使用分类和定位两个分支分别产生在[22]中描述的具有两个1×1卷积层的features map的每个点的2A分数和4A坐标,其中A是anchor的数量。在[15]之后,anchor具有{322,642,1282,2562,512^2}像素的区域,具有{1:2,1:1,2:1}的多个纵横比,每个尺度都被使用在RPN。因此,我们在实现中将A设置为15。在训练期间,anchor的标签是根据他们的IoU与ground truth boxes分配的。如果anchor的ground truth boxes高于IoU0.7,则给anchor分配正标签;如果anchor的ground truth boxes比IoU低0.3,则给anchor分配负标签。注意,具有ground truth boxes的最高IoU的anchor也被分配为正标签,其他anchor在训练期间被忽略。在训练和推理期间,RPN在所有anchor上执行阈值为0.7的NMS之后产生区域建议。与先前工作中的16个像素不同,如果它们的较短尺寸小于2个像素,则建议被消除。因为我们需要保留小的建议,这样可以大大提高对小目标的检测性能(mAPS)。

对于每个区域建议,在[7]中用于从图像特征中提取位置敏感且固定尺寸的特征图的RoIAlign操被引入。不同于[7]使用7×7RoIAlign算子,我们采用更密集的采样(例如,14×14,如[11])对于大目标可以提取更多目标信息,并将更多的信息反馈给主干CNN,这有助于获得更精确的预测和更加有效的微调主干网络。由于ResNet的第5阶段已经用于特征提取,我们使用额外的3×3卷积层和步长2来为每个RoI产生大小为(7,7,256)的特征,然后在最终分类和边界框回归层之前使用两个1024-d的全连接层,这在[15]中用于形成检测器的head结构。上面的每一层之后是ReLU激活,并且不使用dropout[29]。注意,与conv5 head[8]和2-fc MLP head[15]相比,我们的head架构具有更少的参数(对于Faster R-CNN,与2-fc MLP相比约33%),GPU内存使用率。

基于特征金字塔网络的目标检测:FPN是一种具有横向连接的自顶向下体系结构,用于构建多个尺度的高层语义feature map,可以显著提高不同尺度下目标的检测结果。我们采用此设计来建立比Faster R-CNN更强的基线,并评估所提出方法的通用性。

继[15]之后,我们在骨干ResNet模型上利用每个阶段的最终卷积层的特征建立了一个特征金字塔。由于在ResNet的最终阶段使用扩张层,因此仅利用来自第2-nd, 3-rd and 5-th 阶段的特征,这些特征由{C2、C3、C5}表示。我们在每个feature map上应用1×1卷积层,然后通过横向连接产生不同尺度{P2,P3,P5}的256通道特征图,并在C5上应用步长为2的3×3卷积层来产生coarsest(最粗)的分辨率图P6。具有{322 , 642,1282}区域的anchor被分别分配给{P2,P3,P5},具有{2562,5122}区域的anchor被分配给P6。我们认为,在训练过程中,小批量主要由小批量RoI组成,因此分配给粗特征映射的样本通常是很合适的。将大anchor合并到P6可以提高对大对象(mAPL)的检测结果。

优化:我们遵循以图像为中心的采样策略[5,22]来训练我们的模型。所有的输入图像都被调整大小,使得它们的短边是800像素,遵循[7,15]。我们在8个GPU上采用同步SGD训练。每个GPU每个小批量有2幅图像。对于每个图像,256个anchor被采样用于训练RPN,512个RoI[7]被采样,正负之比为1:3,用于训练检测器。我们使用0.0001的权重衰减和0.9的动量。对于Faster R-CNN,我们训练模型80k迭代,其学习速率为0.01,在50k迭代和65k迭代时降低了10。对于带FPN的Faster R-CNN,我们训练模型160k迭代,学习率为0.01,在100k迭代和130k迭代时降低了10。对于全局优化学习,使用我们提出的方法在基线目标检测模型上执行额外的22.5k迭代训练,学习为0.001,在15k迭代时减少10。在训练期间,我们在每个图像上计算mAP,以产生第3.3节中描述的策略梯度。在我们的实现中,在COCO评估之后,以多个(0.5:0.95)IoU阈值计算mAP,其中以多个IoU阈值计算每个实例的精度,然后对其进行平均以获得输入图像的AP。其他训练细节参见[22]。

推断:我们使用单视图测试评估所有模型。在测试时,我们将执行NMS之前和之后的区域建议数分别设置为8000和1000。最终NMS的阈值设置为0.5,这与训练是一致的。
###4.2 消融实验
为了研究我们提出的方法的性能,我们进行了一些消融实验。实验结果显示在表1中。
与基线的比较:为了与没有全局优化训练的基线模型进行公平比较,在基线上执行全局优化学习目标检测模型,其性能不能通过继续训练进一步提高。基线模型和我们提出的模型都使用与提出的改进相同的超参数进行训练,遵循上述细节。

可以看出,在贪婪的NMS环境下,我们提出的方法使Faster R-CNN检测器的mAP比36.3的基线提高了2.0点,使用FPN模型的Faster R-CNN比37.7的基线提高了1.8点。此外,对于小目标(mAPS)和精确检测(mAP75)的性能,在Faster R-CNN上分别提高了3.0和2.1,在具有FPN的Faster R-CNN上提高了3.4和2.5,这是我们用全局优化的思想要解决的核心问题。总之,我们提出的方法大大改善了基线模型。实验结果证明了该方法的有效性。检测结果的示例如图3所示。
图3 基线模型(顶部)与全局优化的目标检测器(底部,Faster R-CNN模型)。我们只保留得分高于0.5的box。我们可以看到,在我们的模型的结果中几乎找不到具有高得分的错误检测
与其他方法的比较:我们使用Faster R-CNN模型对目标函数和NMS进行了比较。我们首先将我们的方法与OHEM[25]进行了比较,达到了36.9mAP,并将基线模型改进了0.6点。可以看出,我们的模型比OHEM模型提高了1.4点,表明我们的方法在训练稀疏检测器方面比OHEM更有效。此外,我们在推理过程中通过执行软NMS[1]来测试我们的模型。软NMS是另一种旨在缩小学习和推理差距的尝试。可以看出,软NMS与OHEM的结果相似,将基线模型提高了0.6mAP。我们注意到,软NMS比基线模型改进了0.4个点(66%的改进),这表明我们的方法可以进一步缩小训练和推理阶段之间的差距。

**联合学习有多重要?**为了理解联合学习策略梯度和交叉熵损失的重要性,我们训练了一个没有交叉熵项(γ=0)的策略梯度模型。通过引入交叉熵概念,可以进一步利用注释信息,稳定训练过程。结果表明,该改进能使测定结果提高0.6mAP。注意,即使没有交叉熵损失,策略梯度也能使学习过程稳定,基线模型提高1.3点。这一结果表明政策梯度在我们的方法中起着更重要的作用。
###4.3. 与现有技术的比较
我们在挑战COCO数据集的边框检测任务上评估了我们提出的方法,并将我们的结果与最近的最新方法进行比较。表2给出了我们的模型的结果,这些模型基于Faster R-CNN和具有FPN基线的Faster R-CNN。与现有方法相比,我们的方法在COCO数据集中取得了非常有竞争力的结果。基于FPN模型的Faster R-CNN算法在极小验证集上优于其他单模型算法。表2 目标检测单模型结果。我们将所提出的方法与现有模型的结果进行比较,在COCO minivalset上进行评估。

5. 结论

本文提出了一种利用策略梯度学习全局优化目标检测器的新方法,该方法是对标准交叉熵梯度的一种简单而有效的改进。虽然我们的方法被设计用于像Faster R-CNN那样的目标检测器,但是它也可以容易地应用于现成的现代目标检测框架,这是未来有趣的工作。


由于时间仓促、水平有限,其中有许多不足之处在所难免,请见谅!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值