概述 pytorch 张量
张量是一种特殊的数据结构,与数组和矩阵非常相似。在PyTorch中,我们使用张量来编码模型的输入和输出以及模型的参数。
张量类似于NumPy的ndarrays,不同之处在于张量能够在GPU或其他硬件加速器上运行。实际上,张量和NumPy数组经常可以共享相同的底层内存,从而避免了复制数据的需要(参见与NumPy的桥梁)。张量也针对自动微分进行了优化(我们将在后面的Autograd部分详细了解)。如果你熟悉ndarrays,那么你会对张量API感到很亲切。如果不熟悉,那就请继续跟随学习吧!
import torch
import numpy as np
初始化一个张量
有多种方法初始化一个张量
直接从 python 的列表
data = [[1, 2, 3], [4, 5,6]]
x_data = torch.tensor(data)
从 numpy 数组初始化
np_data = np.array(data)
x_np = torch.from_numpy(np_data)
从其他的 tensor 变量初始化
# x_data 是前面直接从列表获取数据构建的tensor
x_ones = torch.ones_like(x_data)
# rand生成的数值默认是浮点数,这里不转浮点数,后面相关函数会报错
x_rand = torch.rand_like(x_data, dtype=torch.float)
使用随机量或常量
shape = (2, 3, )
r = torch.rand(shape)
o = torch.ones(shape)
z = torch.zeros(shape)
tensor的属性
tensor的常用属性:shape(形状)、dtype(数据类型)、device(存储设备,主要是cpu或cuda)。
t = torch.rand(shape)
t.shape
t.dtype
t.device
张量操作
包括算术运算、线性代数、矩阵操作(转置、索引、切片)、采样等在内的100多种张量操作,在这里都有详尽的描述。
这些操作均可在GPU上运行(通常比在CPU上速度更快)。如果你正在使用Colab,可以通过“运行时”>“更改运行时类型”>“GPU”来分配GPU。
默认情况下,张量是在CPU上创建的。我们需要通过使用.to
方法显式地将张量移动到GPU上(在此之前需检查GPU是否可用)。请注意,跨设备复制大型张量可能会在时间和内存方面成本较高!
# We move our tensor to the GPU if available
if torch.cuda.is_available():
tensor = tensor.to("cuda")
尝试列表中的一些操作。如果你已经熟悉NumPy的API,你会发现使用Tensor API会非常得心应手。
tensor = torch.ones(4, 4)
print(f"First row: {tensor[0]}")
print(f"First column: {tensor[:, 0]}")
print(f"Last column: {tensor[..., -1]}")
tensor[:,1] = 0
print(tensor)
详细解释一下切片
这段PyTorch代码演示了如何创建一个张量并对它进行基本的索引、切片操作,同时展示了如何使用省略号(...
)进行高级索引。下面是对这段代码的详细解析:
创建张量
tensor = torch.ones(4, 4)
此行代码创建了一个形状为4x4的张量,其中所有元素都初始化为1。torch.ones()
函数用于创建全1张量,参数指定了张量的尺寸。
索引与切片操作
* 第一行
print(f"First row: {tensor[0]}")
这里使用了简单的索引来获取张量的第一行。在Python中,多维数组(如张量)的索引从0开始,因此tensor[0]
返回第一行。
- 第一列
print(f"First column: {tensor[:, 0]}")
使用切片操作:
来选取所有行(:
代表从开始到结束的所有行),然后通过[:, 0]
指定第一列,因此这行代码选取了张量的第一列。
- 最后一列
print(f"Last column: {tensor[..., -1]}")
这里的...
是一个特殊的语法,它代表前缀的所有维度。在二维张量的例子中,...
等价于:
,意味着选取所有行。-1
则表示选取最后一个维度的最后一个元素。因此,tensor[..., -1]
选取了每一行的最后一列,即整个张量的最后一列。这种写法使得代码在处理更高维度张量时更加灵活和通用。
- 修改张量
tensor[:,1] = 0
这行代码将张量中所有行的第二列元素赋值为0,通过切片操作[:, 1]
来定位到第二列,然后将其所有元素设置为0。
- 输出最终张量
print(tensor)
最后,打印修改后的张量,展示索引、切片和赋值操作的结果。
综上所述,这段代码展示了如何创建张量、使用不同类型的索引和切片操作来访问张量的不同部分,以及如何使用省略号...
进行灵活的多维度索引。特别是...
的使用,它允许代码在不同维度的张量上保持一致的行为,提高了代码的可读性和可扩展性。