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([[[...]]])
我需要在 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([[[...]]])