简体   繁体   English

PyTorch 的 conv1d 和 SciPy 的 convolve 的不同结果

[英]Different results from PyTorch's conv1d and SciPy's convolve

I'm building a PyTorch model to estimate Impuse Responses .我正在构建一个 PyTorch model 来估计Impuse Responses Currently I am calculating the loss from the real and estimated impulse response.目前我正在计算真实和估计的脉冲响应的损失。 I would like to convolve both the estimated and real impulse response with a signal and then calculate the loss from those.我想将估计的和实际的脉冲响应与信号进行卷积,然后计算它们的损失。

The pyroomaccoustics package uses SciPy's fftconvolve to convolve the impulse response with a given signal. pyromaccoustics package 使用 SciPy 的fftconvolve将脉冲响应与给定信号进行卷积。 I cannot use this since it would break PyTorch's computation graph.我不能使用它,因为它会破坏 PyTorch 的计算图。 PyTorch's conv1d uses cross-correlation. PyTorch 的conv1d使用互相关。 From this answer it seems that by flipping the filter conv1d can be used for convolution.这个答案看来,通过翻转过滤器conv1d似乎可以用于卷积。

I am confused as to why the following code gives a different result for conv1d and convolve and what must be changed to get the outputs to be equal.我很困惑为什么以下代码会为conv1dconvolve给出不同的结果,以及必须更改哪些内容才能使输出相等。

import torch
from scipy.signal import convolve

a = torch.tensor([.1, .2, .3, .4, .5])
b = torch.tensor([.0, .1, .0])

a1 = a.view(1, 1, -1)
b1 = torch.flip(b, (0,)).view(1, 1, -1)


print(torch.nn.functional.conv1d(a1, b1).view(-1))
# >>> tensor([0.0200, 0.0300, 0.0400])

print(convolve(a, b))
# >>> [0.   0.01 0.02 0.03 0.04 0.05 0.  ]

Take a look at the mode parameter of scipy.signal.convolve .查看scipy.signal.convolvemode参数。 Use mode='valid' to match PyTorch's conv1d :使用mode='valid'匹配 PyTorch 的conv1d

In [20]: from scipy.signal import convolve                                      

In [21]: a = np.array([.1, .2, .3, .4, .5])                                     

In [22]: b = np.array([.0, .1, .0])                                             

In [23]: convolve(a, b, mode='valid')                                           
Out[23]: array([0.02, 0.03, 0.04])

To modify the call of PyTorch's conv1d to give the same output as the default behavior of scipy.signal.convolve (ie to match mode='full' ) for this example, set padding=2 in the call to conv1d .要修改 PyTorch 的conv1d调用以提供与 scipy.signal.convolve 的默认行为相同的scipy.signal.convolve (即匹配mode='full' ),请在对conv1d的调用中设置padding=2 More generally, for a given convolution kernel b , set the padding to len(b) - 1 .更一般地,对于给定的卷积 kernel b ,将填充设置为len(b) - 1

Additional example pictures for full,same,valid in convolve https://www.twblogs.net/a/5c8373f9bd9eee35fc13cb76完整、相同、在卷积中有效的其他示例图片https://www.twblogs.net/a/5c8373f9bd9eee35fc13cb76

select [valid] will match with torch.conv1d select [valid] 将匹配 torch.conv1d

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM