【问题标题】:Creating new observations in pytorch ImageFolder在 pytorch ImageFolder 中创建新的观察结果
【发布时间】:2021-10-21 11:33:47
【问题描述】:

我是 pythorch 的新手,我想做的事情可能很简单,但是我没有在网上找到任何关于实际增加观察次数而不将它们添加到图像(在我的情况下)文件夹中的信息。我不想将图像添加到文件夹中,因为我想尝试不同的转换,看看什么是最好的,而不是一直删除图像。所以我要做的是:

trf = transforms.Compose([
    transforms.ToTensor(),
    transforms.RandomRotation(degrees=45),
    transforms.Grayscale(num_output_channels=1),
    transforms.Normalize(0, 1),
    transforms.functional.invert
])
train_data = torchvision.datasets.ImageFolder(root='./splitted_data/train', transform= trf)
print(len(train_data))
train = DataLoader(train_data, batch_size= batch_size, shuffle= True,  num_workers= os.cpu_count())

这里的输出将与所有文件夹中的图像数量相同,这意味着对现有观察应用了转换,但这不是我想要实现的。我希望每个转换都是一个单独的副本。我该怎么做?

【问题讨论】:

  • 你说的单独复制是什么意思?
  • @Ivan 说我有一个观察。我想对其应用灰度和随机旋转。输出应该是 1. 原图 2. 灰度图 3. 旋转后的图 4. 旋转后的灰度图(不是必须的,前3个就可以了)。所以我们现在有 3 (4) 个观察值而不是 1 个。

标签: python machine-learning pytorch image-recognition


【解决方案1】:

您可以实现一个转换包装器,它将按顺序应用转换并输出每个转换组合。 Torchvision 的随机变换的问题是在调用变换时对参数进行采样。这使得难以重现相同的转换。一种替代方法是堆叠或连接所有图像并在该堆栈上应用一次变换。

我将转换管道分为三个部分:预处理和后处理转换(后者不应该是随机的,因为它是单独应用的)。至于主要转换,它们是您要从中创建组合的转换列表,此处为 RandomRotationGrayscale

请注意,此解决方案在处理影响通道数的变换(例如灰度)时存在局限性。通常,您希望保持相同的张量维度,否则您的连接和/或堆栈将失败。

这是一个可能的解决方案:

class Combination(nn.Module):
    def __init__(self, transforms, pre, post):
        super().__init__()
        self.transforms = transforms
        self.pre = T.Compose(pre)
        self.post = T.Compose(post)

    def stacked_t(self, t, x):
        lengths = [len(o) for o in x]
        return t(torch.cat(x)).split(lengths)

    def forward(self, x):
        out = [self.pre(x)[None]]
        for t in transforms:
            out += self.stacked_t(t, out) # <- for every transform `t` we double
                                          #    the number of instances in` out`
        out = [self.post(o)[0] for o in out]
        return out

以下是输入图像的示例用法:

>>> img

初始化变换组合:

>>> t = Combination(pre=[T.ToTensor()],
...                 post=[T.Normalize(0, 1),
...                       T.functional.invert],
...                 transforms=[T.RandomRotation(degrees=45),
...                             T.Grayscale(num_output_channels=1)])

以下是不同变换组合的预览:

>>> img_ = t(img)
img_[0] img_[1] img_[2] img_[3]

【讨论】:

  • 这太棒了!但是如何从中创建一个数据加载器对象呢?因为如果我像 trf 一样尝试使用它,它仍然是相同的大小。
  • “还是一样大小”,没有resize变换,什么意思?
  • 我的意思是数据集大小。进行转换后,我仍然得到相同数量的图片。
  • 一批张量的形状是什么?
  • 我相信这并不重要,因为我首先谈论的是数据集,而不是数据加载器,但我计划每批使用 10 张图像。在我的问题中,我想增加的大小是len(train_data)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-28
  • 1970-01-01
  • 1970-01-01
  • 2021-07-30
  • 2013-07-12
相关资源
最近更新 更多