我正在为一个包含许多图像对的数据集编写一个简单的转换。作为数据增强,我想对每一对应用一些随机变换,但该对中的图像应该以相同的方式进行变换。例如,给定一对两个图像A
和B
,如果A
被水平翻转,则B
必须被水平翻转为A
。然后下一对C
和D
应该与A
和B
不同地变换,但是C
和D
以相同的方式变换。我在下面的方法中尝试
import random
import numpy as np
import torchvision.transforms as transforms
from PIL import Image
img_a = Image.open("sample_ajpg") # note that two images have the same size
img_b = Image.open("sample_b.png")
img_c, img_d = Image.open("sample_c.jpg"), Image.open("sample_d.png")
transform = transforms.RandomChoice(
[transforms.RandomHorizontalFlip(),
transforms.RandomVerticalFlip()]
)
random.seed(0)
display(transform(img_a))
display(transform(img_b))
random.seed(1)
display(transform(img_c))
display(transform(img_d))
然而,上面的代码没有选择相同的转换,正如我所测试的,它取决于transform
被调用的次数。
有没有办法强制transforms.RandomChoice
在指定时使用相同的转换?
5条答案
按热度按时间tyg4sfes1#
我意识到OP要求使用
torchvision
的解决方案,我认为@Ivan的answer很好地解决了这个问题。然而,对于那些没有绑定到特定增强库的人,我想指出的是,Albumentations似乎在native fashion中很好地处理了这类情况,允许用户将多个源图像,框等传递到同一个转换中。返回的结构为dict
现在您可以访问
transformed['image0']
、transformed['image1']
等,所有这些都将应用随机参数ocebsuys2#
为输入和目标引用随机变换?我想这可能是最干净的方法了。在应用任何转换之前保存随机状态,并在每次后续调用时恢复它
0h4hbjxa3#
简单地说,将PyTorch中的随机化部分放入
if
语句中。下面的代码使用vflip
。类似地,对于水平或其他变换。这个问题已经在PyTorch forum中讨论过了。在官方GitHub存储库page上讨论了几种解决方案的优缺点。PyTorch的维护人员已经提出了这种简单的方法。
不要使用
torchvision.transforms.RandomVerticalFlip(p=1)
。使用torchvision.transforms.functional.vflip
函数转换给予对转换管道的细粒度控制。与上面的变换相反,函数变换不包含用于其参数的随机数生成器。这意味着您必须指定/生成所有参数,但您可以重用函数转换。
3ks5zfa04#
我不知道一个函数来修复随机输出。也许可以尝试不同的逻辑,比如自己创建随机化,以便能够重用相同的转换。逻辑:
vcirk6k65#
通常,解决方法是在第一个图像上应用变换,检索该变换的参数,然后在其余图像上应用具有这些参数的确定性变换。但是,这里
RandomChoice
没有提供API来获取所应用的转换的参数,因为它涉及可变数量的转换。在这些情况下,我通常实现对原始函数的覆盖。看看torchvision的实现,它就像这样简单:
这里有两个可能的解决方案。
1.您可以从
__init__
上的转换列表中采样,而不是从__call__
上采样:因此,您可以:
1.或者更好的是,批量转换图像:
它允许做: