【Pytorch官网tutorial】1.2 TENSORS张量


TENSORS的官方网址:点击进入
以下是内容笔记和相关翻译:

Tensors)是一种专门的数据结构,非常类似于数组和矩阵。在PyTorch中,我们使用张量来编码模型的输入和输出,以及模型的参数。

张量类似于NumPy的ndarrays,唯一的区别是张量可以在GPU或其他硬件加速器上运行。事实上,张量和NumPy数组通常可以共享相同的底层内存,不需要复制数据(参见与NumPy之间的桥接)。张量还对自动微分进行了优化(我们稍后会在Autograd部分看到更多)。如果您熟悉ndarrays,那么Tensor API就非常容易理解。如果不熟悉,跟着我们一起学习吧!

import torch #导入PyTorch库,以便使用PyTorch中的函数和类;
import numpy as np #导入NumPy库,并将其命名为np,以便使用NumPy中的函数和类。通常使用np作为NumPy的别名,是因为这是NumPy官方文档中推荐的做法。

张量的初始化

张量可以通过多种方式进行初始化。以下是几个示例:

从数据直接创建:

可以直接从数据中创建张量。数据类型将被自动推断。

data = [[1, 2],[3, 4]]
x_data = torch.tensor(data)
print(x_data)
从NumPy数组创建:

可以从NumPy数组创建张量(反之亦然 - 参见与NumPy之间的桥接)。

np_array = np.array(data) #np.array()函数是NumPy库提供的一种方法,它将输入数据转换为NumPy数组。转换后的NumPy数组将具有相同的维度和数据类型,以便进行进一步的操作和分析。
print(np_array)
x_np = torch.from_numpy(np_array)  #torch.from_numpy()函数将NumPy数组转换为PyTorch张量,而且这两个数据结构共享底层内存。这意味着,如果修改其中一个对象,另一个对象也会同时被修改。这种共享内存的方式有助于避免数据拷贝的开销,提高内存使用效率。
x_np
从另一个张量创建:

新张量保留参数张量的属性(形状、数据类型),除非明确覆盖。

x_ones = torch.ones_like(x_data) # 生成一个全是1的张量,与x_data具有相同的形状和数据类型。
print(f"Ones Tensor: \n {x_ones} \n")

x_rand = torch.rand_like(x_data, dtype=torch.float) # 生成一个随机张量,与x_data具有相同的形状,但数据类型被明确修改为float类型。
print(f"Random Tensor: \n {x_rand} \n")
使用随机值或常数值:

形状(shape)是一个张量维度的元组。在下面的函数中,它确定输出张量的维度。
下面这段代码展示了如何使用随机值、全1值和全0值初始化张量,并通过打印输出展示了它们的值。

shape = (2,3,) #我们定义了一个形状为(2,3)的元组shape。(2行3列)
rand_tensor = torch.rand(shape) #使用torch.rand()函数创建一个形状为shape的随机张量rand_tensor,该张量的每个元素都是从0到1之间的均匀分布中随机采样得到的。2行3列
ones_tensor = torch.ones(shape) #使用torch.ones()函数创建一个形状为shape的全1张量ones_tensor。
zeros_tensor = torch.zeros(shape)#使用torch.zeros()函数创建一个形状为shape的全0张量zeros_tensor。

print(f"Random Tensor: \n {rand_tensor} \n")
print(f"Ones Tensor: \n {ones_tensor} \n")
print(f"Zeros Tensor: \n {zeros_tensor}")

张量的属性(Attributes)

张量的属性描述了它们的形状、数据类型和存储设备。

tensor = torch.rand(3,4)
tensor = tensor. to('cuda:0') #'cuda:0'表示要将张量移动到的CUDA设备的索引0(如果可用)
print(f"Shape of tensor: {tensor.shape}")
print(f"Datatype of tensor: {tensor.dtype}")
print(f"Device tensor is stored on: {tensor.device}")

张量的操作

包括100多种张量操作,包括算术运算、线性代数、矩阵操作(转置、索引、切片)、采样等。你可以在这里找到详细的说明。
每个操作都可以在GPU上运行(通常比在CPU上速度更快)。如果你使用的是Colab,可以通过转到"runtime" -> "change runtime type" -> "GPU"来分配一个GPU。
默认情况下,张量在CPU上创建。我们需要使用.to方法明确地将张量移动到GPU上(在检查GPU是否可用之后)。请记住,跨设备复制大型张量可能会在时间和内存方面消耗较多的资源!

# We move our tensor to the GPU if available
if torch.cuda.is_available():
    tensor = tensor.to("cuda")
print(tensor.device)

在PyTorch中,如果您熟悉NumPy的操作方式,您将会发现PyTorch中的Tensor API非常容易上手。就像NumPy一样,PyTorch的Tensor API提供了各种各样的操作和功能,可以对张量进行算术运算、线性代数、索引和切片、数学函数等操作。

使用类似于NumPy的方式对张量进行索引和切片操作
tensor = torch.ones(4, 4) #使用torch.ones()函数创建了一个形状为(4,4)的全1张量tensor。
print(f"First row: {tensor[0]}") #通过tensor[0]的方式,我们获取了张量的第一行,并使用打印语句输出。
print(f"First column: {tensor[:, 0]}") #通过tensor[:, 0]的方式,我们获取了张量的第一列,并使用打印语句输出。
print(f"Last column: {tensor[..., -1]}") #通过tensor[..., -1]的方式,我们获取了张量的最后一列。使用...表示我们可以泛化维度,然后使用-1表示倒数第一列。同样,我们使用打印语句输出结果。
tensor[:,1] = 0 #我们使用tensor[:, 1] = 0的方式,将张量的第二列的所有元素赋值为0。这是通过切片和赋值操作实现的,我们通过打印语句输出最终的张量结果。
print(tensor)
张量的连接:

你可以使用torch.cat沿给定维度连接一系列张量。另外,torch.stack也是另一种张量连接操作,与torch.cat有微妙的区别。

t1 = torch.cat([tensor, tensor, tensor], dim=1) #我们使用torch.cat()函数将张量tensor按列(dim=1)进行拼接操作。具体来说,我们将张量tensor分别拼接了三次,得到了一个形状为(4,12)的新张量t1。这是因为在拼接时,我们在“列维度”上将三个张量进行了连接。
t1 = torch.cat([tensor, tensor, tensor], dim=0) #我们又使用torch.cat()函数对张量tensor按行(dim=0)进行拼接操作。同样地,我们将张量tensor分别拼接了三次,得到了一个形状为(12,4)的新张量t1。这是因为在拼接时,我们在“行维度”上将三个张量进行了连接。
print(t1)
运算操作
y1 = tensor @ tensor.T
y2 = tensor.matmul(tensor.T)
print(y1, y2)
#这两行代码计算了两个张量之间的矩阵乘法。y1和y2将具有相同的值。tensor.T返回张量的转置。所以,这两行代码将张量tensor与其转置进行了矩阵乘法运算,得到结果存储在y1和y2中。

y3 = torch.rand_like(y1) #建了一个与y1形状相同的随机张量y3
torch.matmul(tensor, tensor.T, out=y3) #使用torch.matmul()函数计算了tensor与tensor.T的矩阵乘法,并将结果写入给定的输出张量y3。

z1 = tensor * tensor
z2 = tensor.mul(tensor)
#这两行代码计算了两个张量的元素级乘法(也称为逐元素相乘)。z1和z2将具有相同的值。这两行代码分别使用*运算符和.mul()方法对张量进行逐元素相乘运算。

z3 = torch.rand_like(tensor)
torch.mul(tensor, tensor, out=z3)
单元素张量

如果你有一个只有一个元素的张量,例如将一个张量的所有值聚合为一个值,你可以使用item()将其转换为一个Python数值。

agg = tensor.sum() #这行代码计算了张量tensor的总和,并将结果存储在变量agg中。sum()函数用于对张量的所有元素进行求和
agg_item = agg.item() #这行代码将agg中的结果转换为Python标量,并将其存储在变量agg_item中。item()方法用于将张量中的单个元素提取为Python标量
print(agg_item, type(agg_item))
就地操作:

将结果存储到操作数中的操作称为就地操作。它们用_后缀表示。例如:x.copy(y),x.t(),会修改x。

print(f"{tensor} \n")
tensor.add_(5)
print(tensor)

与NumPy的桥接

CPU上的张量和NumPy数组可以共享底层内存位置,对其中一个进行修改会导致另一个也发生变化。

t = torch.ones(5) #这行代码创建了一个形状为(5,)的张量t,并将所有元素初始化为1
print(f"t: {t}")
n = t.numpy() #这行代码将张量t转换为NumPy数组,并将其赋值给变量n
print(f"n: {n}")

在NumPy数组中的更改会影响到与之对应的张量。
由于PyTorch张量和NumPy数组可以相互转换,因此它们可以共享同一段内存。当我们使用torch.from_numpy()将NumPy数组转换为张量时,它们会共享相同的内存位置,这意味着它们指向同一个对象,而不是创建一个新的对象。

np.add(n, 1, out=n) #这行代码使用NumPy的np.add()函数将NumPy数组n的每个元素都加1。这是一个原地操作,即直接修改NumPy数组n的值,并将结果存储在n中。l
print(f"t: {t}")
print(f"n: {n}")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值