implementación de SVD del algoritmo de cóctel ... ¿en una línea de código?

88

En una diapositiva dentro de la conferencia introductoria sobre aprendizaje automático de Andrew Ng de Stanford en Coursera, ofrece la siguiente solución de octava de una línea al problema del cóctel dado que las fuentes de audio están grabadas por dos micrófonos separados espacialmente:

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

En la parte inferior de la diapositiva está "fuente: Sam Roweis, Yair Weiss, Eero Simoncelli" y en la parte inferior de una diapositiva anterior está "Clips de audio cortesía de Te-Won Lee". En el video, el profesor Ng dice:

"Por lo tanto, podría considerar el aprendizaje no supervisado como este y preguntarse: '¿Qué tan complicado es implementar esto?' Parece que para construir esta aplicación, parece que para hacer este procesamiento de audio, escribirías una tonelada de código, o tal vez vincularías a un montón de bibliotecas de C ++ o Java que procesan audio. Parece que sería realmente un programa complicado para hacer este audio: separar el audio y demás. Resulta que el algoritmo para hacer lo que acabas de escuchar, que se puede hacer con una sola línea de código ... se muestra aquí. A los investigadores les llevó mucho tiempo para llegar a esta línea de código. Así que no estoy diciendo que este sea un problema fácil. Pero resulta que cuando se usa el entorno de programación adecuado, muchos algoritmos de aprendizaje serán programas realmente cortos ".

Los resultados de audio separados reproducidos en la videoconferencia no son perfectos pero, en mi opinión, asombrosos. ¿Alguien tiene alguna idea de cómo funciona tan bien esa línea de código? En particular, ¿alguien conoce alguna referencia que explique el trabajo de Te-Won Lee, Sam Roweis, Yair Weiss y Eero Simoncelli con respecto a esa única línea de código?

ACTUALIZAR

Para demostrar la sensibilidad del algoritmo a la distancia de separación del micrófono, la siguiente simulación (en octava) separa los tonos de dos generadores de tonos separados espacialmente.

% 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;

Después de aproximadamente 10 minutos de ejecución en mi computadora portátil, la simulación genera las siguientes tres figuras que ilustran que los dos tonos aislados tienen las frecuencias correctas.

Figura 1 Figura 2 figura 3

Sin embargo, establecer la distancia de separación del micrófono en cero (es decir, dMic = 0) hace que la simulación genere las siguientes tres figuras que ilustran que la simulación no pudo aislar un segundo tono (confirmado por el único término diagonal significativo devuelto en la matriz de svd).

Figura 1 sin separación de micrófono Figura 2 sin separación de micrófono Figura 3 sin separación de micrófono

Tenía la esperanza de que la distancia de separación del micrófono en un teléfono inteligente fuera lo suficientemente grande para producir buenos resultados, pero establecer la distancia de separación del micrófono en 5,25 pulgadas (es decir, dMic = 0,1333 metros) hace que la simulación genere las siguientes cifras, menos que alentadoras, que ilustran más componentes de frecuencia en el primer tono aislado.

Figura 1 en teléfono inteligente Figura 2 en teléfono inteligente Figura 3 en teléfono inteligente

gregS
fuente
1
Tengo vagos recuerdos de esta conferencia, pero no recuerdo cuál xes; ¿Es el espectrograma de la forma de onda o qué?
Isaac
El profesor Ng, en t = 5: 30 en el video introductorio 4 sobre el aprendizaje no supervisado, parece sugerir que x es un vector de las muestras de audio. Quizás esa sección repmat en el argumento svd esté implementando algún tipo de normalización de potencia de la señal.
GregS

Respuestas:

28

Estaba tratando de resolver esto también, 2 años después. Pero tengo mis respuestas; con suerte ayudará a alguien.

Necesitas 2 grabaciones de audio. Puede obtener ejemplos de audio en http://research.ics.aalto.fi/ica/cocktail/cocktail_en.cgi .

la referencia para la implementación es http://www.cs.nyu.edu/~roweis/kica.html

ok, aquí está el código -

[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);

ingrese la descripción de la imagen aquí

Jack Z
fuente
1
¿Puede encontrar una referencia que explique de manera más explícita el fundamento de esa línea de código?
Hans
¿Podría explicar cómo funciona la mezcla de señales dentro del enlace que proporcionó? Usando su código, es bueno extraer dos fuentes de sonido de los dos archivos mixtos descargados del sitio. Sin embargo, cuando trato de mezclar dos señales separadas, parece que el algoritmo no puede generar el resultado correcto. Estoy usando la forma ingenua de obtener las señales mezcladas: mic1 = 0.3 * track1 + 0.5 * track2, mic2 = 0.5 * track1 + 0.3 * track2. Éstas son las señales que traté de enviar al algoritmo. ¡Muchas gracias!
yc2986
Soy un poco nuevo en Matlab. Tengo errores en la línea 3 que dicen que tiene problemas para concatenar 2 matrices de diferentes dimensiones. ¿Cómo debo manejar este problema?
mshrestha
1
Probé ese código pero no funciona muy bien ... (¡no te
culpo
17

x(t) es la voz original de un canal / micrófono.

X = repmat(sum(x.*x,1),size(x,1),1).*x)*x'es una estimación del espectro de potencia de x(t). Aunque X' = X, los intervalos entre filas y columnas no son los mismos en absoluto. Cada fila representa el tiempo de la señal, mientras que cada columna es la frecuencia. Supongo que esta es una estimación y simplificación de una expresión más estricta llamada espectrograma .

La descomposición de valores singulares en el espectrograma se utiliza para factorizar la señal en diferentes componentes según la información del espectro. Los valores diagonales en sson la magnitud de diferentes componentes del espectro. Las filas uy las columnas v'son los vectores ortogonales que mapean el componente de frecuencia con la magnitud correspondiente al Xespacio.

No tengo datos de voz para probar, pero según tengo entendido, por medio de SVD, los componentes caen en los vectores ortogonales similares y, con suerte, se agrupan con la ayuda del aprendizaje no supervisado. Digamos, si las 2 primeras magnitudes diagonales de s están agrupadas, entonces u*s_new*v'formará la voz de una sola persona, donde s_newes la misma de sexcepto que todos los elementos en (3:end,3:end)son eliminados.

Dos artículos sobre la matriz formada por sonido y SVD son para su referencia.

lennon310
fuente
1
gregS, matemáticamente una matriz x n-por-2 todavía puede formar una X con la operación repmat. Sin embargo, el espectrograma solo puede mostrar el canal cada vez. Entonces creo que tiene más sentido usar n-por-1 x cada vez y tratar el problema como una regresión lineal (dos ecuaciones matriciales). Otros dos enfoques posibles son (i) promediar dos canales como n-por-2 x; o (ii) unirlos para construir un 2 * n-por-2 x.
lennon310
2
GregS, reconsideré tu pregunta. Puede funcionar si implementa repmat en un n-por-2 x. Físicamente, puede verse como un promedio de potencia de dos canales en cada momento y en cada frecuencia.
lennon310
Encontré esta publicación después de ver el video de introducción de Machine Learning (el curso acaba de comenzar nuevamente). Me preguntaba si lograste reproducir la separación de audio que se muestra en el video o si se desarrolló durante el curso.
siritinga
@siritinga, busque la publicación de Andrew Ng sobre aprendizaje profundo / no supervisado en audio, gracias
lennon310
1
¿Por qué $ X $ es la potencia del espectro de $ x $? También de acuerdo con la respuesta de Jack Z, $ x $ no es la voz original de la grabación, sino una especie de recíproco procesado del valor propio de la covarianza de la voz original.
Hans