synkilla12
synkilla12

Reputation: 43

Translating tensorflows conv2d to numpy/scipy operations?

This is the documentation for tf.nn.conv2d: Given an input tensor of shape [batch, in_height, in_width, in_channels] and a filter / kernel tensor of shape [filter_height, filter_width, in_channels, out_channels], this op performs the following

  1. Flattens the filter to a 2-D matrix with shape [filter_height * filter_width * in_channels,
  2. Extracts image patches from the input tensor to form a virtual tensor of shape [batch, out_height, out_width, filter_height * filter_width * in_channels].
  3. For each patch, right-multiplies the filter matrix and the image patch vector.

In other words, it takes in a tensor of n images and does convolution with out_channel filters.

I am trying to translate to code that uses only numpy operations and the code is the following:

def my_conv2d(x, kernel):
   nf = kernel.shape[-1]  # number of filters
   rf = kernel.shape[0]  # filter size
   w = kernel
   s = 1 # stride

   h_range = int((x.shape[2] - rf) / s) + 1  # (W - F + 2P) / S
   w_range = int((x.shape[1] - rf) / s) + 1  # (W - F + 2P) / S
   np_o = np.zeros((1, h_range, w_range, nf))
   for i in range(x.shape[0]):
     for z in range(nf):
       for _h in range(h_range):
         for _w in range(w_range):
           np_o[0, _h, _w, z] = np.sum(x[i, _h * s:_h * s + rf, _w * s:_w * s 
                                + rf, * w[:, :, :, z])                     
    return np_o

The problem is that code is extremely slow. Are there any numpy or scipy functions that can replicate what tensorflows' conv2d is doing that is of similar efficiency? I have looked at https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.convolve2d.html and it does convolution ONCE, meaning I have to pass a 2d tensor alongside a 2d kernel (it does not do multiple filters). None of the previous stackoverflow questions helped much with this.

Thanks

Edit: did some testing and my code is about 44000% slower than doing tf.nn.conv2d!

Upvotes: 0

Views: 997

Answers (1)

hampi
hampi

Reputation: 145

Things are slow for you because you are using loops. Implementing with vector operations will be much faster but not as efficient as the high-level APIs such as tf.nn.conv2d or tf.nn.convolution. This post should be able to help you with the vectorized implementation of the same in numpy : https://wiseodd.github.io/techblog/2016/07/16/convnet-conv-layer/

Upvotes: 0

Related Questions