【问题标题】:How to build an autograd-compatible Pytorch module that resizes tensors like images?如何构建一个与 autograd 兼容的 Pytorch 模块,该模块可以像图像一样调整张量的大小?
【发布时间】:2018-10-28 17:44:00
【问题描述】:

我想知道是否可以在 Pytorch 中构建一个图像大小调整模块,该模块将 3*H*W 的 torch.tensor 作为输入并返回一个张量作为调整大小的图像。

我知道可以将张量转换为 PIL 图像并使用 torchvision, 但我也希望将梯度从调整大小的图像反向传播到原始图像,以下示例将返回此类错误(在 Windows 10 上的 PyTorch 0.4.0 中):

import numpy as np
from torchvision import transforms

t2i = transforms.ToPILImage()
i2t = transforms.ToTensor()

trans = transforms.Compose(
    t2i, transforms.Resize(size=200), i2t]
)

test = np.random.normal(size=[3, 300, 300])
test = torch.tensor(test, requires_grad=True)
resized = trans(test)
resized.backward()

print(test.grad)

Traceback (most recent call last):
  File "D:/Projects/Python/PyTorch/test.py", line 41, in <module>
    main()
  File "D:/Projects/Python/PyTorch/test.py", line 33, in main
    resized = trans(test)
  File "D:\Anaconda3\envs\pytorch\lib\site-packages\torchvision\transforms\transforms.py", line 42, in __call__
    img = t(img)
  File "D:\Anaconda3\envs\pytorch\lib\site-packages\torchvision\transforms\transforms.py", line 103, in __call__
    return F.to_pil_image(pic, self.mode)
  File "D:\Anaconda3\envs\pytorch\lib\site-packages\torchvision\transforms\functional.py", line 102, in to_pil_image
    npimg = np.transpose(pic.numpy(), (1, 2, 0))
RuntimeError: Can't call numpy() on Variable that requires grad. Use var.detach().numpy() instead.

如果不先将张量与 autograd 分离,我似乎无法“调整”张量,但分离它会阻止我计算梯度。

有没有办法构建一个与 torchvision.transforms.Resize 相同的功能/模块,它与 autograd 兼容?非常感谢任何帮助!

【问题讨论】:

  • 双线性调整大小只是周围像素值的线性组合,而且这个操作在数学上是可微的,所以 PyTorch 不能反向传播它的梯度是没有意义的......
  • 您可能正在考虑卷积层?一个方便的例子是github.com/yunjey/pytorch-tutorial/blob/master/tutorials/…
  • 我觉得你的问题与空间变换网络非常相似,他们也学习仿射变换参数。 arxiv.org/pdf/1506.02025.pdf
  • autograd 仅适用于 pytorch 操作,它不是魔术。在引擎盖下,它为每个函数调用一个backward() 函数,因此它不能在没有pytorch函数上工作,比如PIL的resize
  • 这能回答你的问题吗? How to resize a PyTorch tensor?

标签: python-3.x image-resizing pytorch tensor resize-image


【解决方案1】:

torch.nn.functional.upsample 为我工作,是的!

【讨论】:

【解决方案2】:

我刚刚弄清楚了在实现自定义损失函数时如何保留渐变。

诀窍是将结果附加到虚拟渐变

def custom_loss(tensor1, tensor2):
    # convert tensors to PIL image, doing calculation, we have output = 0.123
    grad = (tensor1 + tensor2).sum()
    loss = grad - grad + output
    return loss

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    • 2023-04-04
    • 2020-02-28
    • 2017-07-14
    • 1970-01-01
    • 2018-11-16
    • 2011-07-19
    相关资源
    最近更新 更多