Pytorch (1.0) 中类似外观操作的不同 `grad_fn`

Posted

技术标签:

【中文标题】Pytorch (1.0) 中类似外观操作的不同 `grad_fn`【英文标题】:Different `grad_fn` for similar looking operations in Pytorch (1.0) 【发布时间】:2019-09-14 01:49:09 【问题描述】:

我正在研究一个注意力模型,在运行最终模型之前,我正在检查流经代码的张量形状。我有一个需要重塑张量的操作。张量的形状为torch.Size([[30, 8, 9, 64]]),其中30batch_size8 是注意力头的数量(这与我的问题无关)9句子中的单词数,@ 987654327@ 是单词的一些中间嵌入表示。在进一步处理之前,我必须将张量重塑为 torch.size([30, 9, 512]) 的大小。所以我在网上寻找一些参考资料,他们做了以下x.transpose(1, 2).contiguous().view(30, -1, 512) 而我认为这应该可以工作x.transpose(1, 2).reshape(30, -1, 512)

在第一种情况下grad_fn<ViewBackward>,而在我的情况下是<UnsafeViewBackward>。这两个不是同一个操作吗?这会导致训练错误吗?

【问题讨论】:

两个操作不同,所以得到不同的grad_fn。访问here了解更多信息。 【参考方案1】:

这两个不是同一个操作吗?

没有。虽然它们有效地产生相同的张量,但运算 are not the same,并且不能保证它们具有相同的 storage

TensorShape.cpp:

// _unsafe_view() differs from view() in that the returned tensor isn't treated
// as a view for the purposes of automatic differentiation. (It's not listed in
// VIEW_FUNCTIONS in gen_autograd.py).  It's only safe to use if the `self` tensor
// is temporary. For example, the viewed tensor here (a + b) is discarded immediately
// after viewing:
//
//  res = at::_unsafe_view(a + b, size);
//
// This is a hack because in-place operations on tensors treated like views
// can be much more expensive than the same operations on non-view tensors.

请注意,如果应用于complex inputs,可能会产生错误,但这通常在 PyTorch 中尚未完全支持,并且不是此函数独有的。

【讨论】:

以上是关于Pytorch (1.0) 中类似外观操作的不同 `grad_fn`的主要内容,如果未能解决你的问题,请参考以下文章

pytorch的Tensor的操作

PyTorch v1.1.0文档研习60分钟快速上手

PyTorch 1.0 中文文档:数据类型信息

PyTorch 1.0 中文文档:广播语义

PyTorch 1.0 中文文档:torch.Storage

PyTorch 1.0 中文文档:自动求导机制