专栏首页优雅R「笔记」PyTorch预备知识与基础操作

「笔记」PyTorch预备知识与基础操作

参考:

  1. https://pytorch.apachecn.org/docs/1.4[1]
  2. 李沐《动手学深度学习》

导入

import torch # 导入整个包

查阅文档

查找模块中的函数与类

为了知道模块中可以调用哪些函数和类,我们调用 dir 函数。例如,我们可以(查询随机数生成模块中的所有属性:)

In [25]: print(dir(torch.distributions))
['AbsTransform', 'AffineTransform', 'Bernoulli', 'Beta', 'Binomial', 'CatTransform', 'Categorical', 'Cauchy', 'Chi2', 'ComposeTransform', 'ContinuousBernoulli', 'Dirichlet', 'Distribution', 'ExpTransform', 'Exponential', 'ExponentialFamily', 'FisherSnedecor', 'Gamma', 'Geometric', 'Gumbel', 'HalfCauchy', 'HalfNormal', 'Independent', 'Laplace', 'LogNormal', 'LogisticNormal', 'LowRankMultivariateNormal', 'LowerCholeskyTransform', 'MixtureSameFamily', 'Multinomial', 'MultivariateNormal', 'NegativeBinomial', 'Normal', 'OneHotCategorical', 'Pareto', 'Poisson', 'PowerTransform', 'RelaxedBernoulli', 'RelaxedOneHotCategorical', 'SigmoidTransform', 'SoftmaxTransform', 'StackTransform', 'StickBreakingTransform', 'StudentT', 'TanhTransform', 'Transform', 'TransformedDistribution', 'Uniform', 'VonMises', 'Weibull', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'bernoulli', 'beta', 'biject_to', 'binomial', 'categorical', 'cauchy', 'chi2', 'constraint_registry', 'constraints', 'continuous_bernoulli', 'dirichlet', 'distribution', 'exp_family', 'exponential', 'fishersnedecor', 'gamma', 'geometric', 'gumbel', 'half_cauchy', 'half_normal', 'identity_transform', 'independent', 'kl', 'kl_divergence', 'laplace', 'log_normal', 'logistic_normal', 'lowrank_multivariate_normal', 'mixture_same_family', 'multinomial', 'multivariate_normal', 'negative_binomial', 'normal', 'one_hot_categorical', 'pareto', 'poisson', 'register_kl', 'relaxed_bernoulli', 'relaxed_categorical', 'studentT', 'transform_to', 'transformed_distribution', 'transforms', 'uniform', 'utils', 'von_mises', 'weibull']

查找特定函数和类的用法

有关如何使用给定函数或类的更具体说明,我们可以调用 help 函数。例如,我们来[查看张量 ones 函数的用法。]

In [26]: help(torch.ones)

In [27]: ?torch.ones # 仅限于 ipython(包括 Jupyter 笔记本)
In [28]: torch.ones? # 仅限于 ipython

Tensor

Tensor(张量)类似于NumPyndarray,但还可以在GPU上使用来加速计算。

快速构建 tensor

In [2]: x = torch.arange(12) # 1 维 tensor
In [3]: x
Out[3]: tensor([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

In [2]: x = torch.empty(5, 3) # 空矩阵
In [3]: x
Out[3]: 
tensor([[0.0000e+00, 2.0000e+00, 0.0000e+00],
        [2.0000e+00, 1.1735e+36, 4.5769e-41],
        [6.5887e+35, 4.5769e-41, 0.0000e+00],
        [0.0000e+00, 6.6363e+35, 4.5769e-41],
        [6.6386e+35, 4.5769e-41, 1.1840e+36]])
In [4]: x = torch.rand(5, 3) # 随机矩阵
In [5]: x
Out[5]: 
tensor([[0.3323, 0.5025, 0.9657],
        [0.4815, 0.4241, 0.2857],
        [0.1518, 0.6936, 0.1510],
        [0.3635, 0.1421, 0.4776],
        [0.0721, 0.2776, 0.3314]])
In [2]: x = torch.zeros(5, 3, dtype=torch.long) # 零矩阵,数据类型为 long
In [3]: x
Out[3]: 
tensor([[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]])
In [2]: torch.ones(5, 3)
Out[2]: 
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]])

从数据中构造 tensor

In [4]: torch.tensor([5.4, 3])
Out[4]: tensor([5.4000, 3.0000])

In [5]: torch.tensor((5.4, 3))
Out[5]: tensor([5.4000, 3.0000])

In [6]: torch.tensor((5.4, 3), dtype = torch.double)
Out[6]: tensor([5.4000, 3.0000], dtype=torch.float64)

重用已构建 tensor 的属性创建新的 tensor:

In [3]: x = torch.rand(5, 3)

In [4]: x.new_ones(5, 3, dtype=torch.double)
Out[4]: 
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]], dtype=torch.float64)

In [5]: torch.randn_like(x, dtype=torch.float)
Out[5]: 
tensor([[ 1.0804, -1.1380, -0.8551],
        [-1.1124,  0.6538,  0.4079],
        [ 0.5622,  1.4927,  0.9899],
        [-0.0126,  1.4290,  1.8898],
        [-0.1893, -0.5293,  0.7433]])

tensor 的属性与运算

In [4]: import torch

In [5]: x = torch.rand(5, 3)

In [6]: x.size()
Out[6]: torch.Size([5, 3])

In [7]: torch.Size([5, 3]) # 本质上是元组
Out[7]: torch.Size([5, 3])

In [8]: x.numel()
Out[8]: 15
    
In [9]: y = torch.rand(5, 3)

In [10]: x + y
Out[10]: 
tensor([[1.4320, 1.2021, 0.0620],
        [1.0978, 1.0793, 1.2821],
        [1.3716, 0.8742, 0.5661],
        [0.9134, 0.1798, 1.4293],
        [0.7544, 0.7361, 1.3159]])

In [11]: torch.add(x, y) # 另一种形式
Out[11]: 
tensor([[1.4320, 1.2021, 0.0620],
        [1.0978, 1.0793, 1.2821],
        [1.3716, 0.8742, 0.5661],
        [0.9134, 0.1798, 1.4293],
        [0.7544, 0.7361, 1.3159]])
In [29]: x.shape # 与 size() 方法一致
Out[29]: torch.Size([5, 3])

原位操作(inplace,以 _ 为函数后缀,如 copy_()t_() ):

In [12]: y
Out[12]: 
tensor([[0.7367, 0.7452, 0.0162],
        [0.6207, 0.3872, 0.3586],
        [0.5303, 0.3704, 0.0873],
        [0.6344, 0.1556, 0.6411],
        [0.4608, 0.3672, 0.8274]])

In [13]: y.add_(x)
Out[13]: 
tensor([[1.4320, 1.2021, 0.0620],
        [1.0978, 1.0793, 1.2821],
        [1.3716, 0.8742, 0.5661],
        [0.9134, 0.1798, 1.4293],
        [0.7544, 0.7361, 1.3159]])

In [14]: y
Out[14]: 
tensor([[1.4320, 1.2021, 0.0620],
        [1.0978, 1.0793, 1.2821],
        [1.3716, 0.8742, 0.5661],
        [0.9134, 0.1798, 1.4293],
        [0.7544, 0.7361, 1.3159]])

索引(与NumPy一致)

In [15]: x[:, 1]
Out[15]: tensor([0.4568, 0.6921, 0.5038, 0.0242, 0.3689])

改变形状

In [16]: x.view(15)
Out[16]: 
tensor([0.6953, 0.4568, 0.0458, 0.4771, 0.6921, 0.9235, 0.8413, 0.5038, 0.4788,
        0.2789, 0.0242, 0.7882, 0.2935, 0.3689, 0.4885])

In [17]: x.view(-1, 5) # 当使用 -1 时,行的维度会自动推断
Out[17]: 
tensor([[0.6953, 0.4568, 0.0458, 0.4771, 0.6921],
        [0.9235, 0.8413, 0.5038, 0.4788, 0.2789],
        [0.0242, 0.7882, 0.2935, 0.3689, 0.4885]])
In [30]: x.reshape(-1, 5) # 使用 reshape 与 view 一致
Out[30]: 
tensor([[0.6953, 0.4568, 0.0458, 0.4771, 0.6921],
        [0.9235, 0.8413, 0.5038, 0.4788, 0.2789],
        [0.0242, 0.7882, 0.2935, 0.3689, 0.4885]])

只有一个元素时转换为标量:

In [20]: x[0, 0].item()
Out[20]: 0.6953406929969788

更多操作在 https://pytorch.org/docs/stable/torch.html[2]

节省内存

[运行一些操作可能会导致为新结果分配内存]。例如,如果我们用 y= x + y,我们将取消引用 Y 指向的张量,而是指向新分配的内存处的张量。

In [32]: before = id(y)

In [33]: y = y + x

In [34]: id(y) == before
Out[34]: False

幸运的是,(执行原地操作)非常简单。我们可以使用切片表示法将操作的结果分配给先前分配的数组,例如 y[:] = <expression>。为了说明这一点,我们首先创建一个新的矩阵 z,其形状与另一个 y 相同,使用 zeros_like 来分配一个全

的块。

In [35]: z = torch.zeros_like(y)

In [36]: print('id(z):', id(z))
id(z): 140513782045184

In [37]: z[:] = x + y

In [38]: print('id(z):', id(z))
id(z): 140513782045184

上面我们可以使用 x 替换 z ,就可以达到节省内存的目的。

对接NumPy

Torch张量和NumPy数组将共享它们的底层内存位置,因此当一个改变时,另外也会改变。

In [21]: a = torch.ones(5)

In [22]: a
Out[22]: tensor([1., 1., 1., 1., 1.])

In [23]: a.numpy()
Out[23]: array([1., 1., 1., 1., 1.], dtype=float32)

In [24]: torch.from_numpy(a.numpy())
Out[24]: tensor([1., 1., 1., 1., 1.])

CUDA上的Tensor

# 当GPU可用时,我们可以运行以下代码
# 我们将使用`torch.device`来将tensor移入和移出GPU
if torch.cuda.is_available():
    device = torch.device("cuda")          # a CUDA device object
    y = torch.ones_like(x, device=device)  # 直接在GPU上创建tensor
    x = x.to(device)                       # 或者使用`.to("cuda")`方法
    z = x + y
    print(z)
    print(z.to("cpu", torch.double))       # `.to`也能在移动时改变dtype

概率

在统计学中,我们把从概率分布中抽取样本的过程称为_抽样_(sampling)。将概率分配给一些离散选择的分布称为_多项分布_(multinomial distribution)。稍后我们将给出_分布_(distribution)的更正式定义。但笼统来说,可以把它看作是对事件的概率分配。更多查看笔记本:https://github.com/ShixiangWang/d2lNote/blob/main/pytorch/chapter_preliminaries/probability.ipynb[3]

线性代数

  • 标量
  • 向量
  • 矩阵
  • 张量

向量是标量的推广,矩阵是向量的推广,张量是任意维度的推广。**

哈达玛积

两个矩阵的按元素乘法称为 哈达玛积(Hadamard product)(数学符号

点积

给定两个向量

,它们的 点积(dot product)

(或

)是相同位置的按元素乘积的和:

矩阵-向量积

现在我们知道如何计算点积,我们可以开始理解 矩阵-向量积(matrix-vector products)。回顾矩阵

和向量

。让我们从可视化矩阵

开始,用它的行向量表示

其中每个

都是行向量,表示矩阵的

行。[矩阵向量积

是一个长度为

的列向量,其

元素是点积

]:

我们可以把一个矩阵

乘法看作是一个从

向量的转换。这些转换证明是非常有用的。例如,我们可以用方阵的乘法来表示旋转。我们将在后续章节中讲到,我们也可以使用矩阵向量乘积来描述在给定前一层的值时计算神经网络的每一层所需要的计算。在代码中使用张量表示矩阵向量积,我们使用与点积相同的 dot 函数。当我们为矩阵 A 和向量 x 调用 np.dot(A, x)时,会执行矩阵向量积。注意,A 的列维数(沿轴1的长度)必须与 x 的维数(其长度)相同。

矩阵-矩阵乘法

如果你已经掌握了点积和矩阵-向量积的知识,那么 矩阵-矩阵乘法(matrix-matrix multiplication) 应该很简单。

假设我们有两个矩阵

用行向量

表示矩阵

行,并让列向量

作为矩阵

列。要生成矩阵积

,最简单的方法是考虑

的行向量和

的列向量:

当我们简单地将每个元素

计算为点积

:

[我们可以将矩阵-矩阵乘法

看作是简单地执行

次矩阵-向量积,并将结果拼接在一起,形成一个

矩阵]。

范数

线性代数中一些最有用的运算符是 范数(norms)。非正式地说,一个向量的_范数_告诉我们一个向量有多大。这里考虑的 大小(size) 概念不涉及维度,而是分量的大小。在线性代数中,向量范数是将向量映射到标量的函数

。向量范数要满足一些属性。给定任意向量

,第一个性质说,如果我们按常数因子

缩放向量的所有元素,其范数也会按相同常数因子的 绝对值 缩放:

第二个性质是我们熟悉的三角不等式:

第三个性质简单地说范数必须是非负的:

这是有道理的,因为在大多数情况下,任何东西的最小的_大小_是0。最后一个性质要求最小范数,并且只有由所有零组成的向量才能达到最小范数。

你可能会注意到,范数听起来很像距离的度量。如果你还记得小学时的欧几里得距离(想想毕达哥拉斯定理),那么非负性的概念和三角不等式可能会给你一些启发。事实上,欧几里得距离是一个范数:具体而言,它是

范数。假设

-维向量

中的元素是

的 [

范数 是向量元素平方和的平方根:]

(

)

其中,在

范数中常常省略下标

,也就是说,

等同于

在深度学习中,我们更经常地使用平方

范数。你还会经常遇到 [

范数,它表示为向量元素的绝对值之和:]

(

)

范数相比,

范数受异常值的影响较小。为了计算

范数,我们将绝对值函数和按元素求和组合起来。

范数和

范数都是更一般的

范数的特例:

类似于向量的

范数,[矩阵]

(弗罗贝尼乌斯范数(Frobenius norm) 是矩阵元素的平方和的平方根:)

(

)

弗罗贝尼乌斯范数满足向量范数的所有性质。它的行为就好像它是矩阵形向量的

范数。

torch.norm(torch.ones((4, 9)))

在深度学习中,我们经常试图解决优化问题: 最大化 分配给观测数据的概率; 最小化 预测和真实观测之间的距离。为物品(如单词、产品或新闻文章)分配向量表示,以便最小化相似项目之间的距离,最大化不同项目之间的距离。通常,目标,或许是深度学习算法最重要的组成部分(除了数据),被表达为范数。

微分

导数和微分

假设我们有一个函数

,其输入和输出都是标量。(

导数 被定义为)

(

)

如果这个极限存在。如果

存在,则称

处是_可微_(differentiable)的。如果

在一个区间内的每个数上都是可微的,则此函数在此区间中是可微的。让我们熟悉一下导数的几个等价符号。给定

,其中

分别是函数

的自变量和因变量。以下表达式是等价的:

其中符号

是_微分运算符_,表示_微分_操作。我们可以使用以下规则来对常见函数求微分:

是一个常数)

幂律(power rule),

是任意实数)

为了微分一个由一些简单函数(如上面的常见函数)组成的函数,下面的法则使用起来很方便。假设函数

都是可微的,

是一个常数,我们有:

常数相乘法则

加法法则

乘法法则

除法法则

现在我们可以应用上述几个法则来计算

。因此,通过令

,我们有

。当

时,此导数也是曲线

切线的斜率。

偏导数

在深度学习中,函数通常依赖于许多变量。因此,我们需要将微分的思想推广到这些 多元函数 (multivariate function)上。

是一个具有

个变量的函数。

关于第

个参数

的_偏导数_(partial derivative)为:

为了计算

,我们可以简单地将

看作常数,并计算

关于

的导数。对于偏导数的表示,以下是等价的:

梯度

我们可以连结一个多元函数对其所有变量的偏导数,以得到该函数的_梯度_(gradient)向量。设函数

的输入是一个

维向量

,并且输出是一个标量。函数

相对于

的梯度是一个包含

个偏导数的向量:

其中

通常在没有歧义时被

取代。

假设

维向量,在微分多元函数时经常使用以下规则:

  • 对于所有

,都有

  • 对于所有

,都有

  • 对于所有

,都有

同样,对于任何矩阵

,我们都有

。正如我们之后将看到的,梯度对于设计深度学习中的优化算法有很大用处。

链式法则

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

让我们先考虑单变量函数。假设函数

都是可微的,根据链式法则:

现在让我们把注意力转向一个更一般的场景,即函数具有任意数量的变量的情况。假设可微分函数

有变量

,其中每个可微分函数

都有变量

。注意,

的函数。对于任意

,链式法则给出:

自动求导

深度学习框架通过自动计算导数,即 自动求导 (automatic differentiation),来加快这项工作。实际中,根据我们设计的模型,系统会构建一个 计算图 (computational graph),来跟踪数据通过若干操作组合起来产生输出。自动求导使系统能够随后反向传播梯度。这里,反向传播(backpropagate)只是意味着跟踪整个计算图,填充关于每个参数的偏导数。

autograd 包为张量上的所有操作提供了自动求导机制。它是一个在运行时定义(define-by-run)的框架,这意味着反向传播是根据代码如何运行来决定的,并且每次迭代可以是不同的。

torch.Tensor 是这个包的核心类。如果设置它的属性 .requires_gradTrue,那么它将会追踪对于该张量的所有操作。当完成计算后可以通过调用 .backward(),来自动计算所有的梯度。这个张量的所有梯度将会自动累加到.grad属性。

要阻止一个张量被跟踪历史,可以调用 .detach() 方法将其与计算历史分离,并阻止它未来的计算记录被跟踪。为了防止跟踪历史记录(和使用内存),可以将代码块包装在 with torch.no_grad(): 中。在评估模型时特别有用,因为模型可能具有 requires_grad = True 的可训练的参数,但是我们不需要在此过程中对他们进行梯度计算(评估模型的时候计算已经完成了)。

还有一个类对于autograd的实现非常重要:Function

TensorFunction 互相连接生成了一个无圈图(acyclic graph),它编码了完整的计算历史。每个张量都有一个 .grad_fn 属性(梯度函数),该属性引用了创建 Tensor 自身的Function(除非这个张量是用户手动创建的,即这个张量的 grad_fnNone )。

如果需要计算导数,可以在 Tensor 上调用 .backward()。如果 Tensor 是一个标量(即它包含一个元素的数据),则不需要为 backward() 指定任何参数,但是如果它有更多的元素,则需要指定一个 gradient 参数,该参数是形状匹配的张量。

image.png

一个例子

In [1]: import torch

In [2]: x = torch.arange(4.0)

In [3]: x
Out[3]: tensor([0., 1., 2., 3.])

In [4]: x.requires_grad_(True) # inplace 修改
Out[4]: tensor([0., 1., 2., 3.], requires_grad=True)

In [5]: x.grad

In [6]: y = 2 * torch.dot(x, x)

In [7]: y
Out[7]: tensor(28., grad_fn=<MulBackward0>)

In [8]: y.backward() # 反向传播

In [9]: x.grad
Out[9]: tensor([ 0.,  4.,  8., 12.])

In [10]: x.grad == 4 * x # 验证
Out[10]: tensor([True, True, True, True])

在默认情况下,PyTorch会累积梯度,我们需要清除之前的值:

In [11]: x.grad.zero_()
Out[11]: tensor([0., 0., 0., 0.])

In [12]: y = x.sum()

In [13]: y.backward()

In [14]: x.grad
Out[14]: tensor([1., 1., 1., 1.])

非标量变量的反向传播

y 不是标量时,向量y关于向量x的导数的最自然解释是一个矩阵。对于高阶和高维的 yx,求导的结果可以是一个高阶张量。然而,虽然这些更奇特的对象确实出现在高级机器学习中(包括[深度学习中]),但当我们调用向量的反向计算时,我们通常会试图计算一批训练样本中每个组成部分的损失函数的导数。我们的目的不是计算微分矩阵,而是批量中每个样本单独计算的偏导数之和。

对非标量调用backward需要传入一个gradient参数,该参数指定微分函数关于self的梯度。在我们的例子中,我们只想求偏导数的和,所以传递一个1的梯度是合适的

In [15]: x.grad.zero_()
Out[15]: tensor([0., 0., 0., 0.])

In [16]: y = x * x

In [17]: y.sum().backward() # 等价于y.backward(torch.ones(len(x)))

In [18]: x.grad
Out[18]: tensor([0., 2., 4., 6.])

分离计算

有时,我们希望[将某些计算移动到记录的计算图之外]。例如,假设y是作为x的函数计算的,而z则是作为yx的函数计算的。现在,想象一下,我们想计算 z 关于 x 的梯度,但由于某种原因,我们希望将 y 视为一个常数,并且只考虑到 xy被计算后发挥的作用。

在这里,我们可以分离 y 来返回一个新变量 u,该变量与 y 具有相同的值,但丢弃计算图中如何计算 y 的任何信息。换句话说,梯度不会向后流经 ux。因此,下面的反向传播函数计算 z = u * x 关于 x 的偏导数,同时将 u 作为常数处理(那么导数就是 u ),而不是z = x * x * x关于 x 的偏导数。

In [19]: x.grad.zero_()
Out[19]: tensor([0., 0., 0., 0.])

In [20]: y = x * x

In [21]: u = y.detach()

In [22]: z = u * x

In [23]: z.sum().backward()

In [24]: x.grad == u
Out[24]: tensor([True, True, True, True])

In [25]: u
Out[25]: tensor([0., 1., 4., 9.])

Python控制流的梯度计算

使用自动求导的一个好处是,[即使构建函数的计算图需要通过 Python控制流(例如,条件、循环或任意函数调用),我们仍然可以计算得到的变量的梯度]。在下面的代码中,while 循环的迭代次数和 if 语句的结果都取决于输入 a 的值。

In [26]: 
    ...: def f(a):
    ...:     b = a * 2
    ...:     while b.norm() < 1000:
    ...:         b = b * 2
    ...:     if b.sum() > 0:
    ...:         c = b
    ...:     else:
    ...:         c = 100 * b
    ...:     return c
    ...: 

In [27]: a = torch.randn(size = (), requires_grad = True)

In [28]: a
Out[28]: tensor(-0.0054, requires_grad=True)

In [29]: d = f(a)

In [30]: d.backward()

我们现在可以分析上面定义的 f 函数。请注意,它在其输入 a 中是分段线性的。换言之,对于任何 a,存在某个常量标量 k,使得 f(a) = k * a,其中 k 的值取决于输入 a。因此,d / a 允许我们验证梯度是否正确。

In [31]: d
Out[31]: tensor(-142314.2812, grad_fn=<MulBackward0>)

In [32]: a
Out[32]: tensor(-0.0054, requires_grad=True)

In [33]: d / a
Out[33]: tensor(26214400., grad_fn=<DivBackward0>)

In [34]: a.grad
Out[34]: tensor(26214400.)

向量积计算

现在我们来看一个雅可比向量积的例子:

In [38]: x = torch.randn(3, requires_grad = True)

In [39]: y = x * 2

In [40]: while y.data.norm() < 1000:
    ...:     y = y * 2
    ...: 

In [41]: print(y)
tensor([572.4341, 790.8298, 409.4621], grad_fn=<MulBackward0>)

在这种情况下,y 不再是标量。torch.autograd 不能直接计算完整的雅可比矩阵,但是如果我们只想要雅可比向量积,只需将这个向量作为参数传给 backward

In [43]: v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)

In [44]: y.backward(v)

In [45]: x.grad
Out[45]: tensor([5.1200e+01, 5.1200e+02, 5.1200e-02])

阻止 torch 梯度跟踪

可以通过将代码块包装在 with torch.no_grad(): 中,来阻止autograd跟踪设置了 .requires_grad=True 的张量的历史记录。

In [47]: x.requires_grad
Out[47]: True

In [48]: (x ** 2).requires_grad
Out[48]: True
In [50]: with torch.no_grad():
    ...:    print((x ** 2).requires_grad)
    ...: 
False

参考资料

[1]

https://pytorch.apachecn.org/docs/1.4: https://pytorch.apachecn.org/docs/1.4

[2]

https://pytorch.org/docs/stable/torch.html: https://pytorch.org/docs/stable/torch.html

[3]

https://github.com/ShixiangWang/d2lNote/blob/main/pytorch/chapter_preliminaries/probability.ipynb: https://github.com/ShixiangWang/d2lNote/blob/main/pytorch/chapter_preliminaries/probability.ipynb

本文分享自微信公众号 - 优雅R(elegant-r)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-04-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 6000星人气深度学习资源!架构模型技巧全都有,图灵奖得主LeCun推荐

    有这么一份干货,汇集了机器学习架构和模型的经典知识点,还有各种TensorFlow和PyTorch的Jupyter Notebook笔记资源,地址都在,无需等待...

    代码医生工作室
  • 6000星人气深度学习资源!架构模型技巧全都有,图灵奖得主LeCun推荐

    有这么一份干货,汇集了机器学习架构和模型的经典知识点,还有各种TensorFlow和PyTorch的Jupyter Notebook笔记资源,地址都在,无需等待...

    深度学习与Python
  • 6000星人气深度学习资源!架构模型技巧全都有,图灵奖得主LeCun推荐

    有这么一份干货,汇集了机器学习架构和模型的经典知识点,还有各种TensorFlow和PyTorch的Jupyter Notebook笔记资源,地址都在,无需等待...

    量子位
  • 带你少走弯路:强烈推荐的Pytorch快速入门资料和翻译(可下载)

    上次写了TensorFlow的快速入门资料,受到很多好评,读者强烈建议我出一个pytorch的快速入门路线,经过翻译和搜索网上资源,我推荐3份入门资料,希望对大...

    kbsc13
  • Git 与 SVN 命令基础知识笔记

    git config --global user.name "you name"  #设置用户名

    知忆
  • Linq基础知识小记四之操作EF

    1、EF简介 EF之于Linq,EF是一种包含Linq功能对象关系映射技术.EF对数据库架构和我们查询的类型进行更好的解耦,使用EF,我们查询的对象不再是C#类...

    郑小超.
  • 温州大学《深度学习》课程课件(四、浅层神经网络)

    如果是在校老师,请告知我们学校和姓名,我可以发原版ppt文件,请联系我:haiguang2000@wzu.edu.cn

    黄博的机器学习圈子
  • 温州大学《深度学习》课程课件(二、神经网络基础)

    如果是在校老师,请告知我们学校和姓名,我可以发原版ppt文件,请联系我:haiguang2000@wzu.edu.cn

    黄博的机器学习圈子
  • 超全的PyTorch学习资源汇总

    收集整理了大量的PyTorch相关教程,从博客教程,视频教程到出版书籍,开源书籍甚至PyTorch相关论文,应有尽有,号称史上最全的PyTorch学习资源汇总,...

    昱良
  • 新手必备 | 史上最全的PyTorch学习资源汇总

    (1)PyTorch英文版官方手册:https://pytorch.org/tutorials/。对于英文比较好的同学,非常推荐该PyTorch官方文档,一步步...

    磐创AI
  • PyTorch 进阶之路(四):在 GPU 上训练深度神经网络

    在之前的教程中,我们基于 MNIST 数据集训练了一个识别手写数字的 logistic 回归模型,并且达到了约 86% 的准确度。

    机器之心
  • AJAX基础知识与简单的操作示例

    AJAX代表异步的 JavaScript 和 XML。简而言之,就是使用XMLHttpRequest对象与服务器端通信的脚本语言。它可以发送和接收各种格式的信息...

    海拥
  • 双周动态|三大运营商开放用户14天内访地查询;用TinyBERT做搜索,性能达BERT 90%;区块链技术可助力公益慈善更透明

    编者按:【双周动态】是【融智未来】推出的产业动态及投融资事件回顾栏目,主要盘点两周内产业大事件和创新企业投融资动态。

    灯塔大数据
  • 2020年10月GitHub上最热门的Python开源项目

    10月份GitHub上最热门的Python开源项目排行已经出炉啦,一起来看看上榜详情吧:

    龙哥
  • Manning、陈丹琦讲座,2021斯坦福CS224N即将开课

    自然语言处理(NLP)或者计算语言学是信息时代最重要的技术之一。从网络搜索、广告、电子邮件到客户服务、语言翻译、虚拟代理、医疗报告等,NLP 的应用几乎无处不在...

    机器之心
  • 深度学习基础知识(二)--- 卷积操作与池化操作

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明...

    TeeyoHuang
  • 温州大学《深度学习》课程课件(三、浅层神经网络)

    如果是在校老师,请告知我们学校和姓名,我可以发原版ppt文件,请联系我:haiguang2000@wzu.edu.cn

    黄博的机器学习圈子
  • 布客·ApacheCN 编程/后端/大数据/人工智能学习资源 2020.11

    ApacheCN_飞龙
  • (带动画效果)卷积神经网络的讲解.pptx

    如果是在校老师,请告知我们学校和姓名,我可以发原版ppt文件(已经上过课的共8个ppt),请联系我:haiguang2000@wzu.edu.cn

    黄博的机器学习圈子

扫码关注云+社区

领取腾讯云代金券