【Pytorch】Pytorch文档学习1:Tensors

本文介绍了PyTorch中的Tensors,一种类似数组和矩阵的数据结构,用于模型参数和数据表示。讲解了Tensors与NumPy的关系、初始化方法、属性、操作,以及如何在GPU上执行,以及与NumPy的桥梁功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

地址:https://pytorch.org/tutorials/beginner/basics/tensorqs_tutorial.html

Tensors are a specialized data structure that are very similar to arrays and matrices. In PyTorch, we use tensors to encode the inputs and outputs of a model, as well as the model’s parameters.

Tensors are similar to NumPy’s ndarrays, except that tensors can run on GPUs or other hardware accelerators. In fact, tensors and NumPy arrays can often share the same underlying memory, eliminating the need to copy data (see Bridge with NumPy). Tensors are also optimized for automatic differentiation (we’ll see more about that later in the Autograd section). If you’re familiar with ndarrays, you’ll be right at home with the Tensor API. If not, follow along!

简单翻译:
Tensor是一种特殊的数据类型,这种数据类型非常类似于数组和矩阵。在Pytorch中,我们使用tensors去对模型的输入和输出,以及模型的参数进行编码。

Tensors 是非类似于NumPy的ndarrays,除了tensor能偶运行在GPU和其他硬件计算器上以外。事实上,tensors和NumPy数组通常能够共享相同潜在的内存,从而消除复制数据的需要。Tensors也对自动微分进行了优化。如果你熟悉ndarrays,那么你使用Tensor API的时候就像回到家一般亲切。如果不熟悉,那么跟紧(以下教程)就对了。

import numpy as np
import torch

Tensor的初始化

Tensor可以以多种方式初始化,下面是一些例子。

直接由数据初始化
使用矩阵创建一个tensor。程序会自动推断出数据的类型。

data = [[1, 2], [3, 4]]
x_data = torch.tensor(data)

从numpy中获得tensor

np_array = np.array(data)
x_np = torch.from_numpy(np_array)

从其他的tensor中获得tensor:

新的tensor会保留原有tensor的维度和数据类型,除非显式的进行声明


x_ones = torch.ones_like(x_data) # retains the properties of x_data
print(f"Ones Tensor: \n {x_ones} \n")

x_rand = torch.rand_like(x_data, dtype=torch.float) # overrides the datatype of x_data
print(f"Random Tensor: \n {x_rand} \n")
Ones Tensor:
 tensor([[1, 1],
        [1, 1]])

Random Tensor:
 tensor([[0.8823, 0.9150],
        [0.3829, 0.9593]])

从随机或固定的值
shape是一个tensor维度的tuple,在下面的函数中,其决定了输出tensor的维度。

shape = (2, 3,)
rand_tensor = torch.rand(shape)
ones_tensor = torch.ones(shape)
zeros_tensor = torch.zeros(shape, dtype=torch.float)
print(rand_tensor)
print(ones_tensor)
print(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.]])

tensor的属性

tensor拥有三个属性,分别是形状,数据类型和其被存储的位置

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

对tensors的操作

有超过100种tensor的操作,包括运算,线性代数,矩阵操作(变换,索引,切片), 示例和更多信息被全面的描述在此:https://pytorch.org/docs/stable/torch.html

每一个操作都能运行在GPU上(通常速度会高于CPU)。如果你使用Colab,使用GPU的方法是前往Runtime > Change runtime type > GPU。

通常来说, Tensors会被创建于CPU,我们需要显式的将tensors移动到GPU,这会使用".to"方法(在检查GPU可用之后)。必须清楚的是,在时间和内存上而言,将巨大的tensors复制并移动设备会有巨大的花费!

if torch.cuda.is_available():
    tensor = tensor.to("cuda")

请尝试一些列表中的list。如果你熟悉NumPy API,你会发现Tensor API是是非容易使用的。

像numpy一般标准的索引和切片

tensor = torch.ones(4, 4)
print(tensor)
print(f"First row(行): {tensor[0]}")
print(f"First column: {tensor[:, 0]}")
print(f"Last column: {tensor[..., -1]}")
tensor[:, 1] = 0
print(tensor)
First row: tensor([1., 1., 1., 1.])
First column: tensor([1., 1., 1., 1.])
Last column: tensor([1., 1., 1., 1.])
tensor([[1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.]])

tensors的拼接 你可以使用torch.cat去以你所给的维度按照顺序凭借一系列的tensors。另见torch.stack——另外一种拼接tensors的方法。这种方法与torch.cat有细微的区别。

t1 = torch.cat([tensor, tensor, tensor], dim=1)
print(t1)
tensor([[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],
        [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],
        [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.],
        [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.]])

运算操作

# 以下将计算两个矩阵的乘法。y1,y2,y3都拥有相同的value
# tensor.T将返回一个tensor的转置
print(tensor)
y1 = tensor @ tensor.T
y2 = tensor.matmul(tensor.T)
print(y2)

y3 = torch.rand_like(y1)
torch.matmul(tensor, tensor.T, out=y3)


# 此处计算了元素相乘的乘法。其中z1,z2,z3将会拥有相同的value
z1 = tensor * tensor

z3 = torch.rand_like(tensor)
torch.mul(tensor, tensor, out=z3)
print(z3)
tensor([[1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.]])

单元素tensors。 如果你有一个只有一个元素的tensor,比如说将一个tensor的值都聚合成为了一个值,你可以使用item()方法将其转化为Python的数值

agg = tensor.sum()
agg_item = agg.item()
print(agg_item, type(agg_item))
12.0 <class 'float'>

就地操作将结果存储在操作数的操作被称做就地操作。其被表示为添加“”后缀。举例而言:x.copy(y),x.t_(),都会改变x。

print(f"{tensor} \n")
tensor.add_(5)
print(tensor)
tensor([[1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.],
        [1., 0., 1., 1.]])

tensor([[6., 5., 6., 6.],
        [6., 5., 6., 6.],
        [6., 5., 6., 6.],
        [6., 5., 6., 6.]])

注意:
就地操作会节约一些内存,但是在计算倒数的时候也有可能会出现问题,这是因为历史的信息会立即消失。因此,并不推荐使用就地操作。

NumPy的桥梁

在CPU上的Tensors和NumPy数组可以共享他们潜在的内存地址,并且改变其中一个将会改变另一个,即在tensor中的改变也会影响在NumPy中的数组。

Tensor对NumPy数组(的影响)

t = torch.ones(5)
print(f"t: {t}")
n = t.numpy()
print(f"n: {n}")
t: tensor([1., 1., 1., 1., 1.])
n: [1. 1. 1. 1. 1.]

在tensor中的改变会反映在NumPy数组中。

t.add_(1)
print(f"t: {t}")
print(f"n: {n}")
t: tensor([2., 2., 2., 2., 2.])
n: [2. 2. 2. 2. 2.]

NumPy数组对Tensor(的影响)

n = np.ones(5)
t = torch.from_numpy(n)

在NumPys数组中的改变会反映在tensor中。

np.add(n, 1, out=n)
print(f"t: {t}")
print(f"n: {n}")
t: tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
n: [2. 2. 2. 2. 2.]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值