【发布时间】:2020-12-14 08:46:57
【问题描述】:
我正试图更好地理解原因。
在accepted answer 刚刚链接的问题中,Blupon 指出:
您需要将您的张量转换为另一个除了实际值定义之外不需要梯度的张量。
在他链接到的第一个讨论中,albanD 说:
这是预期行为,因为移动到 numpy 会破坏图形,因此不会计算梯度。
如果你实际上不需要梯度,那么你可以显式地 .detach() 需要 grad 的 Tensor 得到一个内容相同但不需要 grad 的张量。然后可以将这个其他张量转换为 numpy 数组。
在他链接到的第二次讨论中,apaszke 写道:
变量不能转换为 numpy,因为它们是保存操作历史的张量的包装器,而 numpy 没有这样的对象。您可以使用 .data 属性检索变量持有的张量。然后,这应该可以工作:var.data.numpy()。
我研究了 PyTorch 的自分化库的内部工作原理,但我仍然对这些答案感到困惑。为什么它会破坏图表以移动到 numpy?是不是因为对numpy数组的任何操作都不会在autodiff图中被跟踪?
什么是变量?它与张量有何关系?
我觉得这里需要一个彻底的高质量 Stack-Overflow 答案,向尚不了解自分化的 PyTorch 新用户解释其原因。
特别是,我认为通过一个图来说明图表并在此示例中显示断开连接是如何发生的会很有帮助:
import torch tensor1 = torch.tensor([1.0,2.0],requires_grad=True) print(tensor1) print(type(tensor1)) tensor1 = tensor1.numpy() print(tensor1) print(type(tensor1))
【问题讨论】:
-
变量接口已经被弃用了很长时间(从 pytorch 0.4.0 开始)。任何说明它们是必要的 autograd 的描述都已经过时了几年。
-
official docs 中是否有一些令人困惑的地方。我认为他们很好地封装了如何使用张量的
grad_fn属性构造计算图(当然,numpy 数组没有为数组填充的grad_fn属性,该属性是由操作产生的,因此无法跟踪梯度对于那些)。 -
它描述了使用
grad_fn属性跟踪操作,该属性为任何新张量填充,这是涉及张量的可微函数的结果。由于此跟踪功能是张量类的一部分,而不是 numpy 数组,因此一旦转换为 numpy 数组,您将无法再跟踪这些操作,因此无法应用微分链规则(也称为反向传播) -
另外,这可能会导致混淆,但没有计算图对象。所谓的计算图实际上是张量和函数的抽象组合。您生成的张量指的是函数(使用
grad_fn),这些函数本身指的是其他张量,这些张量指的是函数等。给定一个张量,您可以通过grad_fn引用进行追溯,最终将引用您的模型参数(叶张量)。如果在中间转换为 numpy 数组,则无法追溯到这些参数,因为只有张量具有grad_fn。 -
@jodag 我的问题最初是通过阅读docs for detach 提示的。既然我已经看到了您的评论答案,我认为该文档只是说分离的张量没有通过 grad_fn 与另一个张量绑定。但它与另一个张量共享内存的事实让人感觉很奇怪。但我觉得这与我在这里想问的问题不同。