transforms.Compose reuslts in "Input type float64 is not supported"

I have images 128x128 and the corresponding labels are multi-element vectors of 128 elements.
I want to use DataLoader with a custom map-style dataset, which at the moment look like this:

# custom dataset
class Dataset(Dataset):
    def __init__(self, images, n, labels=None, transforms=None):
        self.X = images
        self.y = labels
        self.n = n
        self.transforms = transforms
         
    def __len__(self):
        return (len(self.X))
    
    def __getitem__(self, i):
        data = self.X.iloc[i, :]
        data = np.asarray(data).astype(np.float).reshape(1,n, n)
        
        if self.transforms:
            data = self.transforms(data)
            
        if self.y is not None:
            y = self.y.iloc[i,:]
            y = np.asarray(y).astype(np.float).reshape(n,)
            return (data, y)
        else:
            return data

Now I have 20 images and 20 labels.
images.shape = (20, 16384)
labels.shape = (20, 128)

I want to prepare two datasets: one is not normalised, while the other is normalized.
In order to normalise the dataset I use transforms from torchvision:

import torchvision.transforms as transforms

mean_value = 0.0136
std_value = 0.0719

transform = transforms.Compose(
    [transforms.ToPILImage(),
     transforms.ToTensor(),
     transforms.Normalize((mean_value,), (std_value,))
])

Then two datasets (not normalised and normalised) are created by the following two lines:

train_data = Dataset(images, 128, labels, None) # not normalised
train_data_normal = Dataset(images, 128, labels, transform) # normalised

Something is not right with the second line, since when I am trying to print an element of train_data_normal, I get an error.

Input:

print(train_data.__getitem__(1)[1][1])
print(train_data_normal.__getitem__(1)[1][1])

Output:

2.616029869999999e-175
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-120-b3db64ef4a36> in <module>
     13 
     14 print(train_data.__getitem__(1)[1][1])
---> 15 print(train_data_normal.__getitem__(1)[1][1])
     16 
     17 # trainLoader = DataLoader(train_data, batch_size=128, shuffle=True)

<ipython-input-109-9c7d8181d1e9> in __getitem__(self, i)
     16 
     17         if self.transforms:
---> 18             data = self.transforms(data)
     19 
     20         if self.y is not None:

~\anaconda3\lib\site-packages\torchvision\transforms\transforms.py in __call__(self, img)
     59     def __call__(self, img):
     60         for t in self.transforms:
---> 61             img = t(img)
     62         return img
     63 

~\anaconda3\lib\site-packages\torchvision\transforms\transforms.py in __call__(self, pic)
    125 
    126         """
--> 127         return F.to_pil_image(pic, self.mode)
    128 
    129     def __repr__(self):

~\anaconda3\lib\site-packages\torchvision\transforms\functional.py in to_pil_image(pic, mode)
    165 
    166     if mode is None:
--> 167         raise TypeError('Input type {} is not supported'.format(npimg.dtype))
    168 
    169     return Image.fromarray(npimg, mode=mode)

TypeError: Input type float64 is not supported

Could you please point at where the bug is?

to_pil_image wants float32 inputs, I think. It doesn’t make a whole lot of sense to me to use to_pil_image right before to_tensor, but hey, what do I know.

Best regards

Thomas

3 Likes

Thanks for your reply Thomas.
I changed two lines in my Dataset class:

...
data = np.asarray(data).astype(np.float32).reshape(1,n, n)
...
      y = np.asarray(y).astype(np.float32).reshape(n,)
...

And the error is essentially the same but float32-version of it.
Output:

0.0
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-127-b3db64ef4a36> in <module>
     13 
     14 print(train_data.__getitem__(1)[1][1])
---> 15 print(train_data_normal.__getitem__(1)[1][1])
     16 
     17 # trainLoader = DataLoader(train_data, batch_size=128, shuffle=True)
.....
.....
.....
TypeError: Input type float32 is not supported

PIL.Image expects int not float.
Following on from previous comments, I’m not sure what the transform to PILImage and then to Tensor is giving you.

1 Like

I removed transforms.ToPILImage() and it worked. Thanks for looking into the code!

1 Like

Thanks for your reply!