Этот пример демонстрирует подход машинного обучения, чтобы идентифицировать людей на основе функций, извлеченных из записанной речи. Функции, использованные, чтобы обучить классификатор: подача речевых сегментов речи и Коэффициенты кепстра Mel-частоты (MFCC). Это - идентификация динамика замкнутого множества - аудио динамика под тестом сравнено со всеми доступными моделями динамика (конечное множество), и самое близкое соответствие возвращено.
Подход, используемый в этом примере для идентификации динамика, показывают в схеме.
Подача и Коэффициенты кепстра Mel-частоты (MFCC) извлечены от речевых сигналов, зарегистрированных для 10 динамиков. Эти функции используются, чтобы обучить классификатор Соседа K-Nearest (KNN). Затем новые речевые сигналы, которые должны быть классифицированы, проходят то же выделение признаков. Обученный классификатор KNN предсказывает, какой из этих десяти динамиков является самым близким соответствием.
В этом разделе рассматриваются подачу и Коэффициенты Кепстра Mel-частоты (MFCCs), две функции, которые используются, чтобы классифицировать динамики.
Подача
Речь может быть широко категоризирована, как озвучено и неречевая. В случае речевой речи воздух от легких модулируется голосовыми связками и результатами в квазипериодическом возбуждении. Получившийся звук во власти относительно низкочастотного колебания, называемого подачей. В случае неречевой речи воздух от легких проходит через сжатие в речевом тракте и становится бурным, подобным шуму возбуждением. В модели фильтра источника речи возбуждение упоминается как источник, и речевой тракт упоминается как фильтр. Охарактеризование источника является важной частью охарактеризования речевой системы.
Как пример речевой и неречевой речи, рассмотрите представление временного интервала слова "два" (/T UW/). Согласный/T/(неречевая речь) похож на шум, в то время как гласный/UW/(речевая речь) характеризуется сильной основной частотой.
[audioIn, fs] = audioread('Counting-16-44p1-mono-15secs.wav'); twoStart = 110e3; twoStop = 135e3; audioIn = audioIn(twoStart:twoStop); timeVector = linspace((twoStart/fs),(twoStop/fs),numel(audioIn)); figure; plot(timeVector,audioIn); axis([(twoStart/fs) (twoStop/fs) -1 1]); ylabel('Amplitude'); xlabel('Time (s)'); title('Utterance - Two'); sound(audioIn,fs);
Самый простой метод, чтобы различать речевую и неречевую речь должен анализировать нулевой уровень пересечения. Большое количество нулевых пересечений подразумевает, что нет никакого доминирующего низкочастотного колебания.
Если вы изолируете область речевой речи, можно охарактеризовать ее путем оценки подачи. Этот пример использует pitch
, чтобы оценить подачу. Это использует нормированный подход автокорреляции значения по умолчанию к вычислению подачи.
Примените обнаружение подачи к слову "два", чтобы видеть, как подача изменяется в зависимости от времени. Это является известным как контур подачи и является характеристическим динамику.
pD = audiopluginexample.SpeechPitchDetector; [~,pitch] = process(pD,audioIn); figure; subplot(2,1,1); plot(timeVector,audioIn); axis([(110e3/fs) (135e3/fs) -1 1]) ylabel('Amplitude') xlabel('Time (s)') title('Utterance - Two') subplot(2,1,2) plot(timeVector,pitch,'*') axis([(110e3/fs) (135e3/fs) 80 140]) ylabel('Pitch (Hz)') xlabel('Time (s)'); title('Pitch Contour');
Коэффициенты кепстра Mel-частоты (MFCC)
Коэффициенты кепстра Mel-частоты (MFCC) являются популярными функциями, извлеченными от речевых сигналов для использования в задачах распознавания. В модели фильтра источника речи MFCCs, как понимают, представляют фильтр (речевой тракт). Частотная характеристика речевого тракта относительно сглаженна, тогда как источник речевой речи может быть смоделирован как импульсный train. Результат состоит в том, что речевой тракт может быть оценен спектральным конвертом речевого сегмента.
Идея мотивации MFCC состоит в том, чтобы сжать информацию о речевом тракте (сглаживавший спектр) в небольшое количество коэффициентов на основе понимания улитки уха.
Несмотря на то, что нет никакого твердого стандарта для вычисления MFCC, основные шаги обрисованы в общих чертах схемой.
mel filterbank линейно располагает первые 10 треугольных фильтров с интервалами и логарифмически располагает остающиеся фильтры с интервалами. Отдельные полосы взвешиваются для даже энергии. Ниже визуализация типичного mel filterbank.
Этот пример использует mfcc
, чтобы вычислить MFCCs для каждого файла.
Речевой сигнал является динамическим по своей природе и изменяется в зависимости от времени. Это принято, что речевые сигналы стационарные в кратковременных шкалах, и их обработка сделана в окнах 20-40 мс. Этот пример использует окно на 30 мс с 75%-м перекрытием.
Этот пример использует Базу данных переписи (также известный как Базу данных AN4) от CMU Robust Speech Recognition Group [1]. Набор данных содержит записи участников эксперимента и участниц эксперимента, произносящих слова и числа. Функция помощника в этом разделе загружает его для вас и преобразовывает необработанные файлы в flac. Речевые файлы разделены в подкаталоги на основе меток, соответствующих динамикам. Если вы не можете загрузить его, можно загрузить таблицу функций от HelperAN4TrainingFeatures.mat
и перейти непосредственно к разделу Training a Classifier. Функции были извлечены от того же набора данных.
Загрузите и извлеките речевые файлы для 10 динамиков (5 розеток и 5 штекеров) во временную директорию с помощью функции HelperAN4Download
.
dataDir = HelperAN4Download; % Path to data directory
Downloading AN4 dataset... done. Reducing dataset to 5 females and 5 males... done.
Создайте объект audioDatastore
легко управлять этой базой данных для обучения. Datastore позволяет вам собирать необходимые файлы формата файла и читать их.
ads = audioDatastore(dataDir, 'IncludeSubfolders', true,... 'FileExtensions', '.flac',... 'LabelSource','foldernames')
ads = audioDatastore with properties: Files: { ' ...\bhemmat\AppData\Local\Temp\an4\wav\flacData\fejs\an36-fejs-b.flac'; ' ...\bhemmat\AppData\Local\Temp\an4\wav\flacData\fejs\an37-fejs-b.flac'; ' ...\bhemmat\AppData\Local\Temp\an4\wav\flacData\fejs\an38-fejs-b.flac' ... and 122 more } Labels: [fejs; fejs; fejs ... and 122 more categorical] AlternateFileSystemRoots: {} ReadFailureRule: 'error' MaxFailures: Inf OutputDataType: 'double'
Метод splitEachLabel
audioDatastore
разделяет datastore в два или больше хранилища данных. Получившиеся хранилища данных имеют заданную пропорцию звуковых файлов от каждой метки. В этом примере datastore разделен в две части. 80% данных для каждой метки используются для обучения, и остающиеся 20% используются для тестирования. Метод countEachLabel
audioDatastore
используется, чтобы считать количество звуковых файлов на метку. В этом примере метка идентифицирует динамик.
[trainDatastore, testDatastore] = splitEachLabel(ads,0.80);
Отобразите datastore и количество динамиков в datastore train.
trainDatastore trainDatastoreCount = countEachLabel(trainDatastore)
trainDatastore = audioDatastore with properties: Files: { ' ...\bhemmat\AppData\Local\Temp\an4\wav\flacData\fejs\an36-fejs-b.flac'; ' ...\bhemmat\AppData\Local\Temp\an4\wav\flacData\fejs\an37-fejs-b.flac'; ' ...\bhemmat\AppData\Local\Temp\an4\wav\flacData\fejs\an38-fejs-b.flac' ... and 94 more } Labels: [fejs; fejs; fejs ... and 94 more categorical] AlternateFileSystemRoots: {} ReadFailureRule: 'error' MaxFailures: Inf OutputDataType: 'double' trainDatastoreCount = 10×2 table Label Count _____ _____ fejs 10 fmjd 10 fsrb 10 ftmj 10 fwxs 10 mcen 10 mrcb 10 msjm 10 msjr 10 msmn 7
Отобразите datastore и количество динамиков в тестовом datastore.
testDatastore testDatastoreCount = countEachLabel(testDatastore)
testDatastore = audioDatastore with properties: Files: { ' ...\bhemmat\AppData\Local\Temp\an4\wav\flacData\fejs\cen6-fejs-b.flac'; ' ...\bhemmat\AppData\Local\Temp\an4\wav\flacData\fejs\cen7-fejs-b.flac'; ' ...\bhemmat\AppData\Local\Temp\an4\wav\flacData\fejs\cen8-fejs-b.flac' ... and 25 more } Labels: [fejs; fejs; fejs ... and 25 more categorical] AlternateFileSystemRoots: {} ReadFailureRule: 'error' MaxFailures: Inf OutputDataType: 'double' testDatastoreCount = 10×2 table Label Count _____ _____ fejs 3 fmjd 3 fsrb 3 ftmj 3 fwxs 2 mcen 3 mrcb 3 msjm 3 msjr 3 msmn 2
Чтобы предварительно просмотреть содержимое вашего datastore, считайте файл примера и проигрывайте его с помощью аудио устройства по умолчанию.
[sampleTrain, info] = read(trainDatastore); sound(sampleTrain,info.SampleRate)
Чтение от datastore train продвигает указатель чтения так, чтобы можно было выполнить итерации через базу данных. Сбросьте datastore train, чтобы возвратить указатель чтения на запуск для следующего выделения признаков.
reset(trainDatastore);
Сделайте подачу и функции MFCC извлечены от каждого кадра с помощью HelperComputePitchAndMFCC
, который выполняет следующие действия с данными, считанными из каждого звукового файла:
Соберите выборки в кадры 30 мс с перекрытием 75%.
Для каждого кадра используйте audiopluginexample.SpeechPitchDetector.isVoicedSpeech
, чтобы решить, соответствуют ли выборки речевому речевому сегменту.
Вычислите подачу и 13 MFCCs (с первым коэффициентом MFCC, замененным логарифмической энергией звукового сигнала) для целого файла.
Сохраните подачу и информацию MFCC, имеющую отношение к речевым кадрам только.
Получите имя каталога для файла. Это соответствует имени динамика и будет использоваться в качестве метки для обучения классификатор.
HelperComputePitchAndMFCC
возвращает таблицу, содержащую имя файла, подачу, MFCCs и метку (имя динамика) как столбцы для каждого кадра на 30 мс.
lenDataTrain = length(trainDatastore.Files); features = cell(lenDataTrain,1); for i = 1:lenDataTrain [dataTrain, infoTrain] = read(trainDatastore); features{i} = HelperComputePitchAndMFCC(dataTrain,infoTrain); end features = vertcat(features{:}); features = rmmissing(features); head(features) % Display the first few rows
ans = 8×16 table Filename Pitch MFCC1 MFCC2 MFCC3 MFCC4 MFCC5 MFCC6 MFCC7 MFCC8 MFCC9 MFCC10 MFCC11 MFCC12 MFCC13 Label __________________ ______ _______ ______ _______ _______ _______ _________ _________ ________ _______ _________ ________ ________ _________ ______ 'an36-fejs-b.flac' 238.81 -4.4218 3.3816 0.73331 0.98626 0.47093 0.13808 -0.083348 0.069072 0.2345 0.3403 -0.14417 -0.15685 0.022186 'fejs' 'an36-fejs-b.flac' 235.29 -4.3104 4.7899 0.80432 0.7148 0.46027 0.032963 -0.28647 0.38366 0.1449 0.0093271 -0.2559 -0.17832 -0.11693 'fejs' 'an36-fejs-b.flac' 231.88 -3.6432 5.0192 0.74801 0.58299 0.50475 -0.014551 -0.32653 0.39201 0.20982 -0.20282 -0.25637 -0.20576 -0.27675 'fejs' 'an36-fejs-b.flac' 115.94 -3.0934 5.132 0.46794 0.57104 0.64546 -0.085145 -0.22453 0.55408 0.14131 -0.17966 -0.17135 -0.22111 -0.22027 'fejs' 'an36-fejs-b.flac' 112.68 -2.9718 5.3249 0.48934 0.66976 0.56446 -0.14691 -0.26824 0.4536 0.31515 -0.21356 -0.34067 -0.21872 -0.14108 'fejs' 'an36-fejs-b.flac' 111.89 -2.6202 5.2746 0.53966 0.55468 0.50989 0.012264 -0.26755 0.3318 0.32108 -0.18096 -0.44212 -0.21208 -0.21385 'fejs' 'an36-fejs-b.flac' 111.11 -2.6138 5.0492 0.68513 0.40281 0.36792 0.13352 -0.07321 0.25863 0.25314 -0.1787 -0.51149 -0.14679 -0.077431 'fejs' 'an36-fejs-b.flac' 110.34 -2.4483 5.5192 0.64449 0.44857 0.25178 0.25716 0.042426 0.32466 0.17774 -0.194 -0.70127 -0.16868 -0.041083 'fejs'
Заметьте, что подача и MFCC не находятся в той же шкале. Это сместит классификатор. Нормируйте функции путем вычитания среднего значения и деления стандартного отклонения каждого столбца.
featureVectors = features{:,2:15};
m = mean(featureVectors);
s = std(featureVectors);
features{:,2:15} = (featureVectors-m)./s;
head(features) % Display the first few rows
ans = 8×16 table Filename Pitch MFCC1 MFCC2 MFCC3 MFCC4 MFCC5 MFCC6 MFCC7 MFCC8 MFCC9 MFCC10 MFCC11 MFCC12 MFCC13 Label __________________ ________ ________ _______ _________ ________ _______ ________ ________ _________ _______ _________ ________ ________ ________ ______ 'an36-fejs-b.flac' 1.1217 -1.8778 0.11469 0.25866 -0.41449 0.97803 -0.34062 -0.22379 -0.031962 0.62995 0.81708 -0.29036 -0.47 -0.04532 'fejs' 'an36-fejs-b.flac' 1.0631 -1.8143 1.2196 0.32634 -0.65383 0.9623 -0.52854 -0.61983 0.70533 0.40654 -0.066892 -0.60354 -0.53907 -0.51924 'fejs' 'an36-fejs-b.flac' 1.0061 -1.4342 1.3996 0.27266 -0.77005 1.0279 -0.61349 -0.69793 0.72491 0.56842 -0.6335 -0.60484 -0.62735 -1.0637 'fejs' 'an36-fejs-b.flac' -0.93058 -1.1209 1.4881 0.0057061 -0.78058 1.2356 -0.7397 -0.49906 1.1048 0.39759 -0.57164 -0.36655 -0.67672 -0.87127 'fejs' 'an36-fejs-b.flac' -0.98514 -1.0516 1.6394 0.026102 -0.69355 1.116 -0.85012 -0.58429 0.86925 0.83105 -0.66218 -0.84113 -0.66903 -0.60151 'fejs' 'an36-fejs-b.flac' -0.9983 -0.85121 1.5999 0.074074 -0.79501 1.0355 -0.56555 -0.58294 0.5838 0.84584 -0.57511 -1.1255 -0.64767 -0.8494 'fejs' 'an36-fejs-b.flac' -1.0113 -0.8476 1.4231 0.21274 -0.92891 0.82602 -0.34877 -0.20402 0.41231 0.67644 -0.56908 -1.3199 -0.43764 -0.38468 'fejs' 'an36-fejs-b.flac' -1.0241 -0.75325 1.7918 0.174 -0.88856 0.65463 -0.12772 0.021446 0.56706 0.48842 -0.60995 -1.8518 -0.50805 -0.26085 'fejs'
Теперь, когда вы собрали функции всех десяти динамиков, можно обучить классификатор на основе их. В этом примере вы используете соседний классификатор K-nearest. Сосед K-nearest является методом классификации, которому естественно удовлетворяют для классификации мультиклассов. Гиперпараметры для самого близкого соседнего классификатора включают количество самых близких соседей, метрика расстояния раньше вычисляла расстояние до соседей и вес метрики расстояния. Гиперпараметры выбраны, чтобы оптимизировать точность валидации и производительность на наборе тестов. В этом примере номер соседей определяется к 5, и метрика для выбранного расстояния является взвешенным Евклидовым расстоянием в квадрате обратным. Для получения дополнительной информации о классификаторе, обратитесь к fitcknn
.
Обучите классификатор и распечатайте точность перекрестной проверки. crossval
и kfoldloss
используются, чтобы вычислить точность перекрестной проверки для классификатора KNN.
Извлеките предикторы и ответы. Обработайте данные в правильную форму для обучения модель.
inputTable = features; predictorNames = features.Properties.VariableNames; predictors = inputTable(:, predictorNames(2:15)); response = inputTable.Label;
Обучите классификатор. Задайте все опции классификатора и обучите классификатор.
trainedClassifier = fitcknn(... predictors, ... response, ... 'Distance', 'euclidean', ... 'NumNeighbors', 5, ... 'DistanceWeight', 'squaredinverse', ... 'Standardize', false, ... 'ClassNames', unique(response));
Выполните перекрестную проверку.
k = 5; group = (response); c = cvpartition(group,'KFold',k); % 5-fold stratified cross validation partitionedModel = crossval(trainedClassifier,'CVPartition',c);
Вычислите точность валидации.
validationAccuracy = 1 - kfoldLoss(partitionedModel, 'LossFun', 'ClassifError'); fprintf('\nValidation accuracy = %.2f%%\n', validationAccuracy*100);
Validation accuracy = 92.93%
Визуализируйте график беспорядка.
validationPredictions = kfoldPredict(partitionedModel); figure; cm = confusionchart(features.Label,validationPredictions,'title','Validation Accuracy'); cm.ColumnSummary = 'column-normalized'; cm.RowSummary = 'row-normalized';
Можно также использовать приложение classificationLearner
, чтобы испытать и сравнить различные классификаторы с таблицей функций.
В этом разделе вы протестируете обученный классификатор KNN с двумя речевыми сигналами от каждого из десяти докладчиков, чтобы видеть, как хорошо это ведет себя с сигналами, которые не использовались, чтобы обучить его.
Считайте файлы, извлеките функции от набора тестов и нормируйте их.
lenDataTest = length(testDatastore.Files); featuresTest = cell(lenDataTest,1); for i = 1:lenDataTest [dataTest, infoTest] = read(testDatastore); featuresTest{i} = HelperComputePitchAndMFCC(dataTest,infoTest); end featuresTest = vertcat(featuresTest{:}); featuresTest = rmmissing(featuresTest); featuresTest{:,2:15} = (featuresTest{:,2:15}-m)./s; head(featuresTest) % Display the first few rows
ans = 8×16 table Filename Pitch MFCC1 MFCC2 MFCC3 MFCC4 MFCC5 MFCC6 MFCC7 MFCC8 MFCC9 MFCC10 MFCC11 MFCC12 MFCC13 Label __________________ _______ ________ ________ ________ ________ _______ _________ _______ _______ _______ _______ _______ ________ ________ ______ 'cen6-fejs-b.flac' 0.95078 -2.3423 -0.58597 0.037737 -0.54468 0.92912 -0.011486 0.19081 0.52413 0.53979 1.3608 1.4529 0.072385 -0.36157 'fejs' 'cen6-fejs-b.flac' 1.0061 -1.8071 -0.01602 0.46226 -0.40632 0.58718 -0.16343 0.59531 0.74482 1.1505 1.4122 1.0592 0.68586 -0.2466 'fejs' 'cen6-fejs-b.flac' 0.84472 -1.5509 0.4368 0.59678 -0.30302 0.16468 -0.36499 0.60088 0.86908 1.0306 1.4249 1.2195 1.2085 -0.3206 'fejs' 'cen6-fejs-b.flac' 0.79387 -1.3838 0.37673 0.69429 -0.24033 0.29205 -0.27508 0.28735 0.49197 0.99254 1.6082 1.1646 0.89275 -0.34946 'fejs' 'cen6-fejs-b.flac' 0.64935 -1.2784 0.15729 0.71635 -0.28851 0.85877 0.4355 0.35029 0.21002 0.43132 1.444 1.3727 0.75646 -0.3879 'fejs' 'cen6-fejs-b.flac' 0.60368 -1.2499 -0.27023 0.35115 -0.59021 1.0208 0.82701 0.63592 0.84897 0.69597 0.86749 0.65908 0.58337 0.050057 'fejs' 'cen6-fejs-b.flac' 0.64935 -1.1657 -0.66573 0.067037 -0.98629 0.64687 0.70306 0.32048 0.42064 0.57206 0.66513 0.31176 0.61106 0.19282 'fejs' 'cen6-fejs-b.flac' 0.84472 -0.66006 -0.42247 0.23545 -0.91029 0.64841 0.61746 0.12066 0.0988 0.33263 0.49967 0.18377 0.54699 0.074648 'fejs'
Если вы не загружали базу данных AN4, можно загрузить таблицу функций тестовых файлов от HelperAN4TestingFeatures.mat
.
Функциональный HelperTestKNNClassifier
выполняет следующие действия для каждого файла в testDatastore
:
Считайте аудиосэмплы и вычислите подачу и функции MFCC каждого кадра на 30 мс, как описано в разделе Feature Extraction.
Предскажите метку (динамик) для каждого кадра путем вызова predict
на trainedClassifier
.
Для данного файла прогнозы сделаны для каждого кадра. Наиболее часто происходящая метка объявляется как предсказанный динамик для файла. Уверенность прогноза вычисляется как частота прогноза метки, разделенной на общее количество речевых кадров в файле.
result = HelperTestKNNClassifier(trainedClassifier, featuresTest)
result = 28×4 table Filename ActualSpeaker PredictedSpeaker ConfidencePercentage __________________ _____________ ________________ ____________________ 'cen6-fejs-b.flac' fejs fejs 94.41 'cen6-fmjd-b.flac' fmjd fmjd 77.019 'cen6-fsrb-b.flac' fsrb fsrb 55.721 'cen6-ftmj-b.flac' ftmj ftmj 59.615 'cen6-fwxs-b.flac' fwxs fwxs 71.946 'cen6-mcen-b.flac' mcen mcen 74.359 'cen6-mrcb-b.flac' mrcb mrcb 77.519 'cen6-msjm-b.flac' msjm msjm 58.571 'cen6-msjr-b.flac' msjr msjr 64.828 'cen7-fejs-b.flac' fejs fejs 78.102 'cen7-fmjd-b.flac' fmjd fmjd 74.654 'cen7-fsrb-b.flac' fsrb fsrb 72.585 'cen7-ftmj-b.flac' ftmj ftmj 37.441 'cen7-fwxs-b.flac' fwxs fwxs 69.345 'cen7-mcen-b.flac' mcen mcen 77.5 'cen7-mrcb-b.flac' mrcb mrcb 82.828 'cen7-msjm-b.flac' msjm msjm 57.653 'cen7-msjr-b.flac' msjr msjr 79.845 'cen7-msmn-b.flac' msmn msmn 75.191 'cen8-fejs-b.flac' fejs fejs 84.259 'cen8-fmjd-b.flac' fmjd fmjd 57.317 'cen8-fsrb-b.flac' fsrb fsrb 50.427 'cen8-ftmj-b.flac' ftmj ftmj 63.054 'cen8-mcen-b.flac' mcen mcen 77.536 'cen8-mrcb-b.flac' mrcb mrcb 73.171 'cen8-msjm-b.flac' msjm msjm 47.482 'cen8-msjr-b.flac' msjr msjr 63.636 'cen8-msmn-b.flac' msmn msmn 87.773
Предсказанные динамики совпадают с ожидаемыми динамиками для всех файлов под тестом.
Эксперимент был повторен с помощью внутренне разработанного набора данных. Набор данных состоит из 20 динамиков с каждым динамиком, говорящим несколько предложений из списка [2] предложений Гарварда. Для 20 динамиков точность валидации, как находили, составляла 89%.