Facelet-Bank for Fast Portrait Manipulation(腾讯优图:用于快速人像操作的 Facelet-Bank)

本博客是腾讯优图 2018年 入选 cvpr 的论文 Facelet-Bank for Fast Portrait Manipulation 的翻译,因作者本人水平有限,部分地方翻译的可能不准确,还请读者不吝赐教,我一定马上改正!

摘要

随着智能手机和社交网络的普及,数字面部操纵已成为一种流行且引人入胜的操作图像的方式。 由于用户偏好,面部表情和配件种类繁多,因而需要通用且灵活的模型来适应不同类型的面部编辑。 在本文中,我们提出了一个基于端到端卷积神经网络的模型,该模型支持快速推理,编辑效果控制和快速局部模型更新。 另外,该模型使用具有不同属性的未配对图像集进行学习。 实验结果表明,我们的框架可以处理各种表情,配件和化妆效果。 它可以快速产生高分辨率和高质量的结果。

1.介绍

数字脸部操作旨在改变语义表达和有意义的属性,例如微笑和哀悼,或为人脸添加虚拟的妆容或者配件,比如小胡子,眼镜等。 随着智能电话和数码相机的日益普及,对实用,快速的系统的需求急剧增加。 面部操纵已成为计算机视觉和图形学火热的研究课
题[14、3、6、4、33、31、28]。举例说明: 先前的方法专门用于面部美化[19,8],反美化[10],表情操纵[28]和年龄发展[14]。

已有的解决方案,众所周知,对不同的脸部化妆或属性更改需要特殊的操作。 例如,面部美化或反美化处理肤色和纹理,而面部表情操作则更多地关注2D或3D几何。 因此,大多数方法都是专门为个别任务而设计的,其中任何专业化都需要专家的努力和领域知识来为效果的产生建立新的解决方案。

在下文中,我们将详细介绍当寻求一个数据驱动的框架来统一许多面部效果时,面部操作的基本问题。 接着介绍了以此为目标构建我们的系统的有趣工作。

1.1 可能的解决方案及其存在的问题

直接回归 从外部数据学习人脸处理操作的直接方法是直接回归编辑前的输入和编辑后的真实图像 [10, 5]。但是,这一过程需要标注好的配对数据,而很多情况下没有这些数据或者需要大量人力来创建。对于任何以前没有的效果,这些处理都不易建立。
生成对抗网络 最近,生成对抗网络(GAN)已经显示了它在集合至集合的无监督学习中的能力[36]。它使用循环一致性损失来保存图像内容,并且利用对抗损失将一系列的属性转移到另类一组中去。虽然这个概念很明了而且效果惊人,但是很难训练,特别是为了那些需要修改系统组件的新效果。训练需要保持生成和判别的平衡。我们注意到非最佳训练会导致不切实际的操作,在视觉敏感的人脸上很容易注意到
深度特征插值 深度特征插值[29]提供了另一种解决方案,可以从两个不同的集合中学习图像属性的变化。 它基于两个图像集的深层特征。 但是,它不是端到端框架,因此无法全局优化。 此外,由于它涉及数百个面部变形和卷积操作,因此即使在测试期间也需要大量计算。

1.2 我们的解决办法

我们追求用于面部操纵的通用,灵活且高质量的输出网络。 图1显示了我们的方法生成的结果。 我们的工作遵循的是编码器-解码器体系结构,而不是流行的GAN。 受style-Bank [9]学习可替换风格转换层的的启发,我们提出了一个Facelet-Bank框架,该框架使用各自的中级卷积层对面部效果进行建模。 有趣的是,为了产生不同的效果,不需要完全重新设计框架,只要更新中级卷积层即可。
在这里插入图片描述
图片一:使用我们的模型进行面部操作的插图。

同样,考虑到许多人脸操作任务缺少真实数据,我们利用[29]的结果来生成伪目标以学习facelet-bank层。 尽管伪目标通常很嘈杂,但我们的facelet库的本地接受域自然提供了正则化,因此它可以捕获视觉模式与某些网络操作之间的正确关系。

最后,我们证明了这些层可以自动出现在最重要的区域,因此可以以端到端的方式执行面部操作。 我们的方法经过专门设计,允许用户控制效果的水平,因此可以进行交互式人脸操作。 我们的整体贡献是多重的。

  • 我们提出了一个用于人脸操纵的CNN框架。 在训练中不需要配对数据。
  • 该框架可以灵活地通过仅更新几个卷积层来生成不同的效果及其级别,这使得系统开发人员易于使用。
  • 我们的方法自然受益于卷积层的局部先验,它可以规范嘈杂的标签。
  • 实验表明,我们的方法可以快速处理各种面部效果。

2.相关工作

脸部编辑 我们的工作可以归类为面部编辑或操作,这已经在计算机视觉和图形学中得到了广泛的研究[31、3、33、4、6、14]。 传统的脸部编辑包括脸部重新照明[31、3],表情编辑[33],脸部变形[4],属性编辑[6]和脸部老化[14]。 但是,这些模型是为特定任务而设计的,并且严重依赖领域知识。 我们的方法与它们不同,因为它是一个数据驱动的框架,旨在处理一般的面部效果和操作。

图像属性操作 改变图像的语义属性是一个重要的话题。 图像类比[11、7、30]将属性或外观更改从一对图像转移到一个新图像。 近年来,生成对抗网络[12、36、25、27、22]在图像生成和图像到图像转换中变得很流行。 具体来说,[12]中的方法从两组配对数据中学习属性转换。 这个想法被进一步推广到处理未配对的数据[36,27,25]。 这些方法通过训练生成器以模拟在线更新域判别器来更改属性。 但是,在设计和训练系统时,很难解决生成器和鉴别器之间的平衡问题。 放大图像尺寸会使训练更加困难。 此外,这些方法不允许控制编辑程度,例如面部的亮度,这对于实际应用非常重要。

特征插值 我们的工作还与特征插值[17、23、29、32、16、34]有关。变分自动编码器(VAE)[17,34]学习潜在空间,以便可以通过在深度空间中进行简单的算术运算来完成图像处理。但是它隐含地假设目标属性是独立的。给定用于面部操作的不成对数据,通常不满足该假设。 [29]的方法通过提出一种基于KNN的方法来使目标属性更加独立来缓解此问题。然而,仅仅拿样本的子集用于估计,这将导致结果图像中不期望的视觉伪像。另外,计算成本不可避免地很高,这对于快速的面部操纵可能是无法忍受的。我们的工作不同于这些方法。我们使用卷积神经网络来学习移动方向,从而使每个变换都与相应的视觉模式相关联。我们表明,这样,结果方向更好地独立于目标属性。此外,我们的方法是一个支持快速推理的端到端框架。

在这里插入图片描述
图片二:我们模型的图示,(a)是编码器E(·); (b)是我们的facelet-bank 的卷积层V(·); (c)是解码器D(·)。 Facelet库的结构为Conv-ReLU-Conv-ReLU-Conv,其中所有Conv都具有3×3内核。 同样,在给定先前输入的情况下,facelet bank的所有Conv都不会更改通道的高度,宽度和数量。

3.提出的方法

假设有两个具有不同属性的面部区域X和Y。 我们的目标是将域X的图像移向域Y,而无需任何配对数据的指导。 至于面部操作,我们希望该算法产生中间结果,以便用户可以控制操作强度,例如皮肤的光滑度。

这个过程可以表示为:
z = O ( x , λ ) , ( 1 ) z=O(x,\lambda) , \quad\quad(1) z=O(xλ),(1)

x和z 是输入和输出图像, λ \lambda λ 控制强度 O指把x从域X转换到域Y的操作。

请注意,域X和Y通常在语义上有所不同,因此O可能非常复杂。 为了简化O,我们改为在较深的空间中定义操作O,这样我们将等式(1)转换为:
ϕ ( z ) = O ′ ( ϕ ( x ) , λ ) ( 2 ) \phi(z)=O^\prime(\phi(x),\lambda) \quad\quad (2) ϕ(z)=O(ϕ(x)λ)(2)

这里, ϕ ( . ) \phi(.) ϕ(.) 代表深度空间,对于极限情况下,如果 ϕ ( x . ) \phi(x.) ϕ(x.) 捕获足够多的语义信息, O ′ O^\prime O 可以进一步简化为在深度空间的线性变换,即:
ϕ ( z ) = ϕ ( x ) + λ Δ v ( 3 ) \phi(z)=\phi(x)+\lambda\Delta v \quad\quad (3) ϕ(z)=ϕ(x)+λΔv(3)

这里, Δ v \Delta v Δv 代表在深度空间中,从域X到域Y的方向。

如[35]中所述,在大规模数据上训练的网络捕获卷积层中的语义属性。 [20,29]的工作验证了这一思想,该工作使用VGG网络[26]对语义信息进行编码,以进行深度特征插值或样式转换。 我们遵循此思想,使用5个卷积层构造 ϕ ( ⋅ ) \phi(·) ϕ() 。 为了表示不同级别的面部属性,将ReLU3_1,ReLU4_1和ReLU5_1共同用于表示 ϕ ( ⋅ ) \phi(·) ϕ()

反转 ϕ ( . ) \phi(.) ϕ(.) 按照[20,9],我们训练一个固定的解码器网络D对 ϕ ( z ) \phi(z) ϕ(z) 进行解码以获得最终输出。 解码器D具有编码器E的反向架构,除了将经操纵的特征连接到相应层。 我们使用以下损失函数来训练D:

L = ∑ i = 1 n ∥ z i − x i ∥ 2 2 + ω ∑ i = 1 n ∥ ε ( x i ) − ε ( D ( ε ( x i ) ) ) ∥ 2 2 , ( 4 ) L= \sum_{i=1}^n \begin{Vmatrix}z_i-x_i\end{Vmatrix}_2^2 + \omega\sum_{i=1}^n\begin{Vmatrix}\varepsilon(x_i)-\varepsilon(D(\varepsilon(x_i)))\end{Vmatrix}_2^2,\quad\quad (4) L=i=1nzixi22+ωi=1nε(xi)ε(D(ε(xi)))22(4)

其中第一项和第二项分别在像素空间和特征空间中施加一致性,而 ω \omega ω 是权衡两个损失的权重。我们还观察到,用 L = ∑ i = 1 n ∥ ( ε ( x i ) + λ Δ v i ) − ε ( D ( ε ( x i ) + λ Δ v i ) ) ∥ 2 2 L= \sum_{i=1}^n\begin{Vmatrix}(\varepsilon(x_i)+\lambda\Delta v_i)-\varepsilon(D(\varepsilon(x_i)+\lambda\Delta v_i))\end{Vmatrix}_2^2 L=i=1n(ε(xi)+λΔvi)ε(D(ε(xi)+λΔvi))22对解码器进行预训练是有帮助的,其中 Δ v i \Delta v_i Δvi 是使用等式(6)计算的不同属性的伪标签。

整体结构 整个网络架构如图2所示,它由将图像转换为深度空间的编码器E,估算域方向偏移 Δ v \Delta v Δv 的ConvNet V和将操作的深度特征转换回图像的解码器 Av 组成。 图片。 通过这种有效的流水线,编码器和解码器负责一般操作,而V是确定面部操作所需的特定效果的关键组件。

现在,实现从脸上的笑容到增加胡须的所有类型的面部效果的差异,不再需要频繁地重新设计框架。 通过使用不同的V,可以相应地完成这些看似不同的面部操作。 因此,我们将V的集合命名为Facelet Bank,表示可以实现的不同面部效果的集合。

3.1 学习 Facelet Bank

估计 Δ v \Delta v Δv 需要抵消除目标属性以外的所有因素。 如果没有成对的数据,一种简单的方法是计算X和Y之间的平均差[17,34],即:
Δ v ← 1 m ∑ i = 1 m ϕ ( y i ) − 1 n ∑ i = 1 n ϕ ( x i ) , ( 5 ) \Delta v \leftarrow \frac{1}{m} \sum_{i=1}^m \phi(y_i)- \frac{1}{n}\sum_{i=1}^n\phi(x_i),\quad\quad(5) Δvm1i=1mϕ(yi)n1i=1nϕ(xi)(5)

其中m和n分别是域X和Y的训练样本。 但是,这暗示着一个强有力的假设,即所有训练样本都具有与所查询样本相似的属性。 如果不满足此假设,则该模型不会产生实际结果。

生成伪标签 我们通过采用查询自适应属性变换模型V(x)来放宽此假设,其中x是查询样本。
注意,学习V(·)是困难的,因为我们没有成对数据来推断每个训练样本的 Δ v \Delta v Δv 。 受[29]中方法的启发,我们对两个域的每个训练样本的邻居进行平均,以构建属性向量。 具体来说,对于样本x,相应的 Δ v \Delta v Δv 计算为:
Δ v ∗ ( x ) = 1 K ∑ i ∈ N y K ( x ) ϕ ( y i ) − 1 K ∑ i ∈ N x K ( x ) ϕ ( x i ) , ( 6 ) \Delta v^*(x) =\frac{1}{K} \sum_{i \in N_y^K(x)} \phi(y_i) -\frac{1}{K} \sum_{i \in N_x^K(x)}\phi(x_i),\quad\quad (6) Δv(x)=K1iNyK(x)ϕ(yi)K1iNxK(x)ϕ(xi)(6)

其中 N y K ( x ) N_y^K(x) NyK(x) N x K ( x ) N_x^K(x) NxK(x) 分别表示集合Y和X中K 个最近邻居。 为了减少姿势,视点和旋转的影响,所有训练脸部图像都预先与正面脸部模板对齐【1】。 在这里,“平均”运算抑制了不希望的噪声,因此 Δ v ∗ \Delta v^* Δv 倾向于抵消除划分域X和Y的那些因素以外的其他因素。

网络设计 由于 Δ v ∗ \Delta v^* Δv 与深度特征密切相关,因此我们通过将V(·)的输入设置为 V ( ε ( q ) ) V(\varepsilon(q)) V(ε(q)) 来重用提取的深度特征。 我们将3个具有ReLU激活的全卷积层堆叠在一起,以捕获非线性关系。 这样,V可以学习为:
L V = ∑ i = 1 n ∥ V ( ε ( x i ) ) − Δ v ∗ ( x i ) ∥ 2 2 ( 7 ) L_V=\sum_{i=1}^n \begin{Vmatrix} V(\varepsilon(x_i))-\Delta v^*(x_i)\end{Vmatrix}_2^2 \quad\quad (7) LV=i=1nV(ε(xi))Δv(xi)22(7)

这里 x i x_i xi 指集合 X 的训练样本, Δ v ∗ \Delta v^* Δv 在等式(6)中定义。

3.2 Facelet-Bank 的更多分析

尽管我们的 facelet bank 是借助等式(7)中定义的伪配对数据 Δ v ∗ \Delta v^∗ Δv 来学习的。 但是与直接使用∆v ∗相比具有更多优势。
抗噪性 实际上,我们的 facelet bank 甚至可以胜过伪标签 Δ v ∗ \Delta v^∗ Δv 。 为了证明这一点,我们将∆v的热图计算为:
H i , j = ∑ k = 1 c v i , j , k 2 , ( 8 ) H_{i,j}=\sum_{k=1}^c v_{i,j,k}^2 ,\quad\quad (8) Hi,j=k=1cvi,j,k28

其中,i = {1,2,···,h},j = {1,2,···,w},k = {1,2,···,c} 分别表示行,列和通道对应的索引。 图3显示了“添加胡须”操作的热图。 直观上,添加胡须仅与嘴巴区域有关,而其他位置不应更新。 但是,伪目标 Δ v ∗ \Delta v^∗ Δv 在许多区域都会激活,如热图所示。 如图3(c)所示,这可能导致错误位置发生不良变化。 请注意,伪标记仅由样本2的子集计算,不足以消除所有噪声。 相反,我们的面库具有更清晰的热图,仅在正确的区域激活。
在这里插入图片描述
图片三:抗噪声效果的图示。 (a)原始图像。 (b)由等式(3)计算得到的伪移动方向的热图。 蓝色矩形标记了不需要的更改区域。 (c)等式(3)的对应结果。 (d)我们估计的方向偏移的热图。 (e)我们的结果。

尽管乍看之下似乎有点违反直觉,但如果我们考虑卷积神经网络的内置正则化,这实际上是有道理的。 请注意,CNN具有局部接收场,这迫使系统捕获某些视觉模式(在这种情况下为嘴)与相应的操纵操作(在这种情况下为“添加胡须”)之间的关系。 通过对大量样本进行训练,可以很好地抑制无关的激活,并且仅激活相关区域。

隐含的注意机制 Facelet Bank的另一个优势是隐式注意力机制。 注意,计算伪目标需要将面部预先对齐。 测试期间,我们的Facebank不需要此功能。 如图4所示,受过训练的操作适应面部的位置和姿势,并保持停留在正确的区域中。 这是完全卷积架构带来的另一个主要优势。 本质上,小面银行的卷积层捕获了某些视觉模式与相应的∆v的关系,而这些视觉模式与位置无关。 结果,小面堤岸能够检测某些图案(例如,胡须的嘴),并相应地添加效果。
在这里插入图片描述
图片四:注意力区域的可视化。 注意掩模是由等式(8)计算的。 (a),(b)和(c)对应于添加胡须,微笑和改变年龄的操作。 请注意,对于胡须效果,我们的 facelet-bank 集中在嘴巴区域。 对于微笑效果,它涉及与微笑相关的面部肌肉。 至于年龄变化效果,关注区域覆盖了整个脸部。 这些结果符合我们的直觉。

速度 用等式(3)计算 Δ v ∗ \Delta v^∗ Δv 的计算量很大。 代价主要是面部变形,深度特征提取和最近邻居搜索。 对于使用Pytorch实施的系统,并在配备Titan XP GPU和E5-2623 v4 CPU的服务器上运行,对于448×448图像的总测试时间为1.09分钟。 但是对于我们的Facelet Bank,计算V(x)仅需要网络转发,而该转发仅花费0.0194秒。

讨论 与cycleGAN [36]相比,我们的框架具有以下优势。

首先,这很容易训练。 相较于将两个生成器和两个鉴别器共同优化的cycleGAN,我们的系统只需要学习facelet bank的卷积层,既简单又快速。

其次,我们的方法可以处理更高分辨率的图像。 请注意,原始的cycleGAN已在256×256图像上证明了其有效性,而我们的方法处理的分辨率更高,例如640×480。第三,我们的工作通过修改等式(3)中的λ值,方便地改变效果的操作强度。 相反,改变cycleGAN的效应强度需要使用不同的训练数据和模型的重新训练。 另一个相关方法是DFI [29],它不需要训练即可处理最高分辨率的输入数据。 与DFI [29]相比,我们的方法在测试过程中要快得多,因为它不需要在深度空间中执行人脸对齐和KNN搜索。

4.实验

实施细节 我们使用PyTorch [1]实现我们的模型。 在训练 facelet bank 之前,我们使用Adam优化器[15]训练解码器,其初始学习率为0.0001,步长权重衰减。 训练后,解码器固定。 面部效果需要单独训练。 每个对应于 facelet bank 的一组卷积层。 具有默认超参数的Adam优化器用于训练 facelet bank 层。

数据集Celeba [21]是一个大型人脸数据集,其中包含202,599张图像,这些图像属于10,177个身份。 我们随机抽取90%进行培训,其余的用于测试。 landmark 和属性信息用于计算由等式(3)计算的伪标记 Δ v ∗ \Delta v^∗ Δv 。 但是在测试期间不使用它。 除了Celeba数据外,我们还使用Portrait [24]和Helen [18]数据集进行测试。 [24]和[18]的图像是在Flickr上收集的,这些图像具有不同的年龄,肤色,衣服,发型等。我们使用它们来验证跨数据集的泛化能力。

4.1 评估我们的方法

我们方法的重要部分是 facelet bank。 在下文中,我们将对该设计的评估分为三个部分,即 facelet bank 的有效性,使用多层聚合的原因以及强度控制的灵活性。

4.1.1 Facelet Bank的有效性

属性方向偏移 Δ v \Delta v Δv 的估计对于操纵结果至关重要。 我们将Facelet-bank解决方案与几种基准方法进行了比较。 估计 Δ v \Delta v Δv 的最简单方法是对正样本和负样本进行平均,如[17,23,32,34]的方法。 如图5所示,由于全局计算的 Δ v \Delta v Δv 不适用于查询的人脸,因此胡须位置可能不正确。 如果面部姿势与数据集的平均值相差甚远,则该方法将不可避免地失败。 直接应用由等式(6) 计算得出的 Δ v ∗ \Delta v^* Δv 缓解了这个问题。 但是,在这种情况下,肤色会被更改,因为查询的最近邻居没有完全消除颜色因子。 我们的方法学习语义视觉模式(在这种情况下为嘴巴)与相应的胡须添加操作之间的关系,这对其他区域的影响很小。

在这里插入图片描述
图片五:将我们的facelet-bank方法与基线方法进行比较。 请放大以查看详细信息。

4.1.2 多层聚合的有效性

结果表明,不同层次的层彼此互补[29]。 因此,将它们全部一起使用会产生更好的结果。 图6显示了针对“删除面部毛发”任务使用不同图层的结果。 仅使用第5层可去除大部分的面部毛发,但不完整。 通过结合层4和层3,面部毛发的量逐渐减少。使用全部的3层将其完全删除。
在这里插入图片描述
图片六:去除面部毛发的结果。 (a)原始图像; (b),(c)和(d)是分别使用第5层,第5层+第4层和所有三层的结果。 请放大以查看详细信息

4.1.3 不同的操作强度

我们的模型提供了一种快速便捷的方法来控制操作强度。 深度特征 ε ( x ) \varepsilon(x) ε(x) 和估计的属性方向偏移 Δ v \Delta v Δv 均仅计算一次。 之后,更改强度仅需要将 ε + λ Δ v \varepsilon + \lambda\Delta v ε+λΔv 转发到解码器网络。 这在我们的服务器上仅花费9毫秒。 我们认为,它可以类似地在最新的高端移动设备上实现高速。

我们在图7中显示了控制不同编辑强度的结果。对于每种情况,我们使用强度0、0.2、0.4、0.6、0.8、1、1.2、1.4、1.6和1.8来编辑原始图像。 图7相应地显示了生成的图像。 当λ> 1时,编辑可以看作是外推而不是内插。 这样可以对原始图像进行更强的编辑,但有时会产生不自然的结果。
在这里插入图片描述
图片七:不同的强度示例。 (a),(b)和(c)分别显示了不同强度的结果

4.2 与最新技术的比较

图8显示了深度特征插值(DFI)[29]和cycleGAN [36]的总体比较,后者也执行了按组设置的图像属性变换。 测试了三种效果,包括微笑,添加面部毛发和变得年轻。 通常,与CycleGAN相比,我们的方法可以获得更好的结果,而CycleGAN的结果包含更强的效果,而不会引入过多的视觉伪像。
在这里插入图片描述
在这里插入图片描述
与DFI相比,我们的方法在局部效果(例如面部毛发)方面取得了更好的性能,因为我们的方法引入了更少的无关紧要的变化。 对于其他效果,这两种方法的执行方式相似。 在计算量方面,我们的方法比DFI轻得多。 它不需要面部变形,最近邻计算和后向优化。 结果,它比DFI快3,371倍,运行时间分别为0.0194秒和65.4秒。 cycleGAN在一个方向上花费0.0185秒,这比我们的方法稍快。

解开相关属性 我们在图9中比较了“在女人身上加胡须”的结果。有趣的是,我们的模型比DFI做得更好。 值得注意的是,DFI会改变最终面孔的整体外观,而我们的方法则保留了该对象的大多数女性特征。 这是因为DFI本质上是一种基于实例的方法,在很大程度上依赖于训练样本。 由于“胡须”总是带有男人的脸部特征,因此无法区分不同的属性。
在这里插入图片描述
图片9:在女性脸上添加罕见的面部毛发; (a)是原始图像; (b)是外国直接投资的结果[29]; (c)是我们的结果。

相反,我们的方法捕获了“胡须”和“嘴巴”之间的关系。 由于前者是男性特征,而后者在两种性别中均可发现,因此我们的模型自然会忽略其他类似的关系,包括“胡须”与“性别”的比较。 因此,在上面的示例中,尽管不常见,但我们的模型产生了更好的性能。

结束语

在本文中,我们提出了用于面部操作的通用框架。 我们的框架可以从两个图像集中学习面部属性转移,而无需任何配对示例信息。 因此,它不需要费力的人为标签。 此外,我们的框架非常灵活:每个操作仅与几个计算的卷积层有关。 我们已经在实验中证明,与其他设定图像转换模型相比,该方法可产生更好的结果。

参考文献

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值