doc22_035.md 9.3 KB
Newer Older
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
1 2
# 张量属性

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
3
> 原文:[`pytorch.org/docs/stable/tensor_attributes.html`](https://pytorch.org/docs/stable/tensor_attributes.html)
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
4

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
5
每个`torch.Tensor`都有一个`torch.dtype``torch.device``torch.layout`
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
6 7 8 9 10 11 12

## torch.dtype

```py
class torch.dtype
```

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
13
`torch.dtype`是表示`torch.Tensor`的数据类型的对象。PyTorch 有 12 种不同的数据类型:
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
14 15 16

| 数据类型 | dtype | 旧构造函数 |
| --- | --- | --- |
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
17 18 19 20 21 22 23 24 25 26 27
| 32 位浮点数 | `torch.float32``torch.float` | `torch.*.FloatTensor` |
| 64 位浮点数 | `torch.float64``torch.double` | `torch.*.DoubleTensor` |
| 64 位复数 | `torch.complex64``torch.cfloat` |  |
| 128 位复数 | `torch.complex128``torch.cdouble` |  |
| 16 位浮点数 1 | `torch.float16``torch.half` | `torch.*.HalfTensor` |
| 16 位浮点数 2 | `torch.bfloat16` | `torch.*.BFloat16Tensor` |
| 8 位整数(无符号) | `torch.uint8` | `torch.*.ByteTensor` |
| 8 位整数(有符号) | `torch.int8` | `torch.*.CharTensor` |
| 16 位整数(有符号) | `torch.int16``torch.short` | `torch.*.ShortTensor` |
| 32 位整数(有符号) | `torch.int32``torch.int` | `torch.*.IntTensor` |
| 64 位整数(有符号) | `torch.int64``torch.long` | `torch.*.LongTensor` |
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
28 29
| 布尔值 | `torch.bool` | `torch.*.BoolTensor` |

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
30
1
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
31

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
32
有时被称为 binary16:使用 1 个符号位,5 个指数位和 10 个有效数字位。当精度重要时很有用。
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
33

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
34
2
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
35

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
36
有时被称为 Brain Floating Point:使用 1 个符号位,8 个指数位和 7 个有效数字位。当范围重要时很有用,因为它具有与`float32`相同数量的指数位。
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
37

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
38
要确定`torch.dtype`是否为浮点数据类型,可以使用属性`is_floating_point`,如果数据类型是浮点数据类型,则返回`True`
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
39

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
40
要确定`torch.dtype`是否为复数数据类型,可以使用属性`is_complex`,如果数据类型是复数数据类型,则返回`True`
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
41

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
42
当输入到算术操作(add、sub、div、mul)的 dtype 不同时,我们通过找到满足以下规则的最小 dtype 来提升:
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
43 44 45 46 47 48 49

+   如果标量操作数的类型高于张量操作数的类型(其中复数 > 浮点 > 整数 > 布尔),则提升为具有足够大小以容纳该类别的所有标量操作数的类型。

+   如果零维张量操作数的类别高于有尺寸的操作数,则提升为具有足够大小和类别以容纳该类别的所有零维张量操作数的类型。

+   如果没有更高类别的零维操作数,则提升为具有足够大小和类别以容纳所有有尺寸的操作数的类型。

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
50
浮点标量操作数具有 dtype torch.get_default_dtype(),整数非布尔标量操作数具有 dtype torch.int64。与 numpy 不同,我们在确定操作数的最小 dtype 时不检查值。目前不支持量化和复杂类型。
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92

提升示例:

```py
>>> 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 
```

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
93
当指定算术操作的输出张量时,我们允许将其转换为其 dtype,除非:
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124

+   整数输出张量不能接受浮点张量。

+   布尔输出张量不能接受非布尔张量。

+   非复数输出张量不能接受复数张量

转换示例:

```py
# 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

```py
class torch.device
```

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
125
`torch.device`是表示`torch.Tensor`分配或将要分配的设备的对象。
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
126

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
127
`torch.device` 包含设备类型(`'cpu'``'cuda'``'mps'`)和设备类型的可选设备序数。如果设备序数不存在,这个对象将始终表示设备类型的当前设备,即使调用了 `torch.cuda.set_device()`;例如,使用设备 `'cuda'` 构造的 `torch.Tensor` 等同于 `'cuda:X'`,其中 X 是 `torch.cuda.current_device()` 的结果。
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
128

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
129
可以通过 `Tensor.device` 属性访问 `torch.Tensor` 的设备。
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
130

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
131
可以通过字符串或字符串和设备序数构造 `torch.device`
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170

通过字符串:

```py
>>> 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') 
```

通过字符串和设备序数:

```py
>>> 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) 
```

设备对象也可以用作上下文管理器,以更改分配张量的默认设备:

```py
>>> with torch.device('cuda:1'):
...     r = torch.randn(2, 3)
>>> r.device
device(type='cuda', index=1) 
```

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
171
如果工厂函数传递了显式的、非 None 的设备参数,则此上下文管理器不起作用。要全局更改默认设备,请参见 `torch.set_default_device()`
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
172 173 174

警告

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
175
此函数会对每次调用 torch API(不仅是工厂函数)产生轻微的性能成本。如果这给您带来问题,请在 [`github.com/pytorch/pytorch/issues/92701`](https://github.com/pytorch/pytorch/issues/92701) 上发表评论。
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
176 177 178

注意

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
179
函数中的 `torch.device` 参数通常可以用字符串替换。这样可以快速原型化代码。
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
180 181 182 183 184 185 186 187 188 189 190 191 192 193

```py
>>> # Example of a function that takes in a torch.device
>>> cuda1 = torch.device('cuda:1')
>>> torch.randn((2,3), device=cuda1) 
```

```py
>>> # You can substitute the torch.device with a string
>>> torch.randn((2,3), device='cuda:1') 
```

注意

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
194
出于传统原因,可以通过单个设备序数构造设备,该设备被视为 cuda 设备。这与 `Tensor.get_device()` 相匹配,它返回 cuda 张量的序数,不支持 cpu 张量。
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218

```py
>>> torch.device(1)
device(type='cuda', index=1) 
```

注意

接受设备的方法通常会接受(格式正确的)字符串或(传统的)整数设备序数,即以下都是等价的:

```py
>>> torch.randn((2,3), device=torch.device('cuda:1'))
>>> torch.randn((2,3), device='cuda:1')
>>> torch.randn((2,3), device=1)  # legacy 
```  ## torch.layout

```py
class torch.layout
```

警告

`torch.layout` 类处于 beta 阶段,可能会发生变化。

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
219
`torch.layout` 是一个表示 `torch.Tensor` 的内存布局的对象。目前,我们支持 `torch.strided`(稠密张量),并且对 `torch.sparse_coo`(稀疏 COO 张量)提供 beta 支持。
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
220 221 222 223 224 225 226 227 228 229 230 231 232 233

`torch.strided` 表示稠密张量,是最常用的内存布局。每个步幅张量都有一个关联的 `torch.Storage`,用于保存其数据。这些张量提供了一个多维、[步幅](https://en.wikipedia.org/wiki/Stride_of_an_array) 视图的存储。步幅是一个整数列表:第 k 个步幅表示在张量的第 k 维中从一个元素到下一个元素所需的内存跳跃。这个概念使得能够高效地执行许多张量操作。

示例:

```py
>>> x = torch.tensor([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
>>> x.stride()
(5, 1)

>>> x.t().stride()
(1, 5) 
```

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
234
有关 `torch.sparse_coo` 张量的更多信息,请参阅 torch.sparse。
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
235 236 237 238 239 240 241

## torch.memory_format

```py
class torch.memory_format
```

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
242
`torch.memory_format` 是一个表示 `torch.Tensor` 分配或将要分配的内存格式的对象。
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
243 244 245 246 247 248 249

可能的值有:

+   `torch.contiguous_format`:张量被分配在稠密、非重叠的内存中。步幅由值按降序表示。

+   `torch.channels_last`:张量被分配在稠密、非重叠的内存中。步幅由 `strides[0] > strides[2] > strides[3] > strides[1] == 1` 表示,即 NHWC 顺序。

绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
250
+   `torch.channels_last_3d`: 张量将被分配在稠密且不重叠的内存中。步幅由`strides[0] > strides[2] > strides[3] > strides[4] > strides[1] == 1`中的值表示,也称为 NDHWC 顺序。
绝不原创的飞龙's avatar
绝不原创的飞龙 已提交
251 252

+   `torch.preserve_format`: 在像克隆这样的函数中使用,以保留输入张量的内存格式。如果输入张量是在稠密且不重叠的内存中分配的,则输出张量的步幅将从输入中复制。否则,输出步幅将遵循`torch.contiguous_format`