通过梯度下降优化窗口长度(STFT)(在神经网络中)

信息处理 窗函数 stft 优化 神经网络
2022-02-19 07:44:04

本文的作者通过梯度下降(钟形曲线的 σ 参数)与神经网络的其他参数一起优化了高斯窗口大小。

我不使用高斯窗,而是使用汉恩窗。我想知道如何通过梯度下降使用 Hann/Hamming 窗口优化 stft 窗口大小?

问题在于,与高斯窗不同,汉恩窗没有连续参数 σ 作为梯度下降的代理。有没有一种方法可以重写 Hann 窗口,或者是否有可以用来控制窗口大小并且可以微分的参数?目前,n是正整数,不可微分。

torch.hann_window 使用:

w[n]={12(1cos(2πN1n))0nN10otherwise

我挠了挠头,但不知道如何区分它。

非常感谢您的任何提示。

2个回答

最简单的方法是使用支持 autodiff 的运算符来获取 STFT,例如通过 PyTorch。然后只需将窗口设置为可更新参数,初始化为 Hanning 等:

import torch.nn as nn
from scipy.signal import windows

win = torch.from_numpy(windows.hann(128))
win_t = nn.Parameter(win, requires_grad=True)

然后我们会做例如

def forward(self, x):
    x = STFT(x, win_t)
    x = self.conv(x)
    ...

通过例如将窗口的权重定义为初始窗口的一半,但使用使用更新的权重的完整窗口进行操作,这可能有助于应用对称约束。

例如,请参阅这篇文章,将完全可微分 CWT 应用于反演。该网络可以嵌入到一个卷积网络中,如果我们用nn.Parameter.

优化宽度

如果目标是优化预定义窗口函数的参数,则通过可微参数生成窗口:

def gauss(N, sigma):
    t = torch.linspace(-.5, .5, N)
    return torch.exp(-(t / sigma)**2)

N = x.shape[-1]
sigma = nn.Parameter(torch.tensor(0.1))
win_t = gauss(N, sigma)

优化长度

为了优化窗口的样本数量,我们必须确保采样是可微的。

  • Hann 可以arange(N) / N,但N必须是连续的,这需要四舍五入。torch.round不可微分,但torch.clamp可以。
  • 为确保该过程有效,我们通过归一化互相关 (NCC) 定义优化目标:最佳窗口长度将与参考匹配。我们通过conv1d.
  • 通过普通梯度下降进行优化,确保每一步后梯度为零,以避免梯度下降

假设我们从 开始,N=129最优是N_ref=160结果:

在此处输入图像描述

Github上的代码

考虑N作为正实数并使用您的汉恩窗公式,w[n]. 那么偏导数w[n]关于N将会:

w[n]N={πnsin(2πN1n)(N1)20nN10otherwise.

在整数N,w[n]有一个非常简单、稀疏的长度——N离散傅里叶变换 (DFT)。非整数N这种质量丢失了,但我也不知道您在我们的应用程序中是否需要这种质量。