张量
上期文章我们介绍了pytorch的基础知识,本期我们将开始我们的pytorch之旅的第一个技术知识点--张量
Numpy 提供了一个 n 维数组对象,以及许多用于操作这些数组的函数。Numpy 是科学计算的通用框架;它对计算图、深度学习或梯度一无所知。但是,我们可以通过使用 numpy 操作手动实现网络的前向和后向传递。
Numpy 是一个很棒的框架,但它不能利用 GPU 来加速其数值计算。对于现代深度神经网络,GPU 通常提供50 倍或更高的加速,因此不幸的是 numpy 不足以用于现代深度学习。
这里我们介绍最基本的PyTorch 概念:张量。PyTorch Tensor 在概念上与 numpy 数组相同:Tensor 是一个 n 维数组,PyTorch 提供了许多操作Tensor 的函数。在幕后,张量可以跟踪计算图和梯度,但它们也可用作科学计算的通用工具。
同样与 numpy 不同的是,PyTorch Tensors 可以利用 GPU 来加速其数值计算。要在 GPU 上运行 PyTorch Tensor,只需指定正确的设备。
在开始本文章前,我们需要安装pytorch第三方库软件,直接在cmd命令框中输入
pip install pytorch torchvision
张量
#torch-1.9.0 torchvision-0.10.0 本篇文章的环境版本
张量是一种特殊的数据结构,与数组和矩阵非常相似。在 PyTorch 中,我们使用张量对模型的输入和输出以及模型的参数进行编码。
张量类似于NumPy 的ndarray,不同之处在于张量可以在 GPU 或其他硬件加速器上运行。事实上,张量和 NumPy 数组通常可以共享相同的底层内存,从而无需复制数据。张量也针对自动微分进行了优化(我们将在后面的Autograd 部分分享相关信息)
张量
张量的定义import torch
a = torch.ones(5)
print(a)
# tensor([1., 1., 1., 1., 1.])
b = torch.zeros(5)
print(b)
# tensor([0., 0., 0., 0., 0.])
c = torch.tensor([1.0, 2.0, 3.0, 4.0, 5.0])
print(c)
#tensor([1., 2., 3., 4., 5.])
使用以上方法我们定义了一维的数据张量,其中torch.tensor中接受一个numpy的数组
当然我们也可以定义一个2维数据或者多维数据,并可以使用shape属性查看张量的属性
data = [[1, 2],[3, 4]]
x_data = torch.tensor(data)
print(x_data)
tensor([[1, 2],
[3, 4]])
np_array = np.array(data)
x_np = torch.from_numpy(np_array)
print(x_np)
tensor([[1, 2],
[3, 4]], dtype=torch.int32)
g = torch.tensor([[[1., 2.], [3., 4.]], [[5., 6.], [7., 8.]]])
print(g)
print(g.shape)
tensor([[[1., 2.],
[3., 4.]],
[[5., 6.],
[7., 8.]]])
torch.Size([2, 2, 2])
当然通过以上的方式定义一个张量外,我们还可以使用另外一个张量来定义新的张量
这里需要说明除非明确覆盖,否则新张量保留原始张量的属性(形状、数据类型)。
data = [[1, 2],[3, 4]]
x_data = torch.tensor(data)
print(x_data)
x_ones = torch.ones_like(x_data) # 保持原始张量属性
print(f"Ones Tensor: \n {x_ones} \n")
x_rand = torch.rand_like(x_data, dtype=torch.float) # 重新定义张量为float类型
print(f"Random Tensor: \n {x_rand} \n")
################
tensor([[1, 2],
[3, 4]])
Ones Tensor:
tensor([[1, 1],
[1, 1]])
Random Tensor:
tensor([[0.6791, 0.0938],
[0.8537, 0.9403]])
同样的我们还可以使用张量的shape的属性定义一个张量,shape是张量维度的元组,除了shape属性外,张量还有tensor.dtype与tensor.device属性
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}")
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}")
############################
Random Tensor:
tensor([[0.2010, 0.4683, 0.1847],
[0.8443, 0.3900, 0.8123]])
Ones Tensor:
tensor([[1., 1., 1.],
[1., 1., 1.]])
Zeros Tensor:
tensor([[0., 0., 0.],
[0., 0., 0.]])
Shape of tensor: torch.Size([3, 4])
Datatype of tensor: torch.float32
Device tensor is stored on: cpu
张量运算
张量运算与普通的数据运算类似,包括算术、线性代数、矩阵操作(转置、索引、切片)、采样等。这些操作中的每一个都可以在 GPU 上运行(速度通常比在 CPU 上更高)。默认情况下,张量是在 CPU 上创建的。我们需要使用.to方法明确地将张量移动到 GPU
if torch.cuda.is_available():
tensor = tensor.to('cuda')##张量的数学操作可以参考##pytorch.org/docs/stable/torch.html
tensor1 = torch.tensor([[1,2,3],[4,5,6]])
tensor2 = torch.tensor([[-1,2,-3],[4,-5,6]])
print(tensor1+tensor2)
print(torch.add(tensor1,tensor2))
# tensor([[ 0, 4, 0],
# [ 8, 0, 12]])
print(tensor1-tensor2)
print(torch.sub(tensor1,tensor2))
# tensor([[ 2, 0, 6],
# [ 0, 10, 0]])
print(tensor1 * 2)
# tensor([[ 2, 4, 6],
# [ 8, 10, 12]])
print(tensor1 * tensor2)
# tensor([[ -1, 4, -9],
# [ 16, -25, 36]])
tensor3 = torch.tensor([[1,2],[3,4],[5,6]])
print(torch.mm(tensor1,tensor3))
# tensor([[22, 28],
# [49, 64]])
# Tensor with scalar
print(tensor1/2)
# tensor([[0, 1, 1],
# [2, 2, 3]])
##张量除法
print(tensor1/tensor2)
# tensor([[-1, 1, -1],
# [ 1, -1, 1]])
##连接张量
t1 = torch.cat([tensor1, tensor2], dim=1)
print(t1)
tensor([[ 1, 2, 3, -1, 2, -3],
[ 4, 5, 6, 4, -5, 6]])
numpy数组到张量的互相转换张量到 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.]
张量的变化反映在 NumPy 数组中。这是由于CPU 和 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 数组到张量,同样的由于CPU 和 NumPy
数组上的张量可以共享它们的底层内存位置,改变一个将改变另一个
n = np.ones(5)
t = torch.from_numpy(n)
t: tensor([1., 1., 1., 1., 1.], dtype=torch.float64)
n: [1. 1. 1. 1. 1.]
t: tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
n: [2. 2. 2. 2. 2.]
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.