Thực hiện thuật toán tiệc cocktail SVD… trong một dòng mã?


88

Trong một trang trình bày trong bài giảng giới thiệu về máy học của Andrew Ng tại Coursera, Stanford, ông đưa ra giải pháp Octave một dòng sau đây cho vấn đề tiệc cocktail với điều kiện các nguồn âm thanh được ghi lại bằng hai micrô được phân tách theo không gian:

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

Ở cuối trang trình bày là "nguồn: Sam Roweis, Yair Weiss, Eero Simoncelli" và ở cuối trang trình bày trước đó là "Đoạn âm thanh lịch sự của Te-Won Lee". Trong video, Giáo sư Ng nói,

"Vì vậy, bạn có thể nhìn vào việc học không giám sát như thế này và hỏi, 'Làm thế nào phức tạp để thực hiện điều này?' Có vẻ như để xây dựng ứng dụng này, có vẻ như để xử lý âm thanh này, bạn sẽ viết rất nhiều mã hoặc có thể liên kết vào một loạt các thư viện C ++ hoặc Java để xử lý âm thanh. Có vẻ như nó sẽ là một chương trình phức tạp để thực hiện âm thanh này: tách ra âm thanh, v.v. Hóa ra thuật toán để thực hiện những gì bạn vừa nghe, điều đó có thể được thực hiện chỉ với một dòng mã ... được hiển thị ngay tại đây. Các nhà nghiên cứu đã mất nhiều thời gian để đưa ra dòng mã này. Vì vậy, tôi không nói đây là một vấn đề dễ dàng. Nhưng hóa ra là khi bạn sử dụng môi trường lập trình phù hợp, nhiều thuật toán học sẽ là những chương trình thực sự ngắn. "

Kết quả âm thanh tách biệt được phát trong video bài giảng không hoàn hảo nhưng theo tôi, thật tuyệt vời. Có ai có bất kỳ thông tin chi tiết nào về cách một dòng mã hoạt động tốt như vậy không? Đặc biệt, có ai biết tài liệu tham khảo giải thích công việc của Te-Won Lee, Sam Roweis, Yair Weiss và Eero Simoncelli liên quan đến một dòng mã đó không?

CẬP NHẬT

Để chứng minh độ nhạy của thuật toán đối với khoảng cách tách micrô, mô phỏng sau đây (trong Octave) tách các âm từ hai bộ tạo âm cách nhau theo không gian.

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

Sau khoảng 10 phút thực hiện trên máy tính xách tay của tôi, mô phỏng tạo ra ba hình sau minh họa hai âm riêng biệt có tần số chính xác.

Hình 1 Hình 2 Hình 3

Tuy nhiên, việc đặt khoảng cách tách micrô thành 0 (tức là dMic = 0) khiến mô phỏng thay vào đó tạo ra ba hình sau minh họa mô phỏng không thể tách âm thứ hai (được xác nhận bởi số hạng đường chéo quan trọng duy nhất được trả về trong ma trận svd).

Hình 1 không có tách mic Hình 2 không có tách mic Hình 3 không có tách mic

Tôi đã hy vọng khoảng cách tách micrô trên điện thoại thông minh sẽ đủ lớn để tạo ra kết quả tốt nhưng việc đặt khoảng cách tách micrô thành 5,25 inch (tức là dMic = 0,1333 mét) khiến mô phỏng tạo ra những điều sau đây, ít hơn đáng khích lệ, các số liệu minh họa cao hơn các thành phần tần số trong âm cách biệt đầu tiên.

Hình 1 trên điện thoại thông minh Hình 2 trên điện thoại thông minh Hình 3 trên điện thoại thông minh


1
Tôi có những ký ức mơ hồ về bài giảng này, nhưng không thể nhớ xđược là gì ; nó là quang phổ của dạng sóng, hay là gì?
Isaac

Giáo sư Ng, tại t = 5: 30 trong video giới thiệu 4 về học tập không giám sát, dường như gợi ý rằng x là một vectơ của các mẫu âm thanh. Có lẽ phần repmat đó trong đối số svd đang thực hiện một số loại chuẩn hóa tín hiệu.
gregS

Câu trả lời:


28

Tôi cũng đang cố gắng tìm ra điều này, 2 năm sau. Nhưng tôi đã có câu trả lời của mình; hy vọng nó sẽ giúp một ai đó.

Bạn cần 2 bản ghi âm. Bạn có thể lấy ví dụ về âm thanh từ http://research.ics.aalto.fi/ica/cocktail/cocktail_en.cgi .

tài liệu tham khảo để thực hiện là http://www.cs.nyu.edu/~roweis/kica.html

được rồi, đây là mã -

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

nhập mô tả hình ảnh ở đây


1
Bạn có thể tìm thấy một tham chiếu giải thích rõ ràng hơn về cơ sở lý luận cho dòng mã đó không?
Hans

Bạn có thể vui lòng giải thích cách trộn tín hiệu hoạt động bên trong liên kết bạn đã cung cấp không? Sử dụng mã của bạn, rất tốt để trích xuất hai nguồn âm thanh từ hai tệp hỗn hợp được tải xuống từ trang web. Tuy nhiên, khi tôi cố gắng tự trộn hai tín hiệu riêng biệt với nhau, có vẻ như thuật toán không thể đưa ra kết quả chính xác. Tôi đang sử dụng một cách đơn giản để lấy các tín hiệu hỗn hợp: mic1 = 0,3 * track1 + 0.5 * track2, mic2 = 0.5 * track1 + 0.3 * track2. Đây là tín hiệu tôi đã cố gắng cung cấp cho thuật toán. Cảm ơn rât nhiều!
yc2986

Tôi là người mới đối với Matlab. Tôi gặp lỗi ở dòng 3 nói rằng nó có vấn đề khi nối 2 ma trận có kích thước khác nhau. Tôi nên xử lý vấn đề này như thế nào?
mshrestha

1
Tôi đã thử mã đó nhưng nó không hoạt động tốt lắm ... (không đổ lỗi cho bạn !!)
hiểu lầm

17

x(t) là giọng nói gốc từ một kênh / micrô.

X = repmat(sum(x.*x,1),size(x,1),1).*x)*x'là một ước tính về phổ công suất của x(t). Mặc dù X' = X, khoảng cách giữa các hàng và cột không giống nhau chút nào. Mỗi hàng đại diện cho thời gian của tín hiệu, trong khi mỗi cột là tần số. Tôi đoán đây là một ước tính và đơn giản hóa một biểu thức chặt chẽ hơn được gọi là quang phổ .

Phân tích giá trị đơn lẻ trên quang phổ được sử dụng để phân tích tín hiệu thành các thành phần khác nhau dựa trên thông tin phổ. Giá trị đường chéo trong slà độ lớn của các thành phần phổ khác nhau. Các hàng trong uvà cột trong v'là các vectơ trực giao ánh xạ thành phần tần số có độ lớn tương ứng với Xkhông gian.

Tôi không có dữ liệu giọng nói để kiểm tra, nhưng theo hiểu biết của tôi, bằng SVD, các thành phần rơi vào các vectơ trực giao tương tự hy vọng sẽ được nhóm lại với sự trợ giúp của học tập không giám sát. Giả sử, nếu 2 độ lớn đường chéo đầu tiên từ s được nhóm lại, thì u*s_new*v'sẽ tạo thành giọng nói một người, nơi s_newgiống nhau sngoại trừ tất cả các phần tử tại (3:end,3:end)đều bị loại bỏ.

Hai bài báo về ma trận hình thành âm thanhSVD để bạn tham khảo.


1
gregS, về mặt toán học, một ma trận x n-x vẫn có thể tạo thành một chữ X bằng phép toán repmat. Tuy nhiên, biểu đồ quang phổ chỉ có thể hiển thị kênh mỗi lần. Vì vậy, tôi nghĩ sẽ hợp lý hơn nếu sử dụng n-x-1 mỗi lần và coi vấn đề như một hồi quy tuyến tính (hai phương trình ma trận). Hai cách tiếp cận khả thi khác là (i) tính trung bình hai kênh là n-x-2 x; hoặc (ii) ràng buộc chúng với nhau để tạo ra 2 * n-x-2 x.
lennon310 7/12/13

2
gregS, tôi đã xem xét lại câu hỏi của bạn. Nó có thể hoạt động nếu bạn triển khai repmat trên n-x-2 x. Về mặt vật lý, nó có thể được xem là công suất trung bình từ hai kênh tại mỗi thời điểm và mỗi tần số.
lennon310 7/12/13

Tôi tìm thấy bài đăng này sau khi xem video giới thiệu về Học máy (khóa học mới bắt đầu lại). Tôi đã tự hỏi liệu bạn có quản lý để tái tạo sự tách biệt âm thanh được hiển thị trong video hay nó đã được phát triển trong suốt khóa học hay không.
siritinga

@siritinga hãy tìm kiếm công bố Andrew Ng về không có giám sát / học sâu về âm thanh, nhờ
lennon310

1
Tại sao $ X $ là sức mạnh của quang phổ của $ x $? Cũng theo câu trả lời của Jack Z, $ x $ không phải là giọng gốc từ bản ghi âm mà là một dạng đối ứng đã qua xử lý nào đó của giá trị riêng của hiệp phương sai của giọng gốc.
Hans
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.