具有复杂傅立叶变换的 Pytorch Autograd 给出了错误的结果

Pytorch Autograd with complex fourier transforms gives wrong results

我正在尝试使用 pytorch 和 autograd 实现一个实值成本函数,该函数以频率 space 评估复杂输入,因为我对成本函数的梯度感兴趣 w.r.t。输入。当我将 autograd 结果与我手动计算的导数(使用 Wirtinger 微积分)进行比较时,我得到了不同的结果。我不确定我在哪里犯了错误,是在我的实现中还是在我自己的梯度推导中。

成本函数及其手工导数如下所示: Formula of the cost function

我的实现在这里

def f_derivative_by_hand(f):
    f = torch.tensor(f, dtype=torch.complex128)
    ftilde = torch.fft.fft(f)
    absf = torch.abs(ftilde)
    f2 = absf**2
    C = torch.trapz(f2).numpy()
    grads = 2 * torch.fft.ifft((ftilde)).numpy()
    return C, grads

def f_derivative_autograd(f):
    f = torch.tensor(f, dtype=torch.complex128, requires_grad=True)
    ftilde = torch.fft.fft(f)
    f2 = torch.abs(ftilde)**2
    C = torch.trapz(f2)
    C.backward()
    grads = f.grad
    return C.detach().numpy(), grads.detach().numpy()

当我使用一些数据并通过两个函数对其进行评估时,相比之下,具有自动微分的实现的梯度是倾斜的(请注意,我对绘制的数组进行了归一化): Autograd and derivative by hand comparison

我怀疑 fft 的自动微分也可能有问题,因为如果我从成本函数中删除傅里叶变换并在实数中积分该函数 space,两种实现完全匹配,除了边缘(再次归一化): No FFT autograd and derivative by hand

如果有人能帮我找出问题所在,那就太棒了!

经过更多调查,我找到了解决倾斜导数问题的方法。显然,梯形积分规则假定的边界条件会在边界处显示一些伪影,如本 pytorch forum post.

中所讨论的那样

在我原来的问题中,观察到的倾斜是由不对称的傅里叶变换信号的积分产生的。边界伪影引入了使导数倾斜的空间频率 space。

对我来说,最简单的解决方案就是通过频差使用求和和权重。然后,一切顺利。