F.interpolate weird behaviour

Hi !

So I might be missing something basic but I’m getting a weird behavior with F.interpolate :

I created a 3D-tensor using :

t  = torch.randn(4,4,4)

Or a least I thought it was 3D, but F.interpolate doesn’t seem to agree. The following code :

F.interpolate(t, scale_factor=(1,2,1))

gives the error

ValueError: scale_factor shape must match input shape. Input is 1D, scale_factor size is 3

What am I missing here ?

2 Likes

The error message might be a bit weird, but it refers to an input of shape [batch_size, channels, *addidional_dims].
Given that you provide a “1D” input with a length of 4.
Here would be an example using an image tensor:

batch_size, c, h, w = 1, 3, 4, 4
x  = torch.randn(batch_size, c, h, w)
x = F.interpolate(x, scale_factor=(2,1))
print(x.shape)
> torch.Size([1, 3, 8, 4])

As you can see, the batch size as well as the channels won’t be manipulated, just the spatial dimensions.

6 Likes

@ptrblck Hi, ptr.

what about a tensor shape like c=1:

torch.randn(B, 1, 512, 512)

I got error:

ValueError: size shape must match input shape. Input is 1D, size is 2

When try to … interplolate on it

It works for me:

batch_size, c, h, w = 3, 1, 512, 512
x  = torch.randn(batch_size, c, h, w)
x = F.interpolate(x, scale_factor=(2,1))

Based on your error message I guess you are using a 1D tensor?

1 Like

I get this error ValueError: size shape must match input shape. Input is 1D, size is 2

for when I apply transform of resize 2D on a 2D feature. However, I am not fully sure why it tells me my feature is 1D? What do you think?

features is: torch.Size([503, 512])

  transformed_features = self.transform(features)
  File "/SeaExp/mona/venv/dpcc/lib/python3.8/site-packages/torchvision/transforms/transforms.py", line 60, in __call__
    img = t(img)
  File "/SeaExp/mona/venv/dpcc/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1051, in _call_impl
    return forward_call(*input, **kwargs)
  File "/SeaExp/mona/venv/dpcc/lib/python3.8/site-packages/torchvision/transforms/transforms.py", line 297, in forward
    return F.resize(img, self.size, self.interpolation, self.max_size, self.antialias)
  File "/SeaExp/mona/venv/dpcc/lib/python3.8/site-packages/torchvision/transforms/functional.py", line 403, in resize
    return F_t.resize(img, size=size, interpolation=interpolation.value, max_size=max_size, antialias=antialias)
  File "/SeaExp/mona/venv/dpcc/lib/python3.8/site-packages/torchvision/transforms/functional_tensor.py", line 552, in resize
    img = interpolate(img, size=[new_h, new_w], mode=interpolation, align_corners=align_corners)
  File "/SeaExp/mona/venv/dpcc/lib/python3.8/site-packages/torch/nn/functional.py", line 3630, in interpolate
    raise ValueError(
ValueError: size shape must match input shape. Input is 1D, size is 2

and transforms are:

train_transforms = transforms.Compose(
    [
        transforms.Resize((256, 512)),
        transforms.RandomResizedCrop(256),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
    ]
)

val_transforms = transforms.Compose(
    [
        transforms.Resize((256, 512)),
        transforms.CenterCrop(256),
        transforms.ToTensor(),
    ]
)

I apply the transform like this:
dataset_train = GraphDataset(os.path.join(data_path, ""), ids_train, transform=train_transforms)

and I have:

class GraphDataset(data.Dataset):
    """input and label image dataset"""

    def __init__(self, root, ids, target_patch_size=-1, transform=None):
    *code*
    def __getitem__(self, index):
    *code*
     transformed_features = self.transform(features)
     #sample['image'] = features
     sample['image'] = transformed_features
     return sample

I am not precisely sure what I am doing wrong.

Assuming you are passing a tensor to the transformation it should have at least 3 dims as [channels, height, width] and can have additional leading dimensions (e.g. the batch dimension).
If that’s the case, unsqueeze the channel dimension and remove the ToTensor transformation.

transform = transforms.Resize((256, 512))
x = torch.randn(3, 400, 600)
out = transform(x)
print(out.shape)
# > torch.Size([3, 256, 512])

x = torch.randn(503, 512)
out = transform(x)
# > ValueError: size shape must match input shape. Input is 1D, size is 2

Thanks a lot for your response. I removed the ToTensor ones from the transformations, and get same error:


train_transforms = transforms.Compose(
    [
        transforms.Resize((256, 512)),
        transforms.RandomResizedCrop(256),
        transforms.RandomHorizontalFlip(),
        #transforms.ToTensor(),
    ]
)

val_transforms = transforms.Compose(
    [
        transforms.Resize((256, 512)),
        transforms.CenterCrop(256),
        #transforms.ToTensor(),
    ]
)
 transformed_features = self.transform(features)
  File "/SeaExp/mona/venv/dpcc/lib/python3.8/site-packages/torchvision/transforms/transforms.py", line 60, in __call__
    img = t(img)
  File "/SeaExp/mona/venv/dpcc/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1051, in _call_impl
    return forward_call(*input, **kwargs)
  File "/SeaExp/mona/venv/dpcc/lib/python3.8/site-packages/torchvision/transforms/transforms.py", line 297, in forward
    return F.resize(img, self.size, self.interpolation, self.max_size, self.antialias)
  File "/SeaExp/mona/venv/dpcc/lib/python3.8/site-packages/torchvision/transforms/functional.py", line 403, in resize
    return F_t.resize(img, size=size, interpolation=interpolation.value, max_size=max_size, antialias=antialias)
  File "/SeaExp/mona/venv/dpcc/lib/python3.8/site-packages/torchvision/transforms/functional_tensor.py", line 552, in resize
    img = interpolate(img, size=[new_h, new_w], mode=interpolation, align_corners=align_corners)
  File "/SeaExp/mona/venv/dpcc/lib/python3.8/site-packages/torch/nn/functional.py", line 3630, in interpolate
    raise ValueError(
ValueError: size shape must match input shape. Input is 1D, size is 2

torch.Size([2957, 512])

This is despite the fact that features is a 2D input:
features size: torch.Size([1813, 512])
here:

print("features size: ", features.shape)
transformed_features = self.transform(features)

As my code snippet shows, a 3D tensor is expected. You can copy-paste my code and check the error and compare it to the working solution.

I’m sorry but this function can’t be correct, with the size parameter it doesn’t work as expected in any way or with any size.

>>> batch_size, c, h, w = 2, 3, 5, 6
>>> x  = torch.randn(batch_size, c, h, w)
>>> x.shape
torch.Size([2, 3, 5, 6])
>>> x = F.interpolate(x, size=(2, 3, 10, 12))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/oak-d/venvs/depthai/lib/python3.8/site-packages/torch/nn/functional.py", line 3652, in interpolate
    raise ValueError(
ValueError: size shape must match input shape. Input is 2D, size is 4
>>> batch_size, c, h, w = 1, 3, 5, 6
>>> x  = torch.randn(c, h, w)
>>> x.shape
torch.Size([3, 5, 6])
>>> x
tensor([[[ 0.1398,  2.6164,  1.5493, -3.3864, -0.4263,  0.0538],
         [ 0.6553,  1.3214, -0.2174, -0.4452, -0.7426, -0.3066],
         [-0.8942,  0.7908, -0.7685,  0.9150,  0.7674,  0.3924],
         [ 0.7903,  0.5168, -0.3655, -0.6867, -0.5429, -1.5122],
         [-0.5823,  0.5922, -0.0183, -0.5923,  0.0494, -0.0694]],

        [[-0.6175, -0.0933,  0.6786, -0.3152, -0.8401, -0.4897],
         [-0.7455,  0.4002, -0.2659, -0.5124, -0.1008,  1.5574],
         [-0.6002, -0.3244, -0.5347,  0.7308, -2.1288,  0.6471],
         [ 0.2617, -1.5748, -0.1861, -0.8950,  1.6602,  0.3907],
         [ 1.9359, -1.3339,  0.1310, -1.5444, -0.4120,  1.6819]],

        [[-1.1157,  1.1354,  0.9137, -2.6809, -0.4930, -0.5975],
         [ 1.4078,  1.0812,  0.3403,  0.9431, -2.5339,  0.0154],
         [-1.4800,  0.3183, -0.2253, -0.3619, -0.0167, -2.0883],
         [ 1.6934, -1.6267,  1.0259, -0.7392,  0.0561, -0.7352],
         [ 1.1638,  0.7155, -0.1465,  1.4306,  0.5155,  0.2121]]])
>>> x = F.interpolate(x, size=(3, 10, 12))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/oak-d/venvs/depthai/lib/python3.8/site-packages/torch/nn/functional.py", line 3652, in interpolate
    raise ValueError(
ValueError: size shape must match input shape. Input is 1D, size is 3
>>> x  = torch.randn(h, w)
>>> x.shape
torch.Size([5, 6])
>>> x = F.interpolate(x, size=(10, 12))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/oak-d/venvs/depthai/lib/python3.8/site-packages/torch/nn/functional.py", line 3652, in interpolate
    raise ValueError(
ValueError: size shape must match input shape. Input is 0D, size is 2

I’ve been trying to resize a 4D-tensor for hours, with torch.nn.functional.interpolate or with torchvision.transforms.Resize, without success. What is the “canonical” way to resize a batch with PyTorch? Upgrading to torch==1.12.1 and torchvision==0.13.1 has no effect.

Ohhh, it’s devious! At line 3066, torch/nn/functional.py does:

    dim = input.dim() - 2  # Number of spatial dimensions.

    # Process size and scale_factor.  Validate that exactly one is set.
    # Validate its length if it is a list, or expand it if it is a scalar.
    # After this block, exactly one of output_size and scale_factors will
    # be non-None, and it will be a list (or tuple).
    if size is not None and scale_factor is not None:
        raise ValueError('only one of size or scale_factor should be defined')
    elif size is not None:
        assert scale_factor is None 
        scale_factors = None 
        if isinstance(size, (list, tuple)):
            if len(size) != dim: 
                raise ValueError('size shape must match input shape. '
                                 'Input is {}D, size is {}'.format(dim, len(size)))

So, if the tensor has no bs (a 3D-tensor), len(size) must be 1 (square images only?). And if it has a bs (it’s a 4D-tensor) AND len(size) == 2… it finally works! :tada:

Nice, so this function works properly only if tensors have a bs (4D-tensors) and the user specifies (h,w) (and nothing more) as size parameter, every other combination throws a ValueError without providing any meaningful insight in the error message. At least we have unveiled also this mystery.