MMI-SPLICE

音声強調法としてよく知られる SPLICE を MMI 基準で学習する話を紹介します.


MMI-SPLICE の前に,まず SPLICE を紹介します.SPLICE は http://research.microsoft.com/pubs/63610/2002-droppo-icslpa.pdf が詳しいです.


SPLICE は,以下の式で劣化音声特徴量 y からクリーン音声特徴量の推定値 \hat{x} を求めます.
\hat{x}=\sum_k p(k|y) A_k [1;y]
簡単にいえば,区分的線形変換で y\hat{x} の関係をモデル化しています.


通常の SPLICE では,A_k を学習する際, y とクリーン音声特徴量 x のステレオデータ(時間的に同期したデータ)を用い,重み付き最小二乗誤差基準で推定しています.具体的には,
 argmax_{A_k} \sum_{t} p(k|y_t) || A_k [1;y_t] - x_t ||^2
を解いています.ここで t はデータの時間インデックスです.この目的関数は convex で,解析的に厳密解が求まります.
SPLICE の学習を matlab-like な擬似コードで以下に示します.

for ii = 1:nfile
    % データを読む
    input = readhtk( inputfiles{ii} );
    output = readhtk( outputfiles{ii} );

    [ndim nframe] = size(input); % = size(output)

    for kk = 1:nframe
        
        % p(k|y) を計算.gmmmean/gmmvar/gmmweight は予め学習しておく
        w = sum( -0.5 * (gmmmean-input(:,kk)*ones(1,nmix)).^2 ./ gmmvar)';
        w = exp( w ) .* gmmweight ./ sqrt(prod( gmmvar ))';
        w = w ./ sum(w);

        x = output(:,kk);
        z = [1; input(:,kk)];
        
        xz = x * z';
        zz = z * z';
        for ll = 1:nmix
            % 高速化可能(後述)
            Rk_xz(:,:,ll) = Rk_xz(:,:,ll) + w(ll) * xz;
            Rk_zz(:,:,ll) = Rk_zz(:,:,ll) + w(ll) * zz;
        end
    end
end

for ii = 1:nmix
    A(:,:,ii) = Rk_xz(:,:,ii) / Rk_zz(:,:,ii);
end

A_k が学習できれば,\hat{x} を推定するのは以下のような感じでできます.

for kk = 1:nframe
    % p(k|y) を計算
    w = sum( -0.5 * (gmmmean-input(:,kk)*ones(1,nmix)).^2 ./ gmmvar)';
    w = exp( w ) .* gmmweight ./ sqrt(prod( gmmvar ))';
    w = w ./ sum(w);

    z = [1; input(:,kk)];

    for ll = 1:nmix
        % 高速化可能(後述)
        enhanced(:,kk) = enhanced(:,kk) + w(ll) * ( A(:,:,ll) * z );
    end
end

上のコードで「高速化可能」と書いた部分は,適当な閾値などを設けて w(ll) が十分小さい場合に計算を飛ばすようにすると,高速化できます.
一般的に GMM を使って w を計算すると,w はかなりスパースになるので,この高速化は非常に有効です.
SPLICE は,計算量が比較的小さく,かつ精度が高いことが知られています.


SPLICE は,他の音声強調法と比較して2つの大きな特徴があります.
一つは,音声強調時に雑音の推定値が必要ないこと.(逆にいうとせっかく雑音を推定しても使えない.)
もう一つは,学習に yx のステレオデータが必要になるということです.


前者に関しては,手前味噌ですが,雑音の推定値を利用する SPLICE を提案しているので,
もしよろしければ私のHP http://www.gavo.t.u-tokyo.ac.jp/~suzuki/ に書いている論文など御覧ください.


後者に関して,実は,ステレオデータが必要ない A_k の学習法が提案されています.
前置きが長くなってしまいましたが,これが MMI-SPLICE です.
論文はこちら.
http://research.microsoft.com/pubs/57607/2005-jdroppo-eurospeech.pdf


MMI-SPLICE は,通常の SPLICE と,音声強調ステップは完全に共通です.なので,音声強調時の計算量は SPLICE から変化しません.
違いは, A_k の学習に,MMI 基準を用いることだけです.
通常の SPLICE では, A_k を推定する基準は,以下に再掲する重み付き最小二乗誤差基準でした.
 argmax_{A_k} \sum_{t} p(k|y_t) || A_k [1;y_t] - x_t ||^2
MMI-SPLICE では,これを HMM の識別学習などでお馴染みの,MMI (Maximum Mutual Information,相互情報量最大化) 基準で推定します.
 argmax_{A_k} \sum_{r} \ln{\frac{p(\hat{X}_r, w_r)}{ \sum_w p(\hat{X}_r, w) } }
ここで, r は utterance ごとの ID です.\hat{X}_r は SPLICE を使って音声強調された utterance の特徴系列,w_r は utterance r に対する正解単語系列です.
このような基準を使うことで,A_k音声認識率が高くなるように学習されます.
しかも,学習には  y と対応する単語系列があればよく, yx のステレオデータは必要なくなります.


MMI 基準の目的関数は,通常の SPLICE の目的関数と違い,解析解は求まりません.
最適化には最急降下法を用います.
そのためには,A_k で目的関数を偏微分する必要があります.
論文(http://research.microsoft.com/pubs/57607/2005-jdroppo-eurospeech.pdf)には,
A_k の代わりに,そのバイアス成分である b_k のみを用いた場合の偏微分の計算が述べられています.
(個人的には論文の (6) 式の展開が,確かに当たり前のように見えつつも,イマイチ確信をもって説明できません…
詳しい方いらっしゃいましたら,教えて下さい…もっと勉強しなくては…)


A_k偏微分する場合は,最終的な目的関数の微分(論文でいう (9) 式)は以下のような感じになります.
 \frac{ \partial \mathcal{F} }{ \partial A_k } = \sum_{r,t,s^r_t} p(k|y^r_t) (\gamma^{num}_{s^r_t} - \gamma^{den}_{s^r_t}) \Sigma^{-1}_{s^r_t} (\mu_{s^r_t} - x^r_t) [1;y^r_t]^T
各文字の意味については,論文を参照ください.
 \gamma^{num}_{s^r_t}, \gamma^{den}_{s^r_t} は HMM を識別学習するときにでてくる項と同じものです.
(日本語で HMM を識別学習する方法の説明をあまり見ないので,いつかしっかり書いてみたいが,今日はひとまず省略)


気になる MMI-SPLICE の性能ですが,論文によると,通常の SPLICE より,特にノイズ環境のミスマッチが少ない場合良くなるようです.
ノイズ環境のミスマッチがある場合は,ある程度はよくなりますが,すぐに過学習の問題が発生するようです.
MMI-SPLICE は,通常の SPLICE と違って学習にステレオデータが必要無いという大きな利点があるので,この結果は十分うれしい結果です.


なお,MMI 基準ではなく,MCE 基準を使う SPLICE http://hub.hku.hk/bitstream/10722/47081/1/121754.pdf も提案されていますが,
(論文によると)MMI-SPLICE の方が少しだけ性能が良いとのことです.


このブログでは,バイアス成分  b_k だけでなく  A_k を使う場合の式を紹介しましたが,
もしかしたら, A_k を使うと過学習の問題はより顕著になってしまうのかもしれません.
このへんは,MMI-SPLICE を実装していないので今のところわかりません.


本来なら MMI-SPLICE を実装してコードも載せたいところですが,
そこまでは手が回っていないので,今日の一人勉強会はこれでおしまいです.


追記
http://research.microsoft.com/pubs/63600/2005-droppo-asru.pdf
こっちの論文の方が,詳しく書いてあることに今更気づきました.
 A_k で目的関数偏微分する式も,こちらの論文には載っています.