【发布时间】:2020-10-07 18:35:04
【问题描述】:
在使用 Pytorch 时,我一直在努力理解 .clone()、.detach() 和 copy.deepcopy 之间的区别。特别是 Pytorch 张量。
我尝试写下所有关于它们的差异和用例的问题,但很快就不知所措,并意识到也许拥有 Pytorch 张量的 4 个主要属性会更好地阐明使用哪个来解决每个小问题。我意识到需要跟踪的 4 个主要属性是:
- 如果有一个张量的新指针/引用
- 如果有一个新的张量对象实例(因此这个新实例很可能有它自己的元数据,如
require_grads、形状、is_leaf等) - 如果它为张量数据分配了新内存(即,如果这个新张量是不同张量的视图)
- 它是否正在跟踪操作历史记录(或者即使它正在跟踪一个全新的操作历史记录,或者在深拷贝的情况下是相同的旧历史记录)
根据从 Pytorch 论坛和文档中挖掘出来的内容,这是我目前在张量上使用时的区别:
克隆
对于克隆:
x_cloned = x.clone()
我相信这就是它根据主要 4 个属性的行为方式:
- 克隆的
x_cloned有它自己的python 引用/指向新对象的指针 - 它创建了自己的新张量对象实例(带有单独的元数据)
- 它已为
x_new分配了一个新内存,其数据与x相同 - 它正在跟踪原始操作历史,此外还包括此
clone操作.grad_fn=<CloneBackward>
据我所知,它的主要用途似乎是创建事物的副本,以便inplace_ 操作是安全的。此外,再加上 .detach 和 .detach().clone() (顺便说一句“更好”的顺序),它创建了一个全新的张量,该张量已与旧历史分离,从而阻止梯度流过该路径。
分离
x_detached = x.detach()
- 创建一个新的 python 引用(当然,唯一没有这样做的是
x_new = x)。我相信这个可以使用id - 它创建了自己的新张量对象实例(带有单独的元数据)
- 它没有为
x_detached分配了一个与x相同的数据的新内存 - 它切断了梯度的历史,不允许它流过它。我认为将其视为没有历史的全新张量是正确的。
我相信我所知道的唯一明智的用途是在将.clone() 与.detach().clone() 结合使用时,使用自己的内存创建新副本。否则,我不确定它有什么用。由于它指向原始数据,因此执行就地操作可能存在潜在危险(因为它会更改旧数据,但旧数据的更改不在较早的计算图中为 autograd 所知)。
copy.deepcopy
x_deepcopy = copy.deepcopy(x)
- 如果有一个张量的新指针/引用
- 它使用自己的元数据创建一个新的张量实例(所有元数据都应指向深层副本,因此如果按照我希望的那样实现新对象)。
- 它为张量数据分配了自己的内存
- 如果它真的是一个深拷贝,我会期待一个深拷贝的历史。所以它应该对历史进行深度复制。虽然这看起来确实很昂贵,但至少在语义上与深拷贝应该是一致的。
我真的没有看到这方面的用例。我认为任何试图使用它的人真的意味着 1) .detach().clone() 或只是 2) .clone() 本身,这取决于一个人是想用 1 停止梯度流到较早的图形,还是只想用新的图形复制数据记忆 2)。
因此,这是我目前了解差异的最佳方式,而不是询问可能使用它们的所有不同场景。
所以这是对的吗?有没有人发现任何需要纠正的重大缺陷?
我自己担心的是我赋予深度复制的语义,想知道深度复制历史是否正确。
我认为每个用例的常见用例列表会很棒。
资源
这些是我阅读并参与得出此问题结论的所有资源:
- 0.4.0 迁移指南https://pytorch.org/blog/pytorch-0_4_0-migration-guide/
- 关于使用克隆的困惑:https://discuss.pytorch.org/t/confusion-about-using-clone/39673/3
- 在 v0.4.0 中克隆和分离:https://discuss.pytorch.org/t/clone-and-detach-in-v0-4-0/16861/2
- 克隆文档:
- 分离文档(在浏览器中搜索单词分离没有直接链接):
- detach().clone() 和 clone().detach() 的区别:https://discuss.pytorch.org/t/difference-between-detach-clone-and-clone-detach/34173
- 为什么我可以在 Pytorch 中使用 detach 来更改张量的值而计算图不知道它? Why am I able to change the value of a tensor without the computation graph knowing about it in Pytorch with detach?
- Pytorch 张量中 detach、clone 和 deepcopy 的区别是什么? What is the difference between detach, clone and deepcopy in Pytorch tensors in detail?
- Copy.deepcopy() 与 clone() https://discuss.pytorch.org/t/copy-deepcopy-vs-clone/55022/10
【问题讨论】:
-
您的问题很长,也不是很清楚。使用小的编码样本会更容易。
标签: python machine-learning pytorch