【问题标题】:Updating Pytorch variables更新 Pytorch 变量
【发布时间】:2018-11-26 07:43:59
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

    标签: python pytorch autograd


    【解决方案1】:

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

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

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

    更新

    Pytorch 0.3

    来自 Pytorch 0.3 文档:

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

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

    因此,如果您使用 Pytorch 0.3 并希望进行高效推理,您可以在输入中使用 volatile=True

    Pytorch 0.4

    上下文管理器已在 Pytorch 0.4 中引入。来自 Pytorch migration guide between 0.3 and 0.4:

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

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

    至于使用torch.no_grad()的例子,请看this script中的test函数。

    训练期间的静态图

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

    【讨论】:

    • 感谢您的回复。此解决方案的唯一问题是您无法获得易变事物的梯度。无论是否针对变化的变量计算梯度,图拓扑都应该是静态的。有没有办法改变计算梯度的值?
    • 现在我想想,这可能仍然有效。如果我使用 autograd 进行渐变,如果我理解正确,我会创建一个新图形。然后,如果有办法将该图的所有变量转换为非易失性,我就可以进行推理。我猜上下文管理器是一种更简洁的方法,对吗?
    • 你能举一个简单的例子说明如何在 pytorch 0.4 中使用它吗?
    • 已更新以回答您的问题
    猜你喜欢
    • 2019-08-22
    • 2018-06-30
    • 1970-01-01
    • 2019-04-18
    • 2019-05-02
    • 1970-01-01
    • 2018-10-07
    • 2020-09-11
    • 2011-07-08
    相关资源
    最近更新 更多