【问题标题】:Pytorch weighted TensorPytorch 加权张量
【发布时间】:2021-01-10 20:49:59
【问题描述】:

我正在将一些复杂的 TF2 代码移植到 Pytorch。由于 TF2 不区分 Tensor 和 numpy 数组,所以说的很简单。然而,当我遇到几个错误说“你不能在 Pytorch 中混合 Tensor 和 numpy 数组!”时,我感觉我回到了 TF1 时代。这是原始的 TF2 代码:

def get_weighted_imgs(points, centers, imgs):
  weights = np.array([[tf.norm(p - c) for c in centers] for p in points], dtype=np.float32)
  weighted_imgs = np.array([[w * img for w, img in zip(weight, imgs)] for weight in weights])

  weights = tf.expand_dims(1 / tf.reduce_sum(weights, axis=1), axis=-1)
  weighted_imgs = tf.reshape(tf.reduce_sum(weighted_imgs, axis=1), [len(weights), 64*64*3])

  return weights * weighted_imgs

还有我有问题的 Pytorch 代码:

def get_weighted_imgs(points, centers, imgs):
  weights = torch.Tensor([[torch.norm(p - c) for c in centers] for p in points])
  weighted_imgs = torch.Tensor([[w * img for w, img in zip(weight, imgs)] for weight in weights])

  weights = torch.unsqueeze(1 / torch.sum(weights, dim=1), dim=-1)
  weighted_imgs = torch.sum(weighted_imgs, dim=1).view([len(weights), 64*64*3])

  return weights * weighted_imgs

def reproducible():
  points = torch.Tensor(np.random.random((128, 5)))
  centers = torch.Tensor(np.random.random((10, 5)))
  imgs = torch.Tensor(np.random.random((10, 64, 64, 3)))

  weighted_imgs = get_weighted_imgs(points, centers, imgs)

我可以保证张量/数组的维度顺序或形状没有问题。我得到的错误信息是

ValueError: only one element tensors can be converted to Python scalars

来自

weighted_imgs = torch.Tensor([[w * img for w, img in zip(weight, imgs)] for weight in weights])

有人可以帮我解决这个问题吗?将不胜感激。

【问题讨论】:

  • 请提供最少的可重现代码。它会帮助别人帮助你。在这种情况下,请向函数 get_weighted_imgs 提供输入。
  • 按照您的建议,我添加了一个重现此错误的功能 :)
  • 太棒了。所以你有 w 形状的 torch.Size([10]) 和 img 的形状 torch.Size([64, 64, 3]) 并且你在 get_weighted_imgs 的第 2 行中将它们相乘。在这种情况下,您期望的行为是什么?
  • 尽管我的解释很糟糕,但您理解正确。我希望 'weighted_imgs' 是一个形状为 [128, 10, 64, 64, 3] 的张量,稍后将沿轴 = 1 相加,成为形状 [128, 64, 64, 3]。

标签: tensorflow pytorch tensor


【解决方案1】:

也许这会对您有所帮助,但我不确定您在 weights 和 weighted_imgs 之间的最终乘积,因为它们没有相同的形状,即使在您可能想要的重塑之后也是如此。我不确定我是否正确理解了您的逻辑:

import torch
def get_weighted_imgs(points, centers, imgs):
  weights = torch.Tensor([[torch.norm(p - c) for c in centers] for p in points])
  
  imgs = imgs.unsqueeze(0).repeat(weights.shape[0],1,1,1,1)
  dims_to_rep = list(imgs.shape[-3:])
  weights = weights.unsqueeze(-1).unsqueeze(-1).unsqueeze(-1).repeat(1,1,*dims_to_rep)
  weights /= torch.sum(weights[...,0:1,0:1,0:1],dim=1, keepdim=True)
  weighted_imgs =  torch.sum(imgs * weights, dim=1).view(weights.shape[0], -1)
  
  return weighted_imgs #weights.view(weighted_imgs.shape[0],-1) *\
         #weighted_imgs # Shapes are torch.Size([128, 122880]) and torch.Size([128, 12288])

def reproducible():
  points = torch.Tensor(np.random.random((128, 5)))
  centers = torch.Tensor(np.random.random((10, 5)))
  imgs = torch.Tensor(np.random.random((10, 64, 64, 3)))

  weighted_imgs = get_weighted_imgs(points, centers, imgs)
#Test:
reproducible()

【讨论】:

  • 非常感谢!代码运行平稳,尽管它似乎不是最佳的。由于我的时间不多了,这对我来说是完美的。 :)
猜你喜欢
  • 2020-11-17
  • 2022-08-18
  • 2021-02-07
  • 2021-10-11
  • 2022-10-17
  • 1970-01-01
  • 2022-08-09
  • 2020-03-28
  • 2023-04-04
相关资源
最近更新 更多