web-dev-qa-db-ja.com

実空間の畳み込みと比較したFFTによる畳み込みの欠点は何ですか?

したがって、FFTによる畳み込みは、実空間での畳み込みよりも計算の複雑さが低いことを認識しています。しかし、FFT畳み込みの欠点は何ですか?

カーネルサイズは常にイメージサイズと一致する必要がありますか、それとも、たとえばpythons numpyおよびscipyパッケージで、これを処理する関数がありますか?そして、アンチエイリアシング効果はどうですか?

22
ABDreverhaven

FFT畳み込みは、 畳み込み定理 に基づいています。これは、Fd()Fi()の場合、2つの関数fgを与えることを示しています。直接および逆フーリエ変換、および*および.の畳み込みと乗算を示し、次のようになります。

f*g = Fi(Fd(d).Fd(g))

これをシグナルfとカーネルgに適用するには、次の点に注意する必要があります。

  • 乗算ステップを可能にするには、fgのサイズが同じである必要があるため、カーネルをゼロパッドする必要があります。
  • FFTが行うことであるDFTを実行する場合、結果として得られる関数の周波数領域表現は周期的です。これは、デフォルトでは、畳み込みを実行するときにカーネルがエッジをラップアラウンドすることを意味します。これが必要な場合は、すべてが素晴らしいです。ただし、そうでない場合は、カーネルのサイズをゼロパディングして回避する必要があります。
  • ほとんどの(すべて?)FFTパッケージは、大きな素因数を持たないサイズでのみ(パフォーマンス的に)うまく機能します。信号とカーネルサイズを2の次の累乗に切り上げることは一般的な方法であり、(非常に)大幅な速度向上につながる可能性があります。

信号とカーネルのサイズがf_lg_lの場合、時間領域で単純な畳み込みを行うには、g_l * (f_l - g_l + 1)の乗算と(g_l - 1) * (f_l - g_l + 1)の加算が必要です。

FFTアプローチの場合、少なくともf_l + g_lのサイズの3つのFFTと、f_l + g_lの乗算を実行する必要があります。

fgの両方のサイズが大きい場合、FFTはn*log(n)の複雑さで明らかに優れています。小さなカーネルの場合、直接的なアプローチの方が速い場合があります。

scipy.signalには、 convolvefftconvolve の両方のメソッドがあります。また、fftconvolveは、上記のすべてのパディングを透過的に処理します。

26
Jaime

高速畳み込みは、直接形式の畳み込みよりも「大きなO」の複雑さが優れています。いくつかの欠点または警告があります。私はこのトピックについていくつか考えました 記事 しばらく前に書きました。

  1. 「ビッグO」の複雑さが優れていると、必ずしも優れているとは限りません。直接フォーム畳み込みは、特定のサイズよりも小さいフィルターにFFTを使用するよりも高速です。正確なサイズは、使用するプラットフォームと実装によって異なります。クロスオーバーポイントは通常、10〜40の係数範囲にあります。

  2. レイテンシー。高速畳み込みは本質的にブロック単位のアルゴリズムです。変換する前に一度に数百または数千のサンプルをキューに入れることは、一部のリアルタイムアプリケーションでは受け入れられない場合があります。

  3. 実装の複雑さ。直接形式は、メモリ、コードスペース、およびライター/メンテナの理論的背景の点で単純です。

  4. 固定小数点DSPプラットフォーム(汎用CPUではない)の場合:固定小数点FFTのワードサイズに関する考慮事項が限られているため、大きな固定小数点FFTはほとんど役に立たなくなります。サイズスペクトルのもう一方の端では、これらのチップには、直接形式のFIR計算を実行するために適切に設計された特殊なMAC命令があり、O(N ^ 2)直接形式がO(NlogN)よりも高速である範囲が広がります。これらの要因は、固定小数点FFTが高速畳み込みに役立つ限られた「スイートスポット」を作成する傾向があります。

16
Mark Borgerding