计算机视觉(四):浅层/深层神经网络

计算机视觉笔记总目录


1 神经网络的表达能力

理解具有全连接层的神经网络的一个方式是:可以认为它们定义了一个由一系列函数组成的函数族,网络的权重就是每个函数的参数。如此产生的问题是:该函数族的表达能力如何?存在不能被神经网络表达的函数吗?

现在看来,拥有至少一个隐层的神经网络是一个通用的近似器。在研究(例如1989年的论文Approximation by Superpositions of Sigmoidal Function,或者Michael Nielsen的这个直观解释。)中已经证明,给出任意连续函数 f ( x ) f(x) f(x) 和任意 ϵ > 0 \epsilon>0 ϵ>0 ,均存在一个至少含1个隐层的神经网络 g ( x ) g(x) g(x) (并且网络中有合理选择的非线性激活函数,比如sigmoid等),对于 ∀ x \forall x x,使得 ∣ f ( x ) − g ( x ) ∣ < ϵ |f(x)-g(x)|<\epsilon f(x)g(x)<ϵ换句话说,神经网络可以近似任何连续函数。

2 浅层神经网络的前向传播与反向传播

2.1 浅层神经网络表示

之前已经说过神经网络的结构了,在这不重复叙述。假设我们有如下结构的网络
在这里插入图片描述
对于这个网络我们建立一个简单的图示?我们对第一个隐藏层记为[1],输出层为[2]。如下图
在这里插入图片描述
计算图如下
在这里插入图片描述
每个神经元的计算分解步骤如下
在这里插入图片描述
第一层中的第一个神经元

  • ​​ z 1 [ 1 ] = ( w 1 [ 1 ] ) T x + b 1 [ 1 ] z _1^{[1]} = (w_1^{[1]})^Tx+b_1^{[1]} z1[1]=(w1[1])Tx+b1[1]
  • a 1 [ 1 ] = σ ( z 1 [ 1 ] ) a _1^{[1]} = \sigma(z _1^{[1]}) a1[1]=σ(z1[1])

第一层中的第二个神经元

  • ​​ z 2 [ 1 ] = ( w 2 [ 1 ] ) T x + b 2 [ 1 ] z _2^{[1]} = (w_2^{[1]})^Tx+b_2^{[1]} z2[1]=(w2[1])Tx+b2[1]
  • a 2 [ 1 ] = σ ( z 2 [ 1 ] ) a _2^{[1]} = \sigma(z _2^{[1]}) a2[1]=σ(z2[1])

得出第一层的计算:
在这里插入图片描述
第一层多个样本的向量化表示

  • Z [ 1 ] = W [ 1 ] X + b [ 1 ] Z^{[1]} = W^{[1]}X+b^{[1]} Z[1]=W[1]X+b[1]

2.2 激活函数的前向传播和反向传播(了解)

将上述网络的隐层激活函数修改为tanh,最后一层同样还是二分类,所以最后一层激活函数依然选择sigmoid函数

前向传播:

Z [ 1 ] = W [ 1 ] X + b [ 1 ] Z^{[1]} = W^{[1]}X+b^{[1]} Z[1]=W[1]X+b[1]

A [ 1 ] = t a n h ( Z [ 1 ] {A}^{[1]}=tanh(Z^{[1]} A[1]=tanh(Z[1]

Z [ 2 ] = W [ 2 ] A [ 1 ] + b [ 2 ] Z^{[2]} = W^{[2]}A^{[1]}+b^{[2]} Z[2]=W[2]A[1]+b[2]

A [ 2 ] = σ ( Z [ 2 ] ) A^{[2]}=\sigma(Z^{[2]}) A[2]=σ(Z[2])

反向梯度下降:

那么通过这个计算图来理解这个过程,单个样本的计算图:
在这里插入图片描述
由于网络已经存在两层,所以我们需要从后往前得到导数结果,并且多个样本的情况下改写成

最后一个输出层的参数的导数:

d Z [ 2 ] = A [ 2 ] − Y dZ^{[2]}=A^{[2]}-Y dZ[2]=A[2]Y

d W [ 2 ] = 1 m d Z [ 2 ] A [ 1 ] T dW^{[2]}=\frac{1}{m}dZ^{[2]}{A^{[1]}}^{T} dW[2]=m1dZ[2]A[1]T

d b [ 2 ] = 1 m n p . s u m ( d Z [ 2 ] , a x i s = 1 ) db^{[2]}=\frac{1}{m}np.sum(dZ^{[2]}, axis=1) db[2]=m1np.sum(dZ[2],axis=1)

隐藏层的导数计算:

d Z [ 1 ] = W [ 2 ] T d Z [ 2 ] ∗ g ′ ( Z [ 1 ] ) = W [ 2 ] T d Z [ 2 ] ∗ ( 1 − g 2 ( Z [ 1 ] ) ) = W [ 2 ] T d Z [ 2 ] ∗ ( 1 − ( A [ 1 ] ) 2 ) dZ^{[1]} = {W^{[2]}}^{T}dZ^{[2]}*g'(Z^{[1]})={W^{[2]}}^{T}dZ^{[2]}*{ \Big( 1-g^{2}(Z^{[1]})} \Big) = {W^{[2]}}^{T}dZ^{[2]}*{(1-(A^{[1]})^{2})} dZ[1]=W[2]TdZ[2]g(Z[1])=W[2]TdZ[2](1g2(Z[1]))=W[2]TdZ[2](1(A[1])2)

d W [ 1 ] = 1 m d Z [ 1 ] X T dW^{[1]}=\frac{1}{m}dZ^{[1]}X^{T} dW[1]=m1dZ[1]XT

d b [ 1 ] = 1 m n p . s u m ( d Z [ 1 ] , a x i s = 1 ) db^{[1]} = \frac{1}{m}np.sum(dZ^{[1]}, axis=1) db[1]=m1np.sum(dZ[1],axis=1)

注: f ( x ) = t a n h ( x ) f(x) = tanh(x) f(x)=tanh(x) 的导数 f ′ ( x ) = 1 − f 2 ( x ) f'(x) = 1-f^{2}(x) f(x)=1f2(x)

3 神经网络激活函数的选择

涉及到网络的优化时候,会有不同的激活函数选择有一个问题是神经网络的隐藏层和输出单元用什么激活函数。之前我们都是选用 sigmoid 函数,但有时其他函数的效果会好得多,大多数通过实践得来,没有很好的解释性。

可供选用的激活函数有:

  • tanh 函数(the hyperbolic tangent function,双曲正切函数):
    在这里插入图片描述
    效果比 sigmoid 函数好,因为函数输出介于 -1 和 1 之间。

    注 : tanh 函数存在和 sigmoid 函数一样的缺点:当 z 趋紧无穷大(或无穷小),导数的梯度(即函数的斜率)就趋紧于 0,这使得梯度算法的速度会减慢。

  • ReLU 函数(the rectified linear unit,修正线性单元)
    在这里插入图片描述
    当 z > 0 时,梯度始终为 1,从而提高神经网络基于梯度算法的运算速度,收敛速度远大于 sigmoid 和 tanh。然而当 z < 0 时,梯度一直为 0,但是实际的运用中,该缺陷的影响不是很大。

  • Leaky ReLU(带泄漏的 ReLU):
    在这里插入图片描述
    Leaky ReLU 保证在 z < 0 的时候,梯度仍然不为 0。理论上来说,Leaky ReLU 有 ReLU 的所有优点,但在实际操作中没有证明总是好于 ReLU,因此不常用。

3.1 为什么需要非线性的激活函数

使用非线性激活函数和不使用激活函数、直接使用 Logistic 回归没有区别,那么无论神经网络有多少层,输出都是输入的线性组合,与没有隐藏层效果相当,就成了最原始的感知器了。

a [ 1 ] = z [ 1 ] = W [ 1 ] x + b [ 1 ] {a}^{[1]}=z^{[1]} = W^{[1]}x+b^{[1]} a[1]=z[1]=W[1]x+b[1]

a [ 2 ] = z [ 2 ] = W [ 2 ] a [ 1 ] + b [ 2 ] {a}^{[2]}=z^{[2]} = W^{[2]}a^{[1]}+b^{[2]} a[2]=z[2]=W[2]a[1]+b[2]

那么这样的话相当于

a [ 2 ] = z [ 2 ] = W [ 2 ] ( W [ 1 ] x + b [ 1 ] ) + b [ 2 ] = ( W [ 2 ] W [ 1 ] ) x + ( W [ 2 ] b [ 1 ] + b [ 2 ] ) = w x + b {a}^{[2]}=z^{[2]} = W^{[2]}(W^{[1]}x+b^{[1]})+b^{[2]}=(W^{[2]}W^{[1]})x+(W^{[2]}b^{[1]}+b^{[2]})=wx+b a[2]=z[2]=W[2](W[1]x+b[1])+b[2]=(W[2]W[1])x+(W[2]b[1]+b[2])=wx+b

3.2 激活函数对比总结

  • Sigmoid函数饱和使梯度消失。sigmoid神经元有一个不好的特性,就是当神经元的激活在接近0或1处时会饱和:在这些区域,梯度几乎为0。

  • Tanh:和sigmoid神经元一样,它也存在饱和问题,但是和sigmoid神经元不同的是,它的输出是零中心的(sigmoid为0.5)。

  • Relu:

    • 优点:

      • 相较于sigmoid和tanh函数,ReLU对于随机梯度下降的收敛有巨大的加速作用,这是由它的线性,非饱和的公式导致的。
      • sigmoid和tanh神经元含有指数运算等耗费计算资源的操作,而ReLU可以简单地通过对一个矩阵进行阈值计算得到。
    • 缺点:在训练的时候,ReLU单元比较脆弱并且可能“死掉”。

      • 举例来说,当一个很大的梯度流过ReLU的神经元的时候,可能会导致梯度更新到一种特别的状态。如果这种情况发生,那么从此所有流过这个神经元的梯度将都变成0。也就是说,这个ReLU单元在训练中将不可逆转的死亡,因为这导致了数据多样化的丢失。例如,如果学习率设置得太高,可能会发现网络中40%的神经元都会死掉(在整个训练集中这些神经元都不会被激活)。通过合理设置学习率,这种情况的发生概率会降低。
  • Leaky ReLU:

    • Leaky ReLU是为解决“ReLU死亡”问题的尝试。ReLU中当x<0时,函数值为0。而Leaky ReLU则是给出一个很小的负数梯度值,比如0.01。所以其函数公式为 f ( x ) = α x ( x < 0 ) + x ( x > 0 ) f(x) = \alpha x(x<0) + x(x>0) f(x)=αx(x<0)+x(x>0) 其中 α \alpha α 是一个小的常量。有些研究者的论文指出这个激活函数表现很不错,但是其效果并不是很稳定。何凯明等人在2015年发布的论文Delving Deep into Rectifiers中介绍了一种新方法PReLU把负区间上的斜率当做每个神经元中的一个参数。(但是这里的a不是固定下来的,而是可学习的) 然而该激活函数在在不同任务中均有益处的一致性并没有特别清晰。

总结:“那么该用那种呢?”用ReLU非线性函数。注意设置好学习率,或许可以监控你的网络中死亡的神经元占的比例。如果单元死亡问题困扰你,就试试Leaky ReLU,不要再用sigmoid了。

4 为什么使用深层网络

1、神经网络在实践中非常好用,是因为它们表达出的函数不仅平滑,而且对于数据的统计特性有很好的拟合。同时,网络通过最优化算法(例如梯度下降)能比较容易地学习到这个函数。类似的,虽然在理论上深层网络(使用了多个隐层)和单层网络的表达能力是一样的,但是就实践经验而言,深度网络效果比单层网络好。

2、对于人脸识别等应用,神经网络的第一层从原始图片中提取人脸的轮廓和边缘,每个神经元学习到不同边缘的信息;网络的第二层将第一层学得的边缘信息组合起来,形成人脸的一些局部的特征,例如眼睛、嘴巴等;后面的几层逐步将上一层的特征组合起来,形成人脸的模样。随着神经网络层数的增加,特征也从原来的边缘逐步扩展为人脸的整体,由整体到局部,由简单到复杂。层数越多,那么模型学习的效果也就越精确。

通过例子可以看到,随着神经网络的深度加深,模型能学习到更加复杂的问题,功能也更加强大。

5 深层神经网络表示

5.1 什么是深层网络?

在这里插入图片描述
使用浅层网络的时候很多分类等问题得不到很好的解决,所以需要深层的网络。

6 四层网络计算过程

在这里插入图片描述
在这里首先对每层的符号进行一个确定,我们设置L为第几层,n为每一层的个数,L=[L1,L2,L3,L4],n=[5,5,3,1]

6.1 前向传播

首先还是以单个样本来进行表示,每层经过线性计算和激活函数两步计算

z [ 1 ] = W [ 1 ] x + b [ 1 ] , a [ 1 ] = g [ 1 ] ( z [ 1 ] ) , 输 入 x , 输 出 a [ 1 ] z^{[1]} = W^{[1]}x+b^{[1]}, a^{[1]}=g^{[1]}(z^{[1]}),输入x, 输出a^{[1]} z[1]=W[1]x+b[1],a[1]=g[1](z[1]),x,a[1]

z [ 2 ] = W [ 2 ] a [ 1 ] + b [ 2 ] , a [ 2 ] = g [ 2 ] ( z [ 2 ] ) , 输 入 a [ 1 ] , 输 出 a [ 2 ] z^{[2]} = W^{[2]}a^{[1]}+b^{[2]}, a^{[2]}=g^{[2]}(z^{[2]}),输入a^{[1]}, 输出a^{[2]} z[2]=W[2]a[1]+b[2],a[2]=g[2](z[2]),a[1],a[2]

z [ 3 ] = W [ 3 ] a [ 2 ] + b [ 3 ] , a [ 3 ] = g [ 3 ] ( z [ 3 ] ) , 输 入 a [ 2 ] , 输 出 a [ 3 ] z^{[3]} = W^{[3]}a^{[2]}+b^{[3]},a^{[3]}=g^{[3]}(z^{[3]}), 输入a^{[2]} , 输出a^{[3]} z[3]=W[3]a[2]+b[3],a[3]=g[3](z[3]),a[2],a[3]

z [ 4 ] = W [ 4 ] a [ 3 ] + b [ 4 ] , a [ 4 ] = σ ( z [ 4 ] ) , 输 入 a [ 3 ] , 输 出 a [ 4 ] z^{[4]} = W^{[4]}a^{[3]}+b^{[4]},a^{[4]}=\sigma(z^{[4]}), 输入a^{[3]}, 输出a^{[4]} z[4]=W[4]a[3]+b[4],a[4]=σ(z[4]),a[3],a[4]

我们将上式简单的用通用公式表达出来, x = a [ 0 ] x = a^{[0]} x=a[0]

z [ L ] = W [ L ] a [ L − 1 ] + b [ L ] , a [ L ] = g [ L ] ( z [ L ] ) , 输 入 a [ L − 1 ] ​ ​ , 输 出 a [ L ] z^{[L]} = W^{[L]}a^{[L-1]}+b^{[L]},a^{[L]}=g^{[L]}(z^{[L]}), 输入a^{[L-1]}​​ , 输出a^{[L]} z[L]=W[L]a[L1]+b[L],a[L]=g[L](z[L]),a[L1],a[L]

m个样本的向量表示

Z [ L ] = W [ L ] A [ L − 1 ] + b [ L ] Z^{[L]} = W^{[L]}A^{[L-1]} + b^{[L]} Z[L]=W[L]A[L1]+b[L]

A [ L ] = g [ L ] ( Z [ L ] ) A^{[L]}=g^{[L]}(Z^{[L]}) A[L]=g[L](Z[L])

输 入 A [ L − 1 ] , 输 出 A [ L ] 输入A^{[L-1]}, 输出A^{[L]} A[L1],A[L]

6.2 反向传播

因为涉及到的层数较多,所以我们通过一个图来表示反向的过程
在这里插入图片描述
反向传播的结果(理解)

单个样本的反向传播:
d Z [ l ] = d J d a [ l ] d a [ l ] d Z [ l ] = d a [ l ] ∗ g ′ [ l ] ( Z [ l ] ) dZ^{[l]} = \frac{dJ}{da^{[l]}}\frac{da^{[l]}}{dZ^{[l]}}=da^{[l]}*g'^{[l]}(Z^{[l]}) dZ[l]=da[l]dJdZ[l]da[l]=da[l]g[l](Z[l])

d W [ l ] = d J d Z [ l ] d Z [ l ] d W [ l ] = d Z [ l ] ⋅ a [ l − 1 ] dW^{[l]}=\frac{dJ}{dZ^{[l]}}\frac{dZ^{[l]}}{dW^{[l]}}=dZ^{[l]}\cdot a^{[l-1]} dW[l]=dZ[l]dJdW[l]dZ[l]=dZ[l]a[l1]

d b [ l ] = d J d Z [ l ] d Z [ l ] d b [ l ] = d Z [ l ] db^{[l]}=\frac{dJ}{dZ^{[l]}}\frac{dZ^{[l]}}{db^{[l]}}=dZ^{[l]} db[l]=dZ[l]dJdb[l]dZ[l]=dZ[l]

d a [ l − 1 ] = W [ l ] T ⋅ d Z [ l ] da^{[l-1]}=W^{[l]T}\cdot dZ^{[l]} da[l1]=W[l]TdZ[l]

多个样本的反向传播:

d Z [ l ] = d A [ l ] ∗ g ′ [ l ] ( Z [ l ] ) dZ^{[l]}=dA^{[l]}* g'^{[l]}(Z^{[l]}) dZ[l]=dA[l]g[l](Z[l])

d W [ l ] = 1 m d Z [ l ] ⋅ A [ l − 1 ] T dW^{[l]}=\frac{1}{m}dZ^{[l]}\cdot {A^{[l-1]}}^{T} dW[l]=m1dZ[l]A[l1]T

d b [ l ] = 1 m n p . s u m ( d Z [ l ] , a x i s = 1 ) db^{[l]}=\frac{1}{m}np.sum(dZ^{[l]},axis=1) db[l]=m1np.sum(dZ[l],axis=1)

d A [ l ] = W [ l + 1 ] T ⋅ d Z [ l + 1 ] dA^{[l]}=W^{[l+1]T}\cdot dZ^{[l+1]} dA[l]=W[l+1]TdZ[l+1]

7 参数与超参数

7.1 参数

参数即是我们在过程中想要模型学习到的信息(模型自己能计算出来的),例如 W [ l ] , b [ l ] W[l],b[l] W[l]b[l]。而超参数(hyper parameters) 即为控制参数的输出值的一些网络信息(需要人经验判断)。超参数的改变会导致最终得到的参数 W [ l ] , b [ l ] W[l],b[l] W[l]b[l] 的改变。
​​

7.2 超参数

典型的超参数有:

  • 学习速率: α \alpha α
  • 迭代次数: N N N
  • 隐藏层的层数: L L L
  • 每一层的神经元个数: n [ 1 ] , n [ 2 ] , . . . n[1],n[2],... n[1]n[2]...
  • 激活函数 g ( z ) g(z) g(z) 的选择

当开发新应用时,预先很难准确知道超参数的最优值应该是什么。因此,通常需要尝试很多不同的值。应用深度学习领域是一个很大程度基于经验的过程。

7.3 参数初始化

1.为什么要随机初始化权重

如果在初始时将两个隐藏神经元的参数设置为相同的大小,那么两个隐藏神经元对输出单元的影响也是相同的,通过反向梯度下降去进行计算的时候,会得到同样的梯度大小,所以在经过多次迭代后,两个隐藏层单位仍然是对称的。无论设置多少个隐藏单元,其最终的影响都是相同的,那么多个隐藏神经元就没有了意义。

在初始化的时候,W 参数要进行随机初始化,不可以设置为 0。b 因为不存在上述问题,可以设置为 0。

以 2 个输入,2 个隐藏神经元为例:

W = np.random.rand(2,2)* 0.01
b = np.zeros((2,1))

2.初始化权重的值选择

这里将 W 的值乘以 0.01(或者其他的常数值)的原因是为了使得权重 W 初始化为较小的值,这是因为使用 sigmoid 函数或者 tanh 函数作为激活函数时,W 比较小,则 Z=WX+b 所得的值趋近于 0,梯度较大,能够提高算法的更新速度。而如果 W 设置的太大的话,得到的梯度较小,训练过程因此会变得很慢。

ReLU 和 Leaky ReLU 作为激活函数时不存在这种问题,因为在大于 0 的时候,梯度均为 1。
在这里插入图片描述

7.4 设置层的数量和尺寸

在面对一个具体问题的时候该确定网络结构呢?到底是不用隐层呢?还是一个隐层?两个隐层或更多?每个层的尺寸该多大?

首先,要知道当我们增加层的数量和尺寸时,网络的容量上升了。即神经元们可以合作表达许多复杂函数,所以表达函数的空间增加。例如,如果有一个在二维平面上的二分类问题。可以训练3个不同的神经网络,每个网络都只有一个隐层,但是每层的神经元数目不同,更大的神经网络可以表达更复杂的函数。数据是用不同颜色的圆点表示他们的不同类别,决策边界是由训练过的神经网络做出的。
在这里插入图片描述
举例来说,有20个神经元隐层的网络拟合了所有的训练数据,但是其代价是把决策边界变成了许多不相连的红绿区域。而有3个神经元的模型的表达能力只能用比较宽泛的方式去分类数据。它将数据看做是两个大块,并把个别在绿色区域内的红色点看做噪声。在实际中,这样可以在测试数据中获得更好的泛化(generalization)能力。

总结:

1、看起来如果数据不是足够复杂,则似乎小一点的网络更好,因为可以防止过拟合。然而并非如此,防止神经网络的过拟合有很多方法(L2正则化,dropout和输入噪音等),后面会详细讨论。

2、不要减少网络神经元数目的主要原因在于小网络更难使用梯度下降等局部方法来进行训练:虽然小型网络的损失函数的局部极小值更少,也比较容易收敛到这些局部极小值,但是这些最小值一般都很差,损失值很高。相反,大网络拥有更多的局部极小值,但就实际损失值来看,这些局部极小值表现更好,损失更小。因为神经网络是非凸的,就很难从数学上研究这些特性。

  • 还是有一些文章尝试对这些目标函数进行理解,例如The Loss Surfaces of Multilayer Networks这篇论文。在实际中,
    • 如果训练的是一个小网络,那么最终的损失值将展现出多变性:某些情况下运气好会收敛到一个好的地方,某些情况下就收敛到一个不好的极值。从另一方面来说,
    • 如果你训练一个大的网络,你将发现许多不同的解决方法,但是最终损失值的差异将会小很多。这就是说,所有的解决办法都差不多,而且对于随机初始化参数好坏的依赖也会小很多。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
深层神经网络相比于浅层神经网络具有更强的表达能力和学习能力,这一点可以通过以下理论证明来支持: 1. 逼近定理(Approximation Theorem):深层神经网络可以以任意精度逼近任意连续函数。这意味着,通过增加网络的深度,我们可以更好地拟合复杂的非线性函数关系。 2. 堆叠表示(Hierarchical Representation):深层神经网络可以通过逐层学习特征表示,从而构建出更加抽象和高级的特征表示。每一层都可以将前一层的输出作为输入,并进一步提取更高级别的特征。这种层次化的表示能力使得深层神经网络能够更好地捕捉数据中的复杂结构和模式。 3. 梯度传播(Gradient Propagation):深层神经网络使用反向传播算法来进行训练,通过计算损失函数对网络参数的梯度并将其传播回网络中,从而更新参数。在深层网络中,梯度可以更好地传播到较早的层,使得整个网络能够更好地进行参数更新和学习。 4. 参数共享(Parameter Sharing):深层神经网络中的参数共享可以减少网络的参数量,提高模型的泛化能力。通过共享参数,网络可以更好地利用数据中的统计信息,从而提高模型的效率和性能。 5. 迁移学习(Transfer Learning):深层神经网络可以通过预训练在大规模数据集上的模型,将学到的特征迁移到新的任务上。这种迁移学习的能力使得深层神经网络在数据较少的情况下也能取得较好的性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

GeniusAng丶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值