В слайде в вводной лекции по компьютерному обучению Стэнфорда Эндрю Нг в Coursera он дает следующее однострочное решение Octave для проблемы с коктейлем, учитывая, что аудиоисточники записываются двумя пространственно разделенными микрофонами:
[W,s,v]=svd((repmat(sum(x.*x,1),size(x,1),1).*x)*x');
В нижней части слайда находится "источник: Сэм Роуис, Яир Вайс, Ээро Симончелли", а внизу слайда - "Аудиоклипы, любезно предоставленные Те-Вон Ли". Профессор Нг в видео говорит:
"Итак, вы можете посмотреть на неконтролируемое обучение, подобное этому, и спросить:" Насколько сложно реализовать это? "Похоже, что для создания этого приложения кажется, что нужно сделать эту обработку звука, вы бы написали тонну кода или, возможно, ссылку на кучу С++ или Java-библиотек, обрабатывающих аудио. Похоже, это было бы действительно сложная программа для этого аудио: отключение звука и т.д. Оказывается, алгоритм делает то, что вы только что слышали, что может быть сделано только с одной строкой кода... показано здесь. чтобы придумать эту строку кода, поэтому я не говорю, что это непростая задача. Но оказывается, что при использовании правильной среды программирования многие алгоритмы обучения будут действительно короткими программами".
Разделенные звуковые результаты, воспроизводимые в лекции, не идеальны, но, на мой взгляд, потрясающие. У кого-нибудь есть представление о том, как эта одна строка кода работает так хорошо? В частности, кто-нибудь знает ссылку, которая объясняет работу Те-Вона Ли, Сэма Роуиса, Яира Вайса и Ээро Симончелли относительно этой одной строки кода?
UPDATE
Чтобы продемонстрировать чувствительность алгоритма к расстоянию разделения микрофона, следующее моделирование (в 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 м) заставляет моделирование генерировать следующие, менее обнадеживающие, цифры, иллюстрирующие компоненты более высокой частоты в первом изолированном тоне.