音楽コード進行の自動認識(2)

前回はChromaを直接テンプレートと照らし合わせることでコードの認識をしましたが、次は機械学習のアプローチを見てみます。現在主な認識手法として、隠れマルコフモデル(HMM)を使ったコード進行認識技術が数多く提案されてます。Songle.jpで採用された方法はそれだし、この前言ったヤマハのChord Trackerもたぶんそれでしょう。

HMMの仕組みは色んなとこに載ってると思うので省きますが、コード(あるいは調とコードの組)を隠れ状態とし、各時刻で状態から特徴量(クロマベクトル)を出力し、状態間で遷移するHMMで、コード進行をモデル化するわけです。

この手法はよく「音声認識を倣った」と言われてますが、(あんまり詳しくないけど)音声認識は一般的に個々の単語(あるいは音素)ごとにHMMを作って識別させるのに対して、コード認識では一つのHMMの中で解決するところが決定的に違う気がします。

もっと分かりやすくに言うと、音声認識は状態遷移系列は無視して、複数のHMMの状態遷移確率を比較して識別するのにたいして、コード認識は一つのHMMの隠れ状態遷移系列そのものを認識結果とする、というところです。

もっとも音声認識に似た手法(一つのコードを一つのHMMでモデリングしてBaum-Welchで訓練するとか)もありそうだと何となく思うんですが、もうちょっと調べこんでみる必要がありそうです。

さて、ではHMMの構造を考えてみます。今回はメジャー、マイナーコードに加えて、ディミニッシュコードを加えて36種類のコードを認識させてみます。

始点、終点以外に、36個の隠れ状態があり、(自己遷移を含める)すべての状態間に遷移確率があります。各隠れ状態には観測値(12次元ベクトル)の出力確率があり、音声認識では混合ガウスモデル(GMM)をよく使うらしいですが、今回は単純のため多次元正規分布でモデリングしちゃいます。こうすると、コードの出力確率はChromaベクトルの平均値ベクトルと、共分散行列で定義することができます。

訓練データセット(ビートルズの全アルバム)のオーディオとラベルをフレームに分解して分析すれば、コード(隠れ状態)の遷移確率と各コードのクロマベクトル出力確率を計算することができるので、これでHMMが完成。機械学習とは言いにくいなこれ。

認識する時はオーディオ信号をクロマベクトル系列にして、Viterbiアルゴリズムで状態遷移系列を求めれば完了。

(以下8/1更新分)

さて、数学が絶望的にダメなしゃをみんは多次元正規分布とViterbiの実装にずいぶん手間をかけてしまったんですが、ようやく動くものができたので結果をご報告。

まず今回の実装は(途中から)以下のものを参考にしました。主にViterbiの実装。

http://www.ee.columbia.edu/~dpwe/e4896/practicals.html#prac10

コード進行認識の他にも僕が勉強したいものがたくさん載ってます。すばらしいですこれ。

今回学習と認識に使ったChromaのデータも、自分で計算せず、サイトに置いてある学習データ(ビートルズ全曲のChromaとラベル)を使いました。

このデータはBeat-synchronized Chromaといって、前回のように細かいフレームに区切って計算するかわりに拍で区切って計算されたものだそう。

まずは学習データを全部放り込んで分析。遷移確率はこんな感じです。

遷移確率行列

遷移確率行列

主対角線が明るいのは、ビート間でコードが変わらない確率が比較的高いことを示しています。だいたい1小節や2小節ごとに変わりますもんね、普通。

そして各コードのChroma平均ベクトルはこんな感じ。

コードの平均値ベクトル(横軸) 縦軸の0がノーコードで、1から12がメジャーコード、それ以降がマイナー

コードの平均値ベクトル(横軸)
縦軸の0がノーコードで、1から12がメジャーコード、それ以降がマイナー

だいたい予期どおりの形になってますね。

コード進行が比較的はっきりしてそうなLet It Beで試してみたところ正解率は約62%。

青:正解ラベル 緑:認識結果

青:正解ラベル
緑:認識結果

Let It Beのデータも学習に使ったんでチートさせたようなものですが、その割には結果がイマイチ。

まだまだ改善は必要そうです。がんばろうしゃをみん。

ではまた次回に続くと思います。

(8/20補足)

上のサイトに載ってたお手本ではLet It Beの正解率が71%くらいあったので、まだまだ完コピできてない。

多次元ガウシアンの計算にミスがあったかなーと思ってたんですが、今日になってお手本ではChromaベクトルを正規化してたことが発覚。

フレームごとに最大値が1になるようにベクトルを正規化してたのだ。

この処理をすべてのChroma(学習データと認識対象)に適用すればお手本どおりの正解率が実現しました。アルバムごとの平均正解率もだいたい60%前後になります。