张量属性¶
每个 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
有时称为 binary16:使用 1 个符号、5 个指数和 10 个有效数字位。当精度很重要时很有用。
- 2
有时称为 Brain Floating Point:使用 1 个符号、8 个指数和 7 个有效数字位。当范围很重要时很有用,因为它具有与
相同数量的指数位。float32
要了解 torch.dtype
是否是浮点数据类型,可以使用属性 is_floating_point
,如果数据类型是浮点数据类型,则返回 True
要了解 torch.dtype
是否是复杂数据类型,可以使用属性 is_complex
,如果数据类型是复杂数据类型,则返回 True
当算术运算(add、sub、div、mul)的输入的 dtypes 不同时,我们通过查找满足以下规则的最小 dtype 来提升
如果标量操作数的类型比张量操作数的类别更高(其中 complex > floating > integral > boolean),我们提升到具有足够大小以容纳该类别所有标量操作数的类型。
如果零维张量操作数的类别比维度操作数的类别更高,我们提升到具有足够大小和类别以容纳该类别所有零维张量操作数的类型。
如果没有更高类别的零维操作数,我们提升到具有足够大小和类别以容纳所有维度操作数的类型。
浮点标量操作数的 dtype 为 torch.get_default_dtype(),整数非布尔标量操作数的 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
- 当指定算术运算的输出张量时,我们允许将其 dtype 转换为其 dtype,但
整数输出张量不能接受浮点张量。
布尔输出张量不能接受非布尔张量。
非复数输出张量不能接受复数张量
转换示例
# 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()
的结果。
可以通过 Tensor.device
属性访问 torch.Tensor
的设备。
可以通过字符串或字符串和设备序号构建 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)
如果工厂函数传入明确的非 None 设备参数,则此上下文管理器无效。要全局更改默认设备,另请参阅 torch.set_default_device()
。
警告
此函数对每次对 PyTorch API(不仅仅是工厂函数)的 Python 调用施加轻微的性能开销。如果您因此遇到问题,请在 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')
注意
出于传统原因,可以通过单个设备序号构造设备,该序号被视为 cuda 设备。这与 Tensor.get_device()
相匹配,后者为 cuda 张量返回序号,并且不支持 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 维中从一个元素到下一个元素所需的内存跳转。这个概念使得可以高效地执行许多张量操作。
示例
>>> 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
:张量已或将被分配到密集非重叠内存中。步长由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