How to reshape a list?

I have act[‘a’] of torch.Size([1, 64, 32, 32]) and act[‘b’] of torch.Size([1, 128, 16, 16]) and act[‘c’] of torch.Size([1, 256, 8, 8]).
and I have:

target = {'a': [], 'b': [], 'c': []}
for i in range(800):
                target['a'].append(act['a'])
                target['b'].append(act['b'])
                target['c'].append(act['c'])

so now the size of target[‘a’] is [800, 1, 64, 32, 32]. how can I reshape it to [1, 64, 800, 32, 32]?

It sounds like you want to permute the dimensions - shifting the 0th dimension to be the 2nd dimension.
You could use permute(): target['a'].permute((1,2,0,3,4))

Note that permute() only returns a view of the tensor, but doesn’t change the underlying shape. If you want to keep the new shape, you’ll need to save it:

target['a'] = target['a'].permute((1,2,0,3,4))

Also, your code looks like target['a'] is actually a list of tensors. It would need to be a tensor for you to call PyTorch methods. You can either convert it, or preallocate a tensor and then fill it in, or use something like torch.cat().

1 Like

Thank you for your answer.
you mean i should use

torch.unsqueeze(target['a'], 0)

and then torch.cat the result?
cause when I do this it gives this error:

TypeError: unsqueeze(): argument ‘input’ (position 1) must be Tensor, not list

what other way is there to use torch.cat for this problem?

So, the way you currently have it written, target['a'] is a list, not a Tensor, as you can see in the error. Because it’s a list, you can’t use any PyTorch methods on it.

Normally, if target['a'] were a list of lists, you could just call torch.tensor(target['a']) to convert it, and from there, use PyTorch methods like permute(). For example:

a = [1,2,3]
b = []
for i in range(3):
    b.append(a)
b = torch.tensor(b)

However, your target['a'] is a list of tensors, and it seems that you can’t simply cast it to a tensor in this case.

That’s why I suggested either preallocating a large tensor, and then saving to each row. Or concatenating tensors together. According to this post, you can put a list of tensors into torch.cat() to concatenate them together. Meaning, you can do torch.cat(target['a']). However, this will give you a tensor of shape [800,64,32,32].

Also mentioned in the post linked above is that torch.cat() concatenates into a current dimension, while torch.stack() stacks in a new dimension. Therefore, if you want the shape after concatenation to be [800,1,64,32,32], you should use torch.stack().

Note, both torch.cat() and torch.stack() allow you to specify which dimension you want things concatenated / stacked in, so you may be able to avoid needing to permute afterward altogether. I.e.:

torch.stack(target['a'],dim=2)
1 Like

I used

torch.stack(target['a'],dim=2)

it gives this error:

ValueError: Attempt to convert a value (tensor([[[[7.7345e-01,…]]]]) with an unsupported type (<class ‘torch.Tensor’>) to a Tensor.

Interesting… I was unable to reproduce this error with:

a = torch.rand((1,64,32,32))
b = []
for i in range(800):
    b.append(a)

c = torch.stack(b,dim=2)

Output c has shape torch.Size([1,64,800,32,32]).

Is there maybe something funky with your act['a']? Is it actually a tensor? What is the output of type(act['a'])?

1 Like

<class ‘torch.Tensor’>

Sorry, I’m not sure what the problem is - it seems weird that PyTorch can’t convert a tensor into a tensor… My best guess is something strange is in act['a'], but it’s hard to say what exactly it could be.

Similar errors seem to happen here (where the dataset was loaded in incorrectly), and here (where there seem to have been compatibility issues), but both of those posts are with respect to tensorflow, not PyTorch, and they are only somewhat similar to your error.

1 Like

I don’t know why this happened but I’ve had imported tensorflow but wasn’t using it. I deleted it and now the code works!! :))) but

torch.stack(target['a'], dim=2)
print(type(target['a']))

and

torch.cat(target['a'])
print(type(target['a']))

give me

<class ‘list’>

I don’t know what is happening.

Yes, target['a'] is supposed to be a list.

In your first post, you showed:

This means you initialized target['a'] to be a list, and then, in the loop, appended a tensor to the list at each iteration. I.e., at the end of the loop, we should have target['a'] = [act['a'],...,act['a']] where act['a'] is a tensor, and target['a'] is now a list of tensors.

When you encountered your error above, I thought something was wrong with act['a'] and we were checking its type, which is supposed to be a tensor. You were just now checking the type of target['a'], which is supposed to be a list.

In summary, going off my example from above:

we should have a is a tensor, b is a list, and c is a tensor.

1 Like