Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[34.231.180.210] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Доброго времени суток. Просмотрев от начала и до конца раздел "Речевые Технологии" в поиске информации по распознаванию речи, многое для себя уяснил. Но после того, когда начал реализацию, появились некоторые вопросы, надеюсь кто-то сможет прояснить.
Пытаюсь реализовать распознавание одного слова, для этого было записано два варианта этого слова с разной интонацией. Получил 2 файла ~1c, частота дискретизации 16кГц, 16бит. Далее пользуюсь DSP-библиотекой Aquila (github.com/zsiciarz/aquila) разбиваю весь wav файл окном с половинным перекрытием (окно ~20мс), к полученным отрезкам применяю ДПФ, перевожу на мел шкалу, делаю дискретное косинусное преобразование. Получаю по 12 MFCC векторов для каждого отрезка (Значения этих коэффициентов меня больше всего смущают, т.к. получаются большие как положительные, так и отрицательные).Аналогичный алгоритм применяю над вторым файлом. Далее пытаюсь применить DTW с помощью Евклидова расстояния для наборов отрезков из файла 1 и файла 2. Результаты получаю совсем не правдоподобные . Пытаюсь понять где ошибка, возможно она всплывет после этих вопросов: 1. Нужно ли производить нормирование сигнала? 2. Какие значения примерно имеют MFCC коэффициенты? 3. Какое значение должно быть после сравнение DTW, чтобы принять решение о правильности распознавания. Буду признателен за любую помощь. |
Сообщ.
#2
,
|
|
|
Цитата 1. Нужно ли производить нормирование сигнала? Нормировать нужно не сигнал, а MFCC коэффициенты. Вычитать среднее. Цитата 2. Какие значения примерно имеют MFCC коэффициенты? Значения зависят от параметров. Они могут быть и положительными, и отрицательными. 8.693 1.382 0.202 0.412 -0.895 -0.527 0.005 -0.417 -0.101 0.113 8.446 1.356 0.229 0.471 -0.889 -0.496 0.001 -0.477 -0.102 0.118 8.202 1.337 0.317 0.441 -0.795 -0.477 -0.075 -0.495 -0.079 0.151 8.083 1.186 0.430 0.375 -0.735 -0.419 -0.091 -0.533 -0.074 0.121 8.155 1.184 0.376 0.356 -0.753 -0.427 -0.094 -0.547 -0.002 0.098 8.644 1.221 0.284 0.295 -0.885 -0.479 -0.040 -0.462 -0.024 0.064 9.417 1.249 0.150 0.165 -1.004 -0.543 0.057 -0.354 0.001 0.092 10.137 1.239 -0.082 -0.018 -1.049 -0.501 0.182 -0.313 0.065 0.070 10.700 1.220 -0.345 -0.175 -1.023 -0.358 0.266 -0.230 -0.113 0.111 11.269 1.086 -0.528 -0.299 -0.852 -0.271 0.343 -0.287 -0.280 0.114 11.571 0.986 -0.806 -0.205 -0.618 -0.265 0.307 -0.375 -0.383 0.302 11.476 1.072 -1.116 -0.057 -0.358 -0.319 0.168 -0.325 -0.447 0.414 Цитата 3. Какое значение должно быть после сравнение DTW, чтобы принять решение о правильности распознавания. Чтобы протестировать DTW нужно убедиться в следующих фактах: 1. DTW от одинаковых файлов должно быть 0 2. DTW от похожих файлов должно быть меньше DTW от непохожих файлов. Чем больше файлы похожи, тем меньше должно быть расстояние DTW. Далее, используя похожие и непохожие файлы, нужно экспериментально подобрать порог значения, при котором считать, что слово обнаружено. |
Сообщ.
#3
,
|
|
|
nsh, спасибо за ответ. Усреднив коэффициенты для всех отрезков, получаю такой результат:
Схожесть между файлами прослеживается, DTW одинаковых файлов равно 0, DTW похожих файлов меньше, чем при сравнении разных файлов, но ненамного (Например при похожих файлах получаю расстояние 44860, а при разных файлах 68190). |
Сообщ.
#4
,
|
|
|
Цитата Усреднив коэффициенты для всех отрезков, получаю такой результат: В Вашей библиотеке ещё бы lifter не помешало бы применить после dct, чтобы придать больше значения коэффициентам высокого порядка. Результаты получше будут. Цитата Схожесть между файлами прослеживается, DTW одинаковых файлов равно 0, DTW похожих файлов меньше, чем при сравнении разных файлов, но ненамного (Например при похожих файлах получаю расстояние 44860, а при разных файлах 68190). В целом нормально это, но может быть и лучше. Этот результата с вычетом среднего или без? |
Сообщ.
#5
,
|
|
|
Цитата В целом нормально это, но может быть и лучше. Этот результата с вычетом среднего или без? Немного не понял фразу "с вычетом среднего". Я Находил среднее для каждого коэффициента по всем отрезкам (У меня 66 перекрывающихся отрезков сигнала, для каждого отрезка по 12 коэффициентов, усреднив получаю 12 коэффициентов но уже для всего файла). Возник еще вопрос, сможет ли улучшить ситуацию, если пропустить сигнал через оконную функцию, например Хемминга? |
Сообщ.
#6
,
|
|
|
Цитата Немного не понял фразу "с вычетом среднего". Я Находил среднее для каждого коэффициента по всем отрезкам (У меня 66 перекрывающихся отрезков сигнала, для каждого отрезка по 12 коэффициентов, усреднив получаю 12 коэффициентов но уже для всего файла). Чего-то Вы в алгоритме не разобрались. Файл разбивается на 66 окон, для каждого окна высчитывается 12 коэффициентов. Затем для каждого коэффициента находится среднее по всем окнам. Вычитается, в результате получается всё равно 66 окон по 12 коэффициентов. Эти 66x12 чисел подается в DTW. Если Вы в DTW подаете только 12 чисел, не удивительно, что он не работает. |
Сообщ.
#7
,
|
|
|
nsh, спасибо исправления. Будем разбираться.
Поправил программу, теперь сверяю все окна, но результаты пока не лучше, DTW от одинаковых файлов 0, а вот DTW от разных в некоторых случаях может быть меньше, чем DTW от похожих, например сравнение звуков с числами: Число1|Число2 = Расстояние DTW "Один"|"Один" (2 вариант) = 13897 "Один"|"Один" (3 вариант) = 17927 "Один"|"Один" (4 вариант) = 21856 ---------------- "Один"|"Два" = 12258 "Один"|"Три" = 10124 "Один"|"Четыре" = 21084 "Один"|"Пять" = 19774 ---------------- "Два"|"Два" (второй вариант) = 16631 "Два"|"Три" = 18693 "Два"|"Четыре" = 25692 "Два"|"Пять" = 17617 |
Сообщ.
#8
,
|
|
|
Цитата Поправил программу, теперь сверяю все окна, но результаты пока не лучше Нужно искать ошибку. Код не мешало бы показать. |
Сообщ.
#9
,
|
|
|
На данный момент у меня такой код:
Скрытый текст #include "aquila/global.h" #include "aquila/source/WaveFile.h" #include "aquila/source/SignalSource.h" #include "aquila/transform/Mfcc.h" #include "aquila/ml/Dtw.h" #include "aquila/ml/DtwPoint.h" #include "aquila/transform/FftFactory.h" #include <iostream> #include <vector> using namespace std; /* Rounding number of samples */ unsigned int RoundSize (Aquila::WaveFile& wav, int& Sample) { int SIZE = 0; if (wav.getSamplesCount()%Sample == 0) { SIZE = wav.getSamplesCount(); } else { SIZE = wav.getSamplesCount()-(wav.getSamplesCount()%Sample); } return SIZE; } /* Transform wavfile to frame matrix with double overlap */ vector< vector<double> > MatrixFromFile (Aquila::WaveFile& wav, int Row, int Col,int Window) { /* Filling the matrix */ vector< vector<double> > WindowMatrix(Row); int PairCount = 0; for(int i = 0; i < Row; i=i+2) { WindowMatrix[i].resize(Col); for(int j = 0; j < Col; ++j) { WindowMatrix[i][j] = wav.sample(PairCount++); } } int NoPairCount = Window/2; for(int i = 1; i < Row; i=i+2) { WindowMatrix[i].resize(Col); for(int j = 0; j < Col; j++) { WindowMatrix[i][j] = wav.sample(NoPairCount++); } } return WindowMatrix; } /* Calculation of Mel Frequency Cepstral Coefficients for FrameMatrix with subtracting the average */ vector< vector<double> > CalcMFCCforMatrix (vector< vector<double> >& WindowMatrix, int FFTSize, int Row) { vector< vector<double> > result (Row); for(int i = 0; i < Row; ++i) { result[i].resize(FFTSize); Aquila::SignalSource WavFromArr(WindowMatrix.at(i),16000); Aquila::Mfcc fftMFCC (FFTSize); result.at(i) = fftMFCC.calculate(WavFromArr); } /* Searching the average */ vector<double> AverangeMFCC; for(int i = 0; i < 12; ++i) { double TempSum = 0.0; for(int j = 0; j < Row; ++j) { TempSum+= result[j][i]; } AverangeMFCC.push_back(TempSum/Row); } /* Subtracting the average */ for(int i = 0; i < 12; ++i) { for(int j = 0; j < Row; ++j) { result[j][i] = (result[j][i]) - AverangeMFCC.at(i); } } return result; } int main() { Aquila::WaveFile wav("d:\\QT\\Projects\\console\\build-wav-Desktop_Qt_5_0_2_MinGW_32bit-Debug\\debug\\Numbers\\one.wav"); /* firs file */ int Window = 500; /*16kHz = 62.5uS per sample*/ unsigned int Wav1Size = RoundSize (wav,Window); /* Matrix vector< vector<double> > size: * Row - number of windows (one sample = 62.5uS, one WindowSize = sample*window, double overlap) * Column - Window*/ const int RowWav1 = 2*(Wav1Size/Window); const int ColWav1 = Window; /*Wav file to FrameMatrix*/ vector< vector<double> > WindowMatrixWav1 = MatrixFromFile (wav,RowWav1,ColWav1,Window); /* Calculation of Mel Frequency Cepstral Coefficients */ unsigned int FFTSize = 32; vector< vector<double> > Wav1MatrixMFCC = CalcMFCCforMatrix (WindowMatrixWav1,FFTSize,RowWav1); /* second file */ std::cout<<"--------"<<std::endl; Aquila::WaveFile wav2("d:\\QT\\Projects\\console\\build-wav-Desktop_Qt_5_0_2_MinGW_32bit-Debug\\debug\\Numbers\\four.wav"); unsigned int Wav2Size = RoundSize (wav2,Window); /* Matrix vector< vector<double> > size: * Row - number of windows (one sample = 62.5uS, one WindowSize = sample*window, double overlap) * Column - Window*/ const int RowWav2 = 2*(Wav2Size/Window); const int ColWav2 = Window; /*Wav file to FrameMatrix*/ vector< vector<double> > WindowMatrixWav2 = MatrixFromFile (wav2,RowWav2,ColWav2,Window); /* Calculation of Mel Frequency Cepstral Coefficients */ vector< vector<double> > Wav2MatrixMFCC = CalcMFCCforMatrix (WindowMatrixWav2,FFTSize,RowWav2); /*DTW comparison*/ Aquila::DtwDataType from, to; from = Wav1MatrixMFCC; to = Wav2MatrixMFCC; Aquila::Dtw dtw; double distance = dtw.getDistance(from, to); std::cout << "DTW distance (neighbors): " << distance << "\n"; Aquila::Dtw dtwDiag(Aquila::euclideanDistance, Aquila::Dtw::Diagonals); distance = dtwDiag.getDistance(from, to); std::cout << "DTW distance (diagonals): " << distance << "\n"; return 0; } |
Сообщ.
#10
,
|
|
|
Цитата unsigned int FFTSize = 32; Должно быть 512 для 16khz. |
Сообщ.
#11
,
|
|
|
При FFTSize = 512, получаю DTW = inf. Увеличил длительность окна до 62.5 мс, получил такие результаты:
Число1|Число2 = Расстояние DTW "Один"|"Один" (2 вариант) = 3.8e+6 "Один"|"Один" (3 вариант) = 5.9e+6 "Один"|"Один" (4 вариант) = 7.4e+6 ---------------- "Один"|"Два" = 6.1e+6 "Один"|"Три" = 3.2e+6 "Один"|"Четыре" = 6.9e+6 "Один"|"Пять" = 7.1e+6 ---------------- "Два"|"Два" (второй вариант) = 3.1e+6 "Два"|"Три" = 2.9e+6 "Два"|"Четыре" = 5.4e+6 "Два"|"Пять" = 4.3e+6 |
Сообщ.
#12
,
|
|
|
Посмотрел код, как-то он не вызывает доверия. MFCС в библиотеке неправильно вычисляется без лог-компрессии энергии. Надо смотреть ещё.
|
Сообщ.
#13
,
|
|
|
Цитата Посмотрел код, как-то он не вызывает доверия. MFCС в библиотеке неправильно вычисляется без лог-компрессии энергии. Надо смотреть ещё. Спасибо за помощь. Не встречалось ли Вам похожих библиотек с готовым функционалом? |
Сообщ.
#14
,
|
|
|
Цитата valeros @ Спасибо за помощь. Не встречалось ли Вам похожих библиотек с готовым функционалом? Поднимите взгляд к шапке сайта, там есть ссылка "Алгоритмы" |
Сообщ.
#15
,
|
|
|
уважаемый автор и формутчане ) у кого есть наработки? или готовое решение. ищу именно такое по чтоб натрененровать и понимало меня.
Добавлено прошу связаться со мной )) откликнитесь ау. |