Верификация динамика или аутентификация, является задачей подтверждения, что идентичность динамика состоит в том, кем они подразумевают быть. Верификация динамика много лет была активной областью исследования. Ранний прорыв производительности должен был использовать смешанную гауссовскую модель и универсальную фоновую модель (GMM-UBM) [1] на акустических функциях (обычно mfcc
). Для примера смотрите, что Верификация Динамика Использует смешанную гауссовскую модель. Одна из основных трудностей систем GMM-UBM включает изменчивость межсеанса. Объединенный факторный анализ (JFA) был предложен, чтобы компенсировать эту изменчивость путем отдельного моделирования изменчивости междинамика и канала или [2] [3] изменчивости сеанса. Однако [4] обнаружил, что канал включает JFA, также содержал информацию о динамиках и предложил комбинировать канал и пробелы динамика в общий пробел изменчивости. Изменчивость межсеанса была затем компенсирована при помощи процедур бэкэнда, таких как линейный дискриминантный анализ (LDA) и нормализация ковариации в классе (WCCN), сопровождаемая выигрышем, таких как счет подобия косинуса. [5] предложил заменить подобие косинуса, выигрывающее на вероятностный LDA (PLDA). В то время как i-векторы были первоначально предложены для верификации динамика, они были применены ко многим проблемам, как распознавание языка, динамик diarization, распознавание эмоции, оценка возраста и антиспуфинг [10]. Недавно, методы глубокого обучения были предложены, чтобы заменить i-векторы на [8] [6] d-векторов или x-векторов.
В этом примере вы разрабатываете простую систему i-вектора для верификации динамика, которая использует бэкэнд LDA-WCCN с выигрышем подобия косинуса. Пример также делает популярное упрощение диагональной ковариационной матрицы для GMM.
В примере вы найдете живые средства управления на настраиваемых параметрах. Изменение средств управления не повторно выполняет пример. Если вы изменяете управление, необходимо повторно выполнить пример.
Этот пример использует Базу данных Отслеживания Подачи из Технологического университета Граца (PTDB-TUG) [7]. Набор данных состоит из 20 английских носителей языка, читающих 2 342 фонетически богатых предложения из корпуса TIMIT. Загрузите и извлеките набор данных. В зависимости от вашей системы, загружая и извлекая набор данных может занять приблизительно 1,5 часа.
url = 'https://www2.spsc.tugraz.at/databases/PTDB-TUG/SPEECH_DATA_ZIPPED.zip'; downloadFolder = tempdir; datasetFolder = fullfile(downloadFolder,'PTDB-TUG'); if ~exist(datasetFolder,'dir') disp('Downloading PTDB-TUG (3.9 G) ...') unzip(url,datasetFolder) end
Создайте audioDatastore
возразите что точки против набора данных. Набор данных был первоначально предназначен для использования в отслеживающем подачу обучении и оценке, и включает показания ларингографика и базовые решения подачи. Используйте только исходные аудиозаписи.
ads = audioDatastore([fullfile(datasetFolder,"SPEECH DATA","FEMALE","MIC"),fullfile(datasetFolder,"SPEECH DATA","MALE","MIC")], ... 'IncludeSubfolders',true, ... 'FileExtensions','.wav'); fileNames = ads.Files;
Имена файлов содержат идентификаторы динамика. Декодируйте имена файлов, чтобы установить метки на audioDatastore
объект.
speakerIDs = extractBetween(fileNames,'mic_','_'); ads.Labels = categorical(speakerIDs); countEachLabel(ads)
ans=20×2 table
Label Count
_____ _____
F01 236
F02 236
F03 236
F04 236
F05 236
F06 236
F07 236
F08 234
F09 236
F10 236
M01 236
M02 236
M03 236
M04 236
M05 236
M06 236
⋮
Разделите audioDatastore
объект в два: один для обучения, и один для приема и верификации. Набор обучающих данных содержит 16 динамиков. Набор приема и верификации содержит другие четыре динамика. Вы разделите набор приема и верификации позже в примере.
speakersToTest = categorical(["M01","M05","F01","F05"]); adsTrain = subset(ads,~ismember(ads.Labels,speakersToTest)); adsEnrollAndVerify = subset(ads,ismember(ads.Labels,speakersToTest)); adsTrain = shuffle(adsTrain); adsEnrollAndVerify = shuffle(adsEnrollAndVerify);
Отобразите распределения метки двух audioDatastore
объекты.
countEachLabel(adsTrain)
ans=16×2 table
Label Count
_____ _____
F02 236
F03 236
F04 236
F06 236
F07 236
F08 234
F09 236
F10 236
M02 236
M03 236
M04 236
M06 236
M07 236
M08 236
M09 236
M10 236
countEachLabel(adsEnrollAndVerify)
ans=4×2 table
Label Count
_____ _____
F01 236
F05 236
M01 236
M05 236
Считайте звуковой файл из обучающего набора данных, слушайте его и постройте его. Сбросьте datastore.
[audio,audioInfo] = read(adsTrain); fs = audioInfo.SampleRate; t = (0:size(audio,1)-1)/fs; sound(audio,fs) plot(t,audio) xlabel('Time (s)') ylabel('Amplitude') axis([0 t(end) -1 1]) title('Sample Utterance from Training Set')
reset(adsTrain)
Можно уменьшать набор данных, используемый в этом примере, чтобы ускорить время выполнения за счет производительности. В общем случае сокращение набора данных является хорошей практикой для разработки и отладки.
reduceDataset = false; if reduceDataset adsTrain = splitEachLabel (adsTrain, 21); adsEnrollAndVerify = splitEachLabel (adsEnrollAndVerify, 21); end
Создайте audioFeatureExtractor
возразите, чтобы извлечь 20 MFCCs, 20 дельт-MFCCs и 20 дельт дельты MFCCs. Используйте длину окна дельты 9. Извлеките функции из окон Hann на 25 мс с транзитным участком на 10 мс.
numCoeffs = 20; deltaWindowLength = 9; windowDuration = 0.025; hopDuration = 0.01; windowSamples = вокруг (windowDuration*fs); hopSamples = вокруг (hopDuration*fs); overlapSamples = windowSamples - hopSamples; afe = audioFeatureExtractor ( ... 'SampleRate', фс, ... 'Window', hann (windowSamples,'periodic'), ... 'OverlapLength', overlapSamples, ... ... 'mfcc'TRUE, ... 'mfccDelta'TRUE, ... 'mfccDeltaDelta'TRUE; setExtractorParams (afe,'mfcc','DeltaWindowLength', deltaWindowLength,'NumCoeffs', numCoeffs)
Извлеките функции из аудио, считанного из учебного datastore. Функции возвращены как numHops
- numFeatures
матрица.
features = extract(afe,audio); [numHops,numFeatures] = size(features)
numHops = 559
numFeatures = 60
Обучение система i-вектора является в вычислительном отношении дорогим и длительным. Если у вас есть Parallel Computing Toolbox™, можно распространить работу через несколько ядер, чтобы ускорить пример. Определите оптимальное количество разделов для вашей системы. Если у вас нет Parallel Computing Toolbox™, используйте один раздел.
if ~isempty(ver('parallel')) && ~reduceDataset pool = gcp; numPar = numpartitions(adsTrain,pool); else numPar = 1; end
Starting parallel pool (parpool) using the 'local' profile ... Connected to the parallel pool (number of workers: 6).
Используйте функцию помощника, helperFeatureExtraction
, извлекать все функции из набора данных. Функция helperFeatureExtraction извлекает MFCC из областей речи в аудио. Речевое обнаружение выполняется detectSpeech
функция.
featuresAll = {}; tic parfor ii = 1:numPar adsPart = partition(adsTrain,numPar,ii); featuresPart = cell(0,numel(adsPart.Files)); for iii = 1:numel(adsPart.Files) audioData = read(adsPart); featuresPart{iii} = helperFeatureExtraction(audioData,afe,[]); end featuresAll = [featuresAll,featuresPart]; end allFeatures = cat(2,featuresAll{:}); fprintf('Feature extraction from training set complete (%0.0f seconds).',toc)
Feature extraction from training set complete (71 seconds).
Вычислите глобальное среднее и стандартное отклонение каждой функции. Вы будете использовать их в будущих вызовах helperFeatureExtraction
функция, чтобы нормировать функции.
normFactors.Mean = mean(allFeatures,2,'omitnan'); normFactors.STD = std(allFeatures,[],2,'omitnan');
Инициализируйте смешанную гауссовскую модель (GMM), которая будет универсальной фоновой моделью (UBM) в системе i-вектора. Веса компонента инициализируются, как равномерно распределено. Системы, обученные на наборе данных TIMIT обычно, содержат приблизительно 2 048 компонентов.
numComponents = 256; альфа = единицы (1, numComponents)/numComponents; mu = randn (numFeatures, numComponents); vari = rand (numFeatures, numComponents) + eps; ubm = struct ('ComponentProportion'\alpha,'mu'\mu,'sigma', vari);
Обучите UBM использование алгоритма максимизации ожидания (EM).
maxIter = 10; тик for проход = 1:maxIter тик % EXPECTATION N = нули (1, numComponents); F = нули (numFeatures, numComponents); S = нули (numFeatures, numComponents); L = 0; parfor ii = 1:numPar adsPart = раздел (adsTrain, numPar, ii); while hasdata (adsPart) аудиоданные = читают (adsPart); % Extract features Y = helperFeatureExtraction (аудиоданные, afe, normFactors); % Compute a posteriori log-liklihood логарифмическая правдоподобность = helperGMMLogLikelihood (Y, ubm); % Compute a posteriori normalized probability amax = макс. (логарифмическая правдоподобность, [], 1); logLikelihoodSum = amax + журнал (сумма (exp (логарифмическая-правдоподобность-amax), 1)); гамма = exp (логарифмическая правдоподобность - logLikelihoodSum)'; % Compute Baum-Welch statistics n = сумма (гамма, 1); f = Y * гамма; s = (Y. *Y) * гамма; % Update the sufficient statistics over utterances N = N + n; F = F + f; S = S + s; % Update the log-likelihood L = L + сумма (logLikelihoodSum); end end % Print current log-likelihood fprintf'Training UBM: %d/%d complete (%0.0f seconds), Log-likelihood = %0.0f\n', проход, maxIter, toc, L) % MAXIMIZATION N = макс. (N, eps); ubm. ComponentProportion = макс. (N/sum (N), eps); ubm. ComponentProportion = ubm. ComponentProportion/sum (ubm. ComponentProportion); ubm.mu = F./N; ubm.sigma = макс. (S./N - ubm.mu.^ 2, eps); end
Training UBM: 1/10 complete (112 seconds), Log-likelihood = -140389008 Training UBM: 2/10 complete (104 seconds), Log-likelihood = -80118143 Training UBM: 3/10 complete (107 seconds), Log-likelihood = -76497460 Training UBM: 4/10 complete (104 seconds), Log-likelihood = -74883100 Training UBM: 5/10 complete (103 seconds), Log-likelihood = -74039778 Training UBM: 6/10 complete (108 seconds), Log-likelihood = -73545747 Training UBM: 7/10 complete (106 seconds), Log-likelihood = -73241619 Training UBM: 8/10 complete (103 seconds), Log-likelihood = -73044282 Training UBM: 9/10 complete (103 seconds), Log-likelihood = -72905317 Training UBM: 10/10 complete (103 seconds), Log-likelihood = -72799523
Baum-валлийскими статистическими данными является N
(нулевой порядок) и F
(первый порядок) статистика, используемая в алгоритме EM, вычисленное использование итогового UBM.
характеристический вектор во время .
, где количество динамиков. В целях обучения общий пробел изменчивости каждый звуковой файл рассматривается отдельным динамиком (принадлежит ли это физическому одному динамику).
апостериорная вероятность что компонент UBM счета на характеристический вектор .
Вычислите Baum-валлийскую статистику нулевого и первого порядка по набору обучающих данных.
numSpeakers = numel(adsTrain.Files); Nc = {}; Fc = {}; tic parfor ii = 1:numPar adsPart = partition(adsTrain,numPar,ii); numFiles = numel(adsPart.Files); Npart = cell(1,numFiles); Fpart = cell(1,numFiles); for jj = 1:numFiles audioData = read(adsPart); % Extract features Y = helperFeatureExtraction(audioData,afe,normFactors); % Compute a posteriori log-likelihood logLikelihood = helperGMMLogLikelihood(Y,ubm); % Compute a posteriori normalized probability amax = max(logLikelihood,[],1); logLikelihoodSum = amax + log(sum(exp(logLikelihood-amax),1)); gamma = exp(logLikelihood - logLikelihoodSum)'; % Compute Baum-Welch statistics n = sum(gamma,1); f = Y * gamma; Npart{jj} = reshape(n,1,1,numComponents); Fpart{jj} = reshape(f,numFeatures,1,numComponents); end Nc = [Nc,Npart]; Fc = [Fc,Fpart]; end fprintf('Baum-Welch statistics completed (%0.0f seconds).\n',toc)
Baum-Welch statistics completed (102 seconds).
Расширьте статистику в матрицы и центр , как описано в [3], такой, что
isa диагональная матрица, блоки которой .
isa супервектор получен путем конкатенации .
количество компонентов в UBM.
количество функций в характеристическом векторе.
N = Nc; F = Fc; muc = reshape(ubm.mu,numFeatures,1,[]); for s = 1:numSpeakers N{s} = repelem(reshape(Nc{s},1,[]),numFeatures); F{s} = reshape(Fc{s} - Nc{s}.*muc,[],1); end
Поскольку этот пример принимает диагональную ковариационную матрицу для UBM, N
также диагональные матрицы и сохранены как векторы для эффективного расчета.
В модели i-вектора идеальный супервектор динамика состоит из не зависящего от диктора компонента и зависящего от диктора компонента. Зависящий от диктора компонент состоит из общей модели пробела изменчивости и i-вектора докладчика.
супервектор произнесения динамика
динамик - и независимый от канала супервектор, который может быть взят, чтобы быть супервектором UBM.
низкий ранг прямоугольная матрица и представляет общее подпространство изменчивости.
i-вектор для динамика
Размерность i-вектора, , обычно намного ниже, чем C F - размерный супервектор произнесения динамика, делая i-вектор, или i-векторы, намного более компактное и послушное представление.
Обучать общий пробел изменчивости, , сначала случайным образом инициализируйте T
, затем выполните эти шаги итеративно [3]:
Вычислите апостериорное распределение скрытой переменной.
2. Накопите статистику через динамики.
3. Обновите общий пробел изменчивости.
[3] предлагает инициализировать отклонением UBM и затем обновлением согласно уравнению:
где S (s) является Baum-валлийской статистической величиной второго порядка в центре. Однако обновление часто пропускается на практике, когда это оказывает мало влияния. Этот пример не обновляется .
Создайте переменную сигмы.
Sigma = ubm.sigma(:);
Задайте размерность общего пробела изменчивости. Типичное значение, используемое в наборе данных TIMIT, 1000.
numTdim = 256;
Инициализируйте T
и единичная матрица, и предварительно выделяет массивы ячеек.
T = randn(numel(ubm.sigma),numTdim); T = T/norm(T); I = eye(numTdim); Ey = cell(numSpeakers,1); Eyy = cell(numSpeakers,1); Linv = cell(numSpeakers,1);
Определите номер итераций для обучения. Типичное значение, о котором сообщают, равняется 20.
numIterations = 5;
Запустите учебный цикл.
for iterIdx = 1:numIterations tic % 1. Calculate the posterior distribution of the hidden variable TtimesInverseSSdiag = (T./Sigma)'; parfor s = 1:numSpeakers L = (I + TtimesInverseSSdiag.*N{s}*T); Linv{s} = pinv(L); Ey{s} = Linv{s}*TtimesInverseSSdiag*F{s}; Eyy{s} = Linv{s} + Ey{s}*Ey{s}'; end % 2. Accumlate statistics across the speakers Eymat = cat(2,Ey{:}); FFmat = cat(2,F{:}); Kt = FFmat*Eymat'; K = mat2cell(Kt',numTdim,repelem(numFeatures,numComponents)); newT = cell(numComponents,1); for c = 1:numComponents AcLocal = zeros(numTdim); for s = 1:numSpeakers AcLocal = AcLocal + Nc{s}(:,:,c)*Eyy{s}; end % 3. Update the Total Variability Space newT{c} = (pinv(AcLocal)*K{c})'; end T = cat(1,newT{:}); fprintf('Training Total Variability Space: %d/%d complete (%0.0f seconds).\n',iterIdx,numIterations,toc) end
Training Total Variability Space: 1/5 complete (127 seconds). Training Total Variability Space: 2/5 complete (130 seconds). Training Total Variability Space: 3/5 complete (128 seconds). Training Total Variability Space: 4/5 complete (128 seconds). Training Total Variability Space: 5/5 complete (128 seconds).
Если общий пробел изменчивости вычисляется, можно вычислить i-векторы как [4]:
На данном этапе вы все еще рассматриваете каждый учебный файл как отдельный динамик. Однако на следующем шаге, когда вы обучаете матрицу проекции уменьшать размерность и увеличивать различия междинамика, i-векторы должны быть помечены соответствующими, отличными идентификаторами динамика.
Создайте массив ячеек, где каждый элемент массива ячеек содержит матрицу i-векторов через файлы для конкретного динамика.
speakers = unique(adsTrain.Labels); numSpeakers = numel(speakers); ivectorPerSpeaker = cell(numSpeakers,1); TS = T./Sigma; TSi = TS'; ubmMu = ubm.mu; tic parfor speakerIdx = 1:numSpeakers % Subset the datastore to the speaker you are adapting. adsPart = subset(adsTrain,adsTrain.Labels==speakers(speakerIdx)); numFiles = numel(adsPart.Files); ivectorPerFile = zeros(numTdim,numFiles); for fileIdx = 1:numFiles audioData = read(adsPart); % Extract features Y = helperFeatureExtraction(audioData,afe,normFactors); % Compute a posteriori log-likelihood logLikelihood = helperGMMLogLikelihood(Y,ubm); % Compute a posteriori normalized probability amax = max(logLikelihood,[],1); logLikelihoodSum = amax + log(sum(exp(logLikelihood-amax),1)); gamma = exp(logLikelihood - logLikelihoodSum)'; % Compute Baum-Welch statistics n = sum(gamma,1); f = Y * gamma - n.*(ubmMu); ivectorPerFile(:,fileIdx) = pinv(I + (TS.*repelem(n(:),numFeatures))' * T) * TSi * f(:); end ivectorPerSpeaker{speakerIdx} = ivectorPerFile; end fprintf('I-vectors extracted from training set (%0.0f seconds).\n',toc)
I-vectors extracted from training set (222 seconds).
Много различных бэкэндов были предложены для i-векторов. Самый прямой и все еще хорошо выполняющий является комбинацией линейного дискриминантного анализа (LDA) и нормализации ковариации в классе (WCCN).
Создайте матрицу учебных векторов и карты, указывающей, которому i-вектор соответствует который динамик. Инициализируйте матрицу проекции как единичную матрицу.
w = ivectorPerSpeaker; utterancePerSpeaker = cellfun(@(x)size(x,2),w); ivectorsTrain = cat(2,w{:}); projectionMatrix = eye(size(w{1},1));
LDA пытается минимизировать отклонение внутрикласса и максимизировать отклонение между динамиками. Это может быть вычислено, как обрисовано в общих чертах в [4]:
Данный:
где
среднее значение i-векторов для каждого динамика.
средний i-вектор через все динамики.
количество произнесения для каждого динамика.
Решите уравнение собственного значения для лучших собственных векторов:
Лучшие собственные вектора - те с самыми высокими собственными значениями.
performLDA = true; if performLDA тик numEigenvectors = 16; Коротковолновый = нули (размер (projectionMatrix, 1)); Сб = нули (размер (projectionMatrix, 1)); wbar = среднее значение (кошка (2, w {:}), 2); for ii = 1:numel (w) ws = w {ii}; wsbar = среднее значение (ws, 2); Сб = Сб + (wsbar - wbar) * (wsbar - wbar)'; Коротковолновый = коротковолновый + cov (ws',1); end [A, ~] = eigs (Сб, коротковолновый, numEigenvectors); A = (A./vecnorm (A))'; ivectorsTrain = * ivectorsTrain; w = mat2cell (ivectorsTrain, размер (ivectorsTrain, 1), utterancePerSpeaker); projectionMatrix = * projectionMatrix; fprintf'LDA projection matrix calculated (%0.2f seconds).'toc end
LDA projection matrix calculated (0.41 seconds).
WCCN пытается масштабировать i-векторное-пространство обратно пропорционально к ковариации в классе, так, чтобы направления высокой изменчивости внутридинамика были преуменьшены роль в сравнениях i-вектора [9].
Учитывая ковариационную матрицу в классе:
где
среднее значение i-векторов для каждого динамика.
количество произнесения для каждого динамика.
Решите для B использование разложения Холесского:
performWCCN = true; if performWCCN тик альфа = 0.9; W = нули (размер (projectionMatrix, 1)); for ii = 1:numel (w) W = W + cov (w {ii} ', 1); end W = W/numel (w); W = (1 - альфа) *W + alpha*eye (размер (W, 1)); B = chol (pinv (W),'lower'); projectionMatrix = B * projectionMatrix; fprintf'WCCN projection matrix calculated (%0.4f seconds).'toc end
WCCN projection matrix calculated (0.0076 seconds).
Учебный этап теперь завершен. Можно теперь использовать универсальную фоновую модель (UBM), общий пробел изменчивости (T), и матрица проекции, чтобы зарегистрировать и проверить динамики.
Зарегистрируйте новых докладчиков, которые не были в обучающем наборе данных. Во-первых, разделите adsEnrollAndVerify
аудио объект datastore в регистрирует и проверяет. Используйте 20 произнесения на динамик для приема и остальных для тестирования. Увеличение числа произнесения на динамик для приема должно увеличить производительность системы.
numFilesPerSpeakerForEnrollment = 20;
[adsEnroll, adsVerify] = splitEachLabel (adsEnrollAndVerify, numFilesPerSpeakerForEnrollment);
adsVerify = перестановка (adsVerify);
adsEnroll = перестановка (adsEnroll);
countEachLabel (adsEnroll)
ans=4×2 table
Label Count
_____ _____
F01 20
F05 20
M01 20
M05 20
countEachLabel(adsVerify)
ans=4×2 table
Label Count
_____ _____
F01 216
F05 216
M01 216
M05 216
Создайте i-векторы для каждого файла для каждого динамика в зарегистрировать наборе с помощью этой последовательности шагов:
Извлечение признаков
Baum-валлийская Статистика: Определите статистику нулевого и первого порядка
Экстракция i-вектора
Компенсация межсеанса
Затем насчитайте i-векторы через файлы, чтобы создать модель i-вектора для динамика.
speakers = unique(adsEnroll.Labels); numSpeakers = numel(speakers); enrolledSpeakersByIdx = cell(numSpeakers,1); tic parfor speakerIdx = 1:numSpeakers % Subset the datastore to the speaker you are adapting. adsPart = subset(adsEnroll,adsEnroll.Labels==speakers(speakerIdx)); numFiles = numel(adsPart.Files); ivectorMat = zeros(size(projectionMatrix,1),numFiles); for fileIdx = 1:numFiles audioData = read(adsPart); % Extract features Y = helperFeatureExtraction(audioData,afe,normFactors); % Compute a posteriori log-likelihood logLikelihood = helperGMMLogLikelihood(Y,ubm); % Compute a posteriori normalized probability amax = max(logLikelihood,[],1); logLikelihoodSum = amax + log(sum(exp(logLikelihood-amax),1)); gamma = exp(logLikelihood - logLikelihoodSum)'; % Compute Baum-Welch statistics n = sum(gamma,1); f = Y * gamma - n.*(ubmMu); %i-vector Extraction ivector = pinv(I + (TS.*repelem(n(:),numFeatures))' * T) * TSi * f(:); % Intersession Compensation ivector = projectionMatrix*ivector; ivectorMat(:,fileIdx) = ivector; end % i-vector model enrolledSpeakersByIdx{speakerIdx} = mean(ivectorMat,2); end fprintf('Speakers enrolled (%0.0f seconds).\n',toc)
Speakers enrolled (7 seconds).
В бухгалтерских целях преобразуйте массив ячеек i-векторов к структуре с идентификаторами динамика как поля и i-векторы как значения
enrolledSpeakers = struct; for s = 1:numSpeakers enrolledSpeakers.(string(speakers(s))) = enrolledSpeakersByIdx{s}; end
Ложный уровень отклонения (FRR) динамика является уровнем, что данный динамик неправильно отклоняется. Используйте набор данных динамика верификации, чтобы определить динамик FRR для набора порогов.
speakersToTest = unique(adsVerify.Labels); numSpeakers = numel(speakersToTest); thresholdsToTest = -1:0.0001:1; cssFRR = cell(numSpeakers,1); tic parfor speakerIdx = 1:numSpeakers adsPart = subset(adsVerify,adsVerify.Labels==speakersToTest(speakerIdx)); numFiles = numel(adsPart.Files); ivectorToTest = enrolledSpeakers.(string(speakersToTest(speakerIdx))); %#ok<PFBNS> css = zeros(numFiles,1); for fileIdx = 1:numFiles audioData = read(adsPart); % Extract features Y = helperFeatureExtraction(audioData,afe,normFactors); % Compute a posteriori log-likelihood logLikelihood = helperGMMLogLikelihood(Y,ubm); % Compute a posteriori normalized probability amax = max(logLikelihood,[],1); logLikelihoodSum = amax + log(sum(exp(logLikelihood-amax),1)); gamma = exp(logLikelihood - logLikelihoodSum)'; % Compute Baum-Welch statistics n = sum(gamma,1); f = Y * gamma - n.*(ubmMu); % Extract i-vector ivector = pinv(I + (TS.*repelem(n(:),numFeatures))' * T) * TSi * f(:); % Intersession Compensation ivector = projectionMatrix*ivector; % Cosine Similarity Score css(fileIdx) = dot(ivectorToTest,ivector)/(norm(ivector)*norm(ivectorToTest)); end cssFRR{speakerIdx} = css; end cssFRR = cat(1,cssFRR{:}); FRR = mean(cssFRR<thresholdsToTest); fprintf('FRR calculated (%0.0f seconds).\n',toc)
FRR calculated (65 seconds).
Постройте FRR как функцию порога.
figure plot(thresholdsToTest,FRR) title('False Rejection Rate (FRR)') xlabel('Threshold') ylabel('FRR') grid on axis([thresholdsToTest(find(FRR~=0,1)) thresholdsToTest(find(FRR==1,1)) 0 1])
Ложная пропускная способность (FAR) динамика является уровнем, что произнесение, не принадлежащее зарегистрированному докладчику, неправильно принято как принадлежащий зарегистрированному докладчику. Используйте известный набор динамика, чтобы определить FAR динамика для набора порогов.
speakersToTest = unique(adsVerify.Labels); numSpeakers = numel(speakersToTest); cssFAR = cell(numSpeakers,1); totalFiles = 0; tic parfor speakerIdx = 1:numSpeakers adsPart = subset(adsVerify,adsVerify.Labels~=speakersToTest(speakerIdx)); numFiles = numel(adsPart.Files); ivectorToTest = enrolledSpeakers.(string(speakersToTest(speakerIdx))); %#ok<PFBNS> css = zeros(numFiles,1); for fileIdx = 1:numFiles audioData = read(adsPart); % Extract features Y = helperFeatureExtraction(audioData,afe,normFactors); % Compute a posteriori log-likelihood logLikelihood = helperGMMLogLikelihood(Y,ubm); % Compute a posteriori normalized probability amax = max(logLikelihood,[],1); logLikelihoodSum = amax + log(sum(exp(logLikelihood-amax),1)); gamma = exp(logLikelihood - logLikelihoodSum)'; % Compute Baum-Welch statistics n = sum(gamma,1); f = Y * gamma - n.*(ubmMu); % Extract i-vector ivector = pinv(I + (TS.*repelem(n(:),numFeatures))' * T) * TSi * f(:); % Intersession compensation ivector = projectionMatrix * ivector; % Cosine similarity score css(fileIdx) = dot(ivectorToTest,ivector)/(norm(ivector)*norm(ivectorToTest)); end cssFAR{speakerIdx} = css; end cssFAR = cat(1,cssFAR{:}); FAR = mean(cssFAR>thresholdsToTest); fprintf('FAR calculated (%0.0f seconds).\n',toc);
FAR calculated (190 seconds).
Постройте FAR как функцию порога.
figure plot(thresholdsToTest,FAR) title('False Acceptance Rate (FAR)') xlabel('Threshold') ylabel('FAR') grid on axis([thresholdsToTest(find(FAR~=1,1)) thresholdsToTest(find(FAR==0,1)) 0 1])
Когда вы перемещаете порог в систему верификации динамика, вы обмениваете между FAR и FRR. Это упоминается как ошибочный компромисс обнаружения и обычно сообщается в бинарных проблемах классификации.
figure plot(FAR,FRR) grid on xlabel('False Acceptance Rate (FAR)') ylabel('False Rejection Rate (FRR)') title('Detection Error Tradeoff (DET) Curve') axis([0 0.5 0 0.5])
Чтобы сравнить несколько систем, вам нужна одна метрика, которая комбинирует FAR и производительность FRR. Для этого вы определяете равный коэффициент ошибок (EER), который является порогом, где FAR и кривые FRR встречаются. На практике порог EER не может быть лучшим выбором. Например, если бы верификация динамика используется в качестве части подхода мультиаутентификации для проводных передач, FAR был бы, скорее всего, в большей степени взвешен, чем FRR.
[~,EERThresholdIdx] = min(abs(FAR - FRR)); EERThreshold = thresholdsToTest(EERThresholdIdx); EER = mean([FAR(EERThresholdIdx),FRR(EERThresholdIdx)]); figure plot(thresholdsToTest,FAR,'k', ... thresholdsToTest,FRR,'b', ... EERThreshold,EER,'ro','MarkerFaceColor','r') title(sprintf('Equal Error Rate = %0.4f, Threshold = %0.4f',EER,EERThreshold)) xlabel('Threshold') ylabel('Error Rate') legend('False Acceptance Rate (FAR)','False Rejection Rate (FRR)','Equal Error Rate (EER)','Location','southwest') grid on axis([thresholdsToTest(find(FAR~=1,1)) thresholdsToTest(find(FRR==1,1)) 0 1])
function [features,numFrames] = helperFeatureExtraction(audioData,afe,normFactors) % Input: % audioData - column vector of audio data % afe - audioFeatureExtractor object % normFactors - mean and standard deviation of the features used for normalization. % If normFactors is empty, no normalization is applied. % % Output % features - matrix of features extracted % numFrames - number of frames (feature vectors) returned % Normalize audioData = audioData/max(abs(audioData(:))); % Protect against NaNs audioData(isnan(audioData)) = 0; % Isolate speech segment idx = detectSpeech(audioData,afe.SampleRate); features = []; for ii = 1:size(idx,1) f = extract(afe,audioData(idx(ii,1):idx(ii,2))); features = [features;f]; %#ok<AGROW> end % Feature normalization if ~isempty(normFactors) features = (features-normFactors.Mean')./normFactors.STD'; end features = features'; % Cepstral mean subtraction (for channel noise) if ~isempty(normFactors) features = features - mean(features,'all'); end numFrames = size(features,2); end
function L = helperGMMLogLikelihood(x,gmm) xMinusMu = repmat(x,1,1,numel(gmm.ComponentProportion)) - permute(gmm.mu,[1,3,2]); permuteSigma = permute(gmm.sigma,[1,3,2]); Lunweighted = -0.5*(sum(log(permuteSigma),1) + sum(xMinusMu.*(xMinusMu./permuteSigma),1) + size(gmm.mu,1)*log(2*pi)); temp = squeeze(permute(Lunweighted,[1,3,2])); if size(temp,1)==1 % If there is only one frame, the trailing singleton dimension was % removed in the permute. This accounts for that edge case. temp = temp'; end L = temp + log(gmm.ComponentProportion)'; end
[1] Рейнольдс, Дуглас А., и др. “Верификация динамика Используя Адаптированные смешанные гауссовские модели”. Цифровая обработка сигналов, издание 10, № 1-3, январь 2000, стр 19–41. DOI.org (Crossref), doi:10.1006/dspr.1999.0361.
[2] Кенни, Патрик, и др. “Объединенный Факторный анализ По сравнению с Eigenchannels в Распознавании Динамика”. Транзакции IEEE на Аудио, Речи и Обработке Языка, издании 15, № 4, май 2007, стр 1435–47. DOI.org (Crossref), doi:10.1109/TASL.2006.881693.
[3] Кенни, P., и др. “Исследование Изменчивости Междинамика в Верификации Динамика”. Транзакции IEEE на Аудио, Речи, и Обработке Языка, издании 16, № 5, июль 2008, стр 980–88. DOI.org (Crossref), doi:10.1109/TASL.2008.925147.
[4] Dehak, Najim, и др. “Выйдите напрямую Факторный анализ для Верификации Динамика”. Транзакции IEEE на Аудио, Речи, и Обработке Языка, издании 19, № 4, май 2011, стр 788–98. DOI.org (Crossref), doi:10.1109/TASL.2010.2064307.
[5] Matějka, P., и др. "Full-covariance UBM и PLDA с тяжелым хвостом в верификации динамика i-вектора", 2 011 Международных конференций IEEE по вопросам Акустики, Речи и Обработки сигналов (ICASSP), Праги, 2011, стр 4828-4831.
[6] Снайдер, Дэвид, и др. “X-векторы: Устойчивые Вложения DNN для Распознавания Динамика”. 2 018 Международных конференций IEEE по вопросам Акустики, Речи и Обработки сигналов (ICASSP), IEEE, 2018, стр 5329–33. DOI.org (Crossref), doi:10.1109/ICASSP.2018.8461375.
[7] Обработка сигналов и Речевая Коммуникационная Лаборатория. Полученный доступ 12 декабря 2019. https://www.spsc.tugraz.at/databases-and-tools/ptdb-tug-pitch-tracking-database-from-graz-university-of-technology.html.
[8] Variani, Эхсан, и др. “Глубокие нейронные сети для Маленькой Верификации Динамика Текстового Зависимого Места”. 2 014 Международных конференций IEEE по вопросам Акустики, Речи и Обработки сигналов (ICASSP), IEEE, 2014, стр 4052–56. DOI.org (Crossref), doi:10.1109/ICASSP.2014.6854363.
[9] Dehak, Najim, Réda Dehak, Джеймс Р. Стекло, Дуглас А. Рейнольдс и Патрик Кенни. “Подобие косинуса, выигрывающее без методов нормализации счета”. Одиссея (2010).
[10] Verma, Pulkit и Прэдип К. Дас. “I-векторы в Речевых Приложениях обработки: Обзор”. Международный журнал Речевой Технологии, издания 18, № 4, декабрь 2015, стр 529–46. DOI.org (Crossref), doi:10.1007/s10772-015-9295-3.