Diego Ruiz
Diego Ruiz

Reputation: 321

Reshape tensor to matrix and back

I have 2 methods: One to convert 4D matrix (tensor) in a matrix and other to convert 2D matrix in 4D.

Reshaping from 4D to 2D work's well, but when I try reconvert again in a tensor, I don't achieve the same order of the elements. The methods are:

# Method to convert the tensor in a matrix
def tensor2matrix(tensor):
    # rows, columns, channels and filters
    r, c, ch, f = tensor[0].shape
    new_dim = [r*c*ch, f] # Inferer the new matrix dims
    # Transpose is necesary because the columns are the channels weights 
    # flattened in columns
    return np.reshape(np.transpose(tensor[0], [2,0,1,3]), new_dim)

# Method to convert the matrix in a tensor
def matrix2tensor(matrix, fs):
    return np.reshape(matrix, fs, order="F")

I think that the problem is in the np.transpose because when is a matrix only I can permute columns by rows... Is there anyway to back the tensor from the matrix without loops?

Upvotes: 1

Views: 1447

Answers (1)

Helder
Helder

Reputation: 548

Consider the following changes:

  1. Replace the two tensor[0] by tensor, to avoid

    ValueError: not enough values to unpack (expected 4, got 3)

    when running the example provided below

  2. Ensure both np.reshape calls use the same order="F"

  3. Use another np.transpose call inside matrix2tensor to undo the np.transpose from tensor2matrix

The updated code is

import numpy as np

# Method to convert the tensor in a matrix
def tensor2matrix(tensor):
    # rows, columns, channels and filters
    r, c, ch, f = tensor.shape
    new_dim = [r*c*ch, f] # Inferer the new matrix dims
    # Transpose is necesary because the columns are the channels weights 
    # flattened in columns
    return np.reshape(np.transpose(tensor, [2,0,1,3]), new_dim, order="F")

# Method to convert the matrix in a tensor
def matrix2tensor(matrix, fs):
    return np.transpose(np.reshape(matrix, fs, order="F"), [1,2,0,3])

and it can be tested like this:

x,y,z,t = 2,3,4,5
shape = (x,y,z,t)
m1 = np.arange(x*y*z*t).reshape((x*y*z, 5))
t1 = matrix2tensor(m1, shape)
m2 = tensor2matrix(t1)
assert (m1 == m2).all()

t2 = matrix2tensor(m2, shape)
assert (t1 == t2).all()

Upvotes: 1

Related Questions