PyTorch Tensor创建实现
作者:jiang_huixin
使用已有数据
torch.tensor(data)
>>> import torch >>> import numpy as np # 标量 >>> torch.tensor(0) tensor(0) # 列表/元组 >>> torch.tensor([[1.0]]) tensor([[1.]]) # ndarray >>> n = np.arange(3) >>> torch.tensor(n) tensor([0, 1, 2])
可以额外指定数据类型和设备, 默认情况下由数据本身自动推断出类型, 整数使用 torch.int64 类型, 浮点数使用 torch.float32 类型
>>> torch.tensor([1.0, 2.0], dtype=torch.float16, device='cuda') tensor([1., 2.], device='cuda:0', dtype=torch.float16)
使用 torch.tensor 创建 Tensor 时, 总是完全拷贝, 不会共享底层数据
# 不与 ndarray 共享内存数据 >>> n = np.array([1, 2]) >>> t = torch.tensor(n) >>> t[0] = 0 >>> t tensor([0, 2]) >>> n array([1, 2])
torch.as_tensor(data)
与 torch.tensor 不同, 该函数会尽量共享内存, 当然只有 data 是 np.ndarray 或 torch.Tensor 类型时才能共享, data 是列表或元组时没法共享内存
# 与 ndarray 共享内存数据 >>> n = np.array([1, 2]) # 底层调用 torch.from_numpy(n) >>> t = torch.as_tensor(n) >>> t[0] = 0 >>> t tensor([0, 2]) >>> n array([0, 2])
同样可以指定数据类型和设备, 当指定的类型与 data 的数据类型不一致时不共享数据
>>> d = torch.arange(3) >>> t = torch.as_tensor(d, dtype=torch.int16) >>> t[0] = -1 >>> t tensor([-1, 1, 2], dtype=torch.int16) >>> d tensor([0, 1, 2])
torch.Tensor(sequence)
相当于直接实例化一个 torch.Tensor 类型的对象, 默认是 torch.float32 的数据类型, 设备位于 CPU
# 不支持标量 >>> torch.Tensor(1.0) ----------------------------------------------------------- TypeError Traceback (most recent call last) Input In [40], in <cell line: 1>() ----> 1 torch.Tensor(1.0) TypeError: new(): data must be a sequence (got float) >>> n = np.array([0, 1]) # 整型被自动转为 torch.float32 >>> torch.Tensor(n) tensor([0., 1.])
除了 torch.Tensor 还有其他的类型, 也可以这样实例化, 例如 torch.IntTensor, torch.FloatTensor 等 CPU 张量类型, torch.cuda.IntTensor, torch.cuda.FloatTensor 等 GPU 张量类型
torch.Tensor 默认是 torch.FloatTensor 类型即默认张量类型, 这个可以被全局修改
# 使用 CPU 张量类型进行实例化 >>> torch.DoubleTensor([1, 2]) tensor([1., 2.], dtype=torch.float64) # 使用 GPU 张量类型进行实例化 >>> torch.cuda.IntTensor([1, 2]) tensor([1, 2], device='cuda:0', dtype=torch.int32)
数据未初始化
数据未初始化, 直接使用存储设备中的原有数据
torch.empty(*sizes) # 注意与 torch.Tensor(sequence) 的区别 # 这里也可以替换为 torch.IntTensor(*sizes) 等 Tensor 类型 torch.Tensor(*sizes)
示例
>>> torch.empty(1, 2) tensor([[2.9386e+29, 7.1104e-04]]) >>> torch.cuda.IntTensor(2, 3) tensor([[0, 0, 0], [0, 0, 0]], device='cuda:0', dtype=torch.int32)
特殊张量
# 全 0 torch.zeros(*size) # 全 1 torch.ones(*size) # 指定全值 torch.full(size, fill_value) # n 行 m 列单位对角矩阵 torch.eye(n, m=None) # 对角矩阵, 参数 tensor 为一维张量, 指定对角线元素 torch.diag(tensor)
除了末尾两个函数生成的是二维张量, 其余的函数不限张量维度
代码示例:
# 默认数据类型为 torch.float32 >>> torch.zeros(2) tensor([0., 0.]) # 2 行 1 列 >>> torch.ones(2, 1, dtype=torch.int32) tensor([[1], [1]], dtype=torch.int32) # 指定全值 >>> torch.full([2, 2], 3) tensor([[3, 3], [3, 3]]) # 主对角线元素均为 1, 其余元素为 0 >>> torch.eye(2, 3) tensor([[1., 0., 0.], [0., 1., 0.]]) >>> torch.diag(torch.tensor([1, 3, 5])) tensor([[1, 0, 0], [0, 3, 0], [0, 0, 5]])
数列
torch.arange(start=0, end, step=1)
torch.linspace(start, end, steps=100) 间隔相等的张量
torch.logspace(start, end, steps=100, base=10.0) 以对数为间隔的张量
代码示例
>>> torch.arange(3) tensor([0, 1, 2]) >>> torch.arange(1, 3.1, 1.0) tensor([1., 2., 3.]) >>> torch.linspace(-2, 2, 5) tensor([-2., -1., 0., 1., 2.]) # 从 2^(-2) 至 2^2 >>> torch.logspace(-2, 2, steps=5, base=2) tensor([0.2500, 0.5000, 1.0000, 2.0000, 4.0000])
可以看出对于相同的 start, end 和 steps 参数, logspace = base ^ linspace
随机生成
正态分布
# 标准正态分布 torch.randn(*size) # 指定均值与标准差 torch.normal(mean, std, size)
示例
# 指定随机数种子, 保证随机数可以重现 >>> _ = torch.manual_seed(2022) >>> torch.randn(2, 3) tensor([[ 0.1915, 0.3306, 0.2306], [ 0.8936, -0.2044, -0.9081]]) >>> torch.normal(mean=1.0, std=0.1, size=[2, 3]) tensor([[0.7689, 1.1635, 1.2061], [0.9746, 0.8488, 0.8720]]) # 不指定size, 由 mean 和 std 参数的形状推断出结果的维度 # 输出的两个随机数分别服从均值为 1.0 和 2.0 标准差为 0.1 的正态分布 # 显然, 两个数分别在 1.0 和 2.0 的附近(标准差故意选的很小) >>> torch.normal(mean=torch.Tensor([1.0, 2.0]), std=0.1) tensor([1.0111, 2.0205])
均匀分布
# [0, 1] 上的均匀分布 torch.rand(*size)
示例
# [2, 4] 上的均匀分布 >>> 2 * torch.rand(2, 2) + 2 tensor([[2.4388, 2.5786], [3.3569, 2.9994]])
随机序列
# 0, 1, 2, ..., n-1 随机排列 torch.randperm(n)
示例
>>> _ = torch.manual_seed(2022) >>> torch.randperm(6) tensor([5, 1, 3, 2, 0, 4])
随机整数
# 随机生成 low 到 high - 1 的整数, 包括 low 和 high - 1 这两个整数 torch.randint(low=0, high, size)
示例
>>> torch.randint(5, [2, 3]) tensor([[1, 0, 3], [1, 4, 2]]) >>> torch.randint(3, 6, [2, 2]) tensor([[5, 4], [4, 3]])
继承张量类型
使用 Tensor.new_*() 的方式新建一个张量, 该张量与调用者具有相同的张量类型
例如:
# 未初始化 Tensor.new(*sizes) Tensor.new_empty(size) # 全 0 Tensor.new_zeros(size) # 全 1 Tensor.new_ones(size) # 指定初始值 Tensor.new_full(size, fill_value)
示例
>>> t = torch.cuda.IntTensor([2]) >>> t tensor([2], device='cuda:0', dtype=torch.int32) # 继承了数据类型以及设备类型 >>> t.new_full([1, 2], 1) tensor([[1, 1]], device='cuda:0', dtype=torch.int32)
继承维度以及张量类型
使用 torch.*_like(other) 的方式新建一个张量, 该张量与 other 张量具有相同的形状和张量类型
例如:
# 未初始化 torch.empty_like(other) # 全 0 torch.zeros_like(other) # 全 1 torch.ones_like(other) # 指定初始值 torch.full_like(other, fill_value) # 均匀分布 torch.rand_like(other) # 标准正态分布 torch.randn_like(other) # 随机整数 torch.randint_like(other, low=0, high)
示例
>>> t = torch.tensor([[1, 2]], dtype=torch.int16, device='cuda') >>> t tensor([[1, 2]], device='cuda:0', dtype=torch.int16) >>> f = torch.zeros_like(t) # 继承了 t 的形状以及张量类型 >>> f tensor([[0, 0]], device='cuda:0', dtype=torch.int16)
到此这篇关于PyTorch Tensor创建实现的文章就介绍到这了,更多相关PyTorch Tensor创建内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!