可以使用卷积定理和离散时间傅里叶变换 (DTFT) 计算 x * y 形式的线性离散卷积。如果x * y 是一个圆形离散卷积,则可以使用离散傅里叶变换 (DFT) 进行计算。
卷积定理状态x * y 可以使用傅里叶变换计算为
其中 表示傅里叶变换, 表示傅里叶逆变换。当x 和y 是离散的并且它们的卷积是线性卷积时,这是使用 DTFT 计算的
如果 x 和 y 是离散的,并且它们的卷积是循环卷积,则上面的 DTFT 将被 DFT 替换。 注意:线性卷积问题可以嵌入到循环卷积问题中。
我更熟悉 MATLAB,但通过阅读 tf.signal.fft2d 和 tf.signal.ifft2d 的 TensorFlow 文档,通过替换 MATLAB 函数 fft2 和 ifft2,下面的解决方案应该可以轻松转换为 TensorFlow。
在 MATLAB(和 TensorFlow)中,fft2(和 tf.signal.fft2d)使用快速傅里叶变换算法计算 DFT。如果x 和y 的卷积是循环的,则可以通过
ifft2(fft2(x).*fft2(y))
其中.* 表示 MATLAB 中的逐元素乘法。但是,如果它是线性的,那么我们将数据零填充到长度2N-1,其中N 是一维的长度(问题中的 1024)。在 MATLAB 中,这可以通过以下两种方式之一进行计算。首先,由
h = ifft2(fft2(x, 2*N-1, 2*N-1).*fft2(y, 2*N-1, 2*N-1));
其中 MATLAB 通过零填充计算 2*N-1-point 二维傅里叶变换 x 和 y,然后计算 2*N-1-point 二维傅里叶逆变换。此方法不能在 TensorFlow 中使用(根据我对文档的理解),因此下一个是唯一的选择。在 MATLAB 和 TensorFlow 中,可以通过首先将 x 和 y 扩展到 2*N-1 x 2*N-1 的大小,然后计算 2*N-1 点 2D 傅里叶变换和傅里叶逆变换来计算卷积
x_extended = x;
x_extended(2*N-1, 2*N-1) = 0;
y_extended = y;
y_extended(2*N-1, 2*N-1) = 0;
h_extended = ifft2(fft2(x_extended).*fft2(y_extended));
在 MATLAB 中,h 和 h_extended 完全相等。 x 和 y 的卷积可以在没有傅里叶变换的情况下计算出
hC = conv2(x, y);
在 MATLAB 中。
在我笔记本电脑上的 MATLAB 中 conv2(x, y) 需要 55 秒,而傅里叶变换方法需要不到 0.4 秒。