【语音识别】基于矢量量化(VQ)的说话人识别【Matlab 538期】

一、简介

矢量量化方法,即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

三、运行结果

在这里插入图片描述

四、备注

完整代码或者代写添加QQ912100926
往期回顾>>>>>>
【信号处理】基于GUI界面之处理录音与音频【Matlab 123期】
【信号处理】CDR噪声和混响抑制【含Matlab源码 198期】
【信号处理】最小二乘法解决稀疏信号恢复问题【Matlab 199期】
【信号处理】遗传算法的VST混响【Matlab 200期】
【信号处理】HMM的睡眠状态检测【Matlab 201期】
【信号处理】小波变换的音频水印嵌入提取【Matlab 202期】
【信号处理】ICA算法信号分离【Matlab 203期】
【信号处理】基于GUI界面的脉搏信号之脉率存档【Matlab 204期】
【信号处理】基于GUI界面的虚拟信号发生器(各种波形)【Matlab 205期】
【信号处理】基于GUI界面信号发生器之电子琴【Matlab 206期】
【信号处理】数字电子琴设计与实现【Matlab 207期】
【雷达通信】雷达数字信号处理【Matlab 214期】
【雷达通信】线性调频(LFM)脉冲压缩雷达仿真【Matlab 215期】
【雷达通信】距离多普勒(RD)、CS、RM算法的机载雷达成像【Matlab 216期】
【雷达通信】《现代雷达系统分析与设计》【Matlab 217期】
【语音处理】基于matlab GUI语音信号处理平台【含Matlab源码 218期】
【语音采集】基于GUI语音信号采集【Matlab 219期】
【语音调制】基于GUI语音幅度调制【Matlab 220期】
【语音合成】基于GUI语音合成【Matlab 221期】
【语音识别】基于GUI语音基频识别【Matlab 222期】
【语音加密】基于GUI语音信号加密解密【Matlab 223期】
【信号处理】小波变换的语音增强【Matlab 224期】
【信号处理】基于GUI语音去噪【Matlab 225期】
【语音增强】基于GUI维纳滤波之语音增强【Matlab 226期】
【音频处理】基于GUI语音信号处理【含Matlab 227期】
【雷达通信】基于GUI雷达定位【Matlab 244期】
【雷达通信】基于GUI雷达脉冲压缩【Matlab 245期】
【雷达通信】基于GUI雷达定位模拟【Matlab 246期】
【雷达通信】SVM识别雷达数据【Matlab 247期】
【信息处理】GUI数字波束的算法库【Matlab 249期】
【通信】OFDM-MIMO通信建模与仿真【Matlab 250期】
【通信】OFDM仿真【Matlab 251期】
【信号处理】窗函数法的FIR数字滤波器设计【Matlab 252期】
【通信】FIR低通数字滤波器设计【Matlab 253期】
【通信】FIR IIR数字滤波器设计【Matlab 254期】
【调制信号】基于GUI数字调制信号仿真【Matlab 255期】
【通信】扩频通信系统设计【Matlab 256期】
【通信】多径衰落信道的仿真【Matlab 257期】
【语音识别】基于BP神经网络的语音情感识别【Matlab 258期】
【信号处理】音频水印嵌入与提取【Matlab 259期】
【音频水印】小波变换的量化音频数字水印【Matlab 260期】
【语音去噪】低通和自适应滤波去噪【Matlab 261期】
【信号处理】8级m序列【Matlab 262期】
【情感识别】基于GUI语音情感分类识别【Matlab 263期】
【信号处理】FIR与IIR滤波器低通、高通、带通设计【Matlab 273期】
【语音处理】语音信号的预处理【Matlab 274期】
【语音识别】傅立叶变换0-9的数字语音识别【含Matlab 333期】
【语音识别】基于GUI DTW的0-9数字语音识别【Matlab 334期】
【语音播放】基于GUI MP3设计【Matlab 335期】
【语音处理】人耳掩蔽效应的语音增强算法信噪比计算【Matlab 336期】
【语音去噪】谱减法去噪【Matlab 337期】
【语音识别】带动量项的BP神经网络语音识别【Matlab 338期】
【语音隐写】LSB语音隐藏【Matlab 339期】
【语音识别】男女声识别【Matlab 365期】
【信号处理】基于GUI的PCM调制【Matlab 366期】
【语音处理】语音加噪和降噪处理【Matlab 367期】
【语音去噪】最小二乘法(LMS)自适应滤波器【Matlab 368期】
【语音增强】谱减法、最小均方和维纳滤波语音增强【Matlab 369期】
【通信】基于GUI数字频带(ASK、PSK、QAM)调制仿真 【Matlab 422期】
【信号处理】心电信号ECG滤波处理【Matlab 423期】
【语音播报】语音播报【Matlab 487期】
【语音处理】基于GUI双音多频(DTMF)信号检测【Matlab 488期】
【语音隐写】基于LSB实现语音信号的数字水印【Matlab 489期】
【语音处理】基于GUI语音时域频域频谱图分析【Matlab 490期】
【语音去噪】基于LMS、RLS算法语音去噪【Matlab 491期】
【语音去噪】基于LMS谱减法语音去噪【Matlab 492期】
【语音去噪】基于软阈值、硬阈值、折中阈值语音去噪【Matlab 493期】
【语音去噪】小波软阈值语音降噪【Matlab 494期】
【语音去噪】小波硬阈值语音降噪【Matlab 495期】
【语音识别】基于MFCC和SVM的特定人性别识别【Matlab 496期】
【语音识别】特定人的语音识别分辨【Matlab 497期】
【语音识别】基于MFCC的GMM语音识别【Matlab 498期】
【语音识别】基于VQ特定人孤立词语音识别【Matlab 499期】
【语音识别】基于GUI声纹识别【Matlab 500期】
【采集读写】语音采集与读写【Matlab 501期】
【语音编辑】语音编辑【Matlab 502期】
【语音模型】语音信号数学模型【Matlab 503期】
【语音响度】语音声强与响度【Matlab 504期】
【情感识别】基于K近邻分类算法的语音情感识别【Matlab 505期】
【情感识别】基于支持向量机(SVM)的语音情感识别【Matlab 506期】
【情感识别】基于神经网络的语音情感识别【Matlab 507期】
【声源定位】不同空间谱估计的声源定位算法比较【Matlab 508期】
【声源定位】不同信噪比下的麦克风接收信号【Matlab 509期】
【声源定位】单声源双麦克风的房间冲激响应【Matlab 510期】
【声源定位】广义互相关的声源定位【Matlab 511期】
【声源定位】阵列流形矩阵的信号显示【Matlab 512期】
【特征提取】共振峰估计【Matlab 513期】
【特征提取】基音周期估计【Matlab 514期】
【特征提取】语音端点检测【Matlab 515期】
【语音编码】ADPCM编解码【Matlab 516期】
【语音编码】LPC编解码【Matlab 517期】
【语音编码】PCM编解码【Matlab 518期】
【语音分析】倒谱分析与MFCC系数计算【Matlab 519期】
【语音分析】线性预测系数对比 【Matlab 520期】
【语音分析】语音短时频域分析【Matlab 521期】
【语音分析】语音短时时域分析【Matlab 522期】
【语音分析】语音线谱对转换【Matlab 523期】
【语音合成】比例重叠相加法的信号分帧与还原【Matlab 524期】
【语音合成】线性预测共振峰检测和基音参数的语音合成【Matlab 525期】
【语音合成】线性预测系数和基音参数的语音合成【Matlab 526期】
【语音合成】线性预测系数和预测误差的语音合成【Matlab 527期】
【语音合成】语音信号变速【Matlab 528期】
【语音合成】语音信号的变调【Matlab 529期】
【语音合成】重叠存储法的信号分帧与还原【Matlab 530期】
【语音合成】基于重叠相加法的信号分帧与还原【Matlab 531期】
【语音去噪】基于改进谱减法语音去噪【Matlab 532期】
【语音去噪】基于基本维纳滤波算法语音去噪【Matlab 533期】
【语音去噪】基于谱减法语音去噪【Matlab 534期】
【语音去噪】基于先验信噪比的维纳滤波算法语音去噪【Matlab 535期】
【语音识别】基于动态时间规整(DTW)的孤立字语音识别【Matlab 536期】
【语音识别】基于高斯混合模型(GMM)的说话人识别【Matlab 537期】

你可能感兴趣的:(matlab,信号处理)