张量属性¶
每个 torch.Tensor 都有一个 torch.dtype,torch.device 和 torch.layout。
torch.dtype¶
- class torch.dtype¶
一个 torch.dtype 是表示数据类型的对象。
torch.Tensor。PyTorch 有十二种不同的数据类型:
数据类型 |
数据类型(dtype) |
遗产构造函数 |
|---|---|---|
32位浮点数 |
|
|
64位浮点数 |
|
|
64位复数 |
|
|
128位复数 |
|
|
16位浮点数 1 |
|
|
16位浮点数 2 |
|
|
8位整数(无符号) |
|
|
8位整数(有符号) |
|
|
16位整数(有符号) |
|
|
32位有符号整数 |
|
|
64位整数(有符号) |
|
|
布尔值 |
|
|
- 1
有时被称为二进制16:使用1个符号位、5个指数位和10个有效位。在精度很重要的时候很有用。
- 2
有时被称为Brain浮点数:使用1个符号位,8个指数位和7个尾数位。当范围很重要时很有用,因为它与
float32具有相同数量的指数位。
要找出一个 torch.dtype 是否为浮点数据类型,可以使用属性 is_floating_point,
如果数据类型为浮点数据类型,则返回 True。
要找出一个 torch.dtype 是否为复杂数据类型,可以使用属性 is_complex,
如果数据类型是复杂数据类型,则返回 True。
当算术运算(add,sub,div,mul)的输入数据类型不同时,我们通过找到满足以下规则的最小数据类型来进行提升:
如果标量运算符的类型高于张量运算符的类别 (其中复数 > 浮点数 > 整数 > 布尔值),我们将提升到足够大的类型以容纳 该类别的所有标量运算符。
如果零维度张量操作数的类别高于有维度的操作数, 我们将提升到足够大小且类别合适的类型,以容纳所有该类别的零维张量操作数。
如果没有更高类别的零维运算对象,则提升到一个足够大且类别合适的类型以容纳所有有维度的运算对象。
一个浮点标量运算符的数据类型为torch.get_default_dtype(),而整数(非布尔)标量运算符的数据类型为torch.int64。与numpy不同,在确定运算符的最小值dtypes时,我们不会检查值。目前还不支持量化和复数类型。
促销示例:
>>> float_tensor = torch.ones(1, dtype=torch.float)
>>> double_tensor = torch.ones(1, dtype=torch.double)
>>> complex_float_tensor = torch.ones(1, dtype=torch.complex64)
>>> complex_double_tensor = torch.ones(1, dtype=torch.complex128)
>>> int_tensor = torch.ones(1, dtype=torch.int)
>>> long_tensor = torch.ones(1, dtype=torch.long)
>>> uint_tensor = torch.ones(1, dtype=torch.uint8)
>>> double_tensor = torch.ones(1, dtype=torch.double)
>>> bool_tensor = torch.ones(1, dtype=torch.bool)
# zero-dim tensors
>>> long_zerodim = torch.tensor(1, dtype=torch.long)
>>> int_zerodim = torch.tensor(1, dtype=torch.int)
>>> torch.add(5, 5).dtype
torch.int64
# 5 is an int64, but does not have higher category than int_tensor so is not considered.
>>> (int_tensor + 5).dtype
torch.int32
>>> (int_tensor + long_zerodim).dtype
torch.int32
>>> (long_tensor + int_tensor).dtype
torch.int64
>>> (bool_tensor + long_tensor).dtype
torch.int64
>>> (bool_tensor + uint_tensor).dtype
torch.uint8
>>> (float_tensor + double_tensor).dtype
torch.float64
>>> (complex_float_tensor + complex_double_tensor).dtype
torch.complex128
>>> (bool_tensor + int_tensor).dtype
torch.int32
# Since long is a different kind than float, result dtype only needs to be large enough
# to hold the float.
>>> torch.add(long_tensor, float_tensor).dtype
torch.float32
- When the output tensor of an arithmetic operation is specified, we allow casting to its dtype except that:
一个整数输出张量不能接受一个浮点张量。
布尔输出张量不能接受非布尔张量。
一个非复数输出张量不能接受复数张量
示例用法:
# allowed:
>>> float_tensor *= float_tensor
>>> float_tensor *= int_tensor
>>> float_tensor *= uint_tensor
>>> float_tensor *= bool_tensor
>>> float_tensor *= double_tensor
>>> int_tensor *= long_tensor
>>> int_tensor *= uint_tensor
>>> uint_tensor *= int_tensor
# disallowed (RuntimeError: result type can't be cast to the desired output type):
>>> int_tensor *= float_tensor
>>> bool_tensor *= int_tensor
>>> bool_tensor *= uint_tensor
>>> float_tensor *= complex_float_tensor
torch.device¶
- class torch.device¶
一个 torch.device 是表示设备的对象,在该设备上分配了一个 torch.Tensor 或者将会被分配。
这torch.device包含一个设备类型(最常见的为“cpu”或
“cuda”,但也可能是“mps”, “xpu”,
“xla” 或 “meta”) 以及可选的
设备类型的设备序号。如果未提供设备序号,此对象将始终表示
该设备类型的当前设备,即使在调用torch.cuda.set_device()之后也是如此;例如,
使用设备'cuda'构造的torch.Tensor等同于'cuda:X',其中X是
调用torch.cuda.current_device()的结果。
一个 torch.Tensor 的设备可以通过 Tensor.device 属性访问。
一个 torch.device 可以通过字符串或者通过字符串和设备序号来构建
通过字符串:
>>> torch.device('cuda:0')
device(type='cuda', index=0)
>>> torch.device('cpu')
device(type='cpu')
>>> torch.device('mps')
device(type='mps')
>>> torch.device('cuda') # current cuda device
device(type='cuda')
通过字符串和设备序号:
>>> torch.device('cuda', 0)
device(type='cuda', index=0)
>>> torch.device('mps', 0)
device(type='mps', index=0)
>>> torch.device('cpu', 0)
device(type='cpu', index=0)
设备对象也可以用作上下文管理器来更改张量默认分配的设备:
>>> with torch.device('cuda:1'):
... r = torch.randn(2, 3)
>>> r.device
device(type='cuda', index=1)
如果传递了一个明确的、非空设备参数的工厂函数,则此上下文管理器无效。要全局更改默认设备,请参见torch.set_default_device()。
警告
此功能对每次调用Python中的torch API(不仅仅是工厂函数)都会产生轻微的性能开销。如果您遇到问题,请在 https://github.com/pytorch/pytorch/issues/92701发表评论。
注意
函数中的 torch.device 参数通常可以用字符串替换。
这使得代码快速原型设计成为可能。
>>> # Example of a function that takes in a torch.device
>>> cuda1 = torch.device('cuda:1')
>>> torch.randn((2,3), device=cuda1)
>>> # You can substitute the torch.device with a string
>>> torch.randn((2,3), device='cuda:1')
注意
由于历史原因,设备可以通过单个设备序号来构造,这被视为当前的加速器类型。
这与Tensor.get_device()匹配,它为设备张量返回一个序号,并且不支持cpu张量。
>>> torch.device(1)
device(type='cuda', index=1)
注意
接受设备的方法通常可以接受一个格式正确的字符串或(旧版)整数设备序号,即以下几种写法是等价的:
>>> torch.randn((2,3), device=torch.device('cuda:1'))
>>> torch.randn((2,3), device='cuda:1')
>>> torch.randn((2,3), device=1) # legacy
注意
张量绝不会自动在设备之间移动,需要用户明确调用。标量张量(tensor.dim()==0)是这条规则的唯一例外,当需要时,它们会自动从CPU转移到GPU,因为这一操作可以“免费”完成。 示例:
>>> # two scalars
>>> torch.ones(()) + torch.ones(()).cuda() # OK, scalar auto-transferred from CPU to GPU
>>> torch.ones(()).cuda() + torch.ones(()) # OK, scalar auto-transferred from CPU to GPU
>>> # one scalar (CPU), one vector (GPU)
>>> torch.ones(()) + torch.ones(1).cuda() # OK, scalar auto-transferred from CPU to GPU
>>> torch.ones(1).cuda() + torch.ones(()) # OK, scalar auto-transferred from CPU to GPU
>>> # one scalar (GPU), one vector (CPU)
>>> torch.ones(()).cuda() + torch.ones(1) # Fail, scalar not auto-transferred from GPU to CPU and non-scalar not auto-transferred from CPU to GPU
>>> torch.ones(1) + torch.ones(()).cuda() # Fail, scalar not auto-transferred from GPU to CPU and non-scalar not auto-transferred from CPU to GPU
torch.layout¶
- class torch.layout¶
警告
torch.layout 类处于测试阶段,可能会发生变化。
一个 torch.layout 是一个表示内存布局的对象。
torch.Tensor 的内存布局。
目前,我们支持 torch.strided (稠密张量)
并且对 torch.sparse_coo (稀疏 COO 张量)提供了测试支持。
torch.strided 表示密集张量,是最常用的内存布局。每个有步幅的张量都有一个相关的
torch.Storage, 它保存了张量的数据。这些张量提供了对存储的多维、有步幅
视图。步幅是一组整数:第 k 个步幅表示在张量的第 k 维中从一个元素跳到下一个元素所需的内存跳跃。这个概念使得许多张量操作能够高效地执行。
Example:
>>> x = torch.tensor([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
>>> x.stride()
(5, 1)
>>> x.t().stride()
(1, 5)
查看更多有关 torch.sparse_coo 张量的信息,请参阅 torch.sparse。
torch.memory_format¶
- class torch.memory_format¶
一个 torch.memory_format 是一个表示内存格式的对象,在该内存格式上分配了一个 torch.Tensor 或者将会被分配。
可能的值为:
torch.contiguous_format: 张量将分配在密集且不重叠的内存中。步长由递减顺序的值表示。torch.channels_last: Tensor 会被分配在密集且不重叠的内存中。步长由strides[0] > strides[2] > strides[3] > strides[1] == 1值表示,即 NHWC 顺序。torch.channels_last_3d: 张量将被分配在密集且不重叠的内存中。步长由strides[0] > strides[2] > strides[3] > strides[4] > strides[1] == 1值表示,即 NDHWC 顺序。torch.preserve_format: 在像clone这样的函数中使用,以保留输入张量的内存格式。如果输入张量是在密集且不重叠的内存中分配的,则输出张量的步长将从输入中复制。否则,输出步长将遵循torch.contiguous_format。