动手学深度学习2.4微积分-笔记&练习(PyTorch)

以下内容为结合李沐老师的课程和教材补充的学习笔记,以及对课后练习的一些思考,自留回顾,也供同学之人交流参考。
本节课程地址:06 矩阵计算【动手学深度学习v2】_哔哩哔哩_bilibili

本节教材地址:2.4. 微积分 — 动手学深度学习 2.0.0 documentation (d2l.ai)

本节开源代码:…>d2l-zh>pytorch>chapter_preliminaries>calculus.ipynb


微积分

在2500年前,古希腊人把一个多边形分成三角形,并把它们的面积相加,才找到计算多边形面积的方法。
为了求出曲线形状(比如圆)的面积,古希腊人在这样的形状上刻内接多边形。
如下图所示,内接多边形的等长边越多,就越接近圆。
这个过程也被称为逼近法(method of exhaustion)。

在这里插入图片描述

事实上,逼近法就是积分(integral calculus)的起源。
2000多年后,微积分的另一支,微分(differential calculus)被发明出来。
在微分学最重要的应用是优化问题,即考虑如何把事情做到最好。
正如在 2.3.10.1节 中讨论的那样,
这种问题在深度学习中是无处不在的。

在深度学习中,我们“训练”模型,不断更新它们,使它们在看到越来越多的数据时变得越来越好。
通常情况下,变得更好意味着最小化一个损失函数(loss function),
即一个衡量“模型有多糟糕”这个问题的分数。
最终,我们真正关心的是生成一个模型,它能够在从未见过的数据上表现良好。
但“训练”模型只能将模型与我们实际能看到的数据相拟合。
因此,我们可以将拟合模型的任务分解为两个关键问题:

  • 优化(optimization):用模型拟合观测数据的过程;
  • 泛化(generalization):数学原理和实践者的智慧,能够指导我们生成出有效性超出用于训练的数据集本身的模型。

为了帮助读者在后面的章节中更好地理解优化问题和方法,
本节提供了一个非常简短的入门教程,帮助读者快速掌握深度学习中常用的微分知识。

导数和微分

我们首先讨论导数的计算,这是几乎所有深度学习优化算法的关键步骤。
在深度学习中,我们通常选择对于模型参数可微的损失函数。
简而言之,对于每个参数,
如果我们把这个参数增加减少一个无穷小的量,可以知道损失会以多快的速度增加或减少,

假设我们有一个函数 f : R → R f: \mathbb{R} \rightarrow \mathbb{R} f:RR,其输入和输出都是标量。
(如果 f f f导数存在,这个极限被定义为)

( f ′ ( x ) = lim ⁡ h → 0 f ( x + h ) − f ( x ) h .        ( 2.4.1 ) f'(x) = \lim_{h \rightarrow 0} \frac{f(x+h) - f(x)}{h}.~~~~~~(2.4.1) f(x)=h0limhf(x+h)f(x).      (2.4.1) )

如果 f ′ ( a ) f'(a) f(a)存在,则称 f f f a a a处是可微(differentiable)的。
如果 f f f在一个区间内的每个数上都是可微的,则此函数在此区间中是可微的。
我们可以将 (2.4.1) 中的导数 f ′ ( x ) f'(x) f(x)解释为 f ( x ) f(x) f(x)相对于 x x x瞬时(instantaneous)变化率。
所谓的瞬时变化率是基于 x x x中的变化 h h h,且 h h h接近 0 0 0

为了更好地解释导数,让我们做一个实验。
(定义 u = f ( x ) = 3 x 2 − 4 x u=f(x)=3x^2-4x u=f(x)=3x24x)如下:

%matplotlib inline
import numpy as np
from matplotlib_inline import backend_inline
# 导入显示和渲染图形的 backend_inline模块
from d2l import torch as d2l


def f(x):
    return 3 * x ** 2 - 4 * x

[通过令 x = 1 x=1 x=1并让 h h h接近 0 0 0] (2.4.1) 中( f ( x + h ) − f ( x ) h \frac{f(x+h)-f(x)}{h} hf(x+h)f(x)的数值结果接近 2 2 2)。
虽然这个实验不是一个数学证明,但稍后会看到,当 x = 1 x=1 x=1时,导数 u ′ u' u 2 2 2

def numerical_lim(f, x, h):
    return (f(x + h) - f(x)) / h

h = 0.1
for i in range(5):
    print(f'h={h:.5f}, numerical limit={numerical_lim(f, 1, h):.5f}')
    h *= 0.1

输出结果:

h=0.10000, numerical limit=2.30000

h=0.01000, numerical limit=2.03000

h=0.00100, numerical limit=2.00300

h=0.00010, numerical limit=2.00030

h=0.00001, numerical limit=2.00003

让我们熟悉一下导数的几个等价符号。
给定 y = f ( x ) y=f(x) y=f(x),其中 x x x y y y分别是函数 f f f的自变量和因变量。以下表达式是等价的:

f ′ ( x ) = y ′ = d y d x = d f d x = d d x f ( x ) = D f ( x ) = D x f ( x ) , f'(x) = y' = \frac{dy}{dx} = \frac{df}{dx} = \frac{d}{dx} f(x) = Df(x) = D_x f(x), f(x)=y=dxdy=dxdf=dxdf(x)=Df(x)=Dxf(x),

其中符号 d d x \frac{d}{dx} dxd D D D微分运算符,表示微分操作。
我们可以使用以下规则来对常见函数求微分:

  • D C = 0 DC = 0 DC=0 C C C是一个常数)
  • D x n = n x n − 1 Dx^n = nx^{n-1} Dxn=nxn1幂律(power rule), n n n是任意实数)
  • D e x = e x De^x = e^x Dex=ex
  • D ln ⁡ ( x ) = 1 / x D\ln(x) = 1/x Dln(x)=1/x

为了微分一个由一些常见函数组成的函数,下面的一些法则方便使用。
假设函数 f f f g g g都是可微的, C C C是一个常数,则:

常数相乘法则
d d x [ C f ( x ) ] = C d d x f ( x ) , \frac{d}{dx} [Cf(x)] = C \frac{d}{dx} f(x), dxd[Cf(x)]=Cdxdf(x),

加法法则

d d x [ f ( x ) + g ( x ) ] = d d x f ( x ) + d d x g ( x ) , \frac{d}{dx} [f(x) + g(x)] = \frac{d}{dx} f(x) + \frac{d}{dx} g(x), dxd[f(x)+g(x)]=dxdf(x)+dxdg(x),

乘法法则

d d x [ f ( x ) g ( x ) ] = f ( x ) d d x [ g ( x ) ] + g ( x ) d d x [ f ( x ) ] , \frac{d}{dx} [f(x)g(x)] = f(x) \frac{d}{dx} [g(x)] + g(x) \frac{d}{dx} [f(x)], dxd[f(x)g(x)]=f(x)dxd[g(x)]+g(x)dxd[f(x)],

除法法则

d d x [ f ( x ) g ( x ) ] = g ( x ) d d x [ f ( x ) ] − f ( x ) d d x [ g ( x ) ] [ g ( x ) ] 2 . \frac{d}{dx} \left[\frac{f(x)}{g(x)}\right] = \frac{g(x) \frac{d}{dx} [f(x)] - f(x) \frac{d}{dx} [g(x)]}{[g(x)]^2}. dxd[g(x)f(x)]=[g(x)]2g(x)dxd[f(x)]f(x)dxd[g(x)].

现在我们可以应用上述几个法则来计算 u ′ = f ′ ( x ) = 3 d d x x 2 − 4 d d x x = 6 x − 4 u'=f'(x)=3\frac{d}{dx}x^2-4\frac{d}{dx}x=6x-4 u=f(x)=3dxdx24dxdx=6x4
x = 1 x=1 x=1,我们有 u ′ = 2 u'=2 u=2:在这个实验中,数值结果接近 2 2 2
这一点得到了在本节前面的实验的支持。
x = 1 x=1 x=1时,此导数也是曲线 u = f ( x ) u=f(x) u=f(x)切线的斜率。

[为了对导数的这种解释进行可视化,我们将使用matplotlib],
这是一个Python中流行的绘图库。
要配置matplotlib生成图形的属性,我们需要(定义几个函数)。
在下面,use_svg_display函数指定matplotlib软件包输出svg图表以获得更清晰的图像。

注意,注释#@save是一个特殊的标记,会将对应的函数、类或语句保存在d2l包中。
因此,以后无须重新定义就可以直接调用它们(例如,d2l.use_svg_display())。

def use_svg_display():  #@save
    """使用svg格式在Jupyter中显示绘图"""
    backend_inline.set_matplotlib_formats('svg')

我们定义set_figsize函数来设置图表大小。
注意,这里可以直接使用d2l.plt,因为导入语句
from matplotlib import pyplot as plt已标记为保存到d2l包中。

def set_figsize(figsize=(3.5, 2.5)):  #@save
    """设置matplotlib的图表大小"""
    use_svg_display()
    d2l.plt.rcParams['figure.figsize'] = figsize

下面的set_axes函数用于设置由matplotlib生成图表的轴的属性。

#@save
def set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend):
    """设置matplotlib的轴"""
    axes.set_xlabel(xlabel)
    axes.set_ylabel(ylabel)
    axes.set_xscale(xscale)
    axes.set_yscale(yscale)
    axes.set_xlim(xlim) # X轴范围
    axes.set_ylim(ylim) # Y轴范围
    if legend:
        axes.legend(legend)
    axes.grid() # 设置绘图区网格线

通过这三个用于图形配置的函数,定义一个plot函数来简洁地绘制多条曲线,
因为我们需要在整个书中可视化许多曲线。

#@save
def plot(X, Y=None, xlabel=None, ylabel=None, legend=None, xlim=None,
         ylim=None, xscale='linear', yscale='linear',
         fmts=('-', 'm--', 'g-.', 'r:'), figsize=(3.5, 2.5), axes=None):
    """fmts是一个元组,其中包含了用于绘制多条线的不同样式4个字符串元素,这些字符串定义了每条线的绘制样式。每个字符串的格式为[颜色][线型]:
    '-'表示蓝色的实线; 'm--'表示品红色的虚线; 'g-.'表示绿色的点划线; 'r:'表示红色的点线"""
    
    """绘制数据点"""
    if legend is None:
        legend = []

    set_figsize(figsize)
    axes = axes if axes else d2l.plt.gca()
    # 用于设置变量axes的值,如果axes已经有值,则保持不变,否则将其设置为d2l.plt.gca()
    # gca = get current axes

    # 判断输入X是否为一维张量(即ndim=1) 或者 X是否为一个列表且第一个元素是一维数组,如果是,则输出True
    def has_one_axis(X):
        return (hasattr(X, "ndim") and X.ndim == 1 or isinstance(X, list)
                and not hasattr(X[0], "__len__"))

    if has_one_axis(X):
        X = [X]
    if Y is None:
        X, Y = [[]] * len(X), X
        # 在Y为空时,将X的值复制给Y,同时创建一个长度与X相同的空列表作为新X值,确保X和Y长度相等
    elif has_one_axis(Y):
        Y = [Y]
    if len(X) != len(Y):
        X = X * len(Y)
    axes.cla()
    # cla=clear the current axes,清除当前figure中的axes,其他axes不变
    for x, y, fmt in zip(X, Y, fmts):
        if len(x):
            axes.plot(x, y, fmt)
        else:
            axes.plot(y, fmt)
    set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend)

现在我们可以[绘制函数 u = f ( x ) u=f(x) u=f(x)及其在 x = 1 x=1 x=1处的切线 y = 2 x − 3 y=2x-3 y=2x3],
其中系数 2 2 2是切线的斜率。

x = np.arange(0, 3, 0.1)
plot(x, [f(x), 2 * x - 3], 'x', 'f(x)', legend=['f(x)', 'Tangent line (x=1)'])

输出结果:
在这里插入图片描述

偏导数

到目前为止,我们只讨论了仅含一个变量的函数的微分。
在深度学习中,函数通常依赖于许多变量。
因此,我们需要将微分的思想推广到多元函数(multivariate function)上。

y = f ( x 1 , x 2 , … , x n ) y = f(x_1, x_2, \ldots, x_n) y=f(x1,x2,,xn)是一个具有 n n n个变量的函数。
y y y关于第 i i i个参数 x i x_i xi偏导数(partial derivative)为:

∂ y ∂ x i = lim ⁡ h → 0 f ( x 1 , … , x i − 1 , x i + h , x i + 1 , … , x n ) − f ( x 1 , … , x i , … , x n ) h . \frac{\partial y}{\partial x_i} = \lim_{h \rightarrow 0} \frac{f(x_1, \ldots, x_{i-1}, x_i+h, x_{i+1}, \ldots, x_n) - f(x_1, \ldots, x_i, \ldots, x_n)}{h}. xiy=h0limhf(x1,,xi1,xi+h,xi+1,,xn)f(x1,,xi,,xn).

为了计算 ∂ y ∂ x i \frac{\partial y}{\partial x_i} xiy
我们可以简单地将 x 1 , … , x i − 1 , x i + 1 , … , x n x_1, \ldots, x_{i-1}, x_{i+1}, \ldots, x_n x1,,xi1,xi+1,,xn看作常数,
并计算 y y y关于 x i x_i xi的导数。
对于偏导数的表示,以下是等价的:

∂ y ∂ x i = ∂ f ∂ x i = f x i = f i = D i f = D x i f . \frac{\partial y}{\partial x_i} = \frac{\partial f}{\partial x_i} = f_{x_i} = f_i = D_i f = D_{x_i} f. xiy=xif=fxi=fi=Dif=Dxif.

梯度

我们可以连结一个多元函数对其所有变量的偏导数,以得到该函数的梯度(gradient)向量。
具体而言,设函数 f : R n → R f:\mathbb{R}^n\rightarrow\mathbb{R} f:RnR的输入是
一个 n n n维向量 x = [ x 1 , x 2 , … , x n ] ⊤ \mathbf{x}=[x_1,x_2,\ldots,x_n]^\top x=[x1,x2,,xn],并且输出是一个标量。
函数 f ( x ) f(\mathbf{x}) f(x)相对于 x \mathbf{x} x的梯度是一个包含 n n n个偏导数的向量:

∇ x f ( x ) = [ ∂ f ( x ) ∂ x 1 , ∂ f ( x ) ∂ x 2 , … , ∂ f ( x ) ∂ x n ] ⊤ , \nabla_{\mathbf{x}} f(\mathbf{x}) = \bigg[\frac{\partial f(\mathbf{x})}{\partial x_1}, \frac{\partial f(\mathbf{x})}{\partial x_2}, \ldots, \frac{\partial f(\mathbf{x})}{\partial x_n}\bigg]^\top, xf(x)=[x1f(x),x2f(x),,xnf(x)],

其中 ∇ x f ( x ) \nabla_{\mathbf{x}} f(\mathbf{x}) xf(x)通常在没有歧义时被 ∇ f ( x ) \nabla f(\mathbf{x}) f(x)取代。

假设 x \mathbf{x} x n n n维向量,在微分多元函数时经常使用以下规则:

  • 对于所有 A ∈ R m × n \mathbf{A} \in \mathbb{R}^{m \times n} ARm×n,都有 ∇ x A x = A ⊤ \nabla_{\mathbf{x}} \mathbf{A} \mathbf{x} = \mathbf{A}^\top xAx=A
  • 对于所有 A ∈ R n × m \mathbf{A} \in \mathbb{R}^{n \times m} ARn×m,都有 ∇ x x ⊤ A = A \nabla_{\mathbf{x}} \mathbf{x}^\top \mathbf{A} = \mathbf{A} xxA=A
  • 对于所有 A ∈ R n × n \mathbf{A} \in \mathbb{R}^{n \times n} ARn×n,都有 ∇ x x ⊤ A x = ( A + A ⊤ ) x \nabla_{\mathbf{x}} \mathbf{x}^\top \mathbf{A} \mathbf{x} = (\mathbf{A} + \mathbf{A}^\top)\mathbf{x} xxAx=(A+A)x
  • ∇ x ∥ x ∥ 2 = ∇ x x ⊤ x = 2 x \nabla_{\mathbf{x}} \|\mathbf{x} \|^2 = \nabla_{\mathbf{x}} \mathbf{x}^\top \mathbf{x} = 2\mathbf{x} xx2=xxx=2x

同样,对于任何矩阵 X \mathbf{X} X,都有 ∇ X ∥ X ∥ F 2 = 2 X \nabla_{\mathbf{X}} \|\mathbf{X} \|_F^2 = 2\mathbf{X} XXF2=2X
正如我们之后将看到的,梯度对于设计深度学习中的优化算法有很大用处。

链式法则

然而,上面方法可能很难找到梯度。
这是因为在深度学习中,多元函数通常是复合(composite)的,
所以难以应用上述任何规则来微分这些函数。
幸运的是,链式法则可以被用来微分复合函数。

让我们先考虑单变量函数。假设函数 y = f ( u ) y=f(u) y=f(u) u = g ( x ) u=g(x) u=g(x)都是可微的,根据链式法则:

d y d x = d y d u d u d x . \frac{dy}{dx} = \frac{dy}{du} \frac{du}{dx}. dxdy=dudydxdu.

现在考虑一个更一般的场景,即函数具有任意数量的变量的情况。
假设可微分函数 y y y有变量 u 1 , u 2 , … , u m u_1, u_2, \ldots, u_m u1,u2,,um,其中每个可微分函数 u i u_i ui都有变量 x 1 , x 2 , … , x n x_1, x_2, \ldots, x_n x1,x2,,xn
注意, y y y x 1 , x 2 , … , x n x_1, x_2, \ldots, x_n x1,x2,xn的函数。
对于任意 i = 1 , 2 , … , n i = 1, 2, \ldots, n i=1,2,,n,链式法则给出:

∂ y ∂ x i = ∂ y ∂ u 1 ∂ u 1 ∂ x i + ∂ y ∂ u 2 ∂ u 2 ∂ x i + ⋯ + ∂ y ∂ u m ∂ u m ∂ x i \frac{\partial y}{\partial x_i} = \frac{\partial y}{\partial u_1} \frac{\partial u_1}{\partial x_i} + \frac{\partial y}{\partial u_2} \frac{\partial u_2}{\partial x_i} + \cdots + \frac{\partial y}{\partial u_m} \frac{\partial u_m}{\partial x_i} xiy=u1yxiu1+u2yxiu2++umyxium

小结

  • 微分和积分是微积分的两个分支,前者可以应用于深度学习中的优化问题。
  • 导数可以被解释为函数相对于其变量的瞬时变化率,它也是函数曲线的切线的斜率。
  • 梯度是一个向量,其分量是多变量函数相对于其所有变量的偏导数。
  • 链式法则可以用来微分复合函数。

练习

  1. 绘制函数 y = f ( x ) = x 3 − 1 x y = f(x) = x^3 - \frac{1}{x} y=f(x)=x3x1和其在 x = 1 x = 1 x=1处切线的图像。

解:如下:

x = np.arange(0.1, 3, 0.1) # x不能为0
y = f(x) = x^3 - \frac{1}{x}
plot(x, [y, 4 * x - 4], 'x', 'y', legend=['y', 'Tangent line (x=1)'])
  1. 求函数 f ( x ) = 3 x 1 2 + 5 e x 2 f(\mathbf{x}) = 3x_1^2 + 5e^{x_2} f(x)=3x12+5ex2的梯度。

解:

∇ f ( x ) = ( 6 x 1 , 5 e x 2 ) \nabla f(\mathbf{x}) = (6x_1, 5e^{x_2}) f(x)=(6x1,5ex2)

  1. 函数 f ( x ) = ∥ x ∥ 2 f(\mathbf{x}) = \|\mathbf{x}\|_2 f(x)=x2的梯度是什么?

解:

∵ \because
f ( x ) = ∥ x ∥ 2 = ( ∑ i = 1 n ∣ x i ∣ 2 ) 1 / 2 f(\mathbf{x}) = \|\mathbf{x}\|_2 = \left(\sum_{i=1}^n \left|x_i \right|^2 \right)^{1/2} f(x)=x2=(i=1nxi2)1/2
∴ \therefore
∇ f ( x ) = ∂ ( ( ∑ i = 1 n ∣ x i ∣ 2 ) 1 / 2 ) ∂ x = 1 / 2 ( ( ∑ i = 1 n ∣ x i ∣ 2 ) 1 / 2 ) ⋅ 2 ( ∑ i = 1 n ∣ x i ∣ ) = x ∥ x ∥ 2 \nabla f(\mathbf{x}) = \frac{\partial (\left(\sum_{i=1}^n \left|x_i \right|^2 \right)^{1/2})}{\partial x} \\ = 1/2(\left(\sum_{i=1}^n \left|x_i \right|^2 \right)^{1/2}) · 2(\sum_{i=1}^n \left|x_i\right|) \\ = \frac{\mathbf{x}}{\|\mathbf{x}\|_2} f(x)=x((i=1nxi2)1/2)=1/2((i=1nxi2)1/2)2(i=1nxi)=x2x

  1. 尝试写出函数 u = f ( x , y , z ) u = f(x, y, z) u=f(x,y,z),其中 x = x ( a , b ) x = x(a, b) x=x(a,b) y = y ( a , b ) y = y(a, b) y=y(a,b) z = z ( a , b ) z = z(a, b) z=z(a,b)的链式法则。

解:

∂ u ∂ a = ∂ u ∂ x ∂ x ∂ a + ∂ u ∂ y ∂ y ∂ a + ∂ u ∂ z ∂ z ∂ a \frac{\partial u}{\partial a} = \frac{\partial u}{\partial x} \frac{\partial x}{\partial a} + \frac{\partial u}{\partial y} \frac{\partial y}{\partial a} + \frac{\partial u}{\partial z} \frac{\partial z}{\partial a} au=xuax+yuay+zuaz
∂ u ∂ b = ∂ u ∂ x ∂ x ∂ b + ∂ u ∂ y ∂ y ∂ b + ∂ u ∂ z ∂ z ∂ b \frac{\partial u}{\partial b} = \frac{\partial u}{\partial x} \frac{\partial x}{\partial b} + \frac{\partial u}{\partial y} \frac{\partial y}{\partial b} + \frac{\partial u}{\partial z} \frac{\partial z}{\partial b} bu=xubx+yuby+zubz

  • 22
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
动手习深度习是理解和掌握深度习的重要途径之一。PyTorch作为一个开源的深度习框架,具有易用性和灵活性,适合初者入门。下面我将介绍一些练习方法,帮助大家动手PyTorch。 首先,PyTorch的基础知识是必要的。可以通过阅读官方文档、教程和书籍等方式PyTorch的基本概念、操作和函数等知识点,了解它的使用方法和语法规则。 其次,可以通过实践来深入理解和掌握PyTorch。可以选择一些经典的深度习模型,如卷积神经网络(CNN)、递归神经网络(RNN)等,利用PyTorch的功能实现这些模型。可以从模型的搭建、训练和评估等方面入手,逐步掌握PyTorch的使用方法和技巧。 此外,实践过程中可以使用一些已有的深度习数据集,如MNIST手写数字数据集、CIFAR-10图像分类数据集等,用于模型的训练和测试。可以通过探索不同数据集的使用方法,了解数据预处理、批量处理和加载等操作。 同时,还可以PyTorch中的一些常用模块和函数,如优化器(Optimizer)、损失函数(Loss Function)等,了解它们的作用和使用方法,并在实践中尝试不同的组合和调节,优化模型的训练效果。 最后,还可以参与一些开源项目或者比赛,与其他开发者共同习和交流。可以从官方论坛、GitHub等平台获取一些有趣的项目,尝试运行和优化,加深对PyTorch的理解和运用能力。 总之,动手PyTorch的方式是最有效的方式之一。通过实践,可以深入理解深度习的原理和PyTorch的使用方法,提升自己的编程能力和解决实际问题的能力。希望以上的建议对大家有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

scdifsn

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

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

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

打赏作者

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

抵扣说明:

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

余额充值