Closed3

STFTのパラメータとconvolutionのパラメータの対応関係について

bilzardbilzard

STFTのパラメータとconvolutionのパラメータとの対応関係で整理する。

n_fft

STFTを適用する原信号のframe サイズ。畳み込みのkernel sizeに相当する。

filter bankの個数n_fft // 2 + 1はである。

hop_length

畳み込みのstrideに相当する。hop_lengthを小さくとるほど最終的なspectrogramの時間領域の長さを大きく取ることができるが、時間領域での測定の精度[1]はwin_lengthに依存する。

win_length

窓関数のframeサイズ。win_lengthを大きくとるほど周波数領域の測定の精度が高くなる(代わりに時間領域の測定精度を犠牲にする)[1]。

周期的でない信号にSTFTを適用すると原信号の両端が不連続なために、注目しているfilter bankの周波数とは関係ない周波数にartifactができてしまう。このため伝統的に信号処理の分野では周波数フィルタを適用する際に、原信号の両端の信号強度を減衰させる手法が用いられてきた。具体的には窓関数(window funciotn)を時間領域の信号に畳み込む。経験的に良い窓関数としてHann窓やHanning窓が用いられる。

window_lengthとはこの窓関数のフレーム長のこと。STFTを適用する場合、原信号はn_fftの長さのチャンクで処理するので、本来両者は一致している必要がある。このため、librosa[1]やpytorch[2]のSTFTの実装ではwindow_length < n_fftの場合は窓関数の両端を0でパディングするようにしている。

Reference

脚注
  1. 時間方向の分解能。直感的には時間領域の変化に追従できる度合い。 ↩︎

bilzardbilzard

周波数領域と時間領域の解像度がトレードオフになることの直感的な説明は、心拍数を計測する際に、正確に計測しようとしたら測定時間を長く取らないといけないが、測定間隔を長くとるほど移動平均の影響で瞬間瞬間の経時変化に追従しにくくなる、ということの類推で考えることができる。

例えば、測定間隔を1secとする場合、心拍数が概ね1 Hzであると仮定すると、1 sec間の心拍数の測定値は{0, 1, 2}のいずれかの値となり、この測定間隔では心拍数が非常に粗い精度(+- 1sec)でしか計測することができない。一方で、ある瞬間から心拍数が1Hz -> 2Hzに上昇した場合は1sec程度の遅延で検知することができる。

一方で、測定間隔を1000secとする場合、先ほどの例と比べて計測数のサンプル数が約1000倍になるため、周波数方向の測定の精度(標準偏差)は約\sqrt{1000}倍になる。一方で、ある瞬間から心拍数が1 Hz -> 2Hzに上昇したとしても、1000秒間の移動平均で算出した心拍数は過去の系列の影響がしばらく続くため、測定値が2 Hzになるには1000秒の遅延が生じる。

このように時間領域の計測の精度と周波数領域の計測の精度は本質的にトレードオフの関係にある。

bilzardbilzard

このように、STFTにおける時間領域、周波数領域の分解能(resolution)は、convolutionの文脈で使用される「分解能(resolution)」の概念とは異なり、kernel sizeによって律則されるのであり、strideとは独立している。

ところで、convolutionは窓関数を適用しないことやfilter bankの重みが可変であることを除けばSTFTの場合と同じである。したがって、STFTの文脈における解像度(=時間領域、周波数領域の測定精度)がkernel sizeに依存するという現象は、一般的なconvolutionの場合であっても成り立つ。つまり、周期的に変化する情報を抽出しようとした場合はその測定精度はkernel sizeに影響を受けることが推察できる[1]

脚注
  1. 直感的にkernel sizeを大きく取りすぎると近隣の系列との相関が大きくなり、出力系列には強いsmoothingがかかるという事実と整合する。 ↩︎

このスクラップは2024/01/26にクローズされました