【发布时间】:2013-12-23 06:13:30
【问题描述】:
在斯坦福大学的 Andrew Ng 在 Coursera 的机器学习介绍性讲座中的一张幻灯片中,鉴于音频源是由两个空间分离的麦克风记录的,他给出了以下一行 Octave 解决方案来解决鸡尾酒会问题:
[W,s,v]=svd((repmat(sum(x.*x,1),size(x,1),1).*x)*x');
幻灯片底部是“来源:Sam Roweis、Yair Weiss、Eero Simoncelli”,之前幻灯片底部是“音频剪辑由 Te-Won Lee 提供”。在视频中,吴教授说,
“所以你可能会看到这样的无监督学习并问,‘实现它有多复杂?’似乎为了构建这个应用程序,似乎要做这个音频处理,你会编写大量代码,或者可能链接到一堆处理音频的 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 的 s 中返回的单个有效对角项确认矩阵)。
我希望智能手机上的麦克风间隔距离足够大以产生良好的效果,但将麦克风间隔距离设置为 5.25 英寸(即 dMic = 0.1333 米)会导致模拟生成以下结果,这并不令人鼓舞,图示说明了第一个孤立音调中的较高频率成分。
【问题讨论】:
-
我对这次讲座的记忆模糊,但不记得
x是什么;是波形的频谱图,还是什么? -
吴教授在 t=5:30 在关于无监督学习的介绍视频 4 中似乎暗示 x 是音频样本的向量。也许 svd 参数中的 repmat 部分正在实现信号的某种功率归一化。
标签: matlab machine-learning octave linear-algebra svd