Best way to convolve on different channels with single kernel - revisited

Hi,
I tried to utilize the following topic:

what I tried is:

kernel = np.ones((1, 3, 1))
padding_value = math.floor(kernel.shape[1]/2.)
torch_kernel = torch.Tensor(kernel).permute(0, 2, 1)
data = [[[1., 1.], [2., 2.], [3., 3.], [4., 4.], [5., 5.], [6., 6.], [7., 7.]], [[1., 1.], [2., 2.], [3., 3.], [4., 4.], [5., 5.], [6., 6.], [7., 7.]]]
torch_data = torch.Tensor(data).permute(0, 2, 1)
data_reshaped = torch_data.reshape(-1, 1, torch_data.shape[2])
conv_out = (F.conv1d(data_reshaped, torch_kernel, padding=padding_value, bias=None) / torch_kernel.shape[2]).view(torch_data.shape[0], torch_data.shape[2], torch_data.shape[1])

conv_out is the following:

tensor([[[1.0000, 2.0000],
         [3.0000, 4.0000],
         [5.0000, 6.0000],
         [4.3333, 1.0000],
         [2.0000, 3.0000],
         [4.0000, 5.0000],
         [6.0000, 4.3333]],

        [[1.0000, 2.0000],
         [3.0000, 4.0000],
         [5.0000, 6.0000],
         [4.3333, 1.0000],
         [2.0000, 3.0000],
         [4.0000, 5.0000],
         [6.0000, 4.3333]]])

What I would like to see instead is:

tensor([[[1.0000, 1.0000],
         [2.0000, 2.0000],
         [3.0000, 3.0000],
         [4.0000, 4.0000],
         [5.0000, 5.0000],
         [6.0000, 6.0000],
         [4.3333, 4.3333]],

        [[1.0000, 1.0000],
         [2.0000, 2.0000],
         [3.0000, 3.0000],
         [4.0000, 4.0000],
         [5.0000, 5.0000],
         [6.0000, 6.0000],
         [4.3333, 4.3333]]])

I am basically trying to do a convolution for a multiple series with fixed kernel for each series. If I unpack one dimension into batches, then I need multi-channel kernel, which doesn’t do the same thing. Could you please help me achieve the desired form of this operation? Maybe this approach my choice of approach is entirely wrong?

You could permute the result tensor as seen here:

conv_out = (F.conv1d(data_reshaped, torch_kernel, padding=padding_value, bias=None) / torch_kernel.shape[2])
ret = conv_out.view(torch_data.shape).permute(0, 2, 1)
print(ret)
> tensor([[[1.0000, 1.0000],
           [2.0000, 2.0000],
           [3.0000, 3.0000],
           [4.0000, 4.0000],
           [5.0000, 5.0000],
           [6.0000, 6.0000],
           [4.3333, 4.3333]],

          [[1.0000, 1.0000],
           [2.0000, 2.0000],
           [3.0000, 3.0000],
           [4.0000, 4.0000],
           [5.0000, 5.0000],
           [6.0000, 6.0000],
           [4.3333, 4.3333]]])

and you could also use a grouped conv approach:

out = F.conv1d(torch_data, torch_kernel.expand(2, -1, -1), padding=padding_value, bias=None, groups=2) / torch_kernel.shape[2]
out = out.permute(0, 2, 1)
print(out)
1 Like