Верификация динамика Используя i-векторы

Верификация динамика или аутентификация, является задачей подтверждения, что идентичность динамика состоит в том, кем они подразумевают быть. Верификация динамика много лет была активной областью исследования. Ранний прорыв производительности должен был использовать смешанную гауссовскую модель и универсальную фоновую модель (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');

Универсальная фоновая модель (UBM)

Инициализируйте смешанную гауссовскую модель (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-валлийскую статистику

Baum-валлийскими статистическими данными является N (нулевой порядок) и F (первый порядок) статистика, используемая в алгоритме EM, вычисленное использование итогового UBM.

Nc(s)=tγt(c)

Fc(s)=tγt(c)Yt

  • Yt характеристический вектор во время t.

  • s{s1,s2,...,sN}, где N количество динамиков. В целях обучения общий пробел изменчивости каждый звуковой файл рассматривается отдельным динамиком (принадлежит ли это физическому одному динамику).

  • γt(c) апостериорная вероятность что компонент UBM c счета на характеристический вектор Yt.

Вычислите 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).

Расширьте статистику в матрицы и центр F(s), как описано в [3], такой, что

  • N(s) isa CF×CF диагональная матрица, блоки которой Nc(s)I(c=1,...C).

  • F(s) isa CF×1 супервектор получен путем конкатенации Fc(s)  (c=1,...C).

  • C количество компонентов в UBM.

  • F количество функций в характеристическом векторе.

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-вектора докладчика.

M=m+Tw

  • M супервектор произнесения динамика

  • m динамик - и независимый от канала супервектор, который может быть взят, чтобы быть супервектором UBM.

  • T низкий ранг прямоугольная матрица и представляет общее подпространство изменчивости.

  • w i-вектор для динамика

Размерность i-вектора, w, обычно намного ниже, чем C F - размерный супервектор произнесения динамика, делая i-вектор, или i-векторы, намного более компактное и послушное представление.

Обучать общий пробел изменчивости, T, сначала случайным образом инициализируйте T, затем выполните эти шаги итеративно [3]:

  1. Вычислите апостериорное распределение скрытой переменной.

lT(s)=I+T×Σ-1×N(s)×T

2. Накопите статистику через динамики.

Κ=sF(s)×(lT-1(s)×T×Σ-1×F(s))

Ac=sNc(s)lT-1(s)

3. Обновите общий пробел изменчивости.

Tc=Ac-1×Κ

T=[T1T2TC]

[3] предлагает инициализировать Σ отклонением UBM и затем обновлением Σ согласно уравнению:

Σ=(sN(s))-1((sS(s))-diag(Κ×T))

где 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-вектора

Если общий пробел изменчивости вычисляется, можно вычислить i-векторы как [4]:

w=(I+TΣ-1NT)TΣ-1F

На данном этапе вы все еще рассматриваете каждый учебный файл как отдельный динамик. Однако на следующем шаге, когда вы обучаете матрицу проекции уменьшать размерность и увеличивать различия междинамика, 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]:

Данный:

Sb=s=1S(ws-w)(ws-w)

Sw=s=1S1nsi=1ns(wis-ws)(wis-ws)

где

  • ws=(1ns)i=1nswis среднее значение i-векторов для каждого динамика.

  • w=1Ns=1Si=1nswis средний i-вектор через все динамики.

  • ns количество произнесения для каждого динамика.

Решите уравнение собственного значения для лучших собственных векторов:

Sbv=λSwv

Лучшие собственные вектора - те с самыми высокими собственными значениями.

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].

Учитывая ковариационную матрицу в классе:

W=1Ss=1S1nsi=1ns(wis-ws)(wis-ws)

где

  • ws=(1ns)i=1nswis среднее значение i-векторов для каждого динамика.

  • ns количество произнесения для каждого динамика.

Решите для B использование разложения Холесского:

W-1=BB

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-векторы для каждого файла для каждого динамика в зарегистрировать наборе с помощью этой последовательности шагов:

  1. Извлечение признаков

  2. Baum-валлийская Статистика: Определите статистику нулевого и первого порядка

  3. Экстракция i-вектора

  4. Компенсация межсеанса

Затем насчитайте 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) динамика является уровнем, что данный динамик неправильно отклоняется. Используйте набор данных динамика верификации, чтобы определить динамик 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) динамика является уровнем, что произнесение, не принадлежащее зарегистрированному докладчику, неправильно принято как принадлежащий зарегистрированному докладчику. Используйте известный набор динамика, чтобы определить 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])

Ошибочный компромисс обнаружения (DET)

Когда вы перемещаете порог в систему верификации динамика, вы обмениваете между 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])

Равный коэффициент ошибок (EER)

Чтобы сравнить несколько систем, вам нужна одна метрика, которая комбинирует 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.