說話人識別matlab實現

轉自:https://blog.csdn.net/qq_18124075/article/details/78867536

說話人識別

這裏,博主對說話人兩個baseline模型應該matlab的MSR工具箱進行處理。

1、GMM-UBM說話人識別

這裏主要分爲4個步驟:
1、訓練UBM通用背景模型
2、最大後驗準則MAP從UBM通用背景模型裏面訓練每一個說話人的聲學模型
3、交叉得分
4、計算最終的測試效果,這裏用AUC和EER表示,可以方便與最近的深度學習方法做比較。
具體程序
設置環境參數:說話人有20個。每一幀的維度爲13,這裏可以根據MFCC的維度進行修改。一般語音數據都是單信道,這裏可以對信道進行設置,本實驗的信道爲10。
[plain] view plain copy
  1. nSpeakers = 20;  
  2. nDims = 13;             % dimensionality of feature vectors  
  3. nMixtures = 32;         % How many mixtures used to generate data  
  4. nChannels = 10;         % Number of channels (sessions) per speaker  
  5. nFrames = 100;         % Frames per speaker (10 seconds assuming 100 Hz)  
  6. nWorkers = 1;           % Number of parfor workers, if available  

這裏爲了方便不用一般的語音數據庫如TIMIT,直接生產隨機多信道的音頻數據(10信道)。這裏trainSpeakerData和testSpeakerData爲20*10的cell,20爲說話人的個數,10爲說話人的信道數。每個說話人在訓練和測試集裏面是一一對應的。在每一個cell裏面維度爲13*100,13爲分幀之後的維度,100位幀數,在實際中分幀後的語音都會經過MFCC特徵提取。
[plain] view plain copy
  1. % Pick random centers for all the mixtures.  
  2. mixtureVariance = .10;  
  3. channelVariance = .05;  
  4. mixtureCenters = randn(nDims, nMixtures, nSpeakers);  
  5. channelCenters = randn(nDims, nMixtures, nSpeakers, nChannels)*.1;  
  6. trainSpeakerData = cell(nSpeakers, nChannels);  
  7. testSpeakerData = cell(nSpeakers, nChannels);  
  8. speakerID = zeros(nSpeakers, nChannels);  
  9.   
  10. % Create the random data. Both training and testing data have the same  
  11. % layout.  
  12. disp('Create the random data');  
  13. for s=1:nSpeakers  
  14.     trainSpeechData = zeros(nDims, nMixtures);  
  15.     testSpeechData = zeros(nDims, nMixtures);  
  16.     for c=1:nChannels  
  17.         for m=1:nMixtures  
  18.             % Create data from mixture m for speaker s  
  19.             frameIndices = m:nMixtures:nFrames;  
  20.             nMixFrames = length(frameIndices);  
  21.             trainSpeechData(:,frameIndices) = ...  
  22.                 randn(nDims, nMixFrames)*sqrt(mixtureVariance) + ...  
  23.                 repmat(mixtureCenters(:,m,s),1,nMixFrames) + ...  
  24.                 repmat(channelCenters(:,m,s,c),1,nMixFrames);  
  25.             testSpeechData(:,frameIndices) = ...  
  26.                 randn(nDims, nMixFrames)*sqrt(mixtureVariance) + ...  
  27.                 repmat(mixtureCenters(:,m,s),1,nMixFrames) + ...  
  28.                 repmat(channelCenters(:,m,s,c),1,nMixFrames);  
  29.         end  
  30.         trainSpeakerData{s, c} = trainSpeechData;  
  31.         testSpeakerData{s, c} = testSpeechData;  
  32.         speakerID(s,c) = s;                 % Keep track of who this is  
  33.     end  
  34. end  

現在正式進入GMM-UBM階段:
訓練UBM通用背景模型,UBM也可以理解成混合高斯模型,說白了就是多個告訴模型的加權和。它的作用可以在說話人語料不足的情況下,依據UBM模型自適應得到集內說話人的模型。我們對高斯模型進行參數估計,會得到一個ubm的結構體,裏面包含了每個說話人的權值、mu、sigma。
[plain] view plain copy
  1. % Step1: Create the universal background model from all the training speaker data  
  2. disp('Create the universal background model');  
  3. nmix = nMixtures;           % In this case, we know the # of mixtures needed  
  4. final_niter = 10;  
  5. ds_factor = 1;  
  6. ubm = gmm_em(trainSpeakerData(:), nmix, final_niter, ds_factor, nWorkers);  

最大後驗準則MAP從UBM通用背景模型裏面訓練每一個說話人的聲學模型,自適應的策略是根據目標說話人的訓練集trainSpeakerData特徵矢量與第一步求得的UBM的相似程度,將UBM的各個高斯分量按訓練集特徵矢量進行調整,從而形成目標說話人的聲學模型。再根據EM重估公式,計算每一個說話人修正模型的最優參數。

[html] view plain copy
  1. % Step2: Now adapt the UBM to each speaker to create GMM speaker model.  
  2. disp('Adapt the UBM to each speaker');  
  3. map_tau = 10.0;  
  4. config = 'mwv';  
  5. gmm = cell(nSpeakers, 1);  
  6. for s=1:nSpeakers  
  7.     disp(['for the ',num2str(s),' speaker...']);  
  8.     gmm{s} = mapAdapt(trainSpeakerData(s, :), ubm, map_tau, config);  
  9. end  

計算每個說話人模型的得分。因爲在說話人確認系統中,與說話人辨認不同,測試目標testSpeakerData變爲確認某段測試語音是否來源於某個目標說話人,本實驗爲20個說話人。如果測試語音與目標語音來源於相同的說話人,則此次測試爲目標測試(target test);反之,如果測試語音與目標語音來源與不同的說話人,則此次測試爲非目標測試(non-target test)。將目標測試與非目標測試的後驗概率比作爲得分。

[plain] view plain copy
  1. % Step3: Now calculate the score for each model versus each speaker's data.  
  2. % Generate a list that tests each model (first column) against all the  
  3. % testSpeakerData.  
  4. trials = zeros(nSpeakers*nChannels*nSpeakers, 2);  
  5. answers = zeros(nSpeakers*nChannels*nSpeakers, 1);  
  6. for ix = 1 : nSpeakers,  
  7.     b = (ix-1)*nSpeakers*nChannels + 1;  
  8.     e = b + nSpeakers*nChannels - 1;  
  9.     trials(b:e, :)  = [ix * ones(nSpeakers*nChannels, 1), (1:nSpeakers*nChannels)'];  
  10.     answers((ix-1)*nChannels+b : (ix-1)*nChannels+b+nChannels-1) = 1;  
  11. end  
  12. disp('Calculate the score for each model vs test speaker');  
  13. gmmScores = score_gmm_trials(gmm, reshape(testSpeakerData', nSpeakers*nChannels,1), trials, ubm);  

計算指標AUC和EER。對於開集的說話人辨認系統,需要將測試語音的輸出得分與特定的閾值進行比較,以做出是否是集外說話人的判決。對於說話人確認系統,需要對測試語音的輸出得分進行判決,一般是將其與一特定的閾值進行比較,若大於此閾值則接受其爲目標說話人,否則判定其爲冒認說話人。因而,閾值的選取對說話人識別系統的性能有着直接的影響,尤其是在實用的說話人識別系統研究中,閾值選取問題更是得到了研究者們的廣泛關注,提出了許多有效的閾值選取方法,其中比較常用的有等錯誤率(equal error rate,EER)閾值。這裏,博主加入了AUC,可以方便與深度學習方法做對比。

[plain] view plain copy
  1. % Step4: Now compute the EER and plot the DET curve and confusion matrix  
  2. imagesc(reshape(gmmScores,nSpeakers*nChannels, nSpeakers))  
  3. title('Speaker Verification Likelihood (GMM Model)');  
  4. ylabel('Test # (Channel x Speaker)'); xlabel('Model #');  
  5. colorbar; drawnow; axis xy  
  6. figure  
  7. disp('Compute the EER');  
  8. [eer,auc] = compute_eer(gmmScores, answers, true);  

2、基於ivector的GMM-UBM說話人識別

基於ivector的GMM-UBM模型是最近比較流行的baseline方法,這篇博客說得比較詳細。這裏就不再囉嗦地說明了。具體實現步驟爲
1、訓練UBM通用背景模型
2、計算通用背景模型的總變化空間
3、訓練Gaussian 概率線性判別PLDA模型,這樣可以極大程度地提高ivector對說話人識別的影響
4、交叉得分
5、計算最終的測試效果,這裏用AUC和EER表示,可以方便與最近的深度學習方法做比較。
其具體部分程序如下:

[plain] view plain copy
  1. % Step1: Create the universal background model from all the training speaker data  
  2. nmix = nMixtures;           % In this case, we know the # of mixtures needed  
  3. final_niter = 10;  
  4. ds_factor = 1;  
  5. ubm = gmm_em(trainSpeakerData(:), nmix, final_niter, ds_factor, nWorkers);  
  6.   
  7.   
  8. %%  
  9. % Step2.1: Calculate the statistics needed for the iVector model.  
  10. stats = cell(nSpeakers, nChannels);  
  11. for s=1:nSpeakers  
  12.     for c=1:nChannels  
  13.         [N,F] = compute_bw_stats(trainSpeakerData{s,c}, ubm);  
  14.         stats{s,c} = [N; F];  
  15.     end  
  16. end  
  17.   
  18. % Step2.2: Learn the total variability subspace from all the speaker data.  
  19. tvDim = 100;  
  20. niter = 5;  
  21. T = train_tv_space(stats(:), ubm, tvDim, niter, nWorkers);  
  22. %  
  23. % Now compute the ivectors for each speaker and channel.  The result is size  
  24. %   tvDim x nSpeakers x nChannels  
  25. devIVs = zeros(tvDim, nSpeakers, nChannels);  
  26. for s=1:nSpeakers  
  27.     for c=1:nChannels  
  28.         devIVs(:, s, c) = extract_ivector(stats{s, c}, ubm, T);  
  29.     end  
  30. end  
  31.   
  32. %%  
  33. % Step3.1: Now do LDA on the iVectors to find the dimensions that matter.  
  34. ldaDim = min(100, nSpeakers-1);  
  35. devIVbySpeaker = reshape(devIVs, tvDim, nSpeakers*nChannels);  
  36. [V,D] = lda(devIVbySpeaker, speakerID(:));  
  37. finalDevIVs = V(:, 1:ldaDim)' * devIVbySpeaker;  
  38.   
  39. % Step3.2: Now train a Gaussian PLDA model with development i-vectors  
  40. nphi = ldaDim;                  % should be <= ldaDim  
  41. niter = 10;  
  42. pLDA = gplda_em(finalDevIVs, speakerID(:), nphi, niter);  
  43.   
  44. %%  
  45. % Step4.1: OK now we have the channel and LDA models. Let's build actual speaker  
  46. % models. Normally we do that with new enrollment data, but now we'll just  
  47. % reuse the development set.  
  48. averageIVs = mean(devIVs, 3);           % Average IVs across channels.  
  49. modelIVs = V(:, 1:ldaDim)' * averageIVs;  
  50.   
  51.   
  52. % Step4.2: Now compute the ivectors for the test set   
  53. % and score the utterances against the models  
  54. testIVs = zeros(tvDim, nSpeakers, nChannels);   
  55. for s=1:nSpeakers  
  56.     for c=1:nChannels  
  57.         [N, F] = compute_bw_stats(testSpeakerData{s, c}, ubm);  
  58.         testIVs(:, s, c) = extract_ivector([N; F], ubm, T);  
  59.     end  
  60. end  
  61. testIVbySpeaker = reshape(permute(testIVs, [1 3 2]), ...  
  62.                             tvDim, nSpeakers*nChannels);  
  63. finalTestIVs = V(:, 1:ldaDim)' * testIVbySpeaker;  

3、參考文獻

[1] N. Dehak, P. Kenny, R. Dehak, P. Dumouchel, and P. Ouellet, "Front-end factor analysis for speaker verification," IEEE TASLP, vol. 19, pp. 788-798, May 2011. 
[2] P. Kenny, "A small footprint i-vector extractor," in Proc. Odyssey,  The Speaker and Language Recognition Workshop, Jun. 2012.
[3] D. Matrouf, N. Scheffer, B. Fauve, J.-F. Bonastre, "A straightforward and efficient implementation of the factor analysis model for speaker verification," in Proc.         INTERSPEECH, Antwerp, Belgium, Aug. 2007, pp. 1242-1245.  
 
轉自:http://blog.csdn.net/qq_18124075/article/details/78867536
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章