In einer Folie in der Einführungsvorlesung über maschinelles Lernen von Stanfords Andrew Ng in Coursera gibt er die folgende einzeilige Oktavlösung für das Cocktailparty-Problem, da die Audioquellen von zwei räumlich getrennten Mikrofonen aufgezeichnet werden:
[W,s,v]=svd((repmat(sum(x.*x,1),size(x,1),1).*x)*x');
Am unteren Rand der Folie befindet sich "Quelle: Sam Roweis, Yair Weiss, Eero Simoncelli" und am unteren Rand einer früheren Folie "Audioclips mit freundlicher Genehmigung von Te-Won Lee". In dem Video sagt Professor Ng:
"Sie könnten sich also unbeaufsichtigtes Lernen wie dieses ansehen und fragen: 'Wie kompliziert ist es, dies umzusetzen?' Es scheint, als würden Sie zum Erstellen dieser Anwendung eine Menge Code schreiben oder eine Verknüpfung zu einer Reihe von C ++ - oder Java-Bibliotheken herstellen, die Audio verarbeiten. Es scheint, als wäre dies eine echte kompliziertes Programm, um dieses Audio zu machen: Audio trennen und so weiter. Es stellt sich heraus, dass der Algorithmus das tut, was Sie gerade gehört haben, was mit nur einer Codezeile gemacht werden kann ... hier gezeigt. Es hat lange gedauert Ich sage also nicht, dass dies ein einfaches Problem ist. Aber es stellt sich heraus, dass viele Lernalgorithmen wirklich kurze Programme sind, wenn Sie die richtige Programmierumgebung verwenden. "
Die getrennten Audioergebnisse in der Videovorlesung sind nicht perfekt, aber meiner Meinung nach erstaunlich. Hat jemand einen Einblick, wie diese eine Codezeile so gut funktioniert? Kennt jemand eine Referenz, die die Arbeit von Te-Won Lee, Sam Roweis, Yair Weiss und Eero Simoncelli in Bezug auf diese eine Codezeile erklärt?
AKTUALISIEREN
Um die Empfindlichkeit des Algorithmus gegenüber dem Abstand zwischen Mikrofonen zu demonstrieren, trennt die folgende Simulation (in Oktave) die Töne von zwei räumlich getrennten Tongeneratoren.
% 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;
Nach ungefähr 10 Minuten Ausführung auf meinem Laptop generiert die Simulation die folgenden drei Abbildungen, die zeigen, dass die beiden isolierten Töne die richtigen Frequenzen haben.
Wenn Sie jedoch den Abstand zwischen den Mikrofonen auf Null setzen (dh dMic = 0), generiert die Simulation stattdessen die folgenden drei Abbildungen, die veranschaulichen, dass die Simulation keinen zweiten Ton isolieren konnte (bestätigt durch den einzelnen signifikanten diagonalen Term, der in der Matrix von svd zurückgegeben wird).
Ich hatte gehofft, dass der Mikrofonabstand auf einem Smartphone groß genug ist, um gute Ergebnisse zu erzielen. Wenn Sie jedoch den Mikrofonabstand auf 5,25 Zoll (dh dMic = 0,1333 Meter) einstellen, generiert die Simulation die folgenden, weniger als ermutigenden Zahlen, die höhere Werte darstellen Frequenzkomponenten im ersten isolierten Ton.
x
ist; ist es das Spektrogramm der Wellenform oder was?Antworten:
Ich habe auch 2 Jahre später versucht, dies herauszufinden. Aber ich habe meine Antworten bekommen; hoffentlich hilft es jemandem.
Sie benötigen 2 Audioaufnahmen. Audiobeispiele finden Sie unter http://research.ics.aalto.fi/ica/cocktail/cocktail_en.cgi .
Referenz für die Implementierung ist http://www.cs.nyu.edu/~roweis/kica.html
ok, hier ist Code -
quelle
x(t)
ist die Originalstimme von einem Kanal / Mikrofon.X = repmat(sum(x.*x,1),size(x,1),1).*x)*x'
ist eine Schätzung des Leistungsspektrums vonx(t)
. ObwohlX' = X
, sind die Abstände zwischen den Zeilen und Spalten überhaupt nicht das gleiche. Jede Zeile repräsentiert die Zeit des Signals, während jede Spalte die Frequenz ist. Ich denke, dies ist eine Schätzung und Vereinfachung eines strengeren Ausdrucks namens Spektrogramm .Die Singularwertzerlegung im Spektrogramm wird verwendet, um das Signal basierend auf Spektruminformationen in verschiedene Komponenten zu zerlegen. Diagonale Werte in
s
sind die Größe verschiedener Spektralkomponenten. Die Zeilen inu
und Spalten inv'
sind die orthogonalen Vektoren, die die Frequenzkomponente mit der entsprechenden Größe auf denX
Raum abbilden .Ich habe keine Sprachdaten zum Testen, aber nach meinem Verständnis werden die Komponenten mittels SVD in die ähnlichen orthogonalen Vektoren fallen und hoffentlich mit Hilfe von unbeaufsichtigtem Lernen geclustert. Sagen wir, wenn die ersten 2 diagonalen Größen von s gruppiert sind, dann
u*s_new*v'
bilden sie die Ein-Personen-Stimme, wobeis_new
die gleiche ist,s
außer dass alle Elemente bei(3:end,3:end)
eliminiert werden.Zwei Artikel über die klanggeformte Matrix und SVD dienen als Referenz.
quelle