Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Алгоритмы > Вейвлет-пакет в задаче классификации |
Автор: podval 11.3.2003, 05:49 | ||
Итак, по многочисленным просьбам в теме о распознавании речи выделяю сабж в отдельный топик. Для начала имеет смысл напомнить об общей процедуре классификации, приведенной http://forum.vingrad.ru/index.php?act=ST&f=13&t=5714. Здесь только несколько слов о некоторых моментах практической реализации обсуждаемого. В основном будем придерживаться общей схемы процедуры классификации. Начнем с главного. Теорию вейвлетов можно почитать в разных источниках. Наиболее понятные мне: есть на сайте http://www.matlab.ru/wavelet/index.asp (ссылки внизу страницы). Очень толковые материалы здесь: http://www.autex.spb.ru/wavelet/, причем много в pdf. Обращаю ваше внимание на то, что здесь используем именно вейвлет-пакет. Ниже идет код функции, реализующей вейвлет-преобразование сигнала, записанного в массив sg. Для чего нужна переменная flag, скажу позже, там станет ясно. Физический смысл используемого преобразования состоит в том, что для разложения исходного сигнала по уровням используется его прореживание во временной области (для простоты скажем, разбиение на четные и нечетные отсчеты) плюс некоторые дополнительные преобразования. В частотной области это (опять же упрощенно) равносильно разбиению спектра на две половины. Применямый здесь вейвлет вряд ли вы где-либо найдете ![]()
Я здесь не привожу код алгоритма БПФ fft(...), т.к. он уже был показан, например, http://forum.vingrad.ru/index.php?act=ST&f=13&t=6185. To be continued... З.Ы. Просьба ждать терпеливо... ![]() ![]() И напоминаю, что если вам нравится, как мы общаемся, то можете оценить свое настроение по 10-балльной шкале внизу страницы ![]() |
Автор: podval 17.3.2003, 00:10 | ||||
Теперь посмотрим, как этот вейвлет-пакет выглядит. Для начала представим, что у нас в массиве wavesig имеется wavesig_dim отсчетов (в моем варианте не более 1024) сигнала. Формируем вейвлет-пакет с помощью рассмотренных выше функций.
Чтобы посмотреть собственными глазами, выводим это на форму с компонентом TPaintBox
Все еще to be continued... ![]() |
Автор: Crait 1.4.2003, 07:21 |
Podval, очень интересные статьи. Будет ли продолжение ? И вот еще вопрос - не пробовал ли ты сравнивать информативность коэффициентов вейвлет- и Фурье-спектров в процедурах обработки реальной речи ? |
Автор: podval 2.4.2003, 02:12 | ||||
Естественно, я хочу продолжить, только есть один гемморой: хочу выложить картинки, а никак. А то без картинок неинтересно.
Что имеется в виду под информативностью? Я могу сказать, что вейвлетами вытаскиваются мелкие детали окраски тембра, по которым можно однозначно идентифицировать диктора. Фурье-анализом так не сделать. А что еще интересует? |
Автор: Crait 2.4.2003, 04:56 |
Под информативностью я подразумевал вот что. (Sorry, если я хочу слишком много ![]() Сколько коэффициентов вейвлет-спектра стоит использовать в процессах идентификации (по сравнанию с количеством коэффициентов амплитудного спектра Фурье, дающим где-то сходный результат) ? Интересен был бы ответ даже на уровне "больше-меньше". При использовании спектра Фурье для обработки речи дело обстоит так, что характерная информационность сосредоточена в определенной полосе частот, либо, скажем, в первых 12 коэффициентах кепстра. Локализован ли так же вейвлет-спектр, либо для каждого диктора/фонемы по-разному ? Т.е., можно ли на практике не заниматься выделением спектральных составляющих, максимально различных для разных, хм, образов, а проводить типа просто корреляцию с набором образцов ? Далее. Точность прямого расчета Фурье-спектра в таких задачах часто оказывается недостаточной из-за ограничений на длину выборки, обусловленных нестационарностью сигнала. Как обстоят дела у вейвлетов с точностью определения характеристик при ограниченной длине выборки ? И еще. Насколько результаты вейвлет-преобразования, как бы это сказать, дикторо-зависимы, либо, наоборот, дикторо-независимы. В сравнении с Фурье, конечно. Извиняюсь за многословность... |
Автор: podval 3.4.2003, 19:54 | ||||||||||||
Ну что тут сказать?
В моих задачах получалось, что меньше. Но дело тут было еще и в точности. Точность однозначно выше.
Вейвлет более локализован.
точность, как сказано, выше. Ведь вейвлету, по большому счету, наплевать на длительность сигнала. Вейвлет локализован не только по "частоте", но и во времени.
Опять же зависит от того, как сформулировать задачу. В той задаче, что я описал, целью является опознать диктора. Если же ставить целью опознавание семантики, то тут и задачу надо формулировать немного по-другому. Я уверен, что это возможно, но я этим не занимался и не встречал пока готовых продуктов, связанных именно с обработкой речи. Видимо, еще не очень популярны вейвлеты, все-таки относительно недавно появились. Даже производители программ и некоторых игрушек типа говорящий словарь-переводчик пользуются Фурье-анализом. Просто вейвлеты только начинают приживаться. Я зато встречал публикации медиков, где с помощью вейвлетов диагностируют язву желудка по вейвлет-картинке распределения потенциалов и еще много чего. А ведь поставить диагноз - это задача, вообще говоря, "пациенто-независимая" ![]() Так что, главное - правильно формализовать задачу. Надеюсь, удовлетворил? Если что, уточняй.
![]() |
Автор: Crait 3.4.2003, 20:34 |
Спасибо, podval . Вот ты пишешь, что вейвлет локализован не только по частоте, но и во времени. А как полагаешь, не превратится ли локализация его во времени в некоторую проблему при обработке широко распространенным (в узких кругах ![]() когда входной сигнал делится на пакеты, подвергаемые уже дальнейшей обработке. В таком случае ход времени определяется номером обрабатываемого пакета, а тут еще и информация о локализации внутри пакета... Я понимаю, конечно, информация лишней не бывает, но все же - что ее, игнорировать ? Еще вот, принято ли и имеет ли смысл, как это принято в технике Фурье-преобразования, использовать оконные функции в WT ? И как ты полагаешь, как следует переформулировать задачу, чтобы обеспечить возможную при данном подходе дикторо-независимость ? Я конечно понимаю, что все это похоже на технический шпионаж ![]() ![]() |
Автор: podval 5.4.2003, 19:49 | ||||||
А разве это проблема? Сначала режешь на пакеты, а потом анализируешь вейвлетами. Или я чего-то не того?
Разные типы вейвлетов имеют разную форму и разные свойства. Использовать что-то дополнительно вроде не имеет смысла.
Думаю, надо работать с фонемами. Возможно, по тому же принципу, как и с использованием Фурье-анализа. Только вместо Фурье используешь другой аппарат - вейвлеты. Ну, может, какие-то свои тонкости появятся. Не занимался я такой задачей. Тут думать надо. |
Автор: podval 5.4.2003, 20:16 |
Вернемся к нашим баранам. Если все сделано правильно, то вейвлет-пакет должен выглядеть примерно так:![]() Здесь использовано 8 уровней разложения в вейвлет-пакет. Нулевой уровень (на рисунке он верхний) представляет собой ни что иное, как исходный сигнал. Обратите внимание, что основная энергия сигнала концентрируется в основном в низкочастотных коэффициентах (левые "половинки"). И если внимательно вглядывались в приведенный выше код (не для слабонервных ![]() Надеюсь, не очень задурил ![]() Посмотрите, вот, как может концентрироваться энергия сигнала в других участках "спектра" (надеюсь, не забыли, почему слово спектр взято в кавычки?) ![]() |
Автор: Crait 5.4.2003, 21:57 | ||
Я спросил об этом потому, что повышенная точность представления функции ограниченным рядом вейвлетов (аппроксимация) обусловлена, как мне показалось, именно тем, что используется информация не только об амплитуде, еще и о временнОм положении вейвлета. Корректно ли будет ее игнорировать и не потеряется ли при этом преимущество перед рядами Фурье? Хотя, с другой стороны, игнорируем же мы фазовую информацию, анализируя амплитудный Фурье-спектр... |
Автор: podval 6.4.2003, 15:52 | ||
Более того, мы об этом еще не говорили, но вейвлеты можно масштабировать! Если встретишь такое выражение - кратно-масштабный анализ - поинтересуйся, что это за вещь. |
Автор: podval 8.4.2003, 18:19 |
Траблы с картинками устранил. Смотрите, наслаждайтесь, и скоро поедем дальше ![]() |
Автор: podval 13.4.2003, 20:23 | ||
Вернемся к нашей задаче классификации. Наша уель сейчас - посмотреть, как формируется эталонное описание (эталон) на основе вейвлет-пакета. Используем те же функции, что рассмотрены ранее. Только теперь, когда раскладываем выборку сигнала в вейвлет-пакет, будем суммировать энергию отдельных коэффициентов. Это даст нам картинку распределения энергии сигнала. Собственно, мы такую картинку уже наблюдали (см. рисунки выше), когда рассматривали, как может концентрироваться энергия сигнала в различных участках вейвлет-спектра. Теперь только осталось просуммировать энергию отдельных коэффициентов. Поехали... ![]() Нижеследующая функция coefplan берет выборку размером all сигнала sg, раскладывает в вейвлет-пакет по уровням (level - их количество) и записывает в массив e энергии вейвлет-коэффициентов.
В принципе, ничего сложного: взяли ту самую картинку, что выше, и получили новую: ![]() |
Автор: podval 13.4.2003, 20:35 |
Для того, чтобы все имеющиеся эталоны были соизмеримы, надо их еще отнормировать к максимальному значению энергии. Тогда максимальный будет иметь значение, равное единице. В этом случае алгоритм не будет ошибаться на разнице эталонов и реальных сигналов в абсолютных значениях энергетики. |
Автор: Guest_Voland 8.5.2003, 12:30 | ||
Добрый день! Можно покоментировать этот фрагмент? Откуда берётся массив serm и какова его длинна ? Где будут результаты преобразования? В serm или sperm ? |
Автор: Guest_Voland 8.5.2003, 12:51 | ||
Ещё маленький вопрос, функция dabs из какой библиотеки взята ? |
Автор: podval 8.5.2003, 18:33 |
В serm хранится полный результат разложения в вейвлет-пакет. Его размер = (длина выборки)х(число уровней разложения). В sperm хранятся значения энергии вейвлет-коэффициентов. dabs() - это abs() для аргументов типа double. Была там в "учебных" целях. Можно fabs(). |
Автор: Воланд 8.5.2003, 19:25 |
Спасибо. Пытаюсь расскладывать звуковые файлы длиной 32000 отсчётов, результат получается странный, завтра выложу картинки, может у меня чего не того. А возможно на базе результата разложения в вейвлет-пакет построить типичный для вейвлетов трёхмерный график частота-аплитуда-время ? |
Автор: podval 8.5.2003, 19:48 | ||
|
Автор: Guest_Voland 10.5.2003, 15:05 | ||
А почему? Размеры массивов я подогнал... Или дело в особенностях реализации самого пакета? Можно конечно делить сигнал на кадры и проводить покадровое сравнение, но ето довольно громоздко. Вот мои результаты: ![]() ![]() Kaк я понимаю, дальше сравнение сигналов идёт именно на базе рассчёта расстояния Махаланобиса между образцом и еталонными сигналами. Или нужны ещё дополнителные преобразования ? |
Автор: podval 10.5.2003, 21:12 |
Расстояние считается между вот этими штуками (средний рисунок), которые у тебя названы Veivletas. Их надо получить как для эталонов (собственно, эталоны в таком виде и хранятся), так и для сигналов. Вообще по-английски так: wavelet. |
Автор: Voland_Kovno 12.5.2003, 10:07 |
Понятно. Не будет проблем с разложением массива на 32 000 отсчётов при всего восьми уровнях разложения? Совсем не хочется анализировать сигнал покадрово, так как не совсем понимаю как потом из этих кадров получать вейвлет всего сигнала. По поводу названий - просто я с такой экзотической страны, где это называется так :-) Кстати, многотысячные значения коефициентов вейвлет-разложения это нормально? Очевидно, можно провести нормализацию и откинуть часть коефициентов. |
Автор: podval 13.5.2003, 19:50 | ||||
Ну, судя по рисункам, получается же. Только все равно зачем так много?
Я об этом уже сказал. Так и надо делать. |
Автор: Voland_Kovno 3.6.2003, 16:16 |
День добрый. Ну вот, возвращаясь к данной теме - допустим имеем исходный сигнал, сканируем его кадром в 1024 отсчёта, осуществляем вейвлет-преобразование каждого кадра, в результате мы имеем последовательность эталонов для анализируемого сигнала. Вопрос в том, как мы эти эталоны будем сравнивать ( не между собой, конечно, а с аналогичной последовательностью другого сигнала). Очевидно, что покадровое сравнение успеха иметь не будет и придётся прибегать к нелинейной нормализации времени методом динамического программирование ( короче - DTW ) Этот способ совсем даже ничего, только боюсь что его использование сведёт на нет все достоинства вейвлетов. Или каким-то образом мы из набора эталонов составляем общий для всего сигнала эталон. Вот об этом и давайте поговорим - каким образом мы преобразуем набор кадровых эталонов в эталон всего сигнала ? |
Автор: podval 3.6.2003, 18:09 | ||||
В моей задаче этого не надо было делать, т.к. для распознавания диктора достаточно иметь подробную информацию в частотной области. Если же все-таки думать над вопросом,
![]() Я бы сформировал из последовательностей матрицы и искал расстояние между ними. |
Автор: Voland_Kovno 4.6.2003, 09:37 | ||
Не совсем понял - весь сигнал помещался в 1024 отсчёта? Или вейвлет-преобразованием раскладывался не сам сигнал, а его уже готовое преобразование ? Откровенно говоря, в результате экспериментов с данным вами кодом у меня возникло смутное подозрение что функция вейвлет-преобразования уже "настроена" на выделение особенностей речи диктора - так как при записи эталонов от одного диктора они все! получаются довольно похожими, а вот те же эталоны от другого диктора выглядят совершенно подругому. Может это я в мистику ушёл и всё дело в некорректности работы алгоритма в моих условиях ( я всё-таки раскладываю сигнал длинной ни менее 10 000 отсчётов, без увеличения уровня разложения, а одно от другого всё-таки зависит.) Просто в самой функции заданы определённые константы - явно экспериментально - так что наверно только автор сможет объяснить что это за константы и как их подбирать. Идея с формированием матриц довольно интересная, постараюсь попробовать реализацию. Может у кого-нибудь есть информация о работе с матрицами под с++, а то как-то лень писать функции обращения и умножения. |
Автор: podval 4.6.2003, 09:51 | ||||||||
Из всего сигнала бралось только 1024 отсчета. Для выделения частотных особенностей этого предостаточно. И использовался не вейвлет, а ВЕЙВЛЕТ-ПАКЕТ.
Вот это как раз и не удивительно. Мы же хотим распознать ДИКТОРОВ, а не СЛОВА.
|
Автор: Voland_Kovno 4.6.2003, 10:57 |
Понятно. Дело ясное что дело тёмное. Решаемая задача - система управления голосом на базе сигнального процессора, реализованая с использованием перспективных алгоритмов распознавания. Идея немного поэкспериментировать, насколько получится "засунуть" современные эффективные алгоритмы распознавания речи в сигнальный процессор типа TI320C5x и посмотреть что это даст. В идеале должна получится дикторонезависимая система с большим набором команд для управления сложными устройствами. В реале пока получается довольно печально... |
Автор: podval 5.6.2003, 10:38 |
К сожалению, дикторонезависимыми системами не занимался. Рекомендую обратиться на http://dsp-book.narod.ru/ |
Автор: Voland_Kovno 14.12.2004, 11:47 |
День добрый. Возвращаюсь к давно забытым баранам. Кратко анализируя алгоритм, предложенный уважаемым podval`ом, должен отметить что это супер замечательный алгоритм верификации диктора, но для распознавания речи он обсолютно не подходит. Дело в том, что разница между эталонами различных дикторов на порядок больше чем между эталонами одного и того-же диктора, что бы он в микрофон не бубнел. Прелесть ещё и в том что сравнение можно проводить примитивным вычитанием одного эталона из другого, потом считаем суммру результата и получаем оценку свой-чужой. При длинне 2000 отсчётов работает с такой точностью что суммарные энергии разных дикторов отличаются в 10 (!) раз от суммарных энергий одного диктора. Знать бы как этому вейвлету мозги подкрутить... |
Автор: podval 14.12.2004, 16:57 | ||||
Так я ведь об этом говорил ![]() Только, возможно, не в этой теме.
А что требуется сделать? |
Автор: Воланд 16.12.2004, 19:06 |
Коефициенты уезжают сильно влево - такое чувство что алгоритму сигнал слишком неинформативен. В результате неточность сравнения. Пытался умненьшать частоту дискретизации - но всё равно - всё в левой части даже при 6000 Hz, сигнал длинной 2036 ед. |
Автор: podval 16.12.2004, 19:42 | ||
Сразу вопрос: использовался вейвлет-пакет или просто вейвлет-преобразование? Если это обычное вейвлет-преобразование, то что здесь удивительного? На каждом уровне мы выполняем свертку только с НЧ-фильтром. |
Автор: eldo 9.1.2005, 22:51 |
А не подскажете, насколько похоже надо говорить в микрофон, т.е можно ли петь или там другим голосом? А то у меня почему-то больше похожи получаются коэффициенты там, где 2 диктора говорят одно и то же, а не там где один диктор разные вещи говорит ![]() Ничего не понимаю... Может я что-то не так делаю? И еще вопрос: Вот эти коэффициенты, которые мы получаем не похожи ли на разложение в ряд фурье? Ведь получаем тоже зависимость Энергий от частоты... И еще забыл спросить, как говорил Колумбо ![]() Большое спасибо |
Автор: podval 9.1.2005, 23:07 | ||||
И даже нужно ![]() Вообще для распознавания голосов не мешало бы еще и кепстр вычислить и сравнивать уже кепстральные коэффициенты.
О взаимосвязи этих преобразований есть в любом учебнике по вейвлетам. Расстояние Махаланобиса: Dm = [(X1-X2)'*inv(S)*(X1-X2)], где X1, X2 - векторы средних для матриц М1 и М2, S - объединенная ковариационная матрица, inv - операция обращения матриц, ' - операция транспонирования. Объединенная ковариационная матрица считается так: S = (Cov1 + Cov2)/(n1 + n2 - 2), где Cov1 = M1'*M1, Cov2 = M2'*M2. n1, n2 - длины X1, X2. |
Автор: eldo 9.1.2005, 23:34 | ||
По поводу кепстра. Я стока мучаюсь, ищу, ищу, никак не могу понять. Это ж вроде как обратное преобразование Фурье от логарифма преобразования фурье? Если так то мы ж получаем тот же самый сигнал, что был раньше тока по модулю и с меньшей амплитудой? Или я не прав? ЗЫ Спасибо за ответ |
Автор: podval 10.1.2005, 07:04 |
Кепстр - это косинус-преобразование. |
Автор: podval 10.1.2005, 16:08 |
eldo Новые вопросы, не касающиеся вейвлет-пакетов, следует задавать в отдельной теме. Один вопрос - одна тема. |