torch.tensor 、torch.Tensor 、torch.detach()、tensor.data、tensor.clone
首先注意一点:在torch中,可导张量计算出的新张量也是可导的,新张量与原张量具有可导连接,那么原张量就不是叶子张量,新张量成了叶子张量。
torch.tensor(data, *, dtype=None, device=None, requires_grad=False, pin_memory=False) → Tensor
torch.tensor只能从指定的数据创建,但是可以指定数据属性,是否可微分等属性。pin_memory是将张量放置到锁业内存中,所以这个张量只能被cpu使用。
import torch
a = [1, 2, 3]
b = torch.tensor(a, requires_grad=True, dtype=torch.float64)
torch.Tensor有一下几种变形:
整数:torch.ShortTensor 16位,torch.IntTensor 32位,torch.LongTensor 64位
浮点:torch.FloatTensor=torch.Tensor 32位,torch.DoubleTensor 64位
注意:torch.Tensor(int1, int2,int3)会创建[int1, int2,int3]形状的张量,如果传入列表元组等,就会返回该列表元组张量。
import torch
torch.Tensor(3)
'''tensor([-2.6853e+05, 1.9983e-42, 2.3694e-38])'''
torch.Tensor(3, 1)
'''
tensor([[3.2842e-15],
[3.1714e+00],
[2.3694e-38]])
'''
torch.Tensor([3, 1])
'''
tensor([3., 1.])
'''
tensor.data /tensor.detach()/tensor.clone的区别
tensor.data、tensor.detach与原张量,其中一个数值变化其他两个也随之变化,但是detach/tensor.data不参与原张量所在的微分传导图。
tensor.clone不会随着原张量的变化而变化,但是在原张量的微分传到图中。
举例:
import torch
a = torch.tensor(1, requires_grad=True, dtype=torch.float32)
b = a * 2
b_data = b.data
b_detach = b.detach()
b_clone = b.clone()
print(b, b_data, b_detach, b_clone)
'''
tensor(2., grad_fn=<MulBackward0>) tensor(2.) tensor(2.) tensor(2., grad_fn=<CloneBackward0>)
'''
# 当其中一个改变时,tensor.data, tensor.detach也会改变。tensor.clone不会改变。
b_detach.zero_()
print(b, b_data, b_detach, b_clone)
'''
tensor(0., grad_fn=<MulBackward0>) tensor(0.) tensor(0.) tensor(2., grad_fn=<CloneBackward0>)
'''
当tensor.detach或者tensor.data改变数值时,并不会影响原张量的微分传导结果。
import torch
a = torch.tensor(1, requires_grad=True, dtype=torch.float32)
b = a * 2
b_data = b.data
b_detach = b.detach()
b_clone = b.clone()
# a的微分结果不受影响
b_detach.zero_()
b.backward(retain_graph=True)
print(a.grad)
# 如果原张量本身变化,则会受到影响。
b.zero_()
a.grad.zero_()
b.backward()
print(a.grad)
'''
tensor(2.)
tensor(0.)
'''
tensor.clone会保持原张量的微分传导图,并会叠加到结果上。
import torch
a = torch.tensor(1, requires_grad=True, dtype=torch.float32)
b = a * 2
b_clone = b.clone()
b.backward(retain_graph=True)
print(a.grad)
b_clone.backward()
print(a.grad)
'''
tensor(2.)
tensor(4.)
'''