数据增广时 input 和 target 保持相同变换
图像分割任务中,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()
这里第一次写成了
raw = t[i][0]
mask = t[i][1]
这样的话等于调用了两次 dataset 的 __getitem__
,虽然下标是一样的,但是因为调用了两次,会设定两个不同的 seed,改成上面那样先取 item 再拆包就可以了。这个小小的 bug 因为没有注意到,调试了好半天。。。