矢量量化方法,即vector quantization,其具体定义为:将一个向量空间中的点用其中的一个有限子集来进行编码的过程。在矢量量化编码中,关键是码本的建立和码字搜索算法。比如常见的聚类算法,就是一种矢量量化方法。而在ANN近似最近邻搜索中,向量量化方法又以乘积量化(PQ, Product Quantization)最为典型。在之前的博文基于内容的图像检索技术的最后,对PQ乘积量化的方法做过简单的概要。在这一小节里,小白菜结合自己阅读的论文和代码对PQ乘积量化、倒排乘积量化(IVFPQ)做一种更加直观的解释。
1 PQ乘积量化
PQ乘积量化的核心思想还是聚类,或者说具体应用到ANN近似最近邻搜索上,K-Means是PQ乘积量化子空间数目为1的特例。PQ乘积量化生成码本和量化的过程可以用如下图示来说明:
在训练阶段,针对N个训练样本,假设样本维度为128维,我们将其切分为4个子空间,则每一个子空间的维度为32维,然后我们在每一个子空间中,对子向量采用K-Means对其进行聚类(图中示意聚成256类),这样每一个子空间都能得到一个码本。这样训练样本的每个子段,都可以用子空间的聚类中心来近似,对应的编码即为类中心的ID。如图所示,通过这样一种编码方式,训练样本仅使用的很短的一个编码得以表示,从而达到量化的目的。对于待编码的样本,将它进行相同的切分,然后在各个子空间里逐一找到距离它们最近的类中心,然后用类中心的id来表示它们,即完成了待编码样本的编码。
正如前面所说的,在矢量量化编码中,关键是码本的建立和码字的搜索算法,在上面,我们得到了建立的码本以及量化编码的方式。剩下的重点就是查询样本与dataset中的样本距离如何计算的问题了。
在查询阶段,PQ同样在计算查询样本与dataset中各个样本的距离,只不过这种距离的计算转化为间接近似的方法而获得。PQ乘积量化方法在计算距离的时候,有两种距离计算方式,一种是对称距离,另外一种是非对称距离。非对称距离的损失小(也就是更接近真实距离),实际中也经常采用这种距离计算方式。下面过程示意的是查询样本来到时,以非对称距离的方式(红框标识出来的部分)计算到dataset样本间的计算示意:
具体地,查询向量来到时,按训练样本生成码本的过程,将其同样分成相同的子段,然后在每个子空间中,计算子段到该子空间中所有聚类中心得距离,如图中所示,可以得到4*256个距离,这里为便于后面的理解说明,小白菜就把这些算好的距离称作距离池。在计算库中某个样本到查询向量的距离时,比如编码为(124, 56, 132, 222)这个样本到查询向量的距离时,我们分别到距离池中取各个子段对应的距离即可,比如编码为124这个子段,在第1个算出的256个距离里面把编号为124的那个距离取出来就可,所有子段对应的距离取出来后,将这些子段的距离求和相加,即得到该样本到查询样本间的非对称距离。所有距离算好后,排序后即得到我们最终想要的结果。
从上面这个过程可以很清楚地看出PQ乘积量化能够加速索引的原理:即将全样本的距离计算,转化为到子空间类中心的距离计算。比如上面所举的例子,原本brute-force search的方式计算距离的次数随样本数目N成线性增长,但是经过PQ编码后,对于耗时的距离计算,只要计算4*256次,几乎可以忽略此时间的消耗。另外,从上图也可以看出,对特征进行编码后,可以用一个相对比较短的编码来表示样本,自然对于内存的消耗要大大小于brute-force search的方式。
在某些特殊的场合,我们总是希望获得精确的距离,而不是近似的距离,并且我们总是喜欢获取向量间的余弦相似度(余弦相似度距离范围在[-1,1]之间,便于设置固定的阈值),针对这种场景,可以针对PQ乘积量化得到的前top@K做一个brute-force search的排序。
2 倒排乘积量化
倒排PQ乘积量化(IVFPQ)是PQ乘积量化的更进一步加速版。其加速的本质逃不开小白菜在最前面强调的是加速原理:brute-force搜索的方式是在全空间进行搜索,为了加快查找的速度,几乎所有的ANN方法都是通过对全空间分割,将其分割成很多小的子空间,在搜索的时候,通过某种方式,快速锁定在某一(几)子空间,然后在该(几个)子空间里做遍历。在上一小节可以看出,PQ乘积量化计算距离的时候,距离虽然已经预先算好了,但是对于每个样本到查询样本的距离,还是得老老实实挨个去求和相加计算距离。但是,实际上我们感兴趣的是那些跟查询样本相近的样本(小白菜称这样的区域为感兴趣区域),也就是说老老实实挨个相加其实做了很多的无用功,如果能够通过某种手段快速将全局遍历锁定为感兴趣区域,则可以舍去不必要的全局计算以及排序。倒排PQ乘积量化的”倒排“,正是这样一种思想的体现,在具体实施手段上,采用的是通过聚类的方式实现感兴趣区域的快速定位,在倒排PQ乘积量化中,聚类可以说应用得淋漓尽致。
倒排PQ乘积量化整个过程如下图所示:
在PQ乘积量化之前,增加了一个粗量化过程。具体地,先对N个训练样本采用K-Means进行聚类,这里聚类的数目一般设置得不应过大,一般设置为1024差不多,这种可以以比较快的速度完成聚类过程。得到了聚类中心后,针对每一个样本x_i,找到其距离最近的类中心c_i后,两者相减得到样本x_i的残差向量(x_i-c_i),后面剩下的过程,就是针对(x_i-c_i)的PQ乘积量化过程,此过程不再赘述。
在查询的时候,通过相同的粗量化,可以快速定位到查询向量属于哪个c_i(即在哪一个感兴趣区域),然后在该感兴趣区域按上面所述的PQ乘积量化距离计算方式计算距离。
function mfc=my_mfcc(x,fs)
%MY_MFCC:获取Speaker recognition的参数
%x:输入语音信号 fs:采样率
%mfc:十二个mfcc系数和一个能量 以及一阶和二阶差分 共36个参数 每一行为一帧数据
%clc,clear
%[x,fs]=audioread('wo6.wav');
N=256;p=24;
bank=mel_banks(p,N,fs,0,fs/2);
% 归一化mel滤波器组系数
bank=full(bank);
bank=bank/max(bank(:));
% 归一化倒谱提升窗口
w = 1 + 6 * sin(pi * [1:12] ./ 12);
w = w/max(w);
% 预加重滤波器
x=double(x);
x=filter([1 -0.9375],1,x);
% 语音信号分帧
sf=check_ter(x,N,128,10);
x=div_frame(x,N,128);
%sf=sp_ter(x,4,16);
%m=zeros(size(x,1),13);
m=zeros(1,13);
% 计算每帧的MFCC参数
for i=1:size(x,1)
if sf(i)==1
% j=j+1;
y = x(i,:);
y = y' .* hamming(N);
energy=log(sum(y.^2)+eps);%能量
y = abs(fft(y));
y = y.^2+eps;
c1=dct(log(bank * y));
c2 = c1(2:13).*w';%取2~13个系数
%m(i,:)=[c2;energy]';
m1=[c2;energy]';
%m1=c2';
m=[m;m1];
end
end
%差分系数
dm = zeros(size(m));
dmm= zeros(size(m));
for i=2:size(m,1)-1
dm(i,:) = (m(i,:) - m(i-1,:));
end
for i=3:size(m,1)-2
dmm(i,:) = (dm(i,:) - dm(i-1,:));
end
%dm = dm / 3;
function v=lbg(x,k)
%lbg:完成lbg均值聚类算法
% lbg(x,k) 对输入样本x,分成k类。其中,x为row*col矩阵,每一列为一个样本,
% 每个样本有row个元素。
% [v1 v2 v3 ...vk]=lbg(...)返回k个分类,其中vi为结构体,vi.num为该类
% 中含有元素个数,vi.ele(i)为第i个元素值,vi.mea为相应类别的均值
[row,col]=size(x);
%u=zeros(row,k);%每一列为一个中心值
epision=0.03;%选择epision参数
delta=0.01;
%u2=zeros(row,k);
%LBG算法产生k个中心
u=mean(x,2);%第一个聚类中心,总体均值
for i3=1:log2(k)
u=[u*(1-epision),u*(1+epision)];%双倍
%time=0;
D=0;
DD=1;
while abs(D-DD)/DD>delta %sum(abs(u2(:).^2-u(:).^2))>0.5&&(time<=80) %u2~=u
DD=D;
for i=1:2^i3 %初始化
v(i).num=0;
v(i).ele=zeros(row,1);
end
for i=1:col %第i个样本
distance=dis(u,x(:,i));%第i个样本到各个中心的距离
[val,pos]=min(distance);
v(pos).num=v(pos).num+1;%元素的数量加1
if v(pos).num==1 %ele为空
v(pos).ele=x(:,i);
else
v(pos).ele=[v(pos).ele,x(:,i)];
end
end
for i=1:2^i3
u(:,i)=mean(v(i).ele,2);%新的均值中心
for m=1:size(v(i).ele,2)
D=D+sum((v(i).ele(m)-u(:,i)).^2);
end
end
end
end
完整代码或者代写添加QQ 1564658423
往期回顾>>>>>>
【特征提取】基于matlab小波变换的音频水印嵌入提取【含Matlab源码 053期】
【语音处理】基于matlab GUI语音信号处理【含Matlab源码 290期】
【语音采集】基于matlab GUI语音信号采集【含Matlab源码 291期】
【语音调制】基于matlab GUI语音幅度调制【含Matlab源码 292期】
【语音合成】基于matlab GUI语音合成【含Matlab源码 293期】
【语音加密】基于matlab GUI语音信号加密解密【含Matlab源码 295期】
【语音增强】基于matlab小波变换的语音增强【含Matlab源码 296期】
【语音识别】基于matlab GUI语音基频识别【含Matlab源码 294期】
【语音增强】基于matlab GUI维纳滤波之语音增强【含Matlab源码 298期】
【语音处理】基于matlab GUI语音信号处理【含Matlab源码 299期】
【信号处理】基于matlab的语音信号频谱分析仪【含Matlab源码 325期】
【调制信号】基于matlab GUI数字调制信号仿真【含Matlab源码 336期】
【情感识别】基于matlab BP神经网络的语音情感识别【含Matlab源码 349期】
【语音隐写】基于matlab小波变换的量化音频数字水印【含Matlab源码 351期】
【特征提取】基于matlab音频水印嵌入与提取【含Matlab源码 350期】
【语音去噪】基于matlab低通和自适应滤波去噪【含Matlab源码 352期】
【情感识别】基于matlab GUI语音情感分类识别【含Matlab源码 354期】
【基础处理】基于matlab语音信号的预处理【含Matlab源码 364期】
【语音识别】基于matlab 傅立叶变换0-9的数字语音识别【含Matlab源码 384期】
【语音识别】基于matlab GUI DTW的0-9数字语音识别【含Matlab源码 385期】
【语音播放】基于matlab GUI MP3设计【含Matlab源码 425期】
【语音处理】基于人耳掩蔽效应的语音增强算法信噪比计算【含Matlab源码 428期】
【语音去噪】基于matlab谱减法去噪【含Matlab源码 429期】
【语音识别】基于matlab带动量项的BP神经网络语音识别【含Matlab源码 430期】
【语音隐写】基于matlab LSB语音隐藏【含Matlab源码 431期】
【语音识别】基于matlab男女声识别【含Matlab源码 452期】
【语音处理】基于matlab语音加噪和降噪处理【含Matlab源码 473期】
【语音去噪】基于matlab最小二乘法(LMS)自适应滤波器【含Matlab源码 481期】
【语音增强】基于matlab谱减法、最小均方和维纳滤波语音增强【含Matlab源码 482期】
【通信】基于matlab GUI数字频带(ASK、PSK、QAM)调制仿真 【含Matlab源码 483期】
【信号处理】基于matlab心电信号ECG滤波处理【含Matlab源码 484期】
【语音播报】基于matlab语音播报【含Matlab源码 507期】
【信号处理】基于matlab小波变换脑电信号特征提取【含Matlab源码 511期】
【语音处理】基于matlab GUI双音多频(DTMF)信号检测【含Matlab源码 512期】
【语音隐写】基于matlab LSB实现语音信号的数字水印【含Matlab源码 513期】
【语音增强】基于matlab匹配滤波器的语音识别【含Matlab源码 514期】
【语音处理】基于matlab GUI语音时域频域频谱图分析【含Matlab源码 527期】
【语音去噪】基于matlab LMS、RLS算法语音去噪【含Matlab源码 528期】
【语音去噪】基于matlab LMS谱减法语音去噪【含Matlab源码 529期】
【语音去噪】基于matlab 软阈值、硬阈值、折中阈值语音去噪【含Matlab源码 530期】
【语音识别】基于matlab特定人的语音识别分辨【含Matlab源码 534期】
【语音去噪】基于matlab小波软阈值语音降噪【含Matlab源码 531期】
【语音去噪】基于matlab小波硬阈值语音降噪【含Matlab源码 532期】
【语音识别】基于matlab MFCC和SVM的特定人性别识别【含Matlab源码 533期】
【语音识别】基于MFCC的GMM语音识别【含Matlab源码 535期】
【语音识别】基于matlab VQ特定人孤立词语音识别【含Matlab源码 536期】
【语音识别】基于matlab GUI声纹识别【含Matlab源码 537期】
【采集读写】基于matlab语音采集与读写【含Matlab源码 538期】
【语音编辑】基于matlab语音编辑【含Matlab源码 539期】
【语音模型】基于matlab语音信号数学模型【含Matlab源码 540期】
【语音响度】基于matlab语音声强与响度【含Matlab源码 541期】
【情感识别】基于matlab K近邻分类算法的语音情感识别【含Matlab源码 542期】
【情感识别】基于matlab支持向量机(SVM)的语音情感识别【含Matlab源码 543期】
【情感识别】基于神经网络的语音情感识别【含Matlab源码 544期】
【声源定位】基于matlab不同空间谱估计的声源定位算法比较【含Matlab源码 545期】
【声源定位】基于matlab不同信噪比下的麦克风接收信号【含Matlab源码 546期】
【声源定位】基于matlab单声源双麦克风的房间冲激响应【含Matlab源码 547期】
【声源定位】基于matlab广义互相关的声源定位【含Matlab源码 548期】
【声源定位】基于matlab阵列流形矩阵的信号显示【含Matlab源码 549期】
【特征提取】基于matlab共振峰估计【含Matlab源码 550期】
【特征提取】基于matlab基音周期估计【含Matlab源码 551期】
【特征提取】基于matlab语音端点检测【含Matlab源码 552期】
【语音编码】基于matlab ADPCM编解码【含Matlab源码 553期】
【语音编码】基于matlab LPC编解码【含Matlab源码 554期】
【语音编码】基于matlab PCM编解码【含Matlab源码 555期】
【语音分析】基于matlab倒谱分析与MFCC系数计算【含Matlab源码 556期】
【语音分析】基于matlab线性预测系数对比 【含Matlab源码 557期】
【语音分析】基于matlab语音短时频域分析【含Matlab源码 558期】
【语音分析】基于matlab语音短时时域分析【含Matlab源码 559期】
【语音分析】基于matlab语音线谱对转换【含Matlab源码 560期】
【语音合成】基于matlab比例重叠相加法的信号分帧与还原【含Matlab源码 561期】
【语音合成】基于matlab线性预测共振峰检测和基音参数的语音合成【含Matlab源码 562期】
【语音合成】基于matlab线性预测系数和基音参数的语音合成【含Matlab源码 563期】
【语音合成】基于matlab线性预测系数和预测误差的语音合成【含Matlab源码 564期】
【语音合成】基于matlab语音信号变速【含Matlab源码 565期】
【语音合成】基于matlab语音信号的变调【含Matlab源码 566期】
【语音合成】基于matlab重叠存储法的信号分帧与还原【含Matlab源码 567期】
【语音合成】基于matlab重叠相加法的信号分帧与还原【含Matlab源码 568期】
【语音去噪】基于matlab 改进谱减法语音去噪【含Matlab源码 569期】
【语音去噪】基于matlab基本维纳滤波算法语音去噪【含Matlab源码 570期】
【语音去噪】基于matlab谱减法语音去噪【含Matlab源码 571期】
【语音去噪】基于matlab先验信噪比的维纳滤波算法语音去噪【含Matlab源码 572期】
【语音识别】基于matlab动态时间规整(DTW)的孤立字语音识别【含Matlab源码 573期】
【语音识别】基于matlab高斯混合模型(GMM)的说话人识别【含Matlab源码 574期】