gpt4 book ai didi

numpy - FFT 卷积如何以及为什么比直接卷积更快?

转载 作者:行者123 更新时间:2023-12-01 12:05:45 25 4
gpt4 key购买 nike

我读到有关卷积在频域中计算时速度更快,因为它“只是”矩阵乘法(二维),而在时域中它是很多小矩阵乘法。

所以我做了这段代码我们可以看到 FFT 卷积比“普通”卷积更复杂。很明显,我的假设有问题。

怎么了?

from sympy import exp, log, symbols, init_printing, lambdify
init_printing(use_latex='matplotlib')

import numpy as np
import matplotlib.pyplot as plt

def _complex_mult(n):
"""Complexity of a MatMul of a 2 matrices of size (n, n)"""
# see https://en.wikipedia.org/wiki/Matrix_multiplication_algorithm
return n**2.5

def _complex_fft(n):
"""Complexity of fft and ifft"""
# see https://en.wikipedia.org/wiki/Fast_Fourier_transform
return n*log(n)

def fft_mult_fft(n, m):
"""Complexity of a convolution in the freq space.
fft -> mult between M and kernel -> ifft
"""
return _complex_fft(n) * 2 + _complex_mult(n)

def conv(n, m):
"""Complexity of a convolution in the time space.
for every n of M, we execute a MatMul of 2 (m, m) matrices
"""
return n*_complex_mult(m)


n = symbols('n') # size of M = (n, n)
m = symbols('m') # size of kernel = (m, m)

M = np.linspace(1, 1e3+1, 1e1)
kernel_size = np.linspace(2, 7, 7-2+1)**2

fft = fft_mult_fft(n, m)
discrete = conv(n, m)

f1 = lambdify(n, fft, 'numpy')
f2 = lambdify([n, m], discrete, 'numpy')

fig, ax = plt.subplots(1, len(kernel_size), figsize=(30, 10))

f1_computed = f1(M) # independant wrt m, do not compute it at each time

for i, size in enumerate(kernel_size):
ax[i].plot(M, f1_computed, c='red', label='freq domain (fft)')
ax[i].plot(M, f2(M, size), c='blue', label='time domain (normal)')
ax[i].legend(loc='upper left')
ax[i].set_title("kernel size = {}".format(size))
ax[i].set_xlabel("Matrix size")
ax[i].set_ylabel("Complexity")

这是输出:(点击放大)

Graphs

最佳答案

您正在经历两个众所周知的事实:

  • 对于小内核大小,空间方法更快,

  • 对于大内核大小,频率方法可以更快。

您的内核和图像相对较小,无法观察到 FFT 的优势。

关于numpy - FFT 卷积如何以及为什么比直接卷积更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57168089/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com