칵테일 파티 알고리즘 SVD 구현… 코드 한 줄로?


88

Coursera에서 Stanford의 Andrew Ng가 머신 러닝에 대한 입문 강의의 슬라이드에서 그는 오디오 소스가 공간적으로 분리 된 두 개의 마이크에 의해 녹음된다는 점에서 칵테일 파티 문제에 대해 다음과 같은 옥타브 솔루션을 제공합니다.

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

슬라이드의 맨 아래에는 "출처 : Sam Roweis, Yair Weiss, Eero Simoncelli"가 있으며 이전 슬라이드 맨 아래에는 "이태원의 오디오 클립"이 있습니다. 비디오에서 Ng 교수는 이렇게 말합니다.

"그러므로 이러한 비지도 학습을보고 '이것을 구현하는 것이 얼마나 복잡합니까?'라고 질문 할 수 있습니다. 이 응용 프로그램을 빌드하려면이 오디오 처리를 수행하는 것처럼 보이며 많은 코드를 작성하거나 오디오를 처리하는 C ++ 또는 Java 라이브러리에 링크 할 수 있습니다. 이 오디오를 수행하는 복잡한 프로그램 : 오디오 분리 등. 방금들은 것을 수행하는 알고리즘이 밝혀졌습니다. 한 줄의 코드만으로 수행 할 수 있습니다 ... 바로 여기에 표시됩니다. 연구자들은 오랜 시간이 걸렸습니다. 그래서 이것이 쉬운 문제라고 말하는 것이 아닙니다.하지만 올바른 프로그래밍 환경을 사용하면 많은 학습 알고리즘이 정말 짧은 프로그램이 될 것입니다. "

비디오 강의에서 재생되는 분리 된 오디오 결과는 완벽하지는 않지만 제 생각에는 놀랍습니다. 한 줄의 코드가 어떻게 그렇게 잘 수행되는지에 대한 통찰력이있는 사람이 있습니까? 특히 한 줄의 코드와 관련하여 이태원, Sam Roweis, Yair Weiss, Eero Simoncelli의 작업을 설명하는 참고 문헌을 아는 사람이 있습니까?

최신 정보

마이크 분리 거리에 대한 알고리즘의 민감도를 보여주기 위해 다음 시뮬레이션 (옥타브)은 공간적으로 분리 된 두 톤 제너레이터에서 톤을 분리합니다.

% 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 분 동안 실행 한 후 시뮬레이션은 두 개의 격리 된 톤이 올바른 주파수를 가지고 있음을 보여주는 다음 세 가지 그림을 생성합니다.

그림 1 그림 2 그림 3

그러나 마이크 분리 거리를 0 (즉, dMic = 0)으로 설정하면 시뮬레이션이 두 번째 톤을 분리 할 수 ​​없음을 나타내는 다음 세 가지 그림을 대신 생성합니다 (svd의 s 행렬에서 반환 된 단일 유효 대각선 항으로 확인 됨).

마이크 분리가없는 그림 1 마이크 분리가없는 그림 2 마이크 분리가없는 그림 3

스마트 폰의 마이크 이격 거리가 좋은 결과를 얻을 수있을만큼 충분히 커지기를 바랐지만 마이크 이격 거리를 5.25 인치 (즉, dMic = 0.1333 미터)로 설정하면 시뮬레이션에서 다음과 같은 결과가 생성됩니다. 첫 번째 격리 된 톤의 주파수 성분.

스마트 폰의 그림 1 스마트 폰의 그림 2 스마트 폰의 그림 3


1
이 강의에 대한 기억이 모호하지만 무엇인지 기억이 나지 않습니다 x. 파형의 스펙트로 그램입니까, 아니면 무엇입니까?
Isaac

비지도 학습에 대한 소개 비디오 4의 t = 5 : 30에있는 Ng 교수는 x가 오디오 샘플의 벡터라고 제안하는 것 같습니다. 아마도 svd 인수의 repmat 섹션은 신호의 일종의 전력 정규화를 구현하고있을 것입니다.
gregS

답변:


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
해당 코드 줄의 근거를보다 명시 적으로 설명하는 참조를 찾을 수 있습니까?
Hans

제공 한 링크 내에서 신호 믹싱이 어떻게 작동하는지 설명해 주시겠습니까? 코드를 사용하여 사이트에서 다운로드 한 두 개의 혼합 파일에서 두 개의 음원을 추출하는 것이 좋습니다. 그러나 두 개의 개별 신호를 직접 혼합하려고하면 알고리즘이 올바른 결과를 출력하지 못하는 것 같습니다. 혼합 신호를 얻기 위해 순진한 방법을 사용하고 있습니다 : mic1 = 0.3 * track1 + 0.5 * track2, mic2 = 0.5 * track1 + 0.3 * track2. 이것이 내가 알고리즘에 공급하려고 한 신호입니다. 대단히 감사합니다!
yc2986

저는 Matlab에 익숙하지 않습니다. 3 행에 다른 차원의 2 개 행렬을 연결하는 데 문제가 있다는 오류가 있습니다. 이 문제를 어떻게 처리해야합니까?
mshrestha

1
나는 그 코드를 시도했지만 잘 작동하지 않습니다 ... (당신을 비난하지 않습니다 !!)
anderstood

17

x(t) 한 채널 / 마이크의 원래 음성입니다.

X = repmat(sum(x.*x,1),size(x,1),1).*x)*x'의 전력 스펙트럼에 대한 추정치입니다 x(t). 하지만 X' = X행과 열 사이의 간격은 전혀 동일하지 않습니다. 각 행은 신호의 시간을 나타내고 각 열은 주파수입니다. 이것은 spectrogram 이라는 더 엄격한 표현의 추정과 단순화라고 생각합니다 .

특이 값 분해스펙트로 그램의 는 스펙트럼 정보를 기반으로 신호를 여러 구성 요소로 분해하는 데 사용됩니다. 의 대각선 값 s은 다양한 스펙트럼 구성 요소의 크기입니다. 의 행 u과 열 v'은 해당 크기를 가진 주파수 성분을 X공간에 매핑하는 직교 벡터입니다 .

테스트 할 음성 데이터는 없지만 SVD를 통해 유사한 직교 벡터에 속하는 구성 요소가 비지도 학습의 도움으로 클러스터링되기를 바랍니다. s의 처음 2 개 대각선 크기가 클러스터링되면u*s_new*v's_news모든 요소 (3:end,3:end)가 제거 된다는 점 을 제외하고 는 동일한 1 인 음성이 형성됩니다 .

사운드 형식 매트릭스SVD 에 대한 두 개의 기사는 참고 용입니다.


1
gregS, 수학적으로 nx2 행렬 x는 여전히 repmat 연산으로 X를 형성 할 수 있습니다. 그러나 스펙트로 그램은 매번 채널 만 표시 할 수 있습니다. 따라서 매번 nx1 x를 사용하고 문제를 선형 회귀 (두 행렬 방정식)로 처리하는 것이 더 합리적이라고 생각합니다. 또 다른 두 가지 가능한 접근 방식은 (i) 두 채널을 nx2 x로 평균화하는 것입니다. 또는 (ii) 2 * nx2 x를 구성하기 위해 함께 결합합니다.
lennon310 dec. 07 2013-12-07

2
그 렉스, 나는 당신의 질문을 재고했습니다. repmat을 nx2 x에 구현하면 작동 할 수 있습니다. 물리적으로 두 채널의 평균 전력과 각 주파수로 볼 수 있습니다.
lennon310

머신 러닝 소개 영상을 본 후이 게시물을 찾았습니다 (강의가 다시 시작되었습니다). 비디오에 나오는 오디오 분리를 재현 할 수 있었는지 아니면 과정 중에 개발되었는지 궁금합니다.
siritinga

@siritinga 오디오, 덕분에 자율 / 깊은 학습에 앤드류 응의 간행물을 검색하십시오
lennon310

1
$ X $가 $ x $의 스펙트럼의 힘인 이유는 무엇입니까? 또한 Jack Z의 답변에 따르면 $ x $는 녹음 된 원본 음성이 아니라 원본 음성의 공분산 고유 값에 대해 일종의 처리 된 역수입니다.
Hans
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.