实验五 基于LBG算法的最佳码本分析(4课时)
通过Matlab编程掌握语音信号最佳码本设计方法。
最佳设计是指从大量信号样本中训练出好的码本;从实际效果出发寻找到好的失真测度定义公式;用最少的搜索和计算失真的运算量,来实现最大可能的平均信噪比。如果用表示训练用特征矢量与训练处的码本的码字之间的畸变,那么最佳码本设计的任务就是在一定的条件下,使得此畸变的统计平均值达到最小。
LBG算法是一种递推算法,从事先选定的初始码本开始进行迭代,知道系统性能满足要求或者不再有明显改进为止。具体实现步骤如下:
第一步 初始化。给定全部参考矢量集合S,设定失真控制门限, 算法最大迭代次数L,以及初始码本,设置总失真,初始迭代次数m=1,最大迭代次数为L。
第二步:迭代。
(1)根据最邻近准则将S分成J个子集,
(2)计算总失真
(3)计算新码字:每一个码字为其对应子集的质心。
(4)计算相对失真改进量,
与失真控制门限比较,
若转入(5);若转入(6)
(5)若m大于L,则转入(6),否则m+1,转入(1)
(6)得到最终的码书
实验五程序
% vq.m
[x1,x2,x3,y1,y2,y3]=randcz_nn(1,0.2,-1,0.2,-1,0.2,1,0.2,1,0.2,-1,0.2,100,100,100);
x=[x1 x2 x3; y1 y2 y3];
[code,label]=vq_cz(x,3,0.1,20);%[code,label]=vq_cz(x,codelength,tolthr,m)m,maximal iteration time
%randcz_nn.m
function[x1,x2,x3,y1,y2,y3]=randcz_nn(mux1,varx1,mux2,varx2,mux3,varx3,muy1,vary1,muy2,vary2,muy3,vary3,n1,n2,n3)
x1=mux1+sqrt(varx1)*randn(1,n1);
x2=mux2+sqrt(varx2)*randn(1,n2);
x3=mux3+sqrt(varx3)*randn(1,n3);
y1=muy1+sqrt(vary1)*randn(1,n1);
y2=muy2+sqrt(vary2)*randn(1,n2);
y3=muy3+sqrt(vary3)*randn(1,n3);
%vq_cz.m
function [code,label]=vq_cz(x,codelength,tolthr,m)
%the program is to caculate the codebook by the LBG
%code=vq_cz(x,codelength)
%parameter:
%x: input data(N*M)
%codelength: the length of the code book
%tolthr delta
%m maximal iteration times
[r,c]=size(x);
Y=x(:,1:codelength);%随机选取x的前三列为初始码字
d=[];
D=[inf];
l=1;
tol=1;
while (tol>=tolthr && l<=m)
d=[];
l=l+1;
for i=1:codelength
d=[d;sum(repmat(Y(:,i),[1,c]).^2+x.^2-2*repmat(Y(:,i),[1,c]).*x)];%计算训练集矢量和各码字之间距离
end
[a,b]=min(d);% 找出每个x样本距离最近的质心
D(l)=sum(a);% 计算总失真
label=b;% x样本点新的标签
for i=1:codelength
Y(:,i)=sum(x(:,find(b==i)),2)./length(x(find(b==i))); %重新计算码本
end
tol=(D(l-1)-D(l))/D(l)
end
code=Y;
plot(x(1,:),x(2,:),'*')
hold on
plot(code(1,:),code(2,:),'rO')
xlabel('x坐标')
ylabel('y坐标')