吴恩达深度学习课程之第二门课 改善深层神经网络 第一周课程笔记

本文参考黄海广主编针对吴恩达深度学习课程DeepLearning.ai 《深度学习课程 笔记 (V5.1 )》

第一周:深度学习的实用层

1.1 训练,验证,测试集(Train / Dev / Test sets )

在配置训练、验证和测试数据集的过程中做出正确决策会在很大程度上帮助大家创建高效的神经网络。训练神经网络时,我们需要做出很多决策,例如:

神经网络分多少层  每层含有多少个隐藏单元   学习速率是多少  各层采用哪些激活函数

对于很多应用系统,即使是经验丰富的深度学习行家也不太可能开始就预设出最匹配的超级参数,所以说,应用深度学习是一个典型的迭代过程,需要多次循环往复,才能为应用程序找到一个称心的神经网络,因此循环该过程的效率是决定项目进展速度的一个关键因素,而创建高质量的训练数据集,验证集和测试集也有助于提高循环效率。

数据划分

训练集验证集测试集

假设这是训练数据,用一个长方形表示,我们通常会将这些数据划分成几部分,一部分作为训练集一部分作为简单交叉验证集,有时也称之为验证集,方便起见,我就叫它验证集(dev set),其实都是同一个概念,最后一部分则作为测试集

我们开始对训练执行算法,通过验证集或简单交叉验证集选择最好的模型,经过充分验证,我们选定了最终模型,然后就可以在测试集上进行评估了,为了无偏评估算法的运行状况。

在机器学习发展的小数据量时代,常见做法是将所有数据三七分,就是人们常说的 70%验证集,30%测试集,如果没有明确设置验证集,也可以按照 60%训练,20%验证和 20%测试集来划分。这是前几年机器学习领域普遍认可的最好的实践方法。如果只有 100 条,1000 条或者 1 万条数据,那么上述比例划分是非常合理的。
但是在大数据时代,我们现在的数据量可能是百万级别,那么验证集和测试集占数据总量的比例会趋向于变得更小因为验证集的目的就是验证不同的算法,检验哪种算法更有效,并迅速判断出哪种算法更有效。我们可能不需要拿出 20%的数据作为验证集。

总结一下,在机器学习中,我们通常将样本分成训练集,验证集和测试集三部分,数据集规模相对较小,适用传统的划分比例,数据集规模较大的,验证集和测试集要小于数据总量的 20%或 10%。

因为你们要用验证集来评估不同的模型,尽可能地优化性能。如果验证集和测试集来自同一个分布就会很好。但由于深度学习算法需要大量的训练数据,为了获取更大规模的训练数据集,我们可以采用当前流行的各种创意策略,例如,网页抓取,代价就是训练集数据与验证集和测试集数据有可能不是来自同一分布。但只要遵循这个经验法则,你就会发现机器学习算法会变得更快。

最后一点,就算没有测试集也不要紧测试集的目的是对最终所选定的神经网络系统做出无偏估计,如果不需要无偏估计,也可以不设置测试集。所以如果只有验证集,没有测试集,我们要做的就是,在训练集上训练,尝试不同的模型框架,在验证集上评估这些模型,然后迭代并选出适用的模型。因为验证集中已经涵盖测试集数据,其不再提供无偏性能评估。当然,如果你不需要无偏估计,那就再好不过了。

在机器学习中,如果只有一个训练集和一个验证集,而没有独立的测试集,遇到这种情况,训练集还被人们称为训练集,而验证集则被称为测试集,不过在实际应用中,人们只是把测试集当成简单交叉验证集使用,并没有完全实现该术语的功能,因为他们把验证集数据过度拟合到了测试集中。如果某团队跟你说他们只设置了一个训练集和一个测试集,我会很谨慎,心想他们是不是真的有训练验证集,因为他们把验证集数据过度拟合到了测试集中,让这些团队改变叫法,改称其为“训练验证集”,而不是“训练测试集”,可能不太容易。即便我认为“训练验证集“在专业用词上更准确。实际上,如果你不需要无偏评估算法性能,那么这样是可以的。

所以说,搭建训练验证集测试集能够加速神经网络的集成,也可以更有效地衡量算法地偏差和方差,从而帮助我们更高效地选择合适方法来优化算法。

1.2 偏差,方差(Bias /Variance)

假设这就是数据集,如果给这个数据集拟合一条直线,可能得到一个逻辑回归拟合,但它并不能很好地拟合该数据,这是高偏差(high bias)的情况,我们称为“欠拟合” (underfitting)

相反的如果我们拟合一个非常复杂的分类器,比如深度神经网络或含有隐藏单元的神经网络,可能就非常适用于这个数据集,但是这看起来也不是一种很好的拟合方式分类器方差较高(high variance),数据过度拟合(overfitting)

在两者之间,可能还有一些像图中这样的,复杂程度适中,数据拟合适度的分类器,这个数据拟合看起来更加合理,我们称之为“适度拟合”(just right)是介于过度拟合和欠拟合中间的一类。

理解偏差和方差的两个关键数据是训练集误差(Train set error)和验证集误差(Dev set error),为了方便论证,假设我们可以辨别图片中的小猫,我们用肉眼识别几乎是不会出错的

1. 假定训练集误差是 1%,假定验证集误差是 11%,可以看出训练集设置得非常好,而验证集设置相对较差,我们可能过度拟合了训练集,在某种程度上,验证集并没有充分利用交叉验证集的作用,像这种情况,我们称之为“高方差”。通过查看训练集误差和验证集误差,我们便可以诊断算法是否具有高方差。也就是说衡量训练集和验证集误差就可以得出不同结论。
2. 假设训练集误差是 15%,验证集误差是 16%,假设该案例中人的错误率几乎为 0%,人们浏览这些图片,分辨出是不是猫。算法并没有在训练集中得到很好训练,如果训练数据的拟合度不高,就是数据欠拟合,就可以说这种算法偏差比较高。相反,它对于验证集产生的结果却是合理的,验证集中的错误率只比训练集的多了 1%,所以这种算法偏差高,因为它甚至不能拟合训练集,这与上一张幻灯片最左边的图片相似。
3. 训练集误差是 15%,偏差相当高,但是,验证集的评估结果更糟糕,错误率达到 30%,在这种情况下,我会认为这种算法偏差高,因为它在训练集上结果不理想,而且方差也很高,这是方差偏差都很糟糕的情况。
4. 训练集误差是 0.5%,验证集误差是 1%,用户看到这样的结果会很开心,猫咪分类器只有 1%的错误率,偏差和方差都很低

假设人眼辨别的错误率接近 0%,一般来说,最优误差也被称为贝叶斯误差,所以,最优误差接近 0%,我就不在这里细讲了,如果最优误差或贝叶斯误差非常高,比如 15%。我们再看看这个分类器(训练误差 15%,验证误差 16%),15%的错误率对训练集来说也是非常合理的,偏差不高,方差也非常低。相对值。

总结一下,我们讲了如何通过分析在训练集上训练算法产生的误差和验证集上验证算法产生的误差来诊断算法是否存在高偏差和高方差,是否两个值都高,或者两个值都不高,根据算法偏差和方差的具体情况决定接下来你要做的工作。

1.3 机器学习基础(Basic Recipe for Machine Learning)

如果网络足够大,通常可以很好的拟合训练集,但是图片很模糊,算法可能无法拟合该图片,但如果有人可以分辨出图片,如果你觉得基本误差不是很高,那么训练一个更大的网络,至少可以很好地拟合训练集。一旦偏差降低到可以接受的数值,检查一下方差有没有问题,为了评估方差,我们要查看验证集性能,我们能从一个性能理想的训练集推断出验证集的性能是否也理想,如果方差高,最好的解决办法就是采用更多数据,如果你能做到,会有一定的帮助,但有时候,我们无法获得更多数据,我们也可以尝试通过正则化来减少过拟合,这个我们下节课会讲。有时候我们不得不反复尝试,但是,如果能找到更合适的神经网络框架,有时它可能会一箭双雕,同时减少方差和偏差。如何实现呢?想系统地说出做法很难,总之就是不断重复尝试,直到找到一个低偏差,低方差的框架,这时你就成功了。

有两点需要大家注意:
第一点,高偏差和高方差是两种不同的情况,我们后续要尝试的方法也可能完全不同,我通常会用训练验证集来诊断算法是否存在偏差或方差问题,然后根据结果选择尝试部分方法。举个例子,如果算法存在高偏差问题,准备更多训练数据其实也没什么用处,至少这不是更有效的方法,所以大家要清楚存在的问题是偏差还是方差,还是两者都有问题,明确这一点有助于我们选择出最有效的方法。
第二点,在机器学习的初期阶段,关于所谓的偏差方差权衡的讨论屡见不鲜,原因是我们能尝试的方法有很多。可以增加偏差,减少方差,也可以减少偏差,增加方差,但是在深度学习的早期阶段,我们没有太多工具可以做到只减少偏差或方差却不影响到另一方。但在当前的深度学习和大数据时代,只要持续训练一个更大的网络,只要准备了更多数据,那么也并非只有这两种情况,我们假定是这样,那么,只要正则适度,通常构建一个更大的网络便可以,在不影响方差的同时减少偏差,而采用更多数据通常可以在不过多影响偏差的同时减少方差。这两步实际要做的工作是:训练网络,选择网络或者准备更多数据,现在我们有
工具可以做到在减少偏差或方差的同时,不对另一方产生过多不良影响。我觉得这就是深度学习对监督式学习大有裨益的一个重要原因,也是我们不用太过关注如何平衡偏差和方差的一个重要原因
,但有时我们有很多选择,减少偏差或方差而不增加另一方。最终,我们会得到一个非常规范化的网络。

从下节课开始,我们将讲解正则化,训练一个更大的网络几乎没有任何负面影响,而训练一个大型神经网络的主要代价也只是计算时间,前提是网络是比较规范化的。

1.4 正则化(Regularization)

深度学习可能存在过拟合问题——高方差,有两个解决方法,一个是正则化,另一个是准备更多的数据,这是非常可靠的方法,但你可能无法时时刻刻准备足够多的训练数据或者获取更多数据的成本很高,但正则化通常有助于避免过拟合或减少你的网络误差。下图为在神经网络中实现L2正则化

为什么只正则化参数w?为什么不再加上参数 b呢?你可以这么做,只是我习惯省略不写,因为𝑥通常是一个高维参数矢量,已经可以表达高偏差问题,w可能包含有很多参数,我们不可能拟合所有参数,而b只是单个数字,所以w几乎涵盖所有参数,而不是b,如果加了参数b,其实也没太大影响,因为b只是众多参数中的一个,所以我通常省略不计,如果你 想加上这个参数,完全没问题。

如果用的是L1正则化,w最终会是稀疏的,也就是说w向量中有很多 0,有人说这样有利于压缩模型,因为集合中参数均为 0,存储模型所占用的内存更少。实际上,虽然L1正则化使模型变得稀疏,却没有降低太多存储内存,所以我认为这并不是L1正则化的目的,至少不是为了压缩模型,人们在训练网络时,越来越倾向于使用L2正则化。
我们来看最后一个细节,λ 是正则化参数,我们通常使用验证集或交叉验证集来配置这个参数,尝试各种各样的数据,寻找最好的参数,我们要考虑训练集之间的权衡,把参数设置为较小值,这样可以避免过拟合,所以 λ 是另外一个需要调整的超级参数,顺便说一下,为了方便写代码,在 Python 编程语言中,λ 是一个保留字段,编写代码时,我们删掉a,写成lambd,以免与Python 中的保留字段冲突,这在逻辑回归函数中实现L2正则化的过程。

1.5 为 什 么 正 则 化 有 利 于 预 防 过 拟 合 呢 ? ( Why regularization reduces overfitting? )

我们添加正则项,它可以避免数据权值矩阵过大,这就是弗罗贝尼乌斯范数,为什么压缩L2范数,或者弗罗贝尼乌斯范数或者参数可以减少过拟合?

直观上理解就是如果正则化λ 设置得足够大,权重矩阵W被设置为接近于 0 的值,直观理解就是把多隐藏单元的权重设为 0,于是基本上消除了这些这种情况,这个被大大简化了的神经网络会变成一个很小的网络,小到如同一个逻辑回归单元,可是深度却很大,它会使这个网络从过度拟合的状态更接近左图的高偏差状态。

但是λ会存在一个中间值,于是会有一个接近“Just Right”的中间状态。直观理解就是λ增加到足够大,𝑋会接近于 0,实际上是不会发生这种情况的,我们尝试消除或至少减少许多隐藏单元的影响,最终这个网络会变得更简单,这个神经网络越来越接近逻辑回归,我们直觉上认为大量隐藏单元被完全消除了其实不然,实际上是该神经网络的所有隐藏单元依然存在,但是它们的影响变得更小了。神经网络变得更简单了,貌似这样更不容易发生过拟合,因此我不确定这个直觉经验是否有用,不过在编程中执行正则化时,你实际看到一些方差减少的结果。

我们再来直观感受一下,正则化为什么可以预防过拟合,假设我们用的是这样的双曲线
激活函数。

用g(z)表示tanℎ(z),那么我们发现,只要z非常小,如果z只涉及少量参数,这里我们利用了双曲正切函数的线性状态,只要z可以扩展为这样的更大值或者更小值,激活函数开始变得非线性。

 

结一下,如果正则化参数变得很大,参数W很小,z也会相对变小,此时忽略b的影响,z会相对变小,实际上,z的取值范围很小,这个激活函数,也就是曲线函数tanℎ会相对呈线性,整个神经网络会计算离线性函数近的值,这个线性函数非常简单,并不是一个极复杂的高度非线性函数,不会发生过拟合。

正则化要记住梯度函数使用的代价函数增加了正则项。这就是L2正则化,它是我在训练深度学习模型时最常用的一种方法。在深度学习中,还有一种方法也用到了正则化,就是 dropout 正则化,我们下节课再讲。

1.6 dropout 正则化(Dropout Regularization )

除了L2正则化,还有一个非常实用的正则化方法——“Dropout(随机失活)”,我们来看看它的工作原理。

假设你在训练上图这样的神经网络,它存在过拟合,这就是 dropout 所要处理的,我们复制这个神经网络,dropout 会遍历网络的每一层,并设置消除神经网络中节点的概率。假设网络中的每一层,每个节点都以抛硬币的方式设置概率,每个节点得以保留和消除的概率都是 0.5,设置完节点概率,我们会消除一些节点,然后删除掉从该节点进出的连线,最后得到一个节点更少,规模更小的网络,然后用 backprop 方法进行训练。

这是网络节点精简后的一个样本,对于其它样本,我们照旧以抛硬币的方式设置概率,保留一类节点集合,删除其它类型的节点集合。对于每个训练样本,我们都将采用一个精简后神经网络来训练它,这种方法似乎有点怪,单纯遍历节点,编码也是随机的,可它真的有效。不过可想而知,我们针对每个训练样本训练规模极小的网络,最后你可能会认识到为什么要正则化网络,因为我们在训练极小的网络。

如何实施 dropout 呢?方法有几种,接下来我要讲的是最常用的方法,即 inverteddropout(反向随机失活),出于完整性考虑,我们用一个三层(𝑚 = 3)网络来举例说明。编码中会有很多涉及到 3 的地方。我只举例说明如何在某一层中实施 dropout。

1.7 理解 dropout (Understanding Dropout )

Dropout 可以随机删除网络中的神经单元,他为什么可以通过正则化发挥如此大的作用呢?
直观上理解:不要依赖于任何一个特征,因为该单元的输入可能随时被清除,因此该单元通过这种方式传播下去,并为单元的四个输入增加一点权重,通过传播所有权重,dropout将产生收缩权重的平方范数的效果,和之前讲的L2正则化类似;实施 dropout 的结果实它会压缩权重,并完成一些预防过拟合的外层正则化L2对不同权重的衰减是不同的,它取决于激活函数倍增的大小

第二个直观认识是,我们从单个神经元入手,如图,这个单元的工作就是输入并生成一些有意义的输出。通过 dropout,该单元的输入几乎被消除,有时这两个单元会被删除,有时会删除其它单元。

总结一下,dropout 的功能类似于L2正则化,与L2正则化不同的是,被应用的方式不同,dropout 也会有所不同,甚至更适用于不同的输入范围。

总结一下,如果你担心某些层比其它层更容易发生过拟合,可以把某些层的 keep-prob值设置得比其它层更低,缺点是为了使用交叉验证,你要搜索更多的超级参数,另一种方案是在一些层上应用 dropout,而有些层不用 dropout,应用 dropout 的层只含有一个超级参数,就是 keep-prob。 

结束前分享两个实施过程中的技巧,实施 dropout,在计算机视觉领域有很多成功的第一次。计算视觉中的输入量非常大,输入太多像素,以至于没有足够的数据,所以 dropout在计算机视觉中应用得比较频繁,有些计算机视觉研究人员非常喜欢用它,几乎成了默认的选择,但要牢记一点,dropout 是一种正则化方法,它有助于预防过拟合,因此除非算法过拟合,不然我是不会使用 dropout 的,所以它在其它领域应用得比较少,主要存在于计算机视觉领域,因为我们通常没有足够的数据,所以一直存在过拟合,这就是有些计算机视觉研究人员如此钟情于 dropout 函数的原因。直观上我认为不能概括其它学科。

dropout 一大缺点就是代价函数 J 不再被明确定义,每次迭代,都会随机移除一些节点,如果再三检查梯度下降的性能,实际上是很难进行复查的。定义明确的代价函数 J 每次迭代后都会下降,因为我们所优化的代价函数 J 实际上并没有明确定义,或者说在某种程度上很难计算,所以我们失去了调试工具来绘制这样的图片。

1.8 其他正则化方法(Other regularization methods)

除了L2正则化和随机失活(dropout)正则化,还有几种方法可以减少神经网络中的过
拟合:

一.数据扩增

假设你正在拟合猫咪图片分类器,如果你想通过扩增训练数据来解决过拟合,但扩增数据代价高,而且有时候我们无法扩增数据,但我们可以通过添加这类图片来增加训练集。例如,水平翻转图片,并把它添加到训练集。所以现在训练集中有原图,还有翻转后的这张图片,所以通过水平翻转图片,训练集则可以增大一倍,因为训练集有冗余,这虽然不如我们额外收集一组新图片那么好,但这样做节省了获取更多猫咪图片的花费。(随意翻转和裁剪图片

和全新的,独立的猫咪图片数据相比,这些额外的假的数据无法包含像全新数据那么多的信息,但我们这么做基本没有花费,代价几乎为零,除了一些对抗性代价。以这种方式扩增算法数据,进而正则化数据集,减少过拟合比较廉价。

二.early stopping

还有另外一种常用的方法叫作 early stopping,运行梯度下降时,我们可以绘制训练误差,或只绘制代价函数 J 的优化过程,在训练集上用 0-1 记录分类误差次数。呈单调下降趋势,如图。

因为在训练过程中,我们希望训练误差,代价函数 J 都在下降,通过 early stopping,我们不但可以绘制上面这些内容,还可以绘制验证集误差,它可以是验证集上的分类误差,或验证集上的代价函数,逻辑损失和对数损失等,你会发现,验证集误差通常会先呈下降趋势,然后在某个节点处开始上升,early stopping 的作用是,你会说,神经网络已经在这个迭代过程中表现得很好了,我们在此停止训练吧,得到验证集误差,它是怎么发挥作用的?

 early stopping 要做就是在中间点停止迭代过程,我们得到一个w值中等大小的弗罗贝尼乌斯范数,与𝑀2正则化相似,选择参数 w 范数较小的神经网络,但愿你的神经网络过度拟合不严重。

机器学习过程包括几个步骤:

1. 其中一步是选择一个算法来优化代价函数J,我们有很多种工具来解决这个问题,如梯度下降,后面我会介绍其它算法,例如 Momentum,RMSprop 和 Adam 等等。

2. 但是优化代价函数J之后,我也不想发生过拟合,也有一些工具可以解决该问题,比如正则化,扩增数据等等。

early stopping 的主要缺点就是不能独立地处理这两个问题,因为提早停止梯度下降,也就是停止了优化代价函数J,因为现在你不再尝试降低代价函数 J,所以代价函数𝐾的值可能不够小,同时你又希望不出现过拟合,你没有采取不同的方式来解决这两个问题,而是用一种方法同时解决两个问题,这样做的结果是我要考虑的东西变得更复杂。如果不用 early stopping,另一种方法就是L2正则化训练神经网络的时间就可能很长。我发现,这导致超级参数搜索空间更容易分解,也更容易搜索,但是缺点在于,你必须尝试很多正则化参数λ的值,这也导致搜索大量λ值的计算代价太高。

Early stopping 的优点是,只运行一次梯度下降可以找出w的较小值,中间值和较大值,而无需尝试𝑀2正则化超级参数λ的很多值。

这节课讲了如何使用数据扩增,以及如何使用 early stopping 降低神经网络中的方差或预防过拟合。

1.9 归一化输入(Normalizing inputs )

训练神经网络,其中一个加速训练的方法就是归一化输入。假设一个训练集有两个特征,输入特征为 2 维,归一化需要两个步骤:零均值和归一化方差;

1.10 梯度消失/ 梯度爆炸(Vanishing / Exploding gradients )

训练神经网络,尤其是深度神经所面临的一个问题就是梯度消失或梯度爆炸,也就是你训练神经网络的时候,导数或坡度有时会变得非常大,或者非常小,甚至于以指数方式变小,这加大了训练的难度。

总结一下,我们讲了深度神经网络是如何产生梯度消失或爆炸问题的,实际上,在很长一段时间内,它曾是训练深度神经网络的阻力,虽然有一个不能彻底解决此问题的解决方案,但是已在如何选择初始化权重问题上提供了很多帮助。

1.11 神经网络的权重初始化(Weight Initialization for Deep NetworksVanishing / Exploding gradients )

希望对梯度消失或爆炸问题以及如何为权重初始化合理值已经有了一个直观认识,希望设置的权重矩阵既不会增长过快,也不会太快下降到 0,从而训练出一个权重或梯度不会增长或消失过快的深度网络。我们在训练深度网络时,这也是一个加快训练速度的技巧。

1.12 梯度的数值逼近(Numerical approximation of gradients)

在实施 backprop 时,有一个测试叫做梯度检验它的作用是确保 backprop 正确实施。因为有时候,你虽然写下了这些方程式,却不能 100%确定,执行 backprop 的所有细节都是正确的。为了逐渐实现梯度检验,我们首先说说如何计算梯度的数值逼近,下节课,我们将讨论如何在 backprop 中执行梯度检验,以确保 backprop 正确实施。

 

使用双边误差来判断别人给你的函数是否正确实现了函数的偏导

1.13 梯度检验(Gradient checking )

1.14 梯 度 检 验 应 用 的 注 意 事 项 ( Gradient Checking Implementation Notes)

1. 首先,不要在训练中使用梯度检验,它只用于调试。

2. 第二点,如果算法的梯度检验失败,要检查所有项,检查每一项,并试着找出 bug。

3. 第三点,在实施梯度检验时,如果使用正则化,请注意正则项,新的代价函数

4. 第四点,梯度检验不能与 dropout 同时使用,因为每次迭代过程中,dropout 会随机消除隐藏层单元的不同子集,难以计算 dropout 在梯度下降上的代价函数 J。因此 dropout 可作为优化代价函数J 的一种方法,但是代价函数J被定义为对所有指数极大的节点子集求和。

最后一点,也是比较微妙的一点,现实中几乎不会出现这种情况。当w和b接近 0 时,下降的实施是正确的,在随机初始化过程中……,但是在运行梯度下降时,w和b变得更大。可能只有在w和b接近 0 时,backprop 的实施才是正确的。但是当w和b变大时,它会变得越来越不准确。你需要做一件事,我不经常这么做,就是在随机初始化过程中,运行梯度检验,然后再训练网络,w和b会有一段时间远离 0,如果随机初始化值比较小,反复训练网络之后,再重新运行梯度检验。

回顾这一周,我们讲了如何配置训练集,验证集和测试集,如何分析偏差和方差,如何处理高偏差或高方差以及高偏差和高方
差并存的问题,如何在神经网络中应用不同形式的正则化,如L2正则化和 dropout,还有加快神经网络训练速度的技巧,最后是梯度检验。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Clark-dj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值