1. 程式人生 > >矢量量化(VQ)

矢量量化(VQ)

遞增 思想 -s 效果 通過 得到 很好 ids 想要

作者:桂。

時間:2017-05-31 21:14:56

鏈接:http://www.cnblogs.com/xingshansi/p/6925955.html


前言

VQ(Vector Quantization)是一個常用的壓縮技術,本文主要回顧:

  1)VQ原理

  2)基於VQ的說話人識別(SR,speaker recognition)技術

〇、分類問題

說話人識別其實也是一個分類問題:

技術分享

說話人識別技術,主要有這幾大類方法:

  • 模板匹配方法

這類方法比較成熟,主要原理:特征提取、模板訓練、匹配。典型的有:動態時間規整DTW,矢量量化VQ等。

DTW利用動態規劃的思想,但也有不足:1)過分依賴VAD技術;2)沒有充分利用語音的時序動態特性,所以被HMM取代也就容易理解了。

VQ算法是數據壓縮的方法。碼本簡歷、碼字搜索是兩個基本問題,碼本簡歷是從大量信號樣本中訓練出比較好的碼書,碼字搜索是找到一個和輸入最匹配的碼字,該方法簡單,對小系統、差別明顯的聲音較合適。

  • 基於統計模型的分類方法

該類方法本質仍是模式識別系統,都需要提取特征,然後訓練分類器,最後分類決策,典型框架:

技術分享

常用的模型有:GMM、HMM、SVM、ANN、DNN或者各種聯合模型等。

GMM基本框架:

技術分享

類似的還有GMM-UBM(Universal background model)算法,其與GMM的區別在於:對L類整體樣本訓練一個大的GMM,而不像GMM對每一類訓練一個GMM模型。SVM的話MFCC作為特征,每一幀作為一個樣本,可以借助VAD刪除無效音頻段,直接訓練分類。近年來也有利用稀疏表達的方法:

技術分享

一、VQ原理

此段摘自Pluskid博客。

Vector Quantization 這項技術廣泛地用在信號處理以及數據壓縮等領域。事實上,在 JPEG 和 MPEG-4 等多媒體壓縮格式裏都有 VQ 這一步。

  Vector Quantization 這個名字聽起來有些玄乎,其實它本身並沒有這麽高深。大家都知道,模擬信號是連續的值,而計算機只能處理離散的數字信號,在將模擬信號轉換為數字信號的時候,我們可以用區間內的某一個值去代替著一個區間,比如,[0, 1) 上的所有值變為 0 ,[1, 2) 上的所有值變成 1 ,如此類推。其這就是一個 VQ 的過程。一個比較正式一點的定義是:VQ 是將一個向量空間中的點用其中的一個有限子集來進行編碼的過程。

  一個典型的例子就是圖像的編碼。最簡單的情況,考慮一個灰度圖片,0 為黑色,1 為白色,每個像素的值為 [0, 1] 上的一個實數。現在要把它編碼為 256 階的灰階圖片,一個最簡單的做法就是將每一個像素值 x 映射為一個整數 floor(x*255) 。當然,原始的數據空間也並不以一定要是連續的。比如,你現在想要把壓縮這個圖片,每個像素只使用 4 bit (而不是原來的 8 bit)來存儲,因此,要將原來的 [0, 255] 區間上的整數值用 [0, 15] 上的整數值來進行編碼,一個簡單的映射方案是 x*15/255

  不過這樣的映射方案頗有些 Naive ,雖然能減少顏色數量起到壓縮的效果,但是如果原來的顏色並不是均勻分布的,那麽的出來的圖片質量可能並不是很好。例如,如果一個 256 階灰階圖片完全由 0 和 13 兩種顏色組成,那麽通過上面的映射就會得到一個全黑的圖片,因為兩個顏色全都被映射到 0 了。一個更好的做法是結合聚類來選取代表性的點。

實際做法就是:將每個像素點當作一個數據,跑一下 K-means ,得到 k 個 centroids ,然後用這些 centroids 的像素值來代替對應的 cluster 裏的所有點的像素值。對於彩色圖片來說,也可以用同樣的方法來做,例如 RGB 三色的圖片,每一個像素被當作是一個 3 維向量空間中的點。

用本文開頭那張 Rechard Stallman 大神的照片來做一下實驗好了,VQ 2、VQ 10 和 VQ 100 三張圖片分別顯示聚類數目為 2 、10 和 100 時得到的結果:

技術分享

傳統LBG算法就是K-means,基於分裂的LBG稱為LBG-VQ,LBG-VQ算法以及K-means:

技術分享

二、基於VQ的說話人識別技術

基於VQ方法:例如N個說話人,每個說話人建立一個碼本,共N個碼本。每個碼本如何建立呢?以MFCC為例,M幀的MFCC,每一幀都是一個多維N的樣本點,訓練數據量通常較大MxN,聚類成K類是容易實現的(K<<M),LBG-VQ的思路則是利用分裂的思想,通常按倍數遞增,知道碼本數量增加到:碼本的誤差達到預設值停止,最終的結果相當於降維:KxN,也就是碼本的維度。

技術分享

總結一下基於VQ的說話人識別的基本思路:

1)訓練:分別針對每個說話人提取特征,利用特征訓練碼本(Kmeans/LBG-VQ等方法);

2)識別:提取測試數據的特征,與碼本匹配,誤差距離歸一化並求和,最小值即為對應的說話人;

VQLBG代碼

%% VQLBG Vector quantization using the Linde-Buzo-Gray algorithm
% VQLBG Vector quantization using the Linde-Buzo-Gray algorithm
%
% Inputs: d contains training data vectors (one per column)
% k is number of centroids required
%
% Output: r contains the result VQ codebook (k columns, one for each  centroids)

function r = vqlbg(d,k)
e = .01;
r = mean(d, 2);
dpr = 10000;
for i = 1:log2(k)
    r = [r*(1+e), r*(1-e)];
    while (1 == 1)
        z = disteu(d, r);
        [m,ind] = min(z, [], 2);
        t = 0;
        for j = 1:2^i
            r(:, j) = mean(d(:, find(ind == j)), 2); %#ok<FNDSB>
            x = disteu(d(:, find(ind == j)), r(:, j)); %#ok<FNDSB>
            for q = 1:length(x)
                t = t + x(q);
            end
        end
        if (((dpr - t)/t) < e)
            break;
        else
            dpr = t;
        end
    end
end
end
%% DISTEU Function
% DISTEU Pairwise Euclidean distances between columns of two matrices 
% 
% Input: 
% x, y: Two matrices whose each column is an a vector data. 
% 
% Output: 
% d: Element d(i,j) will be the Euclidean distance between two 
% column vectors X(:,i) and Y(:,j) 
% 
% Note: 
% The Euclidean distance D between two vectors X and Y is: 
% D = sum((x-y).^2).^0.5 

function d = disteu(x, y) 
[M, N] = size(x); 
[M2, P] = size(y); 
if (M ~= M2) 
error(‘Matrix dimensions do not match.‘) 
end 
d = zeros(N, P);
% if (N < P) 
% copies = zeros(1,P); 
% for n = 1:N 
% d(n,:) = sum((x(:, n+copies) - y) .^2, 1); 
% end 
% else 
% copies = zeros(1,N); 
% for p = 1:P 
% d(:,p) = sum((x - y(:, p+copies)) .^2, 1)‘; 
% end 
% end 
% d = d.^0.5; 
for ii=1:N 
for jj=1:P 
%d(ii,jj)=sum((x(:,ii)-y(:,jj)).^2).^0.5; 
d(ii,jj) = mydistance(x(:,ii),y(:,jj),2); 
end 
end
%-------------------------------------------------------------------------- 
%--------------------------------------------------------------------------
end

  識別的主要code:

v = mfcc(str{classe},fstr{classe});
% Current distance and sound ID initialization
distmin = Inf;
k1 = 0;
for ii=1:sound_number
	d = disteu(v, code{ii});
	dist = sum(min(d,[],2)) / size(d,1);
	if dist < distmin
		distmin = dist;
		k1 = ii;
	end
end
min_index = k1;

    

參考

  • http://blog.pluskid.org/?p=57
  • http://blog.csdn.net/momosp/article/details/7626971

矢量量化(VQ)