Верификация динамика или аутентификация, является задачей подтверждения, что идентичность динамика состоит в том, кем они подразумевают быть. Верификация динамика много лет была активной областью исследования. Ранний прорыв эффективности должен был использовать смешанную гауссовскую модель и универсальную фоновую модель (GMM-UBM) [1] на акустических функциях (обычно mfcc
). Для примера смотрите, что Верификация Динамика Использует смешанную гауссовскую модель. Одна из основных трудностей систем GMM-UBM включает изменчивость межсеанса. Объединенный факторный анализ (JFA) был предложен, чтобы компенсировать эту изменчивость путем отдельного моделирования изменчивости междинамика и канала или [2] [3] изменчивости сеанса. Однако [4] обнаружил, что канал включает JFA, также содержал информацию о динамиках и предложил комбинировать канал и пробелы динамика в общий пробел изменчивости. Изменчивость межсеанса была затем компенсирована при помощи процедур бэкэнда, таких как линейный дискриминантный анализ (LDA) и нормализация ковариации в классе (WCCN), сопровождаемая выигрышем, таких как счет подобия косинуса. [5] предложил заменить подобие косинуса, выигрывающее на вероятностный LDA (PLDA). [11] и [12] предложил метод Gaussianize i-векторы, и поэтому сделайте Гауссовы предположения в PLDA, называемом G-PLDA или упрощенным PLDA. Далее описанный общее, В то время как i-векторы были первоначально предложены для верификации динамика, они были применены ко многим проблемам, как распознавание языка, динамик diarization, распознавание эмоции, оценка возраста и антиспуфинг [10]. Недавно, методы глубокого обучения были предложены, чтобы заменить i-векторы на [8] [6] d-векторов или x-векторов.
В этом примере вы разрабатываете простую систему i-вектора для верификации динамика, которая использует бэкэнд LDA-WCCN или с выигрышем подобия косинуса или с выигрышем G-PLDA.
В примере вы найдете живые средства управления на настраиваемых параметрах. Изменение средств управления не повторно выполняет пример. Если вы изменяете управление, необходимо повторно выполнить пример.
Этот пример использует Базу данных Отслеживания Подачи из Технологического университета Граца (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)
Можно уменьшать набор данных и количество параметров, используемых в этом примере, чтобы ускорить время выполнения за счет эффективности. В общем случае сокращение набора данных является хорошей практикой для разработки и отладки.
speedUpExample = false; if speedUpExample adsTrain = splitEachLabel (adsTrain, 30); 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 = 889
numFeatures = 60
Обучение система i-вектора является в вычислительном отношении дорогим и длительным. Если у вас есть Parallel Computing Toolbox™, можно распространить работу через несколько ядер, чтобы ускорить пример. Определите оптимальное количество разделов для вашей системы. Если у вас нет Parallel Computing Toolbox™, используйте один раздел.
if ~isempty(ver('parallel')) && ~speedUpExample pool = gcp; numPar = numpartitions(adsTrain,pool); else numPar = 1; end
Используйте функцию помощника, 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 (65 seconds).
Вычислите глобальное среднее и стандартное отклонение каждой функции. Вы будете использовать их в будущих вызовах helperFeatureExtraction
функция, чтобы нормировать функции.
normFactors.Mean = mean(allFeatures,2,'omitnan'); normFactors.STD = std(allFeatures,[],2,'omitnan');
Инициализируйте смешанную гауссовскую модель (GMM), которая будет универсальной фоновой моделью (UBM) в системе i-вектора. Веса компонента инициализируются, как равномерно распределено. Системы, обученные на наборе данных TIMIT обычно, содержат приблизительно 2 048 компонентов.
numComponents = 128; if speedUpExample numComponents = 64; end альфа = единицы (1, numComponents)/numComponents; mu = randn (numFeatures, numComponents); vari = rand (numFeatures, numComponents) + eps; ubm = struct ('ComponentProportion'\alpha,'mu'\mu,'sigma', vari);
Обучите UBM использование алгоритма максимизации ожидания (EM).
maxIter = 3; if speedUpExample maxIter = 2; end тик 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/3 complete (86 seconds), Log-likelihood = -149252841 Training UBM: 2/3 complete (85 seconds), Log-likelihood = -80011645 Training UBM: 3/3 complete (84 seconds), Log-likelihood = -76235688
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 (82 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 = 128; if speedUpExample numTdim = 64; end
Инициализируйте 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 = 3;
Запустите учебный цикл.
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/3 complete (27 seconds). Training Total Variability Space: 2/3 complete (28 seconds). Training Total Variability Space: 3/3 complete (26 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 (110 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.06 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.0033 seconds).
Учебный этап теперь завершен. Можно теперь использовать универсальную фоновую модель (UBM), общий пробел изменчивости (T), и матрица проекции, чтобы зарегистрировать и проверить динамики.
Примените матрицу проекции к составу.
ivectors = cellfun(@(x)projectionMatrix*x,ivectorPerSpeaker,'UniformOutput',false);
Этот алгоритм, реализованный в этом примере, является Гауссовым PLDA, как обрисовано в общих чертах в [13]. В Гауссовом PLDA i-вектор представлен следующим уравнением:
где глобальное среднее значение i-векторов, матрица полной точности шумового термина , и матрица факторной нагрузки, также известная как eigenvoices.
Задайте количество eigenvoices, чтобы использовать. Обычно числа между 10 и 400.
numEigenVoices = 16;
Определите количество непересекающихся людей, количество размерностей в характеристических векторах и количество произнесения на динамик.
K = numel(ivectors); D = size(ivectors{1},1); utterancePerSpeaker = cellfun(@(x)size(x,2),ivectors);
Найдите общее количество выборок и сосредоточьте i-векторы.
ivectorsMatrix = cat(2,ivectors{:}); N = size(ivectorsMatrix,2); mu = mean(ivectorsMatrix,2); ivectorsMatrix = ivectorsMatrix - mu;
Определите матрицу отбеливания из учебных i-векторов и затем побелите i-векторы. Задайте или отбеливание ZCA, отбеливание PCA или никакое отбеливание.
whiteningType = 'ZCA'; if strcmpi (whiteningType,'ZCA') S = cov (ivectorsMatrix'); [~, sD, sV] = svd (S); W = diag (1. / (sqrt (diag (sD)) + eps)) *sV'; ivectorsMatrix = W * ivectorsMatrix; elseif strcmpi (whiteningType,'PCA') S = cov (ivectorsMatrix'); [sV, sD] = eig (S); W = diag (1. / (sqrt (diag (sD)) + eps)) *sV'; ivectorsMatrix = W * ivectorsMatrix; else W = глаз (размер (ivectorsMatrix, 1)); end
Примените нормализацию длины и затем преобразуйте учебную матрицу i-вектора назад в массив ячеек.
ivectorsMatrix = ivectorsMatrix./vecnorm(ivectorsMatrix);
Вычислите глобальный момент второго порядка как
S = ivectorsMatrix*ivectorsMatrix';
Преобразуйте учебную матрицу i-вектора назад в массив ячеек.
ivectors = mat2cell(ivectorsMatrix,D,utterancePerSpeaker);
Сортировка людей согласно количеству выборок и затем группирует i-векторы количеством произнесения на динамик. Предварительно вычислите момент первого порядка - человек th как
uniqueLengths = unique(utterancePerSpeaker); numUniqueLengths = numel(uniqueLengths); speakerIdx = 1; f = zeros(D,K); for uniqueLengthIdx = 1:numUniqueLengths idx = find(utterancePerSpeaker==uniqueLengths(uniqueLengthIdx)); temp = {}; for speakerIdxWithinUniqueLength = 1:numel(idx) rho = ivectors(idx(speakerIdxWithinUniqueLength)); temp = [temp;rho]; %#ok<AGROW> f(:,speakerIdx) = sum(rho{:},2); speakerIdx = speakerIdx+1; end ivectorsSorted{uniqueLengthIdx} = temp; %#ok<SAGROW> end
Инициализируйте eigenvoices матрицу, V, и обратный шумовой термин отклонения, .
V = randn(D,numEigenVoices); Lambda = pinv(S/N);
Задайте количество итераций для алгоритма EM и применить ли минимальное расхождение.
numIter = 5; minimumDivergence = true;
Обучите модель G-PLDA с помощью алгоритма EM, описанного в [13].
for iter = 1:numIter % EXPECTATION gamma = zeros(numEigenVoices,numEigenVoices); EyTotal = zeros(numEigenVoices,K); R = zeros(numEigenVoices,numEigenVoices); idx = 1; for lengthIndex = 1:numUniqueLengths ivectorLength = uniqueLengths(lengthIndex); % Isolate i-vectors of the same given length iv = ivectorsSorted{lengthIndex}; % Calculate M M = pinv(ivectorLength*(V'*(Lambda*V)) + eye(numEigenVoices)); % Equation (A.7) in [13] % Loop over each speaker for the current i-vector length for speakerIndex = 1:numel(iv) % First moment of latent variable for V Ey = M*V'*Lambda*f(:,idx); % Equation (A.8) in [13] % Calculate second moment. Eyy = Ey * Ey'; % Update Ryy R = R + ivectorLength*(M + Eyy); % Equation (A.13) in [13] % Append EyTotal EyTotal(:,idx) = Ey; idx = idx + 1; % If using minimum divergence, update gamma. if minimumDivergence gamma = gamma + (M + Eyy); % Equation (A.18) in [13] end end end % Calculate T TT = EyTotal*f'; % Equation (A.12) in [13] % MAXIMIZATION V = TT'*pinv(R); % Equation (A.16) in [13] Lambda = pinv((S - V*TT)/N); % Equation (A.17) in [13] % MINIMUM DIVERGENCE if minimumDivergence gamma = gamma/K; % Equation (A.18) in [13] V = V*chol(gamma,'lower');% Equation (A.22) in [13] end end
Если вы обучили модель G-PLDA, можно использовать ее, чтобы вычислить счет на основе отношения логарифмической правдоподобности как описано в [14]. Учитывая два i-вектора, которые были сосредоточены, побеленные и нормированные на длину, счет вычисляется как:
где и прием и тестирует i-векторы, матрица отклонения шумового термина, eigenvoice матрица. термин является учтенными константами и может быть пропущен на практике.
speakerIdx = 2; utteranceIdx = 1; w1 = ivectors {speakerIdx} (: utteranceIdx); speakerIdx = 1; utteranceIdx = 10; вес = ivectors {speakerIdx} (: utteranceIdx); VVt = V*V'; SigmaPlusVVt = pinv (Lambda) + VVt; term1 = pinv ([SigmaPlusVVt VVt; VVt SigmaPlusVVt]); term2 = pinv (SigmaPlusVVt); w1wt = [w1; вес]; выиграйте = w1wt '*term1*w1wt - w1 '*term2*w1 - вес '*term2*wt
score = 59.0358
В практике тестовые i-векторы, и в зависимости от вашей системы, прием ivectors, не используются в обучении модели G-PLDA. В следующем разделе оценки вы используете ранее невидимые данные для приема и верификации. Функция поддержки, gpldaScore инкапсулирует шаги выигрыша выше, и дополнительно выполняет центрирование, отбеливание и нормализацию. Сохраните обученную модель G-PLDA как struct для использования с функцией поддержки gpldaScore
.
gpldaModel = struct('mu',mu, ... 'WhiteningMatrix',W, ... 'EigenVoices',V, ... 'Sigma',pinv(Lambda));
Зарегистрируйте новых докладчиков, которые не были в обучающем наборе данных. Во-первых, разделите adsEnrollAndVerify
аудио объект datastore в регистрирует и проверяет. Увеличение числа произнесения на динамик для приема должно увеличить эффективность системы.
numFilesPerSpeakerForEnrollment = 3;
[adsEnroll, adsVerify] = splitEachLabel (adsEnrollAndVerify, numFilesPerSpeakerForEnrollment);
adsVerify = перестановка (adsVerify);
adsEnroll = перестановка (adsEnroll);
countEachLabel (adsEnroll)
ans=4×2 table
Label Count
_____ _____
F01 3
F05 3
M01 3
M05 3
countEachLabel(adsVerify)
ans=4×2 table
Label Count
_____ _____
F01 233
F05 233
M01 233
M05 233
Создайте 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 (1 seconds).
В бухгалтерских целях преобразуйте массив ячеек i-векторов к структуре с идентификаторами динамика как поля и i-векторы как значения
enrolledSpeakers = struct; for s = 1:numSpeakers enrolledSpeakers.(string(speakers(s))) = enrolledSpeakersByIdx{s}; end
Задайте или CSS или G-PLDA выигрыш метода.
scoringMethod = 'GPLDA';
Ложный уровень отклонения (FRR) динамика является уровнем, что данный динамик неправильно отклоняется. Создайте массив музыки к зарегистрированным i-векторам динамика и i-векторам из того же динамика.
speakersToTest = unique(adsVerify.Labels); numSpeakers = numel(speakersToTest); scoreFRR = 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> score = 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; % Score if strcmpi(scoringMethod,'CSS') score(fileIdx) = dot(ivectorToTest,ivector)/(norm(ivector)*norm(ivectorToTest)); else score(fileIdx) = gpldaScore(gpldaModel,ivector,ivectorToTest); end end scoreFRR{speakerIdx} = score; end fprintf('FRR calculated (%0.0f seconds).\n',toc)
FRR calculated (35 seconds).
Ложная пропускная способность (FAR) динамика является уровнем, что произнесение, не принадлежащее зарегистрированному докладчику, неправильно принято как принадлежащий зарегистрированному докладчику. Создайте массив музыки к зарегистрированным докладчикам и i-векторам из различных динамиков.
speakersToTest = unique(adsVerify.Labels); numSpeakers = numel(speakersToTest); scoreFAR = cell(numSpeakers,1); tic parfor speakerIdx = 1:numSpeakers adsPart = subset(adsVerify,adsVerify.Labels~=speakersToTest(speakerIdx)); adsPart = splitEachLabel(adsPart,0.2) % Reduce the number of test files to speed up the example. numFiles = numel(adsPart.Files); ivectorToTest = enrolledSpeakers.(string(speakersToTest(speakerIdx))); %#ok<PFBNS> score = 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; % Score if strcmpi(scoringMethod,'CSS') score(fileIdx) = dot(ivectorToTest,ivector)/(norm(ivector)*norm(ivectorToTest)); else score(fileIdx) = gpldaScore(gpldaModel,ivector,ivectorToTest); end end scoreFAR{speakerIdx} = score; end
Чтобы сравнить несколько систем, вам нужна одна метрика, которая комбинирует FAR и эффективность FRR. Для этого вы определяете равный коэффициент ошибок (EER), который является порогом, где FAR и кривые FRR встречаются. На практике порог EER не может быть лучшим выбором. Например, если бы верификация динамика используется в качестве части подхода мультиаутентификации для проводных передач, FAR был бы, скорее всего, в большей степени взвешен, чем FRR.
amin = min(cat(1,scoreFRR{:},scoreFAR{:})); amax = max(cat(1,scoreFRR{:},scoreFAR{:})); thresholdsToTest = linspace(amin,amax,1000); % Compute the FRR and FAR for each of the thresholds. if strcmpi(scoringMethod,'CSS') % In CSS, a larger score indicates the enroll and test ivectors are % similar. FRR = mean(cat(1,scoreFRR{:})<thresholdsToTest); FAR = mean(cat(1,scoreFAR{:})>thresholdsToTest); else % In G-PLDA, a smaller score indicates the enroll and test ivectors are % similar. FRR = mean(cat(1,scoreFRR{:})>thresholdsToTest); FAR = mean(cat(1,scoreFAR{:})<thresholdsToTest); end [~,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','best') grid on axis tight
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
function score = gpldaScore(gpldaModel,w1,wt) % Center the data w1 = w1 - gpldaModel.mu; wt = wt - gpldaModel.mu; % Whiten the data w1 = gpldaModel.WhiteningMatrix*w1; wt = gpldaModel.WhiteningMatrix*wt; % Length-normalize the data w1 = w1./vecnorm(w1); wt = wt./vecnorm(wt); % Score the similarity of the i-vectors based on the log-likelihood. VVt = gpldaModel.EigenVoices * gpldaModel.EigenVoices'; SVVt = gpldaModel.Sigma + VVt; term1 = pinv([SVVt VVt;VVt SVVt]); term2 = pinv(SVVt); w1wt = [w1;wt]; score = w1wt'*term1*w1wt - w1'*term2*w1 - wt'*term2*wt; 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] Matejka, Павел, Ondrej Glembek, Фабио Кастальдо, M.j. Алам, Oldrich Plchot, Патрик Кенни, Лукаш Бургет и Ян Серноки. “Full-Covariance UBM и PLDA с тяжелым хвостом в Верификации Динамика i-вектора”. 2 011 Международных конференций IEEE по вопросам Акустики, Речи и Обработки сигналов (ICASSP), 2011. https://doi.org/10.1109/icassp.2011.5947436.
[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.
[11] Д. Гарсия-Ромеро и К. замечать-Вильсон, “Анализ Нормализации I-длины-вектора в Системах Распознавания Динамика”. Межречь, 2011, стр 249–252.
[12] Кенни, Патрик. "Байесова верификация динамика с уголовным прошлым с тяжелым хвостом". Одиссея 2010 - семинар распознавания динамика и языка, Брно, Чешская Республика, 2010.
[13] Сизов, Александр, Кун Айк Ли и Томи Киннунен. “Объединяя Вероятностные Варианты Линейного дискриминантного анализа в Биометрической Аутентификации”. Читайте лекции Примечаниям в Информатике Структурное, Синтаксическое, и Статистическое Распознавание образов, 2014, 464–75. https://doi.org/10.1007/978-3-662-44415-3_47.
[14] Раджан, Padmanabhan, Антон Афанасьев, Ville Hautamäki и Tomi Kinnunen. 2014. “От Одного до Нескольких I-векторов Приема: Практический PLDA Выигрыш Вариантов для Верификации Динамика”. Цифровая обработка сигналов 31 (август): 93–101. https://doi.org/10.1016/j.dsp.2014.05.001.