1

首先,我应该提到我使用的是 Torch 版本 0.3.1,但如果有必要,我很乐意升级。

我还在学习,所以如果我在这里误解了什么,请告诉我。

我正在使用变量命令式地构建几个图表。随着时间的推移,数学表达式可能会非常复杂,并且可以使用 autograd 的梯度函数生成图形的某些部分,然后对其进行操作。

我可以创建任何我想要的表达方式。唯一的问题是构建这个图可能非常“慢”——对于相对简单的操作(4x4 矩阵相乘),可能需要几毫秒。

但是,一旦生成了这些图表,我希望我应该能够更快地更新某些变量的值,并评估图表的输出(或任何节点,实际上)。我相信这可能就是这种情况,因为评估应该能够完全在 C 后端进行,这对于速度应该是相当优化的?换句话说,在 python 中构建图形可能会很慢,因为它涉及 python for 循环等,但是重新评估具有静态拓扑的图形应该很快。

这种直觉正确吗?如果是这样,我怎样才能有效地重新分配一个值并重新评估图表?

4

1 回答 1

0

如果您正在谈论更新输入变量的值,并且您只想评估图形的前向而不打算调用.backward(),则可以在 Pytorch 0.3 中volatile=True的输入上使用。Variable

这个特性在 0.4 中被移除,取而代之的是上下文管理器with torch.no_grad():

这通常在推理时完成。如果这样做,将不会创建图表,从而消除开销。

更新

火炬 0.3

来自 Pytorch 0.3 文档:

当您确定您甚至不会调用 .backward() 时,建议将 Volatile 用于纯推理模式。它比任何其他 autograd 设置更有效 - 它将使用绝对最小的内存量来评估模型。volatile 还确定 requires_grad 为 False。

Volatile 与 requires_grad 的不同之处在于标志的传播方式。如果一个操作甚至有一个易失性输入,它的输出也将是易失性的。波动性在图上的传播比不需要梯度要容易得多——你只需要一个 volatile 叶子就可以有一个 volatile 输出,而你需要所有叶子都不需要梯度才能有一个不需要梯度的输出。使用 volatile 标志,您无需更改模型参数的任何设置即可将其用于推理。创建一个 volatile 输入就足够了,这将确保不保存任何中间状态。

因此,如果您使用 Pytorch 0.3 并想要进行有效的推理,您可以使用volatile=True您的输入。

火炬 0.4

Pytorch 0.4 中引入了上下文管理器。来自0.3 和 0.4 之间的 Pytorch迁移指南:

volatile 标志现在已被弃用并且没有效果。以前,任何涉及 volatile=True 变量的计算都不会被 autograd 跟踪。这现在已被一组更灵活的上下文管理器所取代,包括 torch.no_grad()、torch.set_grad_enabled(grad_mode) 等。

所以当你说:“那么,如果有办法将该图的所有变量转换为非易失性,我就可以进行推理。” ,将输入设置为volatile或使用no_grad将完全做到这一点。

至于使用的例子torch.no_grad(),看这个脚本test中的函数。

训练期间的静态图

我不知道有任何方法可以避免在 Pytorch 的训练模式下的每次迭代中创建图形。动态图是有代价的。如果您想要这个,请将您的模型转换为 Tensorflow/Caffe2/任何支持静态图的库,即使根据我的经验,它们不一定会更快。

于 2018-06-17T10:28:28.317 回答