Depthwise convolutions from tf to pytorch

Im trying to port a piece of tensorflow code originally written by VinceMarron to pytorch but am yet to replicate the same results. The tf code is as follows:

d=tf.range(kerneldim, dtype=tf.float32)
d=tf.expand_dims((d-d[kerneldim//2])**2,0)
dist=d+tf.transpose(d)
kernel=tf.exp(-dist*(1./(2.*sigma_sq)))
kernel = kernel/tf.reduce_sum(kernel)
kernel = tf.reshape(kernel, (kerneldim, kerneldim,1,1))
kernel = tf.tile(kernel, (1,1,3,1))

return tf.nn.depthwise_conv2d(x, kernel, [1,1,1,1], padding='SAME')

My attempt at doing the same operation in pytorch:

d = torch.arange(0.,float(kerneldim))
d = torch.unsqueeze((d-d[kernel_size//2])**2,0)
dist = d+d.transpose(0,1)
kernel = torch.exp(-dist*(1./(2.*sigma_sq)))
kernel /= torch.sum(kernel)
kernel = kernel.view(1,kerneldim,kerneldim)
kernel = kernel.repeat(3,1,1,1)


conv = nn.Conv2d(3,3,kerneldim,padding=7,groups=3,bias=False)

c.weight = torch.nn.Parameter(kernel)

return conv(Variable(x,volatile=True)).data

I am getting very different results. It runs but does not replicate the tensorflow results.

I have not had the time to dive deeper into depthwise convolutions. I am also really terrible at tensorflow.

As I do not have enough time to research these things more in depth I just tried to port the code directly.

This is something im doing in my free time for fun so if you want to help me please dont waste too much of your time on me as this is in no way critical.

Thanks in advance!

1 Like

@tetratrio I encountered the same problem. Have you solved it?

In depthwise conv, you just need to transpose the weights by the axises [2, 3, 0, 1]. For me, the problem is not depthwise conv. I missed out the dilation.

Hey! Sorry for the late reply, I did actually return to this problem today with much more experience in pytorch and solved it. I wanted to perform gaussian smoothing on a [BATCH x C x H x W] tensor separately for each channel. I created a [kernel_size x kernel_size] gaussian kernel and used the following to fit it as a weight for a depthwise conv2d:

gaussian_kernel = gaussian_kernel.view(1, 1, kernel_size, kernel_size)
gaussian_kernel = gaussian_kernel.repeat(channels, 1, 1, 1)

self.gaussian_filter = nn.Conv2d(in_channels=channels, out_channels=channels,
                                 kernel_size=kernel_size, groups=channels, bias=False)

self.gaussian_filter.weight.data = gaussian_kernel

I know there are some threads on here where people want to perform gaussian smoothing so I will try to post my entire solution in one of those.

2 Likes