人工知能に関する断創録スマートフォン用の表示で見るスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。ロボティクス、生物学などに興味を持っています。このブログでは人工知能のさまざまな分野について調査したことをまとめています。Learning、Kerasに関する記事が多いです。2012-02-25メル周波数ケプストラム係数(MFCC)音声信号処理Pythonで音声信号処理(2011/05/14)の第19回目。Coefficients)を求めてみました。いわゆるMFCCです。MFCCはケプストラム(2012/2/11)と同じく声道特性を表す特徴量です。ケプストラムとMFCCの違いはMFCCが人間の音声知覚の特徴を考慮していることです。メルという言葉がそれを表しています。MFCCの抽出手順をまとめるとプリエンファシスフィルタで波形の高域成分を強調する窓関数をかけた後にFFTして振幅スペクトルを求める振幅スペクトルにメルフィルタバンクをかけて圧縮する上記の圧縮した数値列を信号とみなして離散コサイン変換する得られたケプストラムの低次成分がMFCCとなります。私が参考にしたコードは振幅スペクトルを使ってたけど、Wikipediaの説明を見るとパワーと書いてある。パワースペクトルの方がいいのかな?ケプストラム分析と違うのは振幅スペクトルにメルフィルタバンクをかけて圧縮するケプストラム領域に移すのにフーリエ変換ではなく、離散コサイン変換を使うの2点であとはだいたい一緒のようです。いうわけでこの手順にそってPythonで実装していきたいと思います。mfcc.py音声信号まず、音声信号を用意します。ケプストラム分析で使った「あ」の音の中心の定常部分をロードします。音声を再生するには、audioタグをサポートしたブラウザが必要です。filter)をかけます。高域成分を強調することで声道特徴がはっきり出るため使った方がよいとのこと。プリエンファシスフィルタの定義は、ここで、x(n)は音声波形データ、pはプリエンファシス係数。0.97を使うことが多いとのこと。FIRフィルタ(2011/10/23)と同じです。FIRフィルタの定義式に上のフィルタ係数を代入するとプリエンファシスフィルタの式と同じになることが確認できます。Pythonだとlfilter()を使って下のように実装できます。p)実際にプリエンファシスフィルタをかけた波形とそのスペクトルを表示してみました。左上がもとの波形、右上がフィルタをかけた波形。左下がもとの波形のスペクトル、右下がフィルタをかけた波形のスペクトルです。プリエンファシスフィルタをかけることで高域成分が強調されているのがよくわかります。振幅スペクトル次にプリエンファシスフィルタをかけた波形にハミング窓をかけてからFFTして振幅スペクトルを求めます。さっきのはハミング窓かけてませんでした。次、メルフィルタバンクを作成します。フィルタバンクというのはバンドパスフィルタ(2011/10/30)を複数並べたものです。ここでは、三角形のバンドパスフィルタをオーバーラップさせながら並べます。三角形のバンドパスフィルタの数をチャネル数と呼びます。ここでただのフィルタバンクではなく、メルがつくのが特徴です。メル尺度は、人間の音声知覚を反映した周波数軸で単位はmelです。低周波ほど間隔が狭く、高周波ほど間隔が広くなっています。人間は低周波なら細かい音の高さの違いがわかるけれど、高周波になるほど音の高さの違いがわからなくなるようです。詳しい説明は参考文献にゆずるとしてHzとmelを相互変換する関数を実装します。1.0)メルフィルタバンクは、バンドパスフィルタの三角窓がメル尺度上で等間隔になるように配置されます。メル尺度上で等間隔にならべたフィルタをHz尺度に戻すと高周波になるほど幅が広い三角形になります。下の図のようなイメージです。メルフィルタバンクを作る関数です。filterbank[c])savefig(&quot;melfilterbank.png&quot;)show()ここで戻り値のfilterbankは行列です。各行が1つのバンドパスフィルタ(三角形)にあたります。音声認識では、20個のバンドパスフィルタを使うことが多いそうです。20チャネルのフィルタバンクです。列数は、FFTのサンプル数(nfft)を2048にしているので、ナイキスト周波数までの半分をとると1024になります。1024)が返ってきます。メルフィルタバンクをかける次に、先の振幅スペクトルにメルフィルタバンクをかけます。振幅スペクトルに対してメルフィルタバンクの各フィルタをかけ、フィルタ後の振幅を足し合わせて対数をとります。言葉で書くとややこしいんだけれどコードだとはっきりします。np.array(mspec)実は、forループで書かなくても下のように行列のかけ算を使うともっと簡潔にかけます。フィルタをかけて振幅を足し合わせるというのは内積で表せるためです。filterbank.T))どっちの方法でも同じ結果になります。これをすると振幅スペクトルがメルフィルタバンクのチャネル数と同じ次元に圧縮されます。今回は、チャネル数20なので20次元のデータになります。元の対数振幅スペクトルとメルフィルタバンクで20次元データをプロットしてみると下のようになります。最後にこの20次元のデータを離散コサイン変換してケプストラム領域に移します。ケプストラム分析だとフーリエ変換で戻してましたけれど、MFCCの場合は離散コサイン変換を使うとのこと。ここら辺がなぜなのか理解できてません。ceps[:nceps]離散コサイン変換の結果から低次の成分を取り出したものがMFCCです。大体、12次までとることが多いとのこと。nceps=12です。-0.29347927]という結果になりました。うーん、一応それっぽい数値が出てきたけどこれであっているのかな?今回は、勉強のために自分で実装してみましたが、実際は、HTKやSPTK(2012/8/5)のような既存ツールを使えばそこそこ簡単に抽出できます。音声認識の原理を直感的にわかりやすく解説。ケプストラム分析でも参照しましたがその続きです。Pythonで実装したMFCCのコード。»プロフィールid:aidiary人工知能とその関連分野に興味があります。Blog|ブログを報告する。