【问题标题】:Different results from PyTorch's conv1d and SciPy's convolvePyTorch conv1d 和 SciPy 卷积的不同结果
【发布时间】:2020-06-08 03:59:00
【问题描述】:

我正在构建一个 PyTorch 模型来估计 Impuse Responses。 目前我正在计算真实和估计脉冲响应的损失。 我想将估计的和实际的脉冲响应与信号进行卷积,然后计算这些损失。

pyroomaccoustics 包使用 SciPy 的 fftconvolve 将脉冲响应与给定信号进行卷积。我不能使用它,因为它会破坏 PyTorch 的计算图。 PyTorch 的 conv1d 使用互相关。从this answer看来,通过翻转过滤器conv1d可以用于卷积。

我很困惑为什么以下代码会为 conv1d 和 convolve 提供不同的结果,以及必须更改哪些内容才能使输出相等。

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.  ]

【问题讨论】:

    标签: python scipy pytorch signal-processing convolution


    【解决方案1】:

    完整、相同、有效卷积的附加示例图片 https://www.twblogs.net/a/5c8373f9bd9eee35fc13cb76

    select [valid] 将与 torch.conv1d 匹配

    【讨论】:

      【解决方案2】:

      看看scipy.signal.convolve的mode参数。使用 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])
      

      要修改 PyTorch 的 conv1d 的调用以提供与此示例中 scipy.signal.convolve 的默认行为相同的输出(即匹配 mode='full'),请将调用中的 padding=2 设置为 conv1d。更一般地,对于给定的卷积核b,将填充设置为len(b) - 1。

      【讨论】:

      • 将conv1d 填充设置为len(b) // 2 + len(b) % 2(因为 b 可能不是奇数)似乎不会得到与scipy.signal.convolve 相同的结果,用于较大的卷积核。例如a = torch.rand((35000,)) 和b = torch.rand((400,))
      • 啊,我的错。试试padding=len(b) - 1。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-07
      • 2020-03-26
      • 1970-01-01
      • 2018-11-11
      • 2018-06-25
      相关资源
      最近更新 更多