pytorch 中两个一维信号之间的可微分卷积

Differentiable convolution between two 1d signals in pytorch

我需要在 pytorch 中实现信号和 window 之间的卷积,我希望它是可微分的。因为我找不到一个已经存在的张量函数(我只能找到具有可学习参数的函数)我自己写了一个但是,我无法在不破坏计算图的情况下让它工作。我该怎么做?我做的函数是:

def Convolve(a, b):
  conv=torch.zeros(a.shape[0], a.shape[1], requires_grad=True).clone()
  l=b.shape[0]
  r=int((l-1)/2)
  l2=a.shape[1]
  for x in range(a.shape[0]):#for evry signal
    for x2 in range(a.shape[1]):#for every time instant
      for x4 in range(l):#compute the convolution (for every window value)
        if (x2-r+x4<0 or x2-r+x4>=l2):#if the index is out of bonds the result is 0 (to avoid zero padding)
           conv[x][x2]+=0
        else:
          conv[x][x2-r+x4]+=a[x][x2-r+x4]*b[x4]#otherwise is window*signal
  return conv

其中 'a' 是二维张量(信号索引、时间),'b' 是 Hann window。 window 的长度是奇数。

(幸运的是!)可以使用 pytorch 原语实现这一点。您可能正在寻找 functional conv1d。下面是它的工作原理。我不确定你是想要关于输入还是权重的导数,所以你两者都有,只需保留适合你需要的 requires_grad :

import torch.nn.functional as F
# batch of 3 signals, each of length 11 with 1 channel
signal = torch.randn(3, 1, 11, requires_grad=True) 
# convolution kernel of size 3, expecting 1 input channel and 1 output channel
kernel = torch.randn(1, 1, 3, requires_grad=True)
# convoluting signal with kernel and applying padding
output = F.conv1d(signal, kernel, stride=1, padding=1, bias=None)
# output.shape is (3, 1, 11)
# backpropagating some kind of loss through the computational graph
output.sum().backward() 
print(kernel.grad)
>>> torch.tensor([[[...]]])