向量#
pytorch 一般使用 torch.tensor()
创建向量。
tensor 称为张量、向量,但是数据概念上还有点区别:
标量: 零维, 只包含一个数字,比如
tensor.tensor(2)
向量: 一维或更高维度,多维数组数组,比如
tensor.tensor([1,2,3])
,tensor.tensor([[1,2,3], [4,5,6]])
向量拥有类型. 下面的例子,传入了浮点数,但是指定为 int 类型,所有数据最终被转为了 int:
a = tensor.tensor([1.9, 2.2], dtype=torch.int32)
print(a)
# tensor([1,2], dtype=torch.int32)
通过 numpy 创建 torch 向量#
import numpy as np
import torch
np_array = np.array(data)
x_np = torch.from_numpy(np_array)
通过其他 torch 向量创建#
这种方式一般用来创建与目标向量 相似 的向量.
如果要创建相同的向量,可以用 .copy()
或 .clone()
方法。
# 创建和 x_data 维度、类型一样的全 1 向量
x_ones = torch.ones_like(x_data)
print(f"Ones Tensor: \n {x_ones} \n")
# 创建和 x_data 维度、类型一样的随机向量,类型指定为 float
x_rand = torch.rand_like(x_data, dtype=torch.float)
print(f"Random Tensor: \n {x_rand} \n")
可以关注 torch 中 _like
后缀的一系列方法,
包括: empty_like
/full_like
/ones_like
/rand_like
/randint_like
/randn_like
/zeros_like
创建常见向量#
# 指定维度为 2 x 3
shape = (2, 3,)
rand_tensor = torch.rand(shape)
ones_tensor = torch.ones(shape)
zeros_tensor = torch.zeros(shape)
print(f"Random Tensor: \n {rand_tensor} \n")
print(f"Ones Tensor: \n {ones_tensor} \n")
print(f"Zeros Tensor: \n {zeros_tensor}")
Random Tensor:
tensor([[0.3904, 0.6009, 0.2566],
[0.7936, 0.9408, 0.1332]])
Ones Tensor:
tensor([[1., 1., 1.],
[1., 1., 1.]])
Zeros Tensor:
tensor([[0., 0., 0.],
[0., 0., 0.]])
向量维度#
向量维度是一个元组,即向量在每个维度上的长度
one_tensor = torch.tensor([[1,2,3], [4,5,6]])
print(one_tensor.shape) # (2, 3)
one_tensor
是一个 \(2*3\) 的向量,按顺序第 0 维长度是 2, 第 1 维长度是 3. 所以前面的是高维,后面是低维。
这个概念会在某些函数的 axis 参数上用到。
以 max 函数为例,我们创建一个 3x3x3 随机数矩阵: a = torch.rand((3,3,3))
, 注意下面的维度对应关系:
b = a.max(axis=0)
: \(b_{j,k} = \max(a_{i,j,k})\)b = a.max(axis=1)
: \(b_{i,k} = \max(a_{i,j,k})\)
向量类型和 device#
tensor = torch.rand(3, 4)
print(f"Shape of tensor: {tensor.shape}")
print(f"Datatype of tensor: {tensor.dtype}")
print(f"Device tensor is stored on: {tensor.device}")
Shape of tensor: torch.Size([3, 4])
Datatype of tensor: torch.float32
Device tensor is stored on: cpu
向量索引#
tensor = torch.tensor([[1,2,3], [4,5,6]])
print(tensor[0]) # tensor([1,2,3])
print(tensor[0, 1]) # tensor(2)
print(tensor[0, -1]) # tensor(3)
print(tensor[:, 1]) # tensor([2, 5])
print(tensor[..., 1]) # tensor([2, 5])
向量操作#
一般向量的运算不会改变向量本身,例如:
a = torch.rand((3, 3))
b = torch.rand((3, 3))
c = a + b
# 等价于 c=a+b
c = a.add(b)
以上操作会生成新的向量 c, 而不会改变 a/b ,如果要原地运算,可以使用带有下划线后缀的系列函数: a.add_(b)
, 运算结果会直接存放在 a 中。
torch 与 numpy 的互操作#
通过 .numpy()
.from_numpy()
函数可以实现 numpy 向量与 torch 向量之间的互转。
one_tensor = torch.ones(5)
np_data = torch_tensor.numpy()
two_tensor = torch.from_numpy(np_data)
通过这两个方法转换后,他们的底层的数据其实是共享的。也就是说,修改 torch 向量后,对应的 numpy 向量也会改变,反之亦然。
tensor = torch.ones(3) # [1,1,1]
np_tensor = tensor.numpy()
np_tensor += 1 # np_tensor => [2,2,2]
print(tensor) # [2,2,2]