Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

2-D convolution as a matrix-matrix multiplication [closed]

I know that, in the 1D case, the convolution between two vectors, a and b, can be computed as conv(a, b), but also as the product between the T_a and b, where T_a is the corresponding Toeplitz matrix for a.

Is it possible to extend this idea to 2D?

Given a = [5 1 3; 1 1 2; 2 1 3] and b=[4 3; 1 2], is it possible to convert a in a Toeplitz matrix and compute the matrix-matrix product between T_a and b as in the 1-D case?

like image 327
no_name Avatar asked May 28 '13 18:05

no_name


People also ask

Can convolution be represented as matrix multiplication?

Yes, it is possible and you should also use a doubly block circulant matrix (which is a special case of Toeplitz matrix). I will give you an example with a small size of kernel and the input, but it is possible to construct Toeplitz matrix for any kernel.

What is the relationship between a convolution and a matrix multiplication?

domain, you simply multiply the signal(X)-which is matrix with Signal(Y), which is also a matrix. So, now you will be able to understand that, Yes convolution is same as matrix multiplication(where matrix X and Y matrix of signal) but ONLY IN FREQUENCY DOMAIN. I hope it helps.

What matrix operation can be used to perform a convolution?

However, rather than sliding this kernel (e.g. using loops), we can perform the convolution operation "in one step" using a matrix-vector multiplication, where the matrix is a circulant matrix containing shifted versions of the kernel (as rows or columns) and the vector is the input.


2 Answers

Yes, it is possible and you should also use a doubly block circulant matrix (which is a special case of Toeplitz matrix). I will give you an example with a small size of kernel and the input, but it is possible to construct Toeplitz matrix for any kernel. So you have a 2d input x and 2d kernel k and you want to calculate the convolution x * k. Also let's assume that k is already flipped. Let's also assume that x is of size n×n and k is m×m.

So you unroll k into a sparse matrix of size (n-m+1)^2 × n^2, and unroll x into a long vector n^2 × 1. You compute a multiplication of this sparse matrix with a vector and convert the resulting vector (which will have a size (n-m+1)^2 × 1) into a n-m+1 square matrix.

I am pretty sure this is hard to understand just from reading. So here is an example for 2×2 kernel and 3×3 input.

enter image description here * enter image description here

Here is a constructed matrix with a vector:

enter image description here

which is equal to enter image description here.

And this is the same result you would have got by doing a sliding window of k over x.

like image 79
Salvador Dali Avatar answered Sep 20 '22 22:09

Salvador Dali


1- Define Input and Filter

Let I be the input signal and F be the filter or kernel.

2d input signal and filter

2- Calculate the final output size

If the I is m1 x n1 and F is m2 x n2 the size of the output will be:

enter image description here

3- Zero-pad the filter matrix

Zero pad the filter to make it the same size as the output.

enter image description here

4- Create Toeplitz matrix for each row of the zero-padded filter

enter image description here

5- Create a doubly blocked Toeplitz matrix

Now all these small Toeplitz matrices should be arranged in a big doubly blocked Toeplitz matrix. enter image description here

enter image description here

6- Convert the input matrix to a column vector

enter image description here

7- Multiply doubly blocked toeplitz matrix with vectorized input signal

This multiplication gives the convolution result.

8- Last step: reshape the result to a matrix form

enter image description here

For more details and python code take a look at my github repository:

Step by step explanation of 2D convolution implemented as matrix multiplication using toeplitz matrices in python

like image 45
Ali Salehi Avatar answered Sep 22 '22 22:09

Ali Salehi