什么是张量,PyTorch创建张量的多种方法(非常详细)
在数学概念中,张量是一个多维数组,它是标量、向量、矩阵的高维拓展。本节介绍张量的概念,以及 PyTorch 中常用的几种创建张量的方法。
张量是一个多维数组,它的每一个方向被称为模(Mode)。张量的阶数就是它的维数,一阶张量就是向量,二阶张量就是矩阵,三阶及以上的张量统称为高阶张量。
Tensor 是 PyTorch 的基本数据结构,在使用时需要表示成 torch.Tensor 的形式,它有 8 个主要的属性,如 data、grad 等,具体说明如下:
其中,前 4 个属性与数据相关,后 4 个属性与梯度求导相关。
torch.dtype 是表示 torch.Tensor 的数据类型的对象,PyTorch 中有 9 种不同的数据类型,具体如下表所示。
【方法 1】使用 torch.tensor() 函数从数组直接创建张量,并查看其数据类型,示例如下:
【方法 2】使用 torch.from_numpy() 函数从 NumPy 创建张量。通过 torch.from_numpy 创建的张量与原 ndarray 共享内存,当修改其中一个时,另一个也会被改动。例如,修改张量中 [0,2] 的数值为 −1,代码如下:
torch.normal() 函数的格式如下:
例如,mean 为张量,std 也为张量,一一对应取 mean 和 std 中的值作为均值和标准差构成正态分布,从每个正态分布中随机抽取一个数字。
示例代码如下:
torch.randn() 函数的格式如下:
torch.randn_like() 函数的格式如下:
torch.rand() 函数的格式如下:
torch.rand_like() 函数的格式如下:
张量及其数据类型
张量及其相关应用是近年来最热门的研究话题之一,因为张量相对于矩阵来说能更加自然和完整地表征自然界的一些现象。张量是一个多维数组,它的每一个方向被称为模(Mode)。张量的阶数就是它的维数,一阶张量就是向量,二阶张量就是矩阵,三阶及以上的张量统称为高阶张量。
Tensor 是 PyTorch 的基本数据结构,在使用时需要表示成 torch.Tensor 的形式,它有 8 个主要的属性,如 data、grad 等,具体说明如下:
- data:被包装的张量;
- dtype:张量的数据类型;
- shape:张量的形状/维度;
- device:张量所在的设备,加速计算的关键,GPU 或 CPU;
- grad:data的梯度;
- grad_fn:创建张量的 Function,这是自动求导的关键;
- requires_grad:指示是否需要计算梯度;
- is_leaf:指示是不是叶子节点。
其中,前 4 个属性与数据相关,后 4 个属性与梯度求导相关。
torch.dtype 是表示 torch.Tensor 的数据类型的对象,PyTorch 中有 9 种不同的数据类型,具体如下表所示。
Data Type | dtype | CPU Tensor | GPU Tensor |
---|---|---|---|
32-bit floating point | torch.float32 or torch.float | torch.FloatTensor | torch.cuda.FloatTensor |
64-bit floating point | torch.float64 or torch.double | torch.DoubleTensor | torch.cuda.DoubleTensor |
16-bit floating point | torch.float16 or torch.half | torch.HalfTensor | torch.cuda.HalfTensor |
8-bit integer (unsigned) | torch.uint8 | torch.ByteTensor | torch.cuda.ByteTensor |
8-bit integer (signed) | torch.int8 | torch.CharTensor | torch.cuda.CharTensor |
16-bit integer (signed) | torch.int16 or torch.short | torch.ShortTensor | torch.cuda.ShortTensor |
32-bit integer (signed) | torch.int32 or torch.int | torch.IntTensor | torch.cuda.IntTensor |
64-bit integer (signed) | torch.int64 or torch.long | torch.LongTensor | torch.cuda.LongTensor |
Boolean | torch.bool | torch.BoolTensor | torch.cuda.BoolTensor |
使用数组直接创建张量
创建张量的方法有多种,其中使用数组直接创建张量主要有以下两种方法。【方法 1】使用 torch.tensor() 函数从数组直接创建张量,并查看其数据类型,示例如下:
import torch import numpy as np # 创建一个3×3的全1数组 arr = np.ones((3, 3)) # 打印数组的数据类型 print("ndarray的数据类型:", arr.dtype) # 将NumPy数组转换为PyTorch张量 t1 = torch.tensor(arr) # 将NumPy数组转换为PyTorch张量,并指定设备为CPU t2 = torch.tensor(arr, device='cpu') # 打印t1张量 print(t1) # 打印t2张量 print(t2)输出结果如下:
ndarray的数据类型: float64 tensor([[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]], dtype=torch.float64) tensor([[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]], dtype=torch.float64)从示例可以看出,以上使用 arr 数组创建了一个新的张量。
【方法 2】使用 torch.from_numpy() 函数从 NumPy 创建张量。通过 torch.from_numpy 创建的张量与原 ndarray 共享内存,当修改其中一个时,另一个也会被改动。例如,修改张量中 [0,2] 的数值为 −1,代码如下:
import torch import numpy as np # 创建一个2×3的数组 arr = np.array([[1, 2, 3], [4, 5, 6]]) # 将NumPy数组转换为PyTorch张量 t = torch.from_numpy(arr) # 打印原始数组和张量 print("原始数组和张量") print(arr) print(t) # 修改张量的数值 print("\n修改张量的数值") t[0, 2] = -1 # 打印修改后的数组和张量 print(arr) print(t)代码输出结果如下:
原始数组和张量 [[1 2 3] [4 5 6]] tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.int32) 修改张量的数值 [[ 1 2 -1] [ 4 5 6]] tensor([[ 1, 2, -1], [ 4, 5, 6]], dtype=torch.int32)
使用概率分布创建张量
1) 从正态分布中抽取随机数创建张量
通过 torch.normal() 函数从给定参数的离散正态分布中抽取随机数创建张量。共有 4 种模式,即均值和标准差分别为标量或张量,当均值和标准差中有一个为张量,另一个为标量时,将会应用 Broadcast 机制把标量扩展成同型张量。torch.normal() 函数的格式如下:
torch.normal(mean,std,size,out=None)代码说明:
- mean:均值;
- std:标准差;
- size:仅在 mean 和 std 均为标量时使用,表示创建张量的形状;
- out:可选,输出张量。如果提供了此参数,结果将被写入此张量中。默认为 None。
例如,mean 为张量,std 也为张量,一一对应取 mean 和 std 中的值作为均值和标准差构成正态分布,从每个正态分布中随机抽取一个数字。
示例代码如下:
import torch # 创建一个从1到4的等差数列,数据类型为float mean = torch.arange(1, 5, dtype=torch.float) # 创建一个从1到4的等差数列,数据类型为float std = torch.arange(1, 5, dtype=torch.float) # 生成一个服从正态分布的张量,均值为mean,标准差为std t = torch.normal(mean, std) # 打印均值、标准差和生成的张量 print("mean:{}\nstd:{}\n{}".format(mean, std, t))输出结果如下:
mean:tensor([1., 2., 3., 4.])
std:tensor([1., 2., 3., 4.])
tensor([ 0.0653, 3.8435, -2.2774, 8.5908])
2) 从标准正态分布中抽取随机数创建张量
可以使用 torch.randn() 函数和 torch.randn_like() 函数从标准正态分布(均值为 0,标准差为 1)中抽取随机数创建张量。torch.randn() 函数的格式如下:
torch.randn(size,out=None,dtype=None,layout=torch.strided,device=None,requires_grad=False)
torch.randn_like() 函数的格式如下:
torch.randn_like(input,dtype=None,layout=None,device=None,requires_grad=False)
3) 从均匀分布中抽取随机数创建张量
可以使用 torch.rand() 函数和 torch.rand_like() 函数从 [0, 1) 上的均匀分布中抽取随机数创建张量。torch.rand() 函数的格式如下:
torch.rand(size,out=None,dtype=None,layout=torch.strided,device=None,requires_grad=False)
torch.rand_like() 函数的格式如下:
torch.rand_like(input,dtype=None,layout=torch.strided,device=None,requires_grad=False)