カクテルパーティーアルゴリズムSVDの実装…1行のコードで?


88

スタンフォード大学のAndrewNgによるCourseraでの機械学習の入門講義のスライドで、オーディオソースが2つの空間的に分離されたマイクで録音されている場合、カクテルパーティーの問題に対する次の1行のオクターブソリューションを示します。

[W,s,v]=svd((repmat(sum(x.*x,1),size(x,1),1).*x)*x');

スライドの下部には「出典:Sam Roweis、Yair Weiss、Eero Simoncelli」があり、前のスライドの下部には「Te-WonLeeの好意によるオーディオクリップ」があります。ビデオの中で、Ng教授は次のように述べています。

「それで、あなたはこのような教師なし学習を見て、 『これを実装するのはどれほど複雑ですか?』と尋ねるかもしれません。このアプリケーションを構築するために、このオーディオ処理を行うように思われます。大量のコードを記述するか、オーディオを処理するC ++またはJavaライブラリの束にリンクする可能性があります。本当にそうだと思われます。このオーディオを実行するための複雑なプログラム:オーディオの分離など。今聞いたことを実行するアルゴリズムが判明しました。これは、ここに示す1行のコードで実行できます。研究者には長い時間がかかりました。このコード行を思い付くために。だから、これが簡単な問題だと言っているわけではありません。しかし、適切なプログラミング環境を使用すると、多くの学習アルゴリズムが本当に短いプログラムになることがわかります。」

ビデオ講義で再生された個別のオーディオ結果は完璧ではありませんが、私の意見では驚くべきものです。その1行のコードがどのようにうまく機能するかについて誰かが何か洞察を持っていますか?特に、その1行のコードに関して、Te-Won Lee、Sam Roweis、Yair Weiss、およびEero Simoncelliの作業を説明するリファレンスを知っている人はいますか?

更新

マイク分離距離に対するアルゴリズムの感度を示すために、次のシミュレーション(Octave)は、2つの空間的に分離されたトーンジェネレーターからトーンを分離します。

% define model 
f1 = 1100;              % frequency of tone generator 1; unit: Hz 
f2 = 2900;              % frequency of tone generator 2; unit: Hz 
Ts = 1/(40*max(f1,f2)); % sampling period; unit: s 
dMic = 1;               % distance between microphones centered about origin; unit: m 
dSrc = 10;              % distance between tone generators centered about origin; unit: m 
c = 340.29;             % speed of sound; unit: m / s 

% generate tones
figure(1);
t = [0:Ts:0.025];
tone1 = sin(2*pi*f1*t);
tone2 = sin(2*pi*f2*t);
plot(t,tone1); 
hold on;
plot(t,tone2,'r'); xlabel('time'); ylabel('amplitude'); axis([0 0.005 -1 1]); legend('tone 1', 'tone 2');
hold off;

% mix tones at microphones
% assume inverse square attenuation of sound intensity (i.e., inverse linear attenuation of sound amplitude)
figure(2);
dNear = (dSrc - dMic)/2;
dFar = (dSrc + dMic)/2;
mic1 = 1/dNear*sin(2*pi*f1*(t-dNear/c)) + \
       1/dFar*sin(2*pi*f2*(t-dFar/c));
mic2 = 1/dNear*sin(2*pi*f2*(t-dNear/c)) + \
       1/dFar*sin(2*pi*f1*(t-dFar/c));
plot(t,mic1);
hold on;
plot(t,mic2,'r'); xlabel('time'); ylabel('amplitude'); axis([0 0.005 -1 1]); legend('mic 1', 'mic 2');
hold off;

% use svd to isolate sound sources
figure(3);
x = [mic1' mic2'];
[W,s,v]=svd((repmat(sum(x.*x,1),size(x,1),1).*x)*x');
plot(t,v(:,1));
hold on;
maxAmp = max(v(:,1));
plot(t,v(:,2),'r'); xlabel('time'); ylabel('amplitude'); axis([0 0.005 -maxAmp maxAmp]); legend('isolated tone 1', 'isolated tone 2');
hold off;

ラップトップコンピューターで約10分間実行した後、シミュレーションにより、2つの分離されたトーンが正しい周波数を持っていることを示す次の3つの図が生成されます。

図1 図2 図3

ただし、マイクの分離距離をゼロ(つまり、dMic = 0)に設定すると、シミュレーションは代わりに次の3つの図を生成し、シミュレーションが2番目のトーンを分離できなかったことを示します(svdのs行列で返される単一の有意な対角項によって確認されます)。

マイク分離なしの図1 マイク分離なしの図2 マイク分離なしの図3

スマートフォンのマイク分離距離が十分に大きくて良い結果が得られることを期待していましたが、マイク分離距離を5.25インチ(つまり、dMic = 0.1333メートル)に設定すると、シミュレーションで次のように生成されます。最初の孤立したトーンの周波数成分。

スマートフォンの図1 スマートフォンの図2 スマートフォンの図3


1
この講義の記憶は漠然としていますxが、何なのか思い出せません。それは波形のスペクトログラムですか、それとも何ですか?
アイザック

Ng教授は、教師なし学習の紹介ビデオ4のt = 5:30で、xがオーディオサンプルのベクトルであることを示唆しているようです。おそらく、svd引数のrepmatセクションは、信号のある種の電力正規化を実装しています。
gregS 2013

回答:


28

2年後、私もこれを理解しようとしていました。しかし、私は答えを得ました。うまくいけば、それは誰かを助けるでしょう。

2つのオーディオ録音が必要です。音声の例はhttp://research.ics.aalto.fi/ica/cocktail/cocktail_en.cgiから入手できます。

実装のリファレンスはhttp://www.cs.nyu.edu/~roweis/kica.htmlです

わかりました、ここにコードがあります-

[x1, Fs1] = audioread('mix1.wav');
[x2, Fs2] = audioread('mix2.wav');
xx = [x1, x2]';
yy = sqrtm(inv(cov(xx')))*(xx-repmat(mean(xx,2),1,size(xx,2)));
[W,s,v] = svd((repmat(sum(yy.*yy,1),size(yy,1),1).*yy)*yy');

a = W*xx; %W is unmixing matrix
subplot(2,2,1); plot(x1); title('mixed audio - mic 1');
subplot(2,2,2); plot(x2); title('mixed audio - mic 2');
subplot(2,2,3); plot(a(1,:), 'g'); title('unmixed wave 1');
subplot(2,2,4); plot(a(2,:),'r'); title('unmixed wave 2');

audiowrite('unmixed1.wav', a(1,:), Fs1);
audiowrite('unmixed2.wav', a(2,:), Fs1);

ここに画像の説明を入力してください


1
そのコード行の論理的根拠をより明確に説明する参照を見つけることができますか?
ハンス

提供したリンク内で信号ミキシングがどのように機能するかを説明してください。コードを使用して、サイトからダウンロードした2つの混合ファイルから2つの音源を抽出することをお勧めします。しかし、2つの別々の信号を自分で混ぜようとすると、アルゴリズムが正しい結果を出力できないようです。混合信号を取得するために単純な方法を使用しています:mic1 = 0.3 * track1 + 0.5 * track2、mic2 = 0.5 * track1 + 0.3 * track2。これらは私がアルゴリズムに供給しようとした信号です。どうもありがとうございました!
yc2986 2016年

私はMatlabに少し慣れていません。3行目にエラーがあり、異なる次元の2つの行列を連結するのに問題があると言っています。この問題をどのように処理する必要がありますか?
mshrestha 2017

1
私はそのコードを試しましたが、うまく機能しません...(あなたを責めません!!)
2018

17

x(t) 1つのチャンネル/マイクからの元の音声です。

X = repmat(sum(x.*x,1),size(x,1),1).*x)*x'のパワースペクトルの推定値ですx(t)。ただしX' = X、行と列の間隔はまったく同じではありません。各行は信号の時間を表し、各列は周波数を表します。これは、スペクトログラムと呼ばれるより厳密な式の推定と簡略化だと思います。

スペクトログラムの特異値分解は、スペクトル情報に基づいて信号をさまざまな成分に分解するために使用されます。の対角値sは、さまざまなスペクトル成分の大きさです。の行uと列はv'、対応する大き​​さの周波数成分をX空間にマッピングする直交ベクトルです。

テストする音声データはありませんが、私の理解では、SVDを使用すると、コンポーネントは同様の直交ベクトルに分類され、教師なし学習の助けを借りてクラスター化されることが期待されます。たとえば、sの最初の2つの対角線の大きさがクラスター化されている場合、u*s_new*v'は1人の声を形成します。ここs_newで、のsすべての要素(3:end,3:end)が削除されることを除いて同じです。

音の形をしたマトリックスSVDに関する2つの記事を参考にしてください。


1
gregS、数学的にはn行2列の行列xは、repmat操作でXを形成できます。ただし、スペクトログラムは毎回チャネルのみを表示できます。したがって、毎回n x 1 xを使用し、問題を線形回帰(2つの行列方程式)として扱う方が理にかなっていると思います。別の2つの可能なアプローチは、(i)2つのチャネルをn行2列のxとして平均化することです。または(ii)それらを結合して2 * n x 2xを構築します。
lennon310 2013

2
gregS、私はあなたの質問を再考しました。n行2列のxにrepmatを実装すると機能する場合があります。物理的には、各時間および各周波数での2つのチャネルからの電力の平均と見なすことができます。
lennon310 2013

機械学習の紹介ビデオを見て、この投稿を見つけました(コースはまだ始まったばかりです)。ビデオに写っているオーディオセパレーションをなんとか再現できたのか、それともコース中に開発されたのかと思いました。
siritinga 2014年

@siritingaは、オーディオの教師なし/ディープラーニングに関するAndrew Ngの出版物を検索してください。ありがとう
ございます

1
$ X $が$ x $のスペクトルのパワーであるのはなぜですか?また、ジャックZの回答によると、$ x $は録音からの元の音声ではなく、元の音声の共分散の固有値のある種の処理された逆数です。
ハンス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.