【问题标题】:Implementing STFT with Pytorch gives a slightly different result than the STFT with Librose使用 Pytorch 实现 STFT 的结果与使用 Librose 的 STFT 略有不同
【发布时间】:2020-04-25 01:38:49
【问题描述】:

我正在尝试用Pytorch 实现STFT。但与Librosa 的实现相比,Pytorch 实现的输出略有偏差。

Librosa 版本

import numpy as np
from librosa.core import stft
import matplotlib.pyplot as plt

np.random.seed(3)
y = np.sin(2*np.pi*50*np.linspace(0,10,2048))+np.sin(2*np.pi*20*np.linspace(0,10,2048)) + np.random.normal(scale=1,size=2048)

S_stft = np.abs(stft(y, hop_length=512, n_fft=2048,center=False))

plt.plot(S_stft)

Pytorch 版本

import torch
from torch.autograd import Variable
from torch.nn.functional import conv1d

from scipy.signal.windows import hann

stride = 512

def create_filters(d,k,low=50,high=6000):
    x = np.arange(0, d, 1)
    wsin = np.empty((k,1,d), dtype=np.float32)
    wcos = np.empty((k,1,d), dtype=np.float32)
    start_freq = low
    end_freq = high
    # num_cycles = start_freq*d/44000.
    # scaling_ind = np.log(end_freq/start_freq)/k

    window_mask = hann(2048, sym=False) # same as 0.5-0.5*np.cos(2*np.pi*x/(k))
    for ind in range(k):
        wsin[ind,0,:] = window_mask*np.sin(2*np.pi*ind/k*x)
        wcos[ind,0,:] = window_mask*np.cos(2*np.pi*ind/k*x)

    return wsin,wcos

wsin, wcos = create_filters(2048,2048)

wsin_var = Variable(torch.from_numpy(wsin), requires_grad=False)
wcos_var = Variable(torch.from_numpy(wcos),requires_grad=False)

network_input = torch.from_numpy(y).float()
network_input = network_input.reshape(1,-1)

zx = np.sqrt(conv1d(network_input[:,None,:], wsin_var, stride=stride).pow(2)+conv1d(network_input[:,None,:], wcos_var, stride=stride).pow(2))
pytorch_Xs = zx.cpu().numpy()
plt.plot(pytorch_Xs[0,:1025,0])

我的问题

这两个图表可能看起来相同,但如果我用np.allclose 检查两个输出,我们可以看到它们略有不同。

np.allclose(S_stft, pytorch_Xs[0,:1025,0].reshape(1025,1))
output >>> False

只有当我将容差调整到1e-5 时,它才会给我True 结果

np.allclose(S_stft, pytorch_Xs[0,:1025,0].reshape(1025,1),atol=1e-5)
output >>> True

是什么导致了价值观的不同?是不是因为使用torch.from_numpy(y).float()进行了数据转换?

我希望有小于1e-7的价值差异,1e-8更好。

【问题讨论】:

    标签: python python-3.x fft pytorch librosa


    【解决方案1】:

    区别在于它们的默认位之间的区别。 NumPy 的浮点数默认为 64 位。 PyTorch 的浮点数默认为 32 位。

    【讨论】:

    • 我试图验证这一点,但无论我为 torch.stft 提供 64 位浮点数组还是 32 位浮点数组,容差仍然为 +- 1e05。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-08
    • 1970-01-01
    • 1970-01-01
    • 2017-10-20
    • 2019-04-26
    • 2017-10-08
    相关资源
    最近更新 更多