ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

pytorch基础

2021-10-13 12:58:31  阅读:183  来源: 互联网

标签:partial tensor torch 基础 张量 pytorch print grad


文章目录

下载安装:

https://pytorch.org/get-started/locally/

张量tensor

简介

几何代数中定义的张量是基于向量和矩阵的推广,比如我们可以将标量视为零阶张量,矢量可以视为一阶张量,矩阵就是二阶张量。

0维张量/标量 标量是一个数字(scalar)

x = torch.tensor(42.)
x
'''
tensor(42.)
'''
x.dim()#维度
'''
0
'''
x.item()#返回value
'''
42.0
'''
2 * x
'''
tensor(84.)
'''

1维张量/向量 1维张量称为“向量”。(vector)

v = torch.tensor([1.5, -0.5, 3.0])
v
'''
tensor([ 1.5000, -0.5000,  3.0000])
'''
v.dim()
'''
1
'''
v.size()
'''
torch.Size([3])
'''

2维张量 2维张量称为矩阵(matrix)

M = torch.tensor([[1., 2.], [3., 4.]])
M
'''
tensor([[1., 2.],
        [3., 4.]])
'''
M.mean()#求均值
'''
tensor(2.5000)
'''

乘法

M.matmul(M)
'''
tensor([[ 7., 10.],
        [15., 22.]])
'''
torch.tensor([1., 0.]).matmul(M)
'''
tensor([1., 2.])
'''
M * M
'''
tensor([[ 1.,  4.],
        [ 9., 16.]])
'''
torch.tensor([1., 2.]).matmul(M)
'''
tensor([ 7., 10.])
'''

加法

x = torch.rand(4, 3) 
x
'''
tensor([[0.3352, 0.2696, 0.5885],
        [0.3994, 0.0066, 0.2920],
        [0.1103, 0.7191, 0.3511],
        [0.5951, 0.7503, 0.8069]])
'''
y = torch.rand(4, 3) 
y
'''
tensor([[0.9592, 0.7950, 0.2895],
        [0.7109, 0.9559, 0.0147],
        [0.7786, 0.7916, 0.2050],
        [0.2201, 0.9062, 0.3068]])
'''
x + y
'''
tensor([[1.2944, 1.0646, 0.8780],
        [1.1103, 0.9625, 0.3067],
        [0.8889, 1.5107, 0.5561],
        [0.8152, 1.6564, 1.1137]])
'''
torch.add(x, y)
'''
tensor([[1.2944, 1.0646, 0.8780],
        [1.1103, 0.9625, 0.3067],
        [0.8889, 1.5107, 0.5561],
        [0.8152, 1.6564, 1.1137]])
'''
# 方式3 提供一个输出 tensor 作为参数
result = torch.empty(4, 3) 
torch.add(x, y, out=result) 
print(result)
'''
tensor([[1.2944, 1.0646, 0.8780],
        [1.1103, 0.9625, 0.3067],
        [0.8889, 1.5107, 0.5561],
        [0.8152, 1.6564, 1.1137]])
'''
# 方式4 in-place
y.add_(x) 
print(y)
'''
tensor([[1.2944, 1.0646, 0.8780],
        [1.1103, 0.9625, 0.3067],
        [0.8889, 1.5107, 0.5561],
        [0.8152, 1.6564, 1.1137]])
'''

3维张量 :公用数据存储在张量 时间序列数据 股价 文本数据 彩色图片(RGB) (n-dimensional tensor)

使用PIL读入一张图片

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
​
pil_im = Image.open('01.jpg')
​
plt.imshow(pil_im)
plt.show()

对于计算机来说,图像是一个由数字组成的巨大的三维数组。在这个图的例子中,图像的大小是高198像素,宽190像素,有3个颜色通道,分别是红、绿和蓝(简称RGB)。如此,该图像就包含了198×190×3=112860个数字,每个数字都是处于范围0~255之间的整型,其中0表示黑,255表示白。

np_im = np.array(pil_im)
print(np_im.shape,np_im.dtype)
np_im
'''
(198, 190, 3) uint8
array([[[ 30,  29,  35],
        [ 30,  29,  35],
        [ 36,  35,  41],
        ...,
        [ 27,  31,  30],
        [ 30,  32,  31],
        [ 40,  42,  41]],

       [[ 32,  31,  37],
        [ 28,  27,  33],
        [ 28,  27,  33],
        ...,
        [ 27,  31,  30],
        [ 30,  32,  31],
        [ 40,  42,  41]],

       [[ 31,  30,  35],
        [ 25,  24,  29],
        [ 22,  21,  26],
        ...,
        [ 27,  31,  30],
        [ 30,  32,  31],
        [ 40,  42,  41]],

       ...,

       [[173, 180, 172],
        [174, 181, 173],
        [175, 182, 174],
        ...,
        [158, 159, 153],
        [159, 160, 155],
        [160, 161, 156]],

       [[161, 168, 160],
        [164, 171, 163],
        [168, 175, 167],
        ...,
        [162, 163, 157],
        [164, 165, 160],
        [164, 165, 160]],

       [[156, 163, 155],
        [160, 167, 159],
        [165, 172, 164],
        ...,
        [165, 166, 160],
        [166, 167, 162],
        [167, 168, 163]]], dtype=uint8)
'''

转换为tensor格式

tensor_pil = torch.from_numpy(np.transpose(np_im, (2, 0, 1)))
tensor_pil
'''
tensor([[[ 30,  30,  36,  ...,  27,  30,  40],
         [ 32,  28,  28,  ...,  27,  30,  40],
         [ 31,  25,  22,  ...,  27,  30,  40],
         ...,
         [173, 174, 175,  ..., 158, 159, 160],
         [161, 164, 168,  ..., 162, 164, 164],
         [156, 160, 165,  ..., 165, 166, 167]],

        [[ 29,  29,  35,  ...,  31,  32,  42],
         [ 31,  27,  27,  ...,  31,  32,  42],
         [ 30,  24,  21,  ...,  31,  32,  42],
         ...,
         [180, 181, 182,  ..., 159, 160, 161],
         [168, 171, 175,  ..., 163, 165, 165],
         [163, 167, 172,  ..., 166, 167, 168]],

        [[ 35,  35,  41,  ...,  30,  31,  41],
         [ 37,  33,  33,  ...,  30,  31,  41],
         [ 35,  29,  26,  ...,  30,  31,  41],
         ...,
         [172, 173, 174,  ..., 153, 155, 156],
         [160, 163, 167,  ..., 157, 160, 160],
         [155, 159, 164,  ..., 160, 162, 163]]], dtype=torch.uint8)
'''
tensor_pil.dim()
'''
3
'''
tensor_pil.size()
'''
torch.Size([3, 198, 190])
'''

张量是现代机器学习的基础。它的核心是一个数据容器,多数情况下,它包含数字,有时候它也包含字符串,但这种情况比较少。因此可以把它想象成一个数字的水桶。

这里有一些存储在各种类型张量的公用数据集类型:

3维=时间序列
4维=图像
5维=视频
例子:一个图像可以用三个字段表示:

(width, height, channel) = 3D

但是,在机器学习工作中,我们经常要处理不止一张图片或一篇文档——我们要处理一个集合。我们可能有10,000张郁金香的图片,这意味着,我们将用到4D张量:

(sample_size, width, height, channel) = 4D

在PyTorch中, torch.Tensor 是存储和变换数据的主要工具。如果你之前用过NumPy,你会发现 Tensor 和NumPy的多维数组非常类似。然而,Tensor 提供GPU计算和自动求梯度等更多功能,这些使 Tensor 这一数据类型更加适合深度学习。

Scalar, vector, matrix, tensor - a drawing by Tai-Danae Bradley

创建tensor

import torch #导包
?torch.tensor #查看文档

常见的构造Tensor的函数

a = torch.rand(2, 3) #构造一个随机初始化的矩阵
a
'''
tensor([[0.8229, 0.3761, 0.9514],
        [0.1849, 0.7565, 0.7958]])
'''
b = torch.randn(4, 2) #随机数服从正态分布
b
'''
tensor([[ 0.3622,  0.4899],
        [-0.5874,  0.0016],
        [ 0.8994, -0.5036],
        [ 0.9156,  0.3732]])
'''
c = torch.ones(2, 3) #全1
c
'''
tensor([[1., 1., 1.],
        [1., 1., 1.]])
'''
d = torch.zeros(2, 3) #全0
d
'''
tensor([[0., 0., 0.],
        [0., 0., 0.]])
'''
e = torch.arange(0, 10, 2) #从0到10,步长为2
e
'''
tensor([0, 2, 4, 6, 8])
'''
f = torch.linspace(1,10,5) #从1到10,均分为5个
f
'''
tensor([ 1.0000,  3.2500,  5.5000,  7.7500, 10.0000])
'''
g = torch.eye(3,2) #对角为1,其余为0
g
'''
tensor([[1., 0.],
        [0., 1.],
        [0., 0.]])
'''
h = torch.randperm(10) #随机排列
h
'''
tensor([3, 0, 1, 8, 4, 5, 7, 9, 6, 2])
'''
i = torch.tensor([5.5, 3]) #直接使用数据,构造一个张量
i
'''
tensor([5.5000, 3.0000])
'''

基于已经存在的 tensor,创建一个 tensor :

j = i.new_ones(4, 3, dtype=torch.double) # 创建一个新的tensor,返回的tensor默认具有相同的 torch.dtype和torch.device
# 也可以像之前的写法 x = torch.ones(4, 3, dtype=torch.double)
print(j)
k = torch.randn_like(j, dtype=torch.float)
# 重置数据类型
print(k)
# 结果会有一样的size
'''
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]], dtype=torch.float64)
tensor([[ 1.4550,  0.7617, -0.0454],
        [-0.5241, -0.1855, -0.1790],
        [ 0.1177,  0.5916,  0.1550],
        [-1.1339, -1.9725, -1.4337]])
'''

empty创建一个未被初始化数值的tensor,tensor的大小是由size确定

l=torch.empty(size=[2,4],out=k)
l
'''
tensor([[ 1.4550,  0.7617, -0.0454, -0.5241],
        [-0.1855, -0.1790,  0.1177,  0.5916]])
'''

创建tensor,用dtype指定类型。注意类型要匹配

m = torch.tensor(1.0, dtype=torch.float)
n = torch.tensor(1, dtype=torch.long)
o = torch.tensor(1.0, dtype=torch.int8)
print(m, n, o)
'''
tensor(1.) tensor(1) tensor(1, dtype=torch.int8)
'''

使用指定类型函数随机初始化指定大小的tensor

p = torch.FloatTensor(2,3)
q = torch.IntTensor(2)
r = torch.IntTensor([1,2,3,4])  #对于python已经定义好的数据结构可以直接转换
print(p, '\n', q, '\n', r)
'''
tensor([[4.1026e-08, 2.0826e+23, 1.0258e-08],
        [3.3528e-09, 2.7477e-06, 1.7186e-04]]) 
 tensor([1, 0], dtype=torch.int32) 
 tensor([1, 2, 3, 4], dtype=torch.int32)
'''

tensor和numpy array之间的相互转换

s = np.array([[1,2,3],[4,5,6]])
print(s)
t = torch.tensor(s)
print(t)
u = torch.from_numpy(s)
print(u)
v = u.numpy()
print(v)
'''
[[1 2 3]
 [4 5 6]]
tensor([[1, 2, 3],
        [4, 5, 6]], dtype=torch.int32)
tensor([[1, 2, 3],
        [4, 5, 6]], dtype=torch.int32)
[[1 2 3]
 [4 5 6]]
'''

扩展&压缩tensor的维度:squeeze

w = u.unsqueeze(1)#unsqueeze:扩充数据维度,在0起的指定位置N加上维数为一的维度
print(w)
print(w.shape,'\n')
​
x = w.squeeze(0)
print(x)
print(x.shape,'\n')
​
y = w.squeeze(1)#squeeze:维度压缩,在0起的指定位置,去掉维数为1的的维度
print(y)
print(y.shape)
'''
tensor([[[1, 2, 3]],

        [[4, 5, 6]]], dtype=torch.int32)
torch.Size([2, 1, 3]) 

tensor([[[1, 2, 3]],

        [[4, 5, 6]]], dtype=torch.int32)
torch.Size([2, 1, 3]) 

tensor([[1, 2, 3],
        [4, 5, 6]], dtype=torch.int32)
torch.Size([2, 3])
'''

索引操作:(类似于numpy)

print(u)
z = u[0,:]
z += 1
print(z)
print(u[0, :]) # 源tensor也被改了了
'''
tensor([[1, 2, 3],
        [4, 5, 6]], dtype=torch.int32)
tensor([2, 3, 4], dtype=torch.int32)
tensor([2, 3, 4], dtype=torch.int32)
'''

view操作可以改变矩阵维度

x = torch.randn(2, 4)
y = x.view(8)
z = x.view(-1, 2) # -1是指这一维的维数由其他维度决定
print(x,'\n',y,'\n',z,'\n')
print(x.size(), y.size(), z.size(),'\n')
​
#注意 view() 返回的新tensor与源tensor共享内存(其实是同一个tensor),也即更改其中的一个,另 外一个也会跟着改变。(顾名思义,view仅仅是改变了对这个张量的观察⻆度)
x += 1
print(x,'\n')
print(y) # 也加了1
'''
tensor([[-0.8137,  1.2395, -0.3258,  0.1758],
        [-0.6160, -1.8669,  0.9111,  0.1596]]) 
 tensor([-0.8137,  1.2395, -0.3258,  0.1758, -0.6160, -1.8669,  0.9111,  0.1596]) 
 tensor([[-0.8137,  1.2395],
        [-0.3258,  0.1758],
        [-0.6160, -1.8669],
        [ 0.9111,  0.1596]]) 

torch.Size([2, 4]) torch.Size([8]) torch.Size([4, 2]) 

tensor([[ 0.1863,  2.2395,  0.6742,  1.1758],
        [ 0.3840, -0.8669,  1.9111,  1.1596]]) 

tensor([ 0.1863,  2.2395,  0.6742,  1.1758,  0.3840, -0.8669,  1.9111,  1.1596])
'''

不想改变原始数据的话可以先用 clone 创造一个副本然后再使用 view

注意:使用 clone 还有一个好处是会被记录在计算图中,即梯度回传到副本时也会传到源 Tensor 。

w = x.clone()
w
'''
tensor([[ 0.1863,  2.2395,  0.6742,  1.1758],
        [ 0.3840, -0.8669,  1.9111,  1.1596]])
'''

广播机制

当对两个形状不同的 Tensor 按元素运算时,可能会触发广播(broadcasting)机制:先适当复制元素使这两个 Tensor 形状相同后再按元素运算。

x = torch.arange(1, 3).view(1, 2)
print(x)
y = torch.arange(1, 4).view(3, 1)
print(y)
print(x + y)
'''
tensor([[1, 2]])
tensor([[1],
        [2],
        [3]])
tensor([[2, 3],
        [3, 4],
        [4, 5]])
'''

自动求导autograd

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

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

注意:在 y.backward() 时,如果 y 是标量,则不需要为 backward() 传入任何参数;否则,需要传入一个与 y 同形的Tensor。

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

还有一个类对于autograd的实现非常重要:FunctionTensorFunction 互相连接生成了一个无环图 (acyclic graph),它编码了完整的计算历史。每个张量都有一个.grad_fn属性,该属性引用了创建 Tensor自身的Function(除非这个张量是用户手动创建的,即这个张量的grad_fnNone )。

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

现在创建一个张量并设置requires_grad = True以跟踪它的计算

x = torch.ones(2, 2, requires_grad=True)
print(x)
'''
tensor([[1., 1.],
        [1., 1.]], requires_grad=True)
'''

在张量上执行操作:

y = x + 2
print(y)
'''
tensor([[3., 3.],
        [3., 3.]], grad_fn=<AddBackward0>)
'''

因为y是通过一个操作创建的,所以它有grad_fn,而x是由用户创建,所以它的grad_fn为None.

print(y.grad_fn)
print(x.grad_fn)
'''
<AddBackward0 object at 0x0000018103A75FA0>
None
'''

在y上执行操作

z = y * y * 3
out = z.mean()
print(z,'\n', out)
'''
tensor([[27., 27.],
        [27., 27.]], grad_fn=<MulBackward0>) 
 tensor(27., grad_fn=<MeanBackward0>)
'''

梯度(Gradients)

现在我们来执行反向传播,out.backward相当于执行out.backward(torch.tensor(1.))

输出out对x的梯度d(out)/dx:

out.backward(retain_graph=True)
#进行一次backward之后,各个节点的值会清除,这样进行第二次backward会报错,如果加上retain_graph==True后,可以再来一次backward
print(x.grad)
'''
tensor([[4.5000, 4.5000],
        [4.5000, 4.5000]])
'''

z i = 3 ( x i + 2 ) 2 z_i=3(x_i+2)^2 zi​=3(xi​+2)2

o u t = z . m e a n ( ) = 1 4 ∑ z i = 3 4 ( x i + 2 ) 2 out=z.mean()=\frac{1}{4}\sum z_i=\frac{3}{4}(x_i+2)^2 out=z.mean()=41​∑zi​=43​(xi​+2)2

求导 ∂ o u t ∂ x i = 3 2 ( x i + 2 ) \frac{\partial out}{\partial x_i}=\frac{3}{2}(x_i+2) ∂xi​∂out​=23​(xi​+2)

out.backward相当于执行out.backward(torch.tensor(1.)),所以 x i = 1 x_i=1 xi​=1

∂ ( o u t ) ∂ x i = 9 2 = 4.5 \frac{\partial (out)}{\partial x_i}=\frac{9}{2}=4.5 ∂xi​∂(out)​=29​=4.5

注意:grad在反向传播过程中是累加的(accumulated),这意味着每一次运行反向传播,梯度都会累加之前的梯度,所以一般在反向传播之前需把梯度清零。

out.backward(retain_graph=True)
print(x.grad)
'''
tensor([[9., 9.],
        [9., 9.]])
'''
out.backward(retain_graph=True)
print(x.grad)
'''
tensor([[13.5000, 13.5000],
        [13.5000, 13.5000]])
'''
out2 = x.sum()
out2.backward(retain_graph=True)
print(x.grad)
'''
tensor([[14.5000, 14.5000],
        [14.5000, 14.5000]])
'''

清零

x.grad.data.zero_()
print(x.grad)
out2.backward(retain_graph=True)
print(x.grad)
'''
tensor([[0., 0.],
        [0., 0.]])
tensor([[1., 1.],
        [1., 1.]])
'''

雅可比向量积

数学上,若有向量函数 y ⃗ = f ( x ⃗ ) \vec{y}=f(\vec{x}) y ​=f(x ),那么 y ⃗ \vec{y} y ​ 关于 x ⃗ \vec{x} x 的梯度就是一个雅可比矩阵:
J = ( ∂ y 1 ∂ x 1 ⋯ ∂ y 1 ∂ x n ⋮ ⋱ ⋮ ∂ y m ∂ x 1 ⋯ ∂ y m ∂ x n ) J=\left(\begin{array}{ccc}\frac{\partial y_{1}}{\partial x_{1}} & \cdots & \frac{\partial y_{1}}{\partial x_{n}} \\ \vdots & \ddots & \vdots \\ \frac{\partial y_{m}}{\partial x_{1}} & \cdots & \frac{\partial y_{m}}{\partial x_{n}}\end{array}\right) J=⎝⎜⎛​∂x1​∂y1​​⋮∂x1​∂ym​​​⋯⋱⋯​∂xn​∂y1​​⋮∂xn​∂ym​​​⎠⎟⎞​
torch.autograd 这个包就是用来计算一些雅可比矩阵向量积的。例如,如果 v v v 是一个标量函数 l = g ( y ⃗ ) l = g(\vec{y}) l=g(y ​) 的梯度:
v = ( ∂ l ∂ y 1 ⋯ ∂ l ∂ y m ) v=\left(\begin{array}{lll}\frac{\partial l}{\partial y_{1}} & \cdots & \frac{\partial l}{\partial y_{m}}\end{array}\right) v=(∂y1​∂l​​⋯​∂ym​∂l​​)
由链式法则,雅可比向量积就是 l l l关于 x ⃗ \vec{x} x 的梯度:
v J = ( ∂ l ∂ y 1 ⋯ ∂ l ∂ y m ) ( ∂ y 1 ∂ x 1 ⋯ ∂ y 1 ∂ x n ⋮ ⋱ ⋮ ∂ y m ∂ x 1 ⋯ ∂ y m ∂ x n ) = ( ∂ l ∂ x 1 ⋯ ∂ l ∂ x n ) v J=\left(\begin{array}{lll}\frac{\partial l}{\partial y_{1}} & \cdots & \frac{\partial l}{\partial y_{m}}\end{array}\right)\left(\begin{array}{ccc}\frac{\partial y_{1}}{\partial x_{1}} & \cdots & \frac{\partial y_{1}}{\partial x_{n}} \\ \vdots & \ddots & \vdots \\ \frac{\partial y_{m}}{\partial x_{1}} & \cdots & \frac{\partial y_{m}}{\partial x_{n}}\end{array}\right)=\left(\begin{array}{lll}\frac{\partial l}{\partial x_{1}} & \cdots & \frac{\partial l}{\partial x_{n}}\end{array}\right) vJ=(∂y1​∂l​​⋯​∂ym​∂l​​)⎝⎜⎛​∂x1​∂y1​​⋮∂x1​∂ym​​​⋯⋱⋯​∂xn​∂y1​​⋮∂xn​∂ym​​​⎠⎟⎞​=(∂x1​∂l​​⋯​∂xn​∂l​​)

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

x = torch.randn(3, requires_grad=True)
print(x)
​
y = x * 2
i = 0
while y.data.norm() < 1000:
    y = y * 2
    i = i + 1
print(y)
print(i)
'''
tensor([-2.0557,  0.4788, -1.5765], requires_grad=True)
tensor([-1052.4996,   245.1473,  -807.1833], grad_fn=<MulBackward0>)
8
'''

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

y.backward()
print(x.grad)
'''
RuntimeError: grad can be implicitly created only for scalar outputs
'''
v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)
​
print(x.grad)
'''
tensor([5.1200e+01, 5.1200e+02, 5.1200e-02])
'''

你可以通过将代码包裹在 with torch.no_grad(),来停止对从跟踪历史中 的 .requires_grad=True 的张量自动求导。

print(x.requires_grad)
print((x ** 2).requires_grad)
​
with torch.no_grad():
    print((x ** 2).requires_grad)
'''
True
True
False
'''

如果我们想要修改 tensor 的数值,但是又不希望被 autograd 记录(即不会影响反向传播), 那么我么可以对 tensor.data 进行操作。

x = torch.ones(1,requires_grad=True)
​
print(x.data) # 还是一个tensor
print(x.data.requires_grad) # 但是已经是独立于计算图之外
​
y = 2 * x
x.data *= 100 # 只改变了值,不会记录在计算图,所以不会影响梯度传播
​
y.backward()
print(x) # 更改data的值也会影响tensor的值 
print(x.grad)
'''
tensor([1.])
False
tensor([100.], requires_grad=True)
tensor([2.])
'''
x = torch.ones(1,requires_grad=True)
​
print(x.data) # 还是一个tensor
print(x.data.requires_grad) # 但是已经是独立于计算图之外
​
y = 2 * x
x *= 100 # 直接对x操作会报错
​
y.backward()
print(x) # 
print(x.grad)
'''
tensor([1.])
False
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-42-9b61d3c7b33e> in <module>
      5 
      6 y = 2 * x
----> 7 x *= 100 #
      8 
      9 y.backward()

RuntimeError: a leaf Variable that requires grad is being used in an in-place operation.
'''

标签:partial,tensor,torch,基础,张量,pytorch,print,grad
来源: https://blog.csdn.net/weixin_45735391/article/details/120600545

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有