# How to correctly transform a 2-dimensional tensor into a 4 dimensional matrix

I have a 2-dimensional lookup/weight table of size vocab_size x channel size. I want to transform this tensor to be 4-dimensional (in order for it work with F.grid_sample).

I have done variations of reshape(), view(), unsqueezing & permute()

``````import torch

tensor_2d = torch.rand(65000,128) #just a random lookup table has to be of this size

tensor_4d = tensor_2d.reshape(1,128,65000,1) # when I do this the channel dimension gets messed up

tensor_4d = tensor_2d.unsqueeze(0).unsqueeze(-1).permute(0,2,1,3) #when I do this the channel dimension is filled with the values of the subsequent row at that index

how can I make it so that the values within the rows of the original tensor stay the same? I

``````

Hi Intern!

The `permute()` version of your 4d conversion works the way I would
expect and would seem to work for what I imagine your use case to be:

``````>>> import torch
>>> torch.__version__
'2.3.1'
>>> L = 5
>>> C = 2
>>> tensor_2d = torch.arange (L * C).float().reshape (L, C)
>>> tensor_2d
tensor([[0., 1.],
[2., 3.],
[4., 5.],
[6., 7.],
[8., 9.]])
>>> tensor_4d = tensor_2d.unsqueeze (0).unsqueeze (-1).permute (0, 2, 1, 3)
>>> tensor_4d
tensor([[[[0.],
[2.],
[4.],
[6.],
[8.]],

[[1.],
[3.],
[5.],
[7.],
[9.]]]])
>>> tensor_4d[0, :, :, 0]
tensor([[0., 2., 4., 6., 8.],
[1., 3., 5., 7., 9.]])
``````

If this isn’t what you want, could you explain what is wrong and illustrate
your use case with a small, fully-self-contained, runnable script, together
with the output you get when you run it?

Best.

K. Frank

Hi K. Frank,

Thank you for your reply! I have attached a simple script. I am trying to get the e_output to match g_output. I have also attached a visual illustration of what I am trying to do with the matrix as well. Using permute, I end up bunching together the first value from

I appreciate the insight and help!

``````import torch

L = 60000
C = 128

tensor_2D = torch.randn(L,C)

tensor_4D = tensor_2D.data.unsqueeze(0).unsqueeze(-1).permute(0,2,1,3)

tensor_2D, tensor_4D[0][0], tensor_2D[0]

Output:
(tensor([[-0.9203, -0.5730,  0.4688,  ..., -1.6398, -0.3495, -0.0658],
[ 0.6133, -0.2353, -0.6844,  ...,  0.0541, -0.2642, -1.6251],
[ 0.7498, -0.5778, -1.2933,  ...,  0.6337, -0.8241,  1.9411],
...,
[-0.5282,  2.1966,  0.9805,  ..., -0.6725, -0.6689,  1.1485],
[-0.7611,  0.0720,  0.1070,  ...,  1.4691,  0.5665, -0.4897],
[ 0.4414,  0.0610, -1.5197,  ..., -1.4009, -0.4101,  0.1082]]),
tensor([[-0.9203],
[ 0.6133],
[ 0.7498],
...,
[-0.5282],
[-0.7611],
[ 0.4414]]),
tensor([-0.9203, -0.5730,  0.4688,  0.7558, -0.0483, -0.7688, -0.0693,  1.0376,
2.4042, -0.3007, -0.8850,  0.3835,  0.8781,  0.3174, -1.0734, -0.0287,
-1.4459, -0.6875,  0.3105,  0.9651,  1.9093,  0.1718, -0.7249,  0.8602,
1.1302,  0.4596, -0.1718, -0.4428, -0.1168, -1.0659,  0.3917,  0.0737,
1.2247, -1.6025,  0.4712,  0.5392, -0.8835,  1.7168,  0.3307, -0.0836,
1.7518,  0.5871, -0.0171,  0.1820, -0.0171, -0.3980, -0.3315, -0.6369,
0.5448, -0.4139, -1.6431, -0.3533, -0.5043,  0.3944,  1.3845, -0.4939,
-1.0925,  0.0763, -0.9511,  1.2899,  1.5805,  0.7202,  0.1146,  1.1339,
-0.7482,  2.1890,  0.3551, -1.9820,  0.5496, -0.6619, -1.0239,  1.1724,
1.1881, -1.3345,  0.0237,  1.9488, -1.5924, -0.3576,  0.2485,  0.4805,
1.8664, -0.8312,  1.1447, -1.2070, -1.0071,  0.4795, -0.9977,  0.2653,
0.8654, -0.5748,  0.9977, -0.5095, -0.8119, -0.5604,  0.9006,  0.3391,
1.5522,  1.1773,  0.0244, -1.4265,  0.0526,  0.3777,  1.6553, -0.4786,
-0.9769, -0.6977, -1.0240,  1.5423,  0.8922,  1.3467, -0.4278,  1.3876,
-1.5790, -1.1220,  2.0624,  0.6103,  0.7713,  0.2780,  0.9061, -1.3642,
0.7891, -2.5755, -0.4350,  0.0559,  0.7300, -1.6398, -0.3495, -0.0658]))
``````

As you can see, instead of being a culmination of the rows, it is instead a culmination of the columns. I would like for the tensor_4D[0][0] to contain the same values as tensor_2D[0].

Hi Intern!

If you want `tensor_4D[0][0]` and `tensor_2D[0]` to contain the same
values, simply leave out the `.permute()` (although I’m still not sure I
understand what you want):

``````>>> import torch
>>> torch.__version__
'2.3.1'
>>> L = 5
>>> C = 2
>>> tensor_2d = torch.arange (L * C).float().reshape (L, C)
>>> tensor_2d
tensor([[0., 1.],
[2., 3.],
[4., 5.],
[6., 7.],
[8., 9.]])
>>> tensor_4d = tensor_2d.unsqueeze (0).unsqueeze (-1)
>>> tensor_4d
tensor([[[[0.],
[1.]],

[[2.],
[3.]],

[[4.],
[5.]],

[[6.],
[7.]],

[[8.],
[9.]]]])
>>> tensor_4d[0][0]
tensor([[0.],
[1.]])
>>> tensor_2d[0]
tensor([0., 1.])
``````

To my mind, the question is whether you want `grid_sample()` to sample
along the vocab_size dimension or along the channel_size dimension.
That would seem to be what determines whether you want the `.permute()`
or not.

Best.

K. Frank