Перейти к содержанию
    

Оценить степень сходства двух фрагментов спектрограмм

Есть спектрограмма аудио-записи, на которой произнесено одно и то же слово несколько раз с некоторыми интервалами.

В качестве опорного изображения (с чем надо будет сравнивать) выделен фрагмент слога - переход с согласной на гласную: слог "ли".

Требуется пройтись по всей аудио-записи и найти ещё этот слог (опорный: "ли").  Акустическая система(микрофон, усилитель, голос диктора, ОСШ) - фиксированы.

В качестве исходных данных - используются 13 коэффициентов MFCC (самый первый - энергия фрейма).  Коэффициенты получены с окна 25 мс, перекрыш 10 мс, окно Хемминга. Был применён стандартный MEL-банк фильтров.

 

Спектрограмма в WAV-редакторе - два раза сказано одно и то же слово (опорный фрагмент - слог "ли" выделен - интервал4 окна по 25 мс ) :

1.thumb.jpg.bb7a37c12d877e020abd240449e826fb.jpg

 

Цветовая интерпретация через коэффициенты MFCC (только для визуализации, сами коэффициенты доступны в формате double/float):

ЧБ:

2.png.40aae6cb025e7d25a2e84aa78ba67335.png

Цветное:

3.png.7b6a4b9477a0affb7b90a6194d3dd914.png

 

Собственно, главный вопрос:  как оценить степень  схожести с опорным фрагментом?   Рассматривал данные как линейный массив, и делал вычисления через Евклидово расстояние, повышал степень  выше квадрата - результаты сходства/различия были, но они провлялись не так сильно.  

Читал про DTW - Dynamic Time Warping, нашёл и отладил алгоритм. Понял , что вещь полезная, но пока не могу её применить к этой задаче, так как непонятно - как сегментировать аудио-поток ?

 

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, repstosw said:

 

Собственно, главный вопрос:  как оценить степень  схожести с опорным фрагментом?   Рассматривал данные как линейный массив, и делал вычисления через Евклидово расстояние, повышал степень  выше квадрата - результаты сходства/различия были, но они провлялись не так сильно.  

 

Использовал взвешенное на первый mfcc коэфф (у меня он тоже- энергия) евклидово расстояние примерно так

        %вычисление расстояний между выборками
        %mfсс-коэффициентов.Используем взвешенное расстояние в пространстве
        %размерности N*M (N - количество кадров в словарном слове M - количество 
        %использованных mfcc коэффицентов)
        function  d = compute_distance(sig, voc)
            len = size(voc,2);
            d  = 0;
            scale = 0;
            for ii = 1:len
                %расстояние как взвешенная сумма расстояний во всех кадрах
                d_i = voc(1,ii) * dot(sig(2:end,ii) - voc(2:end,ii),...
                    sig(2:end,ii) - voc(2:end,ii));
                d = d + d_i;
                %накапливаем общую энергию слова с словаре
                scale = scale + voc(1,ii);
            end    
            d = sqrt(d /scale);    
        end
 

sig - то, что принято

voc -  словарь

Это дает

а) Независимость от уровня входного сигнала

ь) Кадры (окна), где энергия тестового слова маленькая, учитываются с меньшим весом.

DTW вроде не особо нужно в описанном случае - тестовый фрагмент у вас короткий по времени.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, andyp said:

Это дает

а) Независимость от уровня входного сигнала

ь) Кадры (окна), где энергия тестового слова маленькая, учитываются с меньшим весом.

DTW вроде не особо нужно в описанном случае - тестовый фрагмент у вас короткий по времени.

Спасибо!

Переписал функцию на C (пишу на нём):

#define NCEP    13 //число кепстральных коэффициентов (первый - энергия)

#define SAMPLE  16 //число фреймов в образце
#define TOTAL  999 //число фреймов в дорожке

double Ref[NCEP][SAMPLE];  //образец
double Test[NCEP][TOTAL];  //дорожка

double Distance(double Ref[NCEP][SAMPLE],double Test[NCEP][SAMPLE])
{
 double d=0;
 double scale=0;

 for(int i=0;i<SAMPLE;i++)
 {

  double di=0;
  for(int j=1;j<NCEP;j++)di+=pow(Test[j][i]-Ref[j][i],2.0); //расстояние как взвешенная сумма расстояний во всех кадрах
  di*=Ref[0][i];

  d+=di;
  scale+=Ref[0][i]; //накапливаем общую энергию слова в словаре
 }

 d=pow(d/scale,0.5);

 return d;
}

 

Работает.   Движение по массиву данных делаю на +1 фрейм:

for(int d=0;d<TOTAL-SAMPLES;d+=1)
{
 double dist=Distance(Ref,Test[d]);
 printf("%13.13lf\n",10.0*log(dist));
}

 

Взял логарифм с дальности и помножил на 10 (имитация в децибеллах).  Получилось вот так (график в Excel построил).  В записи одинаковое слово произнесено  10 раз.

Первый минимум-совпадение - дистанция резко в ноль (так как образец взят из части тестовой дорожки - идеальное совпадение):

image.thumb.png.9f6ee0297f172903d4944e702d34d590.png

  image.thumb.png.5fa2e128268aee7c73a077c1c5110995.png

 

 

Какие будут замечания,  дополнения?

 

1). Какой должен быть шаг движения по массиву MFCC ?  Сейчас сдвиг на +1 фрейм - на 1 сравнение.

2). Какие требования к числу фреймов образца? Сейчас взято 16 фреймов, что соответствует длительности 0,16 секунд.

3). Для распознавания лучше использовать дифоны вместо фонем?  КМК применять дифоны разумнее: переход одной фонемы в другую - минимум времени и максимум признаков для различия.

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 hours ago, repstosw said:

1). Какой должен быть шаг движения по массиву MFCC ?  Сейчас сдвиг на +1 фрейм - на 1 сравнение.

2). Какие требования к числу фреймов образца? Сейчас взято 16 фреймов, что соответствует длительности 0,16 секунд.

3). Для распознавания лучше использовать дифоны вместо фонем?  КМК применять дифоны разумнее: переход одной фонемы в другую - минимум времени и максимум признаков для различия.

 

1. Я тоже анализировал для каждого окна. Т.е. для Вашего случая полз по выходным данным с шагом 10 мс. Этот параметр можно подбирать -  метрика увеличится для большего шага (перекрытия), но если удастся выставить порог, то ОК - меньше считать придется.

2. Завист от цели всего этого. Если цель - распознавать фикс.  набор слов, то длина образца  подбирается так, чтобы метрики наиболее сильно отличались для отдельных слов  набора.   У меня длина слов в словаре была примерно 500 мс. Если у вас живой диктор, а не повторы записи, то тут уже DTW может потребоваться.

3. Не знаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 hours ago, andyp said:

2. Завист от цели всего этого. Если цель - распознавать фикс.  набор слов, то длина образца  подбирается так, чтобы метрики наиболее сильно отличались для отдельных слов  набора.   У меня длина слов в словаре была примерно 500 мс. Если у вас живой диктор, а не повторы записи, то тут уже DTW может потребоваться.

Цель: разметка звуковой записи на фонемы или дифоны.  При этом, как было указано в нуль-посте: акустический тракт, диктор, скорость и интонация одинаковы.

 

Однако, пока не получил сильного контраста между похожими слогами:  сделал новую запись - "лифт, лев, лифт, лев, лифт, лев, лев, лифт, лифт, лев" и сделал сравнениее с опорным слогом "ли" и "ле". (по 20 фреймов 10 мс)

Дистанции по опорному "ли":

image.thumb.png.62d266a214edc072703100ee87b07b77.png

Дистанции по опорному "ле":

image.thumb.png.893c2bdbb1f3078c57d6d013f5bec0bc.png

 

Ну тоесть выходит, что когда находятся дистанции по опорному слогу "ли", то различия с похожим "ле" - не сильно велики.

При этом, алгоритм учитывает только вес (энергию) по опоре. А энергия в самом треке - не учитывается. А надо бы учесть...

 

Ну и чисто визуально слоги ЛИ и ЛЕ на спектрограмме глазом более различимы, чем высчитанные выше дистанции:

                              ЛИ                                                                         ЛЕ

image.png.60fd6bee6f05b73e3ee93079018ed00e.png  image.png.b5a76cdf47ef1d002f9c293528a42b9c.png

 

Должен быть алгоритм, который даёт большую степень различия между этими слогами.

 

А если вместо MFCC перейти к LPC коэффициентам или линейным спектральным парам LSF/LSP? По ним различия будут более эффективны, чем MFCC?

Или вместе  с MFCC использовать.

Пишут ещё про дерривативы - скорость и ускорение MFCC: dMFCC, ddMFCC. Пробовал по ним строить различия - отношение "сигнал/шум" не изменилось.

Дерривативы считал как разность между соседними фреймами: 

dMFCC[j][i] = MFCC[j][i-1] - MFCC[j][i+1]

 

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

repstosw

Должен быть алгоритм, который даёт большую степень различия между этими слогами.

Считайте расстояния, где ЛИ и ЛЕ различаются между собой, с большим весом, где не отличаются с нулевым.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Quote

При этом, алгоритм учитывает только вес (энергию) по опоре. А энергия в самом треке - не учитывается. А надо бы учесть...

Quote

Ну и чисто визуально слоги ЛИ и ЛЕ на спектрограмме глазом более различимы, чем высчитанные выше дистанции:

В самом треке плохо энергию учитывать имхо. Тогда расстояния от тихих и громких слов будут отличаться. 

Может статься,  И и Е  в один фильтр банка бумкают. Попробуйте больше коэффициентов, ограничьте полосу 3-4 кГц. Ещё, метрика увеличивается, когда принятое слово и словарное сдвинуты по времени, но тут все ОК должно быть - 10 мс ничем

 

 

Изменено пользователем andyp

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пришёл к выводу, что пока рано распознавать фонемы, для начала нужно сделать сегментацию - выделить межфонемные переходы.

КМК это сделать будет эффективно с помощью вейвлет-разложений, в них искать резкие изменения производных.

http://msm.omsu.ru/jrns/jrn23/VishnyakovaLavrov.pdf

Сегментация нужна хотя бы для того, чтобы знать в каких границах искать фонему.

 

Оно всё в теории смотрится красиво, а на практике как всегда придёстя подбирать пороги срабатывания и экпериментировать с коэффициентами.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...