提交 449bb84c 编写于 作者: 片刻小哥哥's avatar 片刻小哥哥

删除 0.4 临时版本

上级 679dd9ed
# 自动求导机制
1. [从后向中排除子图](#excluding-subgraphs-from-backward)
* [requires_grad](#requires_grad)
* [volatile](#volatile)
2. [自动求导如何编码历史信息](#how-autograd-encodes-the-history)
3. [Variable上的In-place操作](#in-place-operations-on-variables)
4. [In-place正确性检查](#in-place-correctness-checks)
* * *
本说明将概述Autograd如何工作并记录操作。没有必要全部了解,但建议您熟悉它,他可以将帮助你编写程序更高效,更清洁;同时还可以帮助您进行调试。
### 向后排除子视图:
每个变量都有一个标记:`requires_grad`允许从梯度计算中细分排除子图,并可以提高效率。
#### requires_grad
如果一个输入变量定义`requires_grad`,那么他的输出也可以使用`requires_grad`;相反,只有当所有的输入变量都不定义`requires_grad`梯度,才不会输出梯度。如果其中所有的变量都不需要计算梯度,在子图中从不执行向后计算。
```py
>>> x = Variable(torch.randn(5, 5))
>>> y = Variable(torch.randn(5, 5))
>>> z = Variable(torch.randn(5, 5), requires_grad=True)
>>> a = x + y
>>> a.requires_grad
False
>>> b = a + z
>>> b.requires_grad
True
```
当您想要冻结部分模型时,这个标志特别有用;除非您事先知道不会使用到某些参数的梯度。
例如,如果您想调整预训练的`CNN`,只要切换冻结模型中的`requires_grad`标志即可,直到计算到最后一层才会保存中间缓冲区,仿射变换和网络输出都需要使用梯度的权值。
```py
model = torchvision.models.resnet18(pretrained=True)
for param in model.parameters():
param.requires_grad = False
# Replace the last fully-connected layer
# Parameters of newly constructed modules have requires_grad=True by default
model.fc = nn.Linear(512, 100)
# Optimize only the classifier
optimizer = optim.SGD(model.fc.parameters(), lr=1e-2, momentum=0.9)
```
### autograd如何编码历史信息:
每个变量都有一个`.creator`属性,它指向把它作为输出的函数。这是一个由`Function`对象作为节点组成的有向无环图(DAG)的入口点,它们之间的引用就是图的边。每次执行一个操作时,一个表示它的新`Function`就被实例化,它的`forward()`方法被调用,并且它输出的`Variable`的创建者被设置为这个`Function`。然后,通过跟踪从任何变量到叶节点的路径,可以重建创建数据的操作序列,并自动计算梯度。
需要注意的一点是,整个图在每次迭代时都是从头开始重新创建的,这就允许使用任意的Python控制流语句,这样可以在每次迭代时改变图的整体形状和大小。在启动训练之前不必对所有可能的路径进行编码—— what you run is what you differentiate.
### Variable上的In-place操作:
支持自动归档中的就地操作是一件很困难的事情,我们在大多数情况下都不鼓励使用它们。Autograd的积极缓冲区释放和重用使其非常高效,并且在现场操作实际上会降低内存使用量的情况下,极少数场合很少。除非您在内存压力很大的情况下运行,否则您可能永远不需要使用它们。
限制现场操作适用性的两个主要原因:
1. 覆盖计算梯度所需的值。这就是为什么变量不支持`log_`。其梯度公式需要原始输入,而通过计算逆运算可以重新创建它,它在数值上是不稳定的,并且需要额外的工作,这往往会失败使用这些功能的目的。
2. 每个`in-place`操作实际上需要实现重写计算图。不合适的版本只需分配新对象,并保留对旧图的引用,而`in-place`操作则需要将所有输入的`creator`更改为`Function`表示此操作。这就比较棘手,特别是如果有许多变量引用相同的存储(例如通过索引或转置创建的),并且如果被修改输入的存储被其他`Variable`引用,则`in-place`函数实际上会抛出错误。
### In-place正确性检测:
每个变量都保留一个版本计数器`version counter`,当在任何操作中被使用时,它都会递增。当函数保存任何用于后向的`tensor`时,还会保存其包含变量的版本计数器`version counter`。一旦访问,`self.saved_tensors`它被会被检查,如果它大于保存的值,则会引起错误。
### 译者署名
| 用户名 | 头像 | 职能 | 签名 |
| --- | --- | --- | --- |
| [Song](https://ptorch.com) | ![](img/2018033000352689884.jpeg) | 翻译 | 人生总要追求点什么 |
此差异已折叠。
此差异已折叠。
# Tensor Attributes
* [torch.dtype](#torch-dtype)
* [torch.device](#torch-device)
* [torch.layout](#torch-layout)
每个`torch.Tensor`都有`torch.dtype`, `torch.device`,和`torch.layout`
### torch.dtype
`torch.dtype`是表示`torch.Tensor`的数据类型的对象。`PyTorch`有八种不同的数据类型:
| | Data type | dtype | Tensor types |
| --- | --- | --- | --- |
| 32-bit floating point | torch.float32 or torch.float | torch.*.FloatTensor |
| 64-bit floating point | torch.float64 or torch.double | torch.*.DoubleTensor |
| 16-bit floating point | torch.float16 or torch.half | torch.*.HalfTensor |
| 8-bit integer (unsigned) | torch.uint8 | torch.*.ByteTensor |
| 8-bit integer (signed) | torch.int8 | torch.*.CharTensor |
| 16-bit integer (signed) | torch.int16 or torch.short | torch.*.ShortTensor |
| 32-bit integer (signed) | torch.int32 or torch.int | torch.*.IntTensor |
| 64-bit integer (signed) | torch.int64 or torch.long | torch.*.LongTensor |
使用方法:
```py
>>> x = torch.Tensor([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
>>> print x.type()
torch.FloatTensor
```
### torch.device
`torch.device`代表将`torch.Tensor`分配到的设备的对象。
`torch.device`包含一个设备类型(`'cpu'``'cuda'`设备类型)和可选的设备的序号。如果设备序号不存在,则为当前设备; 例如,`torch.Tensor`用设备构建`'cuda'`的结果等同于`'cuda:X'`,其中`X``torch.cuda.current_device()`的结果。
`torch.Tensor`的设备可以通过`Tensor.device`访问属性。
构造`torch.device`可以通过字符串/字符串和设备编号。
通过一个字符串:
```py
>>> torch.device('cuda:0')
device(type='cuda', index=0)
>>> torch.device('cpu')
device(type='cpu')
>>> torch.device('cuda') # current cuda device
device(type='cuda')
```
通过字符串和设备序号:
```py
>>> torch.device('cuda', 0)
device(type='cuda', index=0)
>>> torch.device('cpu', 0)
device(type='cpu', index=0)
```
> **注意**
> `torch.device`函数中的参数通常可以用一个字符串替代。这允许使用代码快速构建原型。
>
> ```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), 'cuda:1')
> ```
* * *
> **注意**
> 出于传统原因,可以通过单个设备序号构建设备,将其视为`cuda`设备。这匹配`Tensor.get_device()`,它为`cuda`张量返回一个序数,并且不支持`cpu`张量。
>
> ```py
> >> torch.device(1)
> device(type='cuda', index=1)
> ```
* * *
> **注意**
> 指定设备的方法可以使用(properly formatted)字符串或(legacy)整数型设备序数,即以下示例均等效:
>
> ```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
`torch.layout`表示`torch.Tensor`内存布局的对象。目前,我们支持`torch.strided(dense Tensors)`并为`torch.sparse_coo(sparse COO Tensors)`提供实验支持。
`torch.strided`代表密集张量,是最常用的内存布局。每个`strided`张量都会关联 一个`torch.Storage`,它保存着它的数据。这些张力提供了多维度, 存储的`strided`视图。`Strides`是一个整数型列表:`k-th stride`表示在张量的第k维从一个元素跳转到下一个元素所需的内存。这个概念使得可以有效地执行多张量。
例:
```py
>>> 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](https://ptorch.com/docs/8/torch-sparse)
### 译者署名
| 用户名 | 头像 | 职能 | 签名 |
| --- | --- | --- | --- |
| [Song](https://ptorch.com) | ![](img/2018033000352689884.jpeg) | 翻译 | 人生总要追求点什么 |
此差异已折叠。
此差异已折叠。
# torch.Storage
* * *
`torch.Storage`是单个数据类型的连续的`一维数组`,每个`torch.Tensor`都具有相同数据类型的相应存储。
```py
class torch.FloatStorage
```
* `byte()`:将Storage转为byte类型
* `char()`:将Storage转为char类型
* `clone()`:返回Storage的副本
* `copy_()`
* `cpu()`:如果尚未在CPU上,则返回Storage的CPU副本
* `cuda(device=None, async=False)`:在CUDA内存中返回此对象的副本。如果该对象已经在CUDA内存中,并且在正确的设备上,则不会执行任何操作,并返回原始对象。 参数说明:
1. device (int) - 目标GPU的id。默认值是当前设备。
2. async (bool) -如果值为True,且源在锁定内存中,则副本相对于宿主是异步的。否则此参数不起效果。
* `data_ptr()`: 返回一个时间戳
* `double()`:将Storage转为double类型
* `element_size()`:返回参数的size
* `fill_()`
* `float()`:将Storage转为float类型
* `from_buffer()`
* `half()`:将Storage转为half类型
* `int()`:将Storage转为int类型
* `is_cuda = False`
* `is_pinned()`
* `is_shared()`
* `is_sparse = False`
* `long()`:将Storage转为long类型
* `new()`
* `pin_memory()`:将存储复制到固定内存(如果尚未固定)。
* `resize_()`
* `share_memory_()`:这对于已经在共享内存和CUDA存储器中的存储器是无效的,不需要为了跨进程共享而移动。无法调整共享内存中的存储空间。返回:self
* `short()`:将Storage转为short类型
* `size()`:返回Storage转的大小
* `tolist()`:返回一个包含Storage中元素的列表
* `type(new_type=None, async=False)`:将此对象转为指定类型。如果已经是正确类型,不会执行复制操作,直接返回原对象。
参数说明:
1. `new_type` (type或string) -需要转成的类型
2. `async (bool)` -如果值为True,并且源处于固定内存中,目标位于GPU上,反之亦然,则相对于主机异步执行该副本。否则,参数没有效果。
具体使用教程请参考:[使用torch.Storage共享多个张量的相同存储以及将torch.Tensor转化为torch.Storage](https://ptorch.com/news/52.html)
### 译者署名
| 用户名 | 头像 | 职能 | 签名 |
| --- | --- | --- | --- |
| [Song](https://ptorch.com) | ![](img/2018033000352689884.jpeg) | 翻译 | 人生总要追求点什么 |
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# torch.distributions
### 译者署名
| 用户名 | 头像 | 职能 | 签名 |
| --- | --- | --- | --- |
| [Song](https://ptorch.com) | ![](img/2018033000352689884.jpeg) | 翻译 | 人生总要追求点什么 |
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# torch.utils.ffi
```py
torch.utils.ffi.create_extension(name, headers, sources, verbose=True, with_cuda=False, package=False, relative_to='.', **kwargs)
```
创建并配置一个构建PyTorch扩展的cffi.FFI对象。
参数:
1. **name (str)** – 包名。可以是嵌套的模块如 `.ext.my_lib`
2. **headers (str or List[str])** – 仅包含导出函数的头文件列表
3. **sources (List[str])** – 要编译的源列表。
4. **verbose (bool, optional)** – 如果设置为`False`,则不打印任何输出(默认值:`True`)。
5. **with_cuda (bool, optional)** – 设置为`True`表示使用CUDA头进行编译(默认值:`False`)。
6. **package (bool, optional)** – 设置为`True`表示以程序包的模式构建(对于要以pip包安装的模块)(默认值:`False`)。
7. **relative_to (str, optional)** –构建文件的路径。 `package``True`时需要。最好使用`__file__`作为参数。
8. **kwargs** – 传递给ffi以声明扩展名的其他参数。详情请参阅[扩展API参考](https://docs.python.org/3/distutils/apiref.html#distutils.core.Extension)
### 译者署名
| 用户名 | 头像 | 职能 | 签名 |
| --- | --- | --- | --- |
| [Song](https://ptorch.com) | ![](img/2018033000352689884.jpeg) | 翻译 | 人生总要追求点什么 |
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册