【问题标题】:Indexing elements from a batch tensor in PyTorchPyTorch 中批量张量的索引元素
【发布时间】:2021-09-14 11:03:21
【问题描述】:

说,我在 PyTorch 中有一批图像。对于每张图片,我还有一个像素位置,比如(x, y)。可以使用img[x, y] 读取一张图像的像素值。我正在尝试读取批次中每个图像的像素值。请看下面的代码sn-p:

import torch

# create tensors to represent random images in torch format
img_1 = torch.rand(1, 200, 300)
img_2 = torch.rand(1, 200, 300)
img_3 = torch.rand(1, 200, 300)
img_4 = torch.rand(1, 200, 300)

# for each image, x-y value are know, so creating a tuple
img1_xy = (0, 10, 70)
img2_xy = (0, 40, 20)
img3_xy = (0, 30, 50)
img4_xy = (0, 80, 60)

# this is what I am doing right now
imgs = [img_1, img_2, img_3, img_4]
imgs_xy = [img1_xy, img2_xy, img3_xy, img4_xy]
x = [img[xy] for img, xy in zip(imgs, imgs_xy)]
x = torch.as_tensor(x)

我的疑虑和问题

  1. 在每个图像中,像素位置(即(x, y))是已知的。但是,我必须创建一个包含更多元素的元组,即 0 以确保元组与图像的形状相匹配。有什么优雅的方式吗?
  2. 不使用tuple,就不能使用张量,然后获取像素值吗?
  3. 所有图像都可以连接成一个批次img_batch = torch.cat((img_1, img_2, img_3, img_4))。但是元组呢?

【问题讨论】:

    标签: python indexing pytorch tensor


    【解决方案1】:

    您可以连接图像以形成(4, 200, 300) 形状的堆叠张量。然后,我们可以用已知的(x, y) 对来索引每个图像,如下所示:我们需要[0, x1, y1] 用于第一张图像,[1, x2, y2] 用于第二张图像,[2, x3, y3] 用于第三张图像,依此类推。这些可以通过“花式索引”来实现:

    # stacking as you did
    >>> stacked_imgs = torch.cat(imgs)
    >>> stacked_imgs.shape
    (4, 200, 300)
    
    # no need for 0s in front
    >>> imgs_xy = [(10, 70), (40, 20), (30, 50), (80, 60)]
    
    # need xs together and ys together: take transpose of `imgs_xy`
    >>> inds_x, inds_y = torch.tensor(imgs_xy).T
    
    >>> inds_x
    tensor([10, 40, 30, 80])
    
    >>> inds_y
    tensor([70, 20, 50, 60])
    
    # now we index into the batch
    >>> num_imgs = len(imgs)
    >>> result = stacked_imgs[range(num_imgs), inds_x, inds_y]
    >>> result
    tensor([0.5359, 0.4863, 0.6942, 0.6071])
    

    我们可以检查结果:

    >>> torch.tensor([img[0, x, y] for img, (x, y) in zip(imgs, imgs_xy)])
    
    tensor([0.5359, 0.4863, 0.6942, 0.6071])
    

    回答您的问题:

    1:由于我们堆叠了图像,这个问题得到了缓解,我们使用range(4) 来索引每个单独的图像。

    2: 是的,我们确实将x, y 位置转换为张量。

    3:我们将它们分离成张量后直接用它们进行索引。

    【讨论】:

    • 非常感谢。有用。但是,我刚刚意识到 PyTorch 创建了形状 (4, 1, 200, 300) 的批次,所以应该将 0 插入为 stacked_imgs[range(num_imgs), 0, inds_x, inds_y] 吗?还是优雅的方式?
    • 嗨@RaviJoshi,这很有趣,但我无法制作。不过,您可以squeeze 批处理以完全摆脱形状中的 1:stacked_imgs = stacked_imgs.squeeze()
    猜你喜欢
    • 2020-03-28
    • 2019-11-26
    • 2022-11-24
    • 1970-01-01
    • 2019-06-01
    • 2020-07-04
    • 1970-01-01
    • 2021-06-27
    • 2021-11-04
    相关资源
    最近更新 更多