在 Pytorch 中转换自定义数据集时出错
Error in Transforming custom Dataset in Pytorch
我正在学习本教程:https://pytorch.org/tutorials/beginner/data_loading_tutorial.html 为 MuNuSeg 数据集制作我自己的自定义数据加载器,但我坚持了一点。数据加载器工作正常,但是当我向它添加转换时,出现错误。
我遇到的问题与此处提到的类似:
根据那里的答案,我已经为每个内置变换进行了自定义变换,以便同时变换整个样本。以下是我的自定义转换
class AffineTrans(object):
def __init__(self, degrees, translate):
self.degrees = degrees
self.translate = translate
def __call__(self, sample):
image, contour, clrmask = sample['image'], sample['contour'], sample['clrmask']
TF = transforms.RandomAffine(degrees = self.degrees, translate=self.translate)
image = TF(image)
contour = TF(contour)
clrmask = (clrmask)
class Flip(object):
def __call__(self, sample):
image, contour, clrmask = sample['image'], sample['contour'], sample['clrmask']
TF1 = transforms.RandomHorizontalFlip()
TF2 = transforms.RandomVerticalFlip()
image = TF1(image)
contour = TF1(contour)
clrmask = TF1(clrmask)
image = TF2(image)
contour = TF2(contour)
clrmask = TF2(clrmask)
class ClrJitter(object):
def __init__(self, brightness, contrast, saturation, hue):
self.brightness = brightness
self.contrast = contrast
self.saturation = saturation
self.hue = hue
def __call__(self, sample):
image, contour, clrmask = sample['image'], sample['contour'], sample['clrmask']
TF = transforms.ColorJitter(self.brightness, self.contrast, self.saturation, self.hue)
image = TF(image)
contour = TF(contour)
clrmask = TF(clrmask)
并按以下方式组合它们
composed = transforms.Compose([RandomCrop(256),
AffineTrans(15.0,(0.1,0.1)),
Flip(),
ClrJitter(10, 10, 10, 0.01),
ToTensor()])
这是 trainLoader 代码
class trainLoader(Dataset):
def __init__(self, transform=None):
"""
Args:
transform (callable, optional): Optional transform to be applied
on a sample.
"""
[self.train_data , self.test_data1, self.test_data2] = dirload()
self.transform = transform
def __len__(self):
return(len(self.train_data[0]))
def __getitem__(self, idx):
if torch.is_tensor(idx):
idx = idx.tolist()
img_name = self.train_data[0][idx]
contour_name = self.train_data[1][idx]
color_name = self.train_data[2][idx]
image = cv2.imread(img_name)
contour = cv2.imread(contour_name)
clrmask = cv2.imread(color_name)
sample = {'image': image, 'contour': contour, 'clrmask': clrmask}
if self.transform:
sample = self.transform(sample)
return sample
为了检查上述代码的工作情况,我正在执行以下操作
train_dat = trainLoader(composed)
for i in range(len(train_dat)):
sample = train_dat[i]
print(i, sample['image'].shape, sample['contour'].shape, sample['clrmask'].shape)
cv2.imshow('sample',sample['image'])
cv2.waitKey()
if i == 3:
break
但我还是,一次又一次,遇到如下错误
runcell(0, 'F:/Moodle/SEM 8/SRE/code/MoNuSeg/main.py')
runcell(1, 'F:/Moodle/SEM 8/SRE/code/MoNuSeg/main.py')
Traceback (most recent call last):
File "F:\Moodle\SEM 8\SRE\code\MoNuSeg\main.py", line 212, in <module>
sample = train_dat[i]
File "F:\Moodle\SEM 8\SRE\code\MoNuSeg\main.py", line 109, in __getitem__
sample = self.transform(sample)
File "F:\Moodle\Anaconda3\lib\site-packages\torchvision\transforms\transforms.py", line 60, in __call__
img = t(img)
File "F:\Moodle\SEM 8\SRE\code\MoNuSeg\main.py", line 156, in __call__
image = TF(image)
File "F:\Moodle\Anaconda3\lib\site-packages\torchvision\transforms\transforms.py", line 1018, in __call__
ret = self.get_params(self.degrees, self.translate, self.scale, self.shear, img.size)
File "F:\Moodle\Anaconda3\lib\site-packages\torchvision\transforms\transforms.py", line 992, in get_params
max_dx = translate[0] * img_size[0]
TypeError: 'int' object is not subscriptable
这是一个相当模糊的错误,因为我完全不明白错误是什么
任何帮助将不胜感激
问题是您传递的是 NumPy 数组,而转换需要 PIL 图像。您可以通过添加 transforms.ToPILImage()
作为第一个转换来解决此问题:
composed = transforms.Compose([
transforms.ToPILImage(),
RandomCrop(256),
AffineTrans(15.0,(0.1,0.1)),
Flip(),
ClrJitter(10, 10, 10, 0.01),
ToTensor()
])
假设你的开头有一个from torchvision import transforms
。
问题的根源在于您正在使用 OpenCV 加载图像:
def __getitem__(self, idx):
# [...]
image = cv2.imread(img_name)
您也可以将这些从 OpenCV 到 PIL 的加载调用替换为解决问题。
正如您所知,对于 NumPy 数组,.size()
returns 和 int
是您遇到问题的原因。检查以下代码的区别:
import numpy as np
from PIL import Image
# NumPy
img = np.zeros((30, 30))
print(img.size) # output: 900
# PIL
pil_img = Image.fromarray(img)
print(pil_img.size) # output: (30, 30)
我正在学习本教程:https://pytorch.org/tutorials/beginner/data_loading_tutorial.html 为 MuNuSeg 数据集制作我自己的自定义数据加载器,但我坚持了一点。数据加载器工作正常,但是当我向它添加转换时,出现错误。
我遇到的问题与此处提到的类似:
根据那里的答案,我已经为每个内置变换进行了自定义变换,以便同时变换整个样本。以下是我的自定义转换
class AffineTrans(object):
def __init__(self, degrees, translate):
self.degrees = degrees
self.translate = translate
def __call__(self, sample):
image, contour, clrmask = sample['image'], sample['contour'], sample['clrmask']
TF = transforms.RandomAffine(degrees = self.degrees, translate=self.translate)
image = TF(image)
contour = TF(contour)
clrmask = (clrmask)
class Flip(object):
def __call__(self, sample):
image, contour, clrmask = sample['image'], sample['contour'], sample['clrmask']
TF1 = transforms.RandomHorizontalFlip()
TF2 = transforms.RandomVerticalFlip()
image = TF1(image)
contour = TF1(contour)
clrmask = TF1(clrmask)
image = TF2(image)
contour = TF2(contour)
clrmask = TF2(clrmask)
class ClrJitter(object):
def __init__(self, brightness, contrast, saturation, hue):
self.brightness = brightness
self.contrast = contrast
self.saturation = saturation
self.hue = hue
def __call__(self, sample):
image, contour, clrmask = sample['image'], sample['contour'], sample['clrmask']
TF = transforms.ColorJitter(self.brightness, self.contrast, self.saturation, self.hue)
image = TF(image)
contour = TF(contour)
clrmask = TF(clrmask)
并按以下方式组合它们
composed = transforms.Compose([RandomCrop(256),
AffineTrans(15.0,(0.1,0.1)),
Flip(),
ClrJitter(10, 10, 10, 0.01),
ToTensor()])
这是 trainLoader 代码
class trainLoader(Dataset):
def __init__(self, transform=None):
"""
Args:
transform (callable, optional): Optional transform to be applied
on a sample.
"""
[self.train_data , self.test_data1, self.test_data2] = dirload()
self.transform = transform
def __len__(self):
return(len(self.train_data[0]))
def __getitem__(self, idx):
if torch.is_tensor(idx):
idx = idx.tolist()
img_name = self.train_data[0][idx]
contour_name = self.train_data[1][idx]
color_name = self.train_data[2][idx]
image = cv2.imread(img_name)
contour = cv2.imread(contour_name)
clrmask = cv2.imread(color_name)
sample = {'image': image, 'contour': contour, 'clrmask': clrmask}
if self.transform:
sample = self.transform(sample)
return sample
为了检查上述代码的工作情况,我正在执行以下操作
train_dat = trainLoader(composed)
for i in range(len(train_dat)):
sample = train_dat[i]
print(i, sample['image'].shape, sample['contour'].shape, sample['clrmask'].shape)
cv2.imshow('sample',sample['image'])
cv2.waitKey()
if i == 3:
break
但我还是,一次又一次,遇到如下错误
runcell(0, 'F:/Moodle/SEM 8/SRE/code/MoNuSeg/main.py')
runcell(1, 'F:/Moodle/SEM 8/SRE/code/MoNuSeg/main.py')
Traceback (most recent call last):
File "F:\Moodle\SEM 8\SRE\code\MoNuSeg\main.py", line 212, in <module>
sample = train_dat[i]
File "F:\Moodle\SEM 8\SRE\code\MoNuSeg\main.py", line 109, in __getitem__
sample = self.transform(sample)
File "F:\Moodle\Anaconda3\lib\site-packages\torchvision\transforms\transforms.py", line 60, in __call__
img = t(img)
File "F:\Moodle\SEM 8\SRE\code\MoNuSeg\main.py", line 156, in __call__
image = TF(image)
File "F:\Moodle\Anaconda3\lib\site-packages\torchvision\transforms\transforms.py", line 1018, in __call__
ret = self.get_params(self.degrees, self.translate, self.scale, self.shear, img.size)
File "F:\Moodle\Anaconda3\lib\site-packages\torchvision\transforms\transforms.py", line 992, in get_params
max_dx = translate[0] * img_size[0]
TypeError: 'int' object is not subscriptable
这是一个相当模糊的错误,因为我完全不明白错误是什么
任何帮助将不胜感激
问题是您传递的是 NumPy 数组,而转换需要 PIL 图像。您可以通过添加 transforms.ToPILImage()
作为第一个转换来解决此问题:
composed = transforms.Compose([
transforms.ToPILImage(),
RandomCrop(256),
AffineTrans(15.0,(0.1,0.1)),
Flip(),
ClrJitter(10, 10, 10, 0.01),
ToTensor()
])
假设你的开头有一个from torchvision import transforms
。
问题的根源在于您正在使用 OpenCV 加载图像:
def __getitem__(self, idx):
# [...]
image = cv2.imread(img_name)
您也可以将这些从 OpenCV 到 PIL 的加载调用替换为解决问题。
正如您所知,对于 NumPy 数组,.size()
returns 和 int
是您遇到问题的原因。检查以下代码的区别:
import numpy as np
from PIL import Image
# NumPy
img = np.zeros((30, 30))
print(img.size) # output: 900
# PIL
pil_img = Image.fromarray(img)
print(pil_img.size) # output: (30, 30)