张量的意思是一个多维数组,它是标量、向量、矩阵的高维扩展。标量可以称为 0 维张量,向量可以称为 1 维张量,矩阵可以称为 2 维张量,RGB 图像可以表示 3 维张量。你可以把张量看作多维数组。
参考链接
Torch 中定义的数据类型如下所示,CPU 和 GPU 上分别具有不同的数据类型。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zqG7UVMv-
torch.tensor(data, *, dtype=None, device=None, requires_grad=False, pin_memory=False)
示例:
torch.tensor([0,1])
torch.tensor([[0.1, 1.2], [2.2, 3.1], [4.9, 5.2]])
# 创建 GPU 上的 Tensor
torch.tensor([[0.11111, 0.222222, 0.3333333]],dtype=torch.float64,device=torch.device('cuda:0'))
# 创建标量 Tensor
torch.tensor(3.14159)
# 创建一个空的 Tensor
torch.tensor([])
# 创建一个全 1 Tensor
torch.ones((2,3,3))
# 创建一个全 0 Tensor
torch.zeros((2,3,3))
# 创建连续数字构成的 tensor
X = torch.arange(12,dtype=torch.float32).reshape((3,4))
# _like 根据指定的形状创建
Y = torch.zeros_like(X)
Y2 = torch.ones_like(X)
# full 填充
Z = torch.full((4,2),1.0)
Z2 = torch.full_like(X,12.2)
# 创建单位对角矩阵,默认为方阵
torch.eye(4)
# 指定 起始-终止-步长
t = torch.arange(2, 10, 2) # tensor([2, 4, 6, 8])
# 指定 起始-终止-元素个数
t2 = torch.linspace(2,10,6) # tensor([ 2.0000, 3.6000, 5.2000, 6.8000, 8.4000, 10.0000])
# 创建对数均分的 1 维张量
# 指定 起始-终止-元素个数-底数(默认10)
t3 = torch.logspace(1,20,6) # tensor([1.0000e+01, 6.3096e+04, 3.9811e+08, 2.5119e+12, 1.5849e+16, 1.0000e+20])
torch.normal(mean, std, *, generator=None, out=None)
t1 = torch.normal(0.,1.,size=(4,)) # tensor([ 1.5481, -2.6444, -0.1168, -0.0224])
mean = torch.arange(1, 5, dtype=torch.float)
std = 1
t2 = torch.normal(mean, std) # tensor([0.3120, 3.8869, 2.8768, 5.1489])
mean = torch.arange(1, 5, dtype=torch.float)
std = torch.arange(1, 5, dtype=torch.float)
t3 = torch.normal(mean, std) # tensor([-0.8261, 0.9518, 0.7300, 5.5800])
在区间 [0, 1)
上生成均匀分布:
t1 = torch.rand((3,4))
t2 = torch.rand_like(t1)
[low, high)
上生成整数均匀分布t1 = torch.randint(0,10,(3,3))
t2 = torch.randint_like(t1,20,100)
常用于生成索引。
t = torch.randperm(10)
a = torch.empty(3,3).uniform_(0,1)
t = torch.bernoulli(a)
# 创建连续数字构成的 tensor
x = torch.arange(12)
# 查看 Tensor 每个轴上的形状
x.shape
# 查看 Tensor 的元素个数
x.numel()
# 改变 Tensor 的形状
y = x.reshape(3,4)
# cat 操作
X = torch.arange(12,dtype=torch.float32).reshape((3,4))
Y = torch.tensor([[4.1,2.5,1.0,2],[9.0,1,2.3,5.0],[6.1,2,3.4,6.8]])
torch.cat((X,Y),dim=0),torch.cat((X,Y),dim=1)
# 利用 == 构建 bool Tensor
X == Y
x = torch.tensor([1.0,2.,4,8.0])
y = torch.tensor([2.0,3.0,4.0,5.0])
x + y, x - y, x * y, x / y, x ** y # 加减乘除幂
# 按元素求自然对数的指数
torch.exp(x)
# 对 tensor 的所有元素求和
x.sum()
即使形状不同,我们仍然可以通过调用 广播机制(broadcasting mechanism)来执行按元素操作。 这种机制的工作方式如下:
a = torch.arange(3).reshape((3,1))
b = torch.arange(2).reshape((1,2))
a + b
Tensor 中的元素可以通过索引访问。 与任何 python 数组一样:第一个元素的索引是 0
,最后一个元素索引是 -1
; 可以指定范围以包含第一个元素和最后一个之前的元素。
X = torch.arange(12,dtype=torch.float32).reshape(3,4)
X[-1],X[1:2]
# 指定索引修改数据
X[1, 2] = 900
X[1:2,:] = 100
运行一些操作可能会导致为新结果分配内存。 例如,如果我们用Y = X + Y,我们将取消引用Y指向的张量,而是指向新分配的内存处的张量。
X = torch.tensor([1.2])
Y = torch.tensor([6.5])
before = id(Y)
Y = X + Y
id(Y) == before # False
我们可以使用切片表示法将操作的结果分配给先前分配的数组:
Z = torch.zeros_like(Y)
print(("id(Z):",id(Z))) # print(("id(Z):",id(Z)))
Z[:] = X + Y
print(("id(Z):",id(Z))) # print(("id(Z):",id(Z)))
如果在后续计算中没有重复使用X, 我们也可以使用 X[:] = X + Y
或 X += Y
来减少操作的内存开销:
before = id(X)
X += Y
id(X) == before # True
torch tensor 和 numpy 数组将共享它们的底层内存,就地操作更改一个张量也会同时更改另一个张量:
X = torch.tensor([1.2])
A = X.numpy()
B = torch.tensor(A)
print(type(A)) #
print(type(B)) #
A[0] = 190
X,A,B # (tensor([190.]), array([190.], dtype=float32), tensor([1.2000]))
要将大小为 1 的张量转换为 python 标量,我们可以调用 item 函数或 python 的内置函数:
a = torch.tensor([3.5])
a, a.item(), float(a), int(a) # (tensor([3.5000]), 3.5, 3.5, 3)