图像分割任务中,input 和 target 都是图片,此时做数据增广时如果用到随机变换,例如随机翻转和旋转,则需要保证两者随机值相同,否则分割 label 就不准确。

例如变换:

self.transform = transforms.Compose([
    transforms.RandomHorizontalFlip(),
    transforms.RandomRotation(90),
    transforms.CenterCrop(480),
    transforms.ToTensor(),
    transforms.ToPILImage()
])

在使用时如果直接

image = self.transform(image)
bulb = self.transform(bulb)

则输入图片和 label 会产生不同的翻转/旋转角,造成数据不对应的问题。

解决办法:

torchvision.transforms 内使用的是 python 原生 random 库(pytorch vision 1.5),在两次变换前指定相同的 random seed 即可。

seed = random.randint(0, 2 ** 32)
random.seed(seed)  # set the same seed to transform together
image = self.transform(image)
random.seed(seed)  # set the same seed to transform together
bulb = self.transform(bulb)

测试代码:

t = MRIDataset('/home/sunyf/dataset/ob/new', ['01', '02'])
import matplotlib.pyplot as plt
for i in range(20):
    data = t[i]  # 测试时应该按照调用方式,只调用一次,否则两次seed不同
    raw = data[0]
    mask = data[1]
    fig = plt.figure()
    plt.title(str(i))
    plt.subplot(1, 2, 1), plt.imshow(raw, cmap='gray')
    plt.subplot(1, 2, 2), plt.imshow(mask, cmap='gray')

    plt.show()

Snipaste_2020-05-11_19-37-49.png

这里第一次写成了

raw = t[i][0]
mask = t[i][1]

这样的话等于调用了两次 dataset 的 __getitem__,虽然下标是一样的,但是因为调用了两次,会设定两个不同的 seed,改成上面那样先取 item 再拆包就可以了。这个小小的 bug 因为没有注意到,调试了好半天。。。

标签: 深度学习, pytorch, random, transform, torchvision

添加新评论