Note_004 微积分【深度学习_学习笔记】

在深度学习中,我们“训练”模型,不断更新它们,使它们在看到越来越多的数据时变得越来越好。
通常情况下,变得更好意味着最小化一个损失函数(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 . f'(x) = \lim_{h \rightarrow 0} \frac{f(x+h) - f(x)}{h}. f(x)=h0limhf(x+h)f(x).

如果 f ′ ( a ) f'(a) f(a)存在,则称 f f f a a a处是可微(differentiable)的,如果 f f f在一个区间内的每个数上都是可微的,则此函数在此区间中是可微的。
我们可以将导数 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 如下:

import numpy as np
from matplotlib_inline import 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 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

import numpy as np
from matplotlib_inline import backend_inline
from d2l import torch as d2l


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

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中流行的绘图库。

import numpy as np
import matplotlib.pyplot as plt

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

# 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

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


def set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend):
    axes.set_title("BeYoung")
    """设置matplotlib的轴"""
    axes.set_xlabel(xlabel)
    axes.set_ylabel(ylabel)
    axes.set_xscale(xscale)
    axes.set_yscale(yscale)
    axes.set_xlim(xlim)
    axes.set_ylim(ylim)
    if legend:
        axes.legend(legend)
    axes.grid()


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):
    """绘制数据点"""
    if legend is None:
        legend = []

    set_figsize(figsize)
    axes = axes if axes else plt.gca()

    # 如果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
    elif has_one_axis(Y):
        Y = [Y]
    if len(X) != len(Y):
        X = X * len(Y)
    axes.cla()
    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)
	plt.show()

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

Alt

偏导数

在深度学习中,函数通常依赖于许多变量。
因此,我们需要将微分的思想推广到多元函数(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处切线的图像。
  2. 求函数 f ( x ) = 3 x 1 2 + 5 e x 2 f(\mathbf{x}) = 3x_1^2 + 5e^{x_2} f(x)=3x12+5ex2的梯度。
  3. 函数 f ( x ) = ∥ x ∥ 2 f(\mathbf{x}) = \|\mathbf{x}\|_2 f(x)=x2的梯度是什么?
  4. 尝试写出函数 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)的链式法则。

练习答案

  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处切线的图像。

import numpy as np
import matplotlib.pyplot as plt

def f(x):
    return x ** 3 - x ** -1

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

def set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend):
    axes.set_title("BeYoung")
    """设置matplotlib的轴"""
    axes.set_xlabel(xlabel)
    axes.set_ylabel(ylabel)
    axes.set_xscale(xscale)
    axes.set_yscale(yscale)
    axes.set_xlim(xlim)
    axes.set_ylim(ylim)
    if legend:
        axes.legend(legend)
    axes.grid()

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):
    """绘制数据点"""
    if legend is None:
        legend = []

    set_figsize(figsize)
    axes = axes if axes else plt.gca()

    # 如果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
    elif has_one_axis(Y):
        Y = [Y]
    if len(X) != len(Y):
        X = X * len(Y)
    axes.cla()
    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)


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

在这里插入图片描述

  1. 求函数 f ( x ) = 3 x 1 2 + 5 e x 2 f(\mathbf{x}) = 3x_1^2 + 5e^{x_2} f(x)=3x12+5ex2的梯度。

{\kern 10pt} { f ′ x 1 = 6 x 1 f ′ x 2 = 5 e x 2 \begin{cases} f'\mathbf{x_1} = 6 \mathbf x_1\\f'\mathbf{x_2} = 5e^{x_2} \end{cases} {fx1=6x1fx2=5ex2 {\kern 50pt} ∇ f ( x ) \nabla f(\mathbf{x}) f(x) = [ 6 x 1 6 \mathbf x_1 6x1 5 e x 2 5e^{x_2} 5ex2]

  1. 函数 f ( x ) = ∥ x ∥ 2 f(\mathbf{x}) = \|\mathbf{x}\|_2 f(x)=x2的梯度是什么?
    x = ( x 1 , x 2 , x 3 , . . . , x n ) x =(x_1,x_2,x_3,...,x_n) x=(x1,x2,x3,...,xn)

{\kern 15pt} ⟹ \Longrightarrow f ( x ) = ∥ x ∥ 2 = x 1 2 + x 2 2 + . . . + x n 2 f(x) =\|\mathbf{x}\|_2=\sqrt{x_1^2 + x_2^2 + ... +x_n^2} f(x)=x2=x12+x22+...+xn2

{\kern 15pt} ⟹ \Longrightarrow
∂ f ∂ x = ( ∑ i = 1 ∞ x i 2 ∂ x 1 , ∑ i = 1 ∞ x i 2 ∂ x 2 , . . . , ∑ i = 1 ∞ x i 2 ∂ x n ) \frac{\partial f}{\partial x}= (\frac{\sqrt {\sum_{i=1}^\infty x_i^2}}{\partial x_1}, \frac{\sqrt {\sum_{i=1}^\infty x_i^2}}{\partial x_2},... ,\frac{\sqrt {\sum_{i=1}^\infty x_i^2}}{\partial x_n}) xf=(x1i=1xi2 ,x2i=1xi2 ...xni=1xi2
{\kern 15pt} ⟹ \Longrightarrow
∂ f ∂ x = ( 1 2 ∗ 2 x 1 ∗ ( ∑ i = 1 ∞ x i 2 ) − 1 2 , 1 2 ∗ 2 x 2 ∗ ( ∑ i = 1 ∞ x i 2 ) − 1 2 , . . . , 1 2 ∗ 2 x n ∗ ( ∑ i = 1 ∞ x i 2 ) − 1 2 ) \frac{\partial f}{\partial x}= (\frac{1}{2}*2x_1*(\sum_{i=1}^\infty x_i^2)^{-\frac{1}{2}},\frac{1}{2}*2x_2*(\sum_{i=1}^\infty x_i^2)^{-\frac{1}{2}},...,\frac{1}{2}*2x_n*(\sum_{i=1}^\infty x_i^2)^{-\frac{1}{2}}) xf=(212x1(i=1xi2)21,212x2(i=1xi2)21...212xn(i=1xi2)21
{\kern 15pt} ⟹ \Longrightarrow
∂ f ∂ x = ( x 1 ∑ i = 1 n x i 2 , x 2 ∑ i = 1 n x i 2 , . . . , x n ∑ i = 1 n x i 2 ) \frac{\partial f}{\partial x}= (\frac{x_1}{\sum_{i=1}^{n}x_i^2},\frac{x_2}{\sum_{i=1}^{n}x_i^2},...,\frac{x_n}{\sum_{i=1}^{n}x_i^2}) xf=(i=1nxi2x1,i=1nxi2x2,...,i=1nxi2xn)
{\kern 15pt} ⟹ \Longrightarrow
∂ f ∂ x = ( x 1 ∥ x ∥ 2 , x 2 ∥ x ∥ 2 , . . . , x n ∥ x ∥ 2 ) = x ∥ x ∥ 2 \frac{\partial f}{\partial x}= (\frac{x_1}{\|\mathbf{x}\|_2},\frac{x_2}{\|\mathbf{x}\|_2},...,\frac{x_n}{\|\mathbf{x}\|_2})=\frac{x}{\|\mathbf{x}\|_2} xf=(x2x1,x2x2,...,x2xn)=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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值