Внедрение алгоритма SVD для вечеринки… в одной строке кода?

55

В слайде в вводной лекции по компьютерному обучению Стэнфорда Эндрю Нг в 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 минут выполнения на моем ноутбуке симуляция генерирует следующие три цифры, иллюстрирующие два изолированных тона, которые имеют правильные частоты.

Изображение 525Изображение 526Изображение 527

Однако установка расстояния разделения микрофона до нуля (т.е. dMic = 0) заставляет симуляцию вместо этого генерировать следующие три цифры, иллюстрирующие симуляцию, не может изолировать второй тон (подтвержденный одним значительным диагональным термином, возвращаемым в svd s матрица).

Изображение 528Изображение 529Изображение 530

Я надеялся, что расстояние для ветки микрофона на смартфоне будет достаточно большим для получения хороших результатов, но установление расстояния разделения микрофона до 5,25 дюймов (т.е. dMic = 0,1333 м) заставляет моделирование генерировать следующие, менее обнадеживающие, цифры, иллюстрирующие компоненты более высокой частоты в первом изолированном тоне.

Изображение 531Изображение 532Изображение 533

  • 1
    У меня смутные воспоминания об этой лекции, но я не могу вспомнить, что такое x ; это спектрограмма сигнала или как?
  • 0
    Профессор Нг, во время t = 5:30 во вводном видео 4 по обучению без учителя, кажется, предполагает, что x является вектором аудиосэмплов. Возможно, этот раздел repmat в аргументе svd реализует некоторую нормализацию мощности сигнала.
Теги:
linear-algebra
numerical-methods
octave
svd

2 ответа

16
Лучший ответ

Я тоже пытался понять это, 2 года спустя. Но я получил ответы; надеюсь, это поможет кому-то.

Вам нужно 2 аудиозаписи. Вы можете получить примеры аудио из http://research.ics.aalto.fi/ica/cocktail/cocktail_en.cgi.

ссылка для реализации http://www.cs.nyu.edu/~roweis/kica.html

ok, здесь код -

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

Изображение 6292

  • 0
    Можете ли вы найти ссылку, которая более четко объясняет обоснование этой строки кода?
  • 0
    Не могли бы вы объяснить, как работает микширование сигналов внутри предоставленной вами ссылки? Используя ваш код, полезно извлечь два источника звука из двух смешанных файлов, загруженных с сайта. Однако, когда я пытаюсь смешать два отдельных сигнала вместе, кажется, что алгоритм не может вывести правильный результат. Я использую наивный способ получения смешанных сигналов: mic1 = 0.3 * track1 + 0.5 * track2, mic2 = 0.5 * track1 + 0.3 * track2. Это сигнал, который я пытался передать алгоритму. Большое спасибо!
Показать ещё 2 комментария
13

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, то u*s_new*v' образует голос одного человека, где s_new совпадает с s, за исключением того, что все элементы в (3:end,3:end) устранены.

Две статьи о звуковой матрице и SVD для вашей справки.

  • 1
    gregS, математически матрица x размером 2 × 2 все еще может сформировать X с помощью операции repmat. Однако спектрограмма может показывать только канал каждый раз. Поэтому я думаю, что имеет больше смысла использовать n-на-1 x каждый раз, и рассматривать проблему как линейную регрессию (два матричных уравнения). Еще два возможных подхода: (i) усреднить два канала как n-на-2 x; или (ii) связать их вместе, чтобы построить 2 * n-на-2 x.
  • 0
    вы можете обновить ваш экспериментальный прогресс!
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню