ในสไลด์ภายในการบรรยายเบื้องต้นเกี่ยวกับแมชชีนเลิร์นนิงโดย Andrew Ng จาก Stanford ที่ Coursera เขาได้ให้คำตอบหนึ่งบรรทัดต่อไปนี้สำหรับปัญหางานเลี้ยงค็อกเทลเนื่องจากแหล่งที่มาของเสียงถูกบันทึกโดยไมโครโฟนสองตัวที่แยกกัน
[W,s,v]=svd((repmat(sum(x.*x,1),size(x,1),1).*x)*x');
ที่ด้านล่างของสไลด์คือ "แหล่งที่มา: Sam Roweis, Yair Weiss, Eero Simoncelli" และที่ด้านล่างของสไลด์ก่อนหน้าคือ "คลิปเสียงเอื้อเฟื้อโดย Te-Won Lee" ในวิดีโอศาสตราจารย์ Ng พูดว่า
"ดังนั้นคุณอาจมองไปที่การเรียนรู้ที่ไม่มีผู้ดูแลเช่นนี้และถามว่า 'การใช้สิ่งนี้ซับซ้อนแค่ไหน?' ดูเหมือนว่าในการสร้างแอปพลิเคชันนี้ดูเหมือนว่าจะทำการประมวลผลเสียงนี้คุณจะต้องเขียนโค้ดจำนวนมากหรืออาจเชื่อมโยงไปยังไลบรารี C ++ หรือ Java จำนวนมากที่ประมวลผลเสียงดูเหมือนว่ามันจะเป็นจริงๆ โปรแกรมที่ซับซ้อนในการทำเสียงนี้: แยกเสียงออกไปและอื่น ๆ ปรากฎว่าอัลกอริทึมทำสิ่งที่คุณเพิ่งได้ยินซึ่งสามารถทำได้โดยใช้โค้ดเพียงบรรทัดเดียว ... แสดงไว้ที่นี่นักวิจัยใช้เวลานาน เพื่อสร้างโค้ดบรรทัดนี้ดังนั้นฉันไม่ได้บอกว่านี่เป็นปัญหาที่ง่าย แต่ปรากฎว่าเมื่อคุณใช้สภาพแวดล้อมการเขียนโปรแกรมที่เหมาะสมอัลกอริทึมการเรียนรู้จำนวนมากจะเป็นโปรแกรมสั้น ๆ จริงๆ "
ผลลัพธ์เสียงแยกที่เล่นในการบรรยายวิดีโอนั้นไม่สมบูรณ์แบบ แต่ในความคิดของฉันมันยอดเยี่ยมมาก ใครมีข้อมูลเชิงลึกว่าโค้ดหนึ่งบรรทัดทำงานได้ดีเพียงใด โดยเฉพาะอย่างยิ่งมีใครทราบข้อมูลอ้างอิงที่อธิบายการทำงานของ Te-Won Lee, Sam Roweis, Yair Weiss และ Eero Simoncelli เกี่ยวกับรหัสบรรทัดเดียวหรือไม่?
อัปเดต
เพื่อแสดงให้เห็นถึงความไวของอัลกอริทึมต่อระยะการแยกไมโครโฟนการจำลองต่อไปนี้ (ใน Octave) จะแยกโทนเสียงออกจากเครื่องกำเนิดโทนเสียงที่แยกจากกันสองตัว
% 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 นาทีการจำลองจะสร้างตัวเลขสามตัวต่อไปนี้ซึ่งแสดงให้เห็นว่าโทนเสียงที่แยกได้ทั้งสองมีความถี่ที่ถูกต้อง
อย่างไรก็ตามการตั้งค่าระยะห่างการแยกไมโครโฟนเป็นศูนย์ (เช่น dMic = 0) ทำให้การจำลองสร้างตัวเลขสามตัวต่อไปนี้ที่แสดงการจำลองไม่สามารถแยกโทนเสียงที่สองได้ (ยืนยันโดยคำในแนวทแยงที่มีนัยสำคัญเพียงคำเดียวที่ส่งคืนในเมทริกซ์ของ svd)
ฉันหวังว่าระยะห่างการแยกไมโครโฟนบนสมาร์ทโฟนจะใหญ่พอที่จะให้ผลลัพธ์ที่ดี แต่การตั้งค่าระยะการแยกไมโครโฟนเป็น 5.25 นิ้ว (เช่น dMic = 0.1333 เมตร) ทำให้การจำลองสร้างสิ่งต่อไปนี้น้อยกว่าการให้กำลังใจตัวเลขที่แสดงให้เห็นสูงขึ้น ส่วนประกอบความถี่ในโทนเสียงแรกที่แยกได้
x
คืออะไร มันคือสเปกโตรแกรมของรูปคลื่นหรืออะไร?