音声データを処理するAIモデルを構築する際、音声そのままでは特徴を捉えずらいデータであるため、音声特性を予め抽出しておいてあげると学習が安定します。
音声特性を抽出した最終形態がメルスペクトログラムとなります。
メルスペクトログラムが何かというと、時系列周波数特性を人の感覚に合わせて表現した2次元データです。
2次元データであるため画像として表現することができ、CNNなどのモデルを用いて学習させることができるようになります。
本記事ではそのようなメルスペクトログラムの作り方について説明していきます。
【補足】
実際に実装する場合、PythonではPytorchのtorchaudioなど、既に処理が用意されているためスクラッチで実装する必要はないです。
しかし、スクラッチで実装する必要はないですが、理解しておくと意図したパラメータ設定が可能となります。
スペクトル / スペクトログラム
ここで一度用語を整理しておきます。
スペクトル:ある時刻、または信号全体における周波数特性。どの周波数が強いか弱いかを示す。
スペクトログラム:スペクトルを時系列に並べたもの。
以降はスペクトルとスペクトログラムで記述していきます。
メルスペクトログラムができるまでの流れ
大まかな流れとしては以下の2ステップとなります。
- 短時間フーリエ変換(STFT)によって、各時刻のスペクトルを抽出
- 人の聴覚に合わせた周波数特性(メル尺度)への変換 ※メル尺度については後述
1で作られるものがスペクトログラム、2でメル尺度に変換したスペクトログラムがメルスペクトログラムです。
フーリエ変換~短時間フーリエ変換
フーリエ変換、離散フーリエ変換、高速フーリエ変換、短時間フーリエ変換の順で説明します。
※詳細語ると大学の講義になってしまうのと、スクラッチでの実装もする必要がないため、なんとなくでわかる程度の内容にします。
フーリエ変換(FT)
音声データのような信号は様々な周期・振幅の正弦波が合成されて構成されてます。
そのような信号に対して、どの周波数成分がどの程度含まれているか抽出する処理がフーリエ変換です。
成分を抽出する処理を別名でスペクトル解析とも呼びます。
以下は10Hzと30Hzの波を合成したものになります。

このような信号に対してフーリエ変換をすることでこの波には10Hz、30Hzの成分の波が入ってるということがわかるようになります。(下図参照)

音声では以下のようにさらに複雑な波形となりますが、どれだけ複雑であっても同様な処理で成分を抽出することができます。

離散フーリエ変換(DFT)
フーリエ変換は連続値を想定してますが、実際のデータはサンプリングデータ(離散値)となっています。
離散フーリエ変換は離散値に対応したフーリエ変換となります。
高速フーリエ変換(FFT)
離散フーリエ変換を素直に計算すると計算量が最も計算量が多い ですが、それを まで減らして処理を高速化するアルゴリズムとなります。
離散フーリエ変換の処理は基本的にFFTで行われます。
短時間フーリエ変換(STFT)
短時間フーリエ変換は以下のイメージのように波形を切り取る窓をスライドさせて区間を切り取り、それぞれの区間をDFT(or FFT)します。

これにより時間毎の周波数成分を見れるので周波数の時間特性を取得できます。
上図にも記載してますが、このときの切り取る窓には窓関数が使われます。
窓関数にいくつか種類があり、kaggleの解法などにおいてどの窓を使用したかなどが出てくることがあるため、窓関数についても説明しておきます。
【補足】窓関数について
DFTは周期的な信号を想定した処理であるため、切り取った区間の最初と最後が非連続の場合にDFTをするとスペクトルにノイズ(リップル)が発生します。
非連続のイメージを以下に示します。

このような波形を切り取り、これがループして周期的に続くと考えると、区間の最後から最初に戻るときに滑らかにつながらず突然値がジャンプしてしまい、それによってノイズが発生します。
ノイズ発生を抑制するために使用されるのが以下のような窓関数となります。

下図のように窓関数を信号に対して乗算してあげることで非連続な信号の両端が0に収束して連続な周期としてみなせるようになり、ノイズが低減されます。

メルスペクトログラム
前述したSTFTを用いて取得したスペクトログラムを人の聴覚に合わせた周波数特性である”メル尺度”に変換するとメルスペクトログラムとなります。
メル尺度への変換方法ですが、メルフィルタバンクというものを使用します。
以下にメルフィルタバンクを示します。

三角形がたくさん見えますが、これら一つ一つがメルフィルタとなっています。
スペクトログラムの各時刻のスペクトルに対して各メルフィルタで畳み込みを行い、これによってスペクトログラムがメルスペクトログラムに変換されます。
ここから少々補足ですが、メルフィルタ一つ一つの面積は1になるようになってます。※理論値では1ですが、処理の都合上きれいな1にはなっていないです。
低周波領域ではフィルタの幅が狭く細かい、一方で高周波に引くほど幅が広く粗くなっています。
これは人の聴覚が低周波の変化に対して敏感であり、高周波の変化には鈍感であることを再現してるためとのことです。
話を戻し、上図ではフィルタが64個となっているため、スペクトログラムが各フィルタによって畳み込まれた結果として、メルスペクトログラムにおける各時刻の周波数特性は64個となります。
このように情報が圧縮されることがメルスペクトログラムの利点であり、特徴量エンジニアリングのような役目を果たします。
最後に、度々登場していた以下の音声信号をメルスペクトログラムに変換したものが2枚目の図に示します。


縦軸のサイズが64になってますね。
人が読み取りやすいように縦軸と横軸の単位を変えたものも以下に載せておきます。

ちなみにこの音声データkaggle2026年のBirdClefのコンペから持ってきたものであり、動物の鳴き声が含まれている音声となります。(音声処理の学習も兼ねて参加してみました。)
添付した音声は1分ですが先ほどの処理は前半30秒だけを切り取って処理したものとなります。
メルスペクトログラム上で8000Hz付近に一定リズムで出てくるものがありますが、音声を聞くと虫が一定間隔でリンリン鳴いてるのがわかるので周波数特性を適切に抽出できてそうです。
リンリンという音以外にも鈴虫のようなじりりりという音があり、それらがおそらく10kHzから12kHzあたりに出てる強い音声だと思われます。
最後に
音声データをAIモデルで学習できるようにするためにメルスペクトログラムについて説明しました。
実際には自身で実装することがあまりないと思うため数学要素を極力排除して説明記載しましたが、理解の一助になれば幸いです。
音声データを扱えることで実務であれば機械の故障検知や音声分類といったことが実現できます。
最後までご覧いただきありがとうございます。

