通信工程课程设计文档
本项目主要研究的是低噪声环境下基于ICA的语音分离技术。大致可以
将我们的项目分为以下几个内容:
1、 语音信号的输入; 2、 语音信号的混合处理;
3、 混合信号的中心化;
4、 混合信号的白化; 5、 FASTICA算法;
6、 解混输出。
我们希望得到的最终结果是,将我们的输入的三个信号在经过混合和解
混后以尽可能小的失真还原出来。 项目成员:
提交日期:
基于ICA的语音分离技术
指导教师:
1、 项目总结
1.1、 设计动机
语音助手是一类可以通过语音交互来实现或替代部分我们在手机上的查询与操作的应用,通过此类应用,可以大大提高在不同场景下操作手机的便利性。现在的语音助手发展已经到了一个很高的位置,其中具有代表性三大语音助手是苹果公司的Siri语音助手、微软公司的Cortana和谷歌的Google Now。这些软件现在已经是在我们生活当中使用了,而语音助手中最重要的一环就是对用户输入的语音信号的识别。语音信号的采集比较简单,但是对语音信号的处理就是一项比较复杂的工作了。
语音信号处理是一门语音学和数字信号处理两个学科相结合的产物。它和认知学、心理学、语言学、计算机科学、模式识别和人工智能等学科有着紧密的联系。语音信号处理的发展依赖于这些学科的发展,而语音信号处理技术的进步也会促进这些领域的进步。
语音信号处理的目的就是要得到某些语音特征参数以便高效地传输或储存;或者是通过某种处理运算以达到某种用途的要求,例如人工合成语音、辨识出讲话者、识别出讲话的内容、进行语音控制等等。
1.2、 问题分析
语音信号分离处理就是利用盲源分离(Blind Source Separation,BSS)技术对麦克风检测到的一段语音信号进行处理。混合语音信号的分离是盲分离的重要内容,目前的混叠语音分离大多是建立在低噪声环境中的混叠情形下,以BSS为主,根据信号的统计特性从几个观测信号中恢复出未知的独立源成分。
盲信号分离问题是信号处理中一个传统而又极具挑战性的课题。BSS是指仅从观测的混合信号(通常是多个传感器的输出)中恢复独立的源信号,这里的“盲”是指:
(1) 源信号是不可观测的; (2) 混合系统是事先未知的。
本项目主要是基于独立分量分析(Independent component analysis,ICA)技术的盲源分离。基本思路是以非高斯信号为研究对象,在独立性假设的前提下,对多路观测信号进行盲源分离。在满足一定的条件下,能够从多路观测信号中,较好地分离出隐含的独立源信号。
1.3、 需求分析
声音是人类从外界环境中获取信息的一个重要来源,如何对获取的声音进行加工处理显得尤为重要。对一个好的音频处理系统来说,应尽可能的还原出嘈杂环境中我们所需要的声音。然而在对获取的声音提取过程中,常常不可避免的会混进噪声,噪声可以理解为妨碍人的听觉器官或系统传感器对所接收的声源信息进行理解或分析的各种因素。
多年来,随着科技的发展,人们接收着大量的图像和声音信息,用传感器检测包含信息的信号,并通对这些信息进行加工来获得知识和改造自然的能力。然而传感器检测到的往往是多个未知成分混在一起的信号。在传感器检测方面人们一直追求对真实源信号的检测,新原理新方法新技术不断出现,如尽可能将传感器布置靠近源信号位置,采用多个传感器等措施来检测真实的源信号。由于检测到的信号是混合信号,因此对于有些情况(如公共场合信号等)中的真实源信号检测就更加困难。
所以就需要一种能够比较好的对收到的信号中的独立源信号分离的方法。我们这个项目进行的是初期的研究,也就是在理想的低噪声环境下来进行的模拟仿真实验。
2、 系统设计
2.1、系统简介
本项目研究的是输入三个语音信号,然后通过混合这三个信号来模拟我们现实中的情景,达到我们一般的麦克风接收到的语音信号的情况。我们项目的重点是使用FastICA算法来实现语音信号的分离,所以我们需要有信号的输入、FastICA语音信号分离和最终结果语音信号的输出。我们决定采用的MATLAB来进行仿真,因为我们比较熟悉的就是MATLAB仿真平台。
2.2、系统结构分析
首先在语音信号的输入方面 ,可以从简单的模型来研究,最后再推广到更加复杂的情况下来运用。因此在语音信号的输入方面我们采用了三个语音信号作为信号源作为输入,然后对其进行混合后再处理。
在混合三个语音信号方面是利用矩阵的方式将三个信号处理到一个矩阵中。再通过一个随机权矩阵与合并的信号矩阵进行乘,得出我们处理过的混合信号。对混合后的观测信号我们做ICA前的预处理。实际接收的数据是复杂而繁多的,其中包含有用信息和无用信
息,特别是传感器数量较多时,计算就很复杂,这时对观测数据进行预处理,能在一定条件下降低数据维数,减少后面处理的计算量。在ICA处理之前,通常先要对观测数据进行预处理,预处理主要有信号的中心化和白化。
信号中心化是将观测信号X减去其均值E{X},有X’=X-E{X}这样E{X’}=0,叫做信号X的中心化。在解混合之后,再将均值向量加回到解混得到的信号中去。
白化过程是对观测信号X实施线性变换到V,即V =MX,且使得E {VV’} =I,其中M为白化矩阵。该变换仅仅是去掉了观测信号X之间的相关性。若要达到降维的作用,可对其协方差阵进行特征值分解,起到降维作用。
通过FastICA算法对预处理后的数据进行处理,对信号进行特征提取处理。
图1 快速ICA算法流程
(1) 初始化w(0),令其模1,置k=1; (2)
计算出来; (3) 用||w(x)||去除w(k);
期望值可由大量x向量的采样点
(4) 如果|w(k-1)|不是足够接近1,那么令k=k+1,返回第(2)步,否则输出w(k)。
2.3、系统层次
我们将采用自上而下的设计方法来实现这个系统的功能。本系统分为三层:(详细的系统结构会在下一节中具体介绍)
第一层:也就是顶层,是对系统整体结构的设计; 第二层:对其中的核心部分进行分解,分为几个功能模块;
第三层:本层是对各个模块如进行分析,具体分出各个模块的功能是如何实现的。
3、 详细设计
出于对分离结果的直观性考虑,本次仿真主要通过以下方式进行:
1、鉴于声音文件的图像不够直观(如下图),我们通过两个主函数通过不同的形式来完成仿真(main_ica.m主要完成对声音文件的分离;main_ica_fig.m主要完成对通过程序产生的信号的分离)。
2、将各个功能模块函数化,通过函数调用的形式完成仿真。这使得ICA算法的流程在主程序中显得更加清晰,同时增强了仿真程序的可移植性。
图2 函数调用流程图
3.1、第一层
语音信号输入 信号混合和分离 解混信号输出
3.2、第二层
语音信号输入 混合系统 ICA预处理 解混系统 解混信号输出 3.3、第三层(如下图)
混合 输入 输入信号矩阵化 随机权矩阵 矩阵相乘 预处理 计算 信号 均值 中心化 求协方差 特征值分解 求白化矩阵 白化
确定循环次数C 初始化寄存矩阵B 解混 初始化迭代变量p 确定最大迭代次数m 选取初始化权矢量b 是 p=m? P=m? 否 p=p+11 FICA迭代 对b规范化 否 b收敛? 是 保存b 否 r>C? 是 解混输出
4、 原型设计
4.1、前期准备
我们选择的是MATLAB仿真软件,这个软件我们在以前的课程中学习过,所以掌握起来比较容易。在知识储备方面我们选择了两本书《独立分量分析的原理与应用》[1]《独立成分分析》[2]。我们的仿真需要有音频信号的输入,所以就需要音频文件,这里使用的是man.wav、music.wav、dragen.wav。
4.2、设计方法
因为通过自上而下的设计方法来设计我们这次的系统,所以在MATLAB中建立了一个main文件,这个文件是我们系统的核心文件,而当中的标准化和白化等都采用函数调用的方法来实现,所以主函数是比较简洁的。而调用的函数有mean_ica.m,white_ica.m,fpica.m,fastica.m。
4.3、仿真计划
前期我们准备的是对信号的混合,然后将混合后的信号输出来测试我们的混合效果如何。
中期就是对混合后的信号进行标准化和白化然后再用FastICA算法对其处理,输出解混后的信号。但是在这其中我们遇到了迭代一直循环不出去的情况,就是我们的预处理过的信号一直不收敛。因此在这里用了很长一段时间来解决。最后发现是我们的信号问题,信号如果是没有混合的信号,那么它将不会收敛,而混合后的信号才会收敛。
最后是对程序进行优化和排错。在我们测试的时候就发现,如果我们的音频信号的输入是三维的话,那么信号的混合就会很难得到我们想要的效果,因此会影响到混合那一步的执行,每次到这一步程序都会死掉。所以我们这个程序是有局限性的,那就是对一维的音频信号是可以比较好的实现混合和再解混,然而对多维的信号则会出现程序死掉BUG。这个BUG我们还在讨论解决中。
5、 评价标准选择
标准一:直接通过对比分离前后的信号图形,图形越接近则分离效果越好。 标准二:通过设置不同的收敛标准。
当epsilon=1e-4时所得出的分离结果
图3
当epsilon=1e-5时所得出的分离结果
图4
当epsilon=1e-9时所得出的分离结果
图5
由上图可知,当收敛越小的时候(如图2和3),分离结果就越好。同时我们发现,当收敛标准越高的时候,迭代次数会增加,即程序的运算量会加大,所以我们最终将收敛标准定为epsilon=1e-5。
6、 任务列表及分工 周次 计划任务 Xx 项目分工 Xx Xx xx 7 前期准备 查阅相关资料分析语音分离算法的可行性(算法、目标函数的确定) 安装matlab并熟悉MATLAB语音信号处理相关函数 8 深入学习和掌握FICA算法的思路 实现语音信号的混合 实现语音信号的预处理 实现语音信号的解混 完善程序的衔接 阅读相关书籍熟悉算法流程 准备中期答辩相关材料 声音文件读入和混合代码编写 信号生成和画图代码编写 9 10 11 12 13 编写信号中心化编写信号白化相关代相关代码 码 ica迭代算法基本流程代码的实现 编写程序衔接相关代码并最终调试 ica算法流程的完善及相关漏洞调试 准备答辩相关材料
7、 阶段成果
7.1、中心化程序
function [newVectors,meanValue] = mean_ica(vectors) (见附录) %该函数实现信号的中心化
7.2、白化程序
function [newVectors, whiteningMatrix,dewhiteningMatrix] = white_ica (vectors,s_verbose) (见附录)
%该函数实现对信号的白化并返回白化矩阵
7.3、固定点的ICA算法程序
function [A, W] = fpica(X, whiteningMatrix, dewhiteningMatrix, numOfIC, epsilon, maxNumIterations) (见附录)
%该函数主要实现固定点的fastICA算法迭代 %输出估计矩阵A及其逆阵W.
7.4、仿真图
参考文献
[1]杨福生,洪波著.独立分量分析的原理与应用,清华大学出版社,2006,北京 [2]独立分量分析=Independent component analysis海韦里恩,hai wei
lienA.;Hyvarinen,;Karhumen,Juha;Oja,,Erkki;周宗潭zhou zong tan;董国华dong guo hua;徐昕xu xin,电子工业出版社,2007,北京
[3] 马建仓、牛弈龙、陈海洋编.盲信号处理[M].北京:国防工业出版社,2006.90-92.
[4] 胡昌华,周涛.基于MATLAB的系统分析与设计-时频分析[M].西安:西安电子科技大学出版社,2002. [5] 谭丽丽.语音信号盲分离算法的研究.博士学位论文,华南理工大学,2001.
[6]http://wenku.baidu.com/link?url=ygq3GC5X5x38PUMvOYz6sEvh12KM9ZDJHabYO-cpLHR1D6XvTpDzigKBNw7V0PBbvRB1i-mDEGjgzOPBUoUdPAgn1R4LXhtf_jK5dKmVidW&qq-pf-to=pcqq.c2c
[7] 曹慧荣,马莉电子学报:基于快速ICA算法的混合图象分离.
[8]http://wenku.baidu.com/link?url=lraOYEsl1sLVTZODKroTB6PGbXSdwJAVhMvj6oAI1OtuyC7xpd3tSHz2MiAamBoBByF7bhNSHx6GuKmwF_6ojWvkMK0uip9SxeRV4q3ihQm [9]http://blog.sina.com.cn/s/blog_6218d35501013b75.html
附录
主程序(main_ica.m)部分
clc;clear all;close all;
% 读入声音文件
I1=wavread ('dragen.wav')';
[y1,fs1,nbits1]=wavread ('dragen.wav'); I2=wavread ('man.wav')';
[y2,fs2,nbits2]=wavread ('man.wav'); I3=wavread ('music.wav')';
[y3,fs3,nbits3]=wavread ('music.wav');
% 将声音组成混合矩阵 S=[I1;I2;I3];
Sweight=rand(size(S,1)); % 取一随机矩阵,作为信号混合的权矩阵 MixedS=Sweight*S; %写出混合声音文件
wavwrite(MixedS(1,:),fs1,nbits1,'MixS1_'); wavwrite(MixedS(2,:),fs2,nbits2,'MixS2_'); wavwrite(MixedS(3,:),fs3,nbits3,'MixS3_');
% 调用函数,实现ica分离 [icasig] = fastica(MixedS);
% 写出解混声音
wavwrite(icasig(1,:),fs1,nbits1,'ica1_'); wavwrite(icasig(2,:),fs2,nbits2,'ica2_'); wavwrite(icasig(3,:),fs3,nbits3,'ica3_');
主程序(main_ica_fig.m)部分
%信号产生程序 clear all;clc;
N=200;n=1:N;%N为采样点数 I1=2*sin(0.02*pi*n);%正弦信号
t=1:N;I2=2*square(100*t,50);%方波信号
a=linspace(1,-1,25);I3=2*[a,a,a,a,a,a,a,a];%锯齿信号
% 将声音组成混合矩阵 S=[I1;I2;I3];
Sweight=rand(size(S,1)); % 取一随机矩阵,作为信号混合的权矩阵 MixedS=Sweight*S; %源信号波形图 figure(1);
subplot(3,3,1);plot(I1);axis([0 N -5,5]);title('源信号'); subplot(3,3,2);plot(I2);axis([0 N -5,5]);
subplot(3,3,3);plot(I3);axis([0 N -5,5]);xlabel('Time/ms');
%观测信号波形图
subplot(3,3,4);plot(MixedS(1,:));title('观测(混合)信号'); subplot(3,3,5);plot(MixedS(2,:));
subplot(3,3,6);plot(MixedS(3,:));xlabel('Time/ms');
% 调用函数,实现ica分离 [icasig] = fastica(MixedS);
%解混信号波形图
subplot(3,3,7);plot(icasig(1,:));title('解混信号'); subplot(3,3,8);plot(icasig(2,:));
subplot(3,3,9);plot(icasig(3,:));xlabel('Time/ms');
函数调用(fastica.m)部分
function [Out1 Out2 Out3] = fastica(mixedsig) %该函数主要通过函数调用实现ICA算法流程 %其中调用了中心化和白化函数实现ICA预处理 %以及调用了ICA迭代函数
%判断输入参数的规范性 if nargin == 0,
error ('请输入信号.'); end
if ~isa (mixedsig, 'double')
fprintf ('输入信号数据类型错误(double).\\n'); mixedsig = double (mixedsig); end
%调用函数,实现中心化
[mixedsig,mixedmean] = mean_ica(mixedsig);
%调用函数,实现白化 verbose = 'on';
[whitesig, whiteningMatrix,dewhiteningMatrix] = white_ica ... (mixedsig,verbose);
%------调用函数,实现ica迭代------ X=whitesig;
[vectorSize, numSamples] = size(X); numOfIC = vectorSize; %分量个数 %epsilon = 0.0001; %收敛标准 epsilon = 1e-5; %收敛标准
maxNumIterations = 1000; %最大迭代次数
[A, W] = fpica (whitesig, whiteningMatrix, dewhiteningMatrix, ... numOfIC, epsilon, maxNumIterations);
icasig=W*mixedsig+(W*mixedmean)*ones(1,numSamples); Out1 = icasig;
Out2 = A; Out3 = W;
中心化部分
function [newVectors,meanValue] = mean_ica(vectors) %该函数实现信号的中心化
newVectors = zeros (size (vectors));
meanValue = mean (vectors')'; %计算各信号均值
newVectors = vectors - meanValue * ones (1,size (vectors, 2)); %中心化
白化部分
function [newVectors, whiteningMatrix,dewhiteningMatrix] = white_ica ... (vectors,s_verbose)
%该函数实现对信号的白化并返回白化矩阵
%参数s_verbose(on,off)供用户检测信号白化的效果
%初始化参数s_verbose
if nargin < 2, s_verbose = 'on'; end switch lower(s_verbose) case 'on'
b_verbose = 1; case 'off'
b_verbose = 0; end
covarianceMatrix = cov(vectors',1); %计算协方差矩阵
[E, D] = eig(covarianceMatrix); %计算协方差阵的特征值和特征向量 whiteningMatrix = inv(sqrt (D)) * E'; %白化矩阵 newVectors = whiteningMatrix * vectors; %白化 dewhiteningMatrix = E * sqrt (D); %反白化矩阵 %检测白化后的信号的正交化程度 if b_verbose
fprintf ('白化信号的协方差阵与单位阵的逼近程度 [ %g ].\\n', ... max (max (abs (cov (newVectors', 1) - eye (size (newVectors, 1)))))); end
ica迭代算法部分
function [A, W] = fpica(X, whiteningMatrix, dewhiteningMatrix, ... numOfIC, epsilon, maxNumIterations)
%该函数主要实现固定点的fastICA算法迭代 %输出估计矩阵A及其逆阵W.
% whitesig(白化信号)whiteningMatrix(白化矩阵)
%dewhiteningMatrix(反白化矩阵)均可由白化函数求得
%判断输入的参数数量
if nargin < 3, error('输入参数不足!'); end [vectorSize, numSamples] = size(X); if ~isreal(X)
error('输入信号不能为复数.'); end
%初始化寄存矩阵B B = zeros(vectorSize); round = 1;
%设置合理迭代范围内不收敛的标志 numFailures = 0;
failureLimit=vectorSize; %ICA外层循环
while round <= numOfIC, % 显示循环的进程... fprintf('ICA %d ', round);
%随机设置初始权矢量,并对其标准化 w = randn (vectorSize, 1); w = w - B * B' * w; w = w / norm(w);
wOld = zeros(size(w));%寄存前次迭代结果
% 固定点fastICA迭代算法 i = 1;
while i <= maxNumIterations + 1 w = w - B * B' * w; w = w / norm(w);
if i == maxNumIterations + 1 %循环结束处理
fprintf('\\n分量 %d 在第 %d 次迭代中不收敛.\\n', round, maxNumIterations); round = round - 1;
numFailures = numFailures + 1; if numFailures > failureLimit
fprintf('各分量(%d)迭代结果均不收敛. 分离失败!.\\n', numFailures); if round == 0 A=[]; W=[]; end return; end
% 各分量迭代均不收敛,则跳出循环 break; end
% 显示循环的进程... fprintf('.'),
%若收敛,则...
if norm(w - wOld) < epsilon | norm(w + wOld) < epsilon numFailures = 0; % 保存所得向量w B(:, round) = w; % 计算估计矩阵
A(:,round) = dewhiteningMatrix * w; W(round,:) = w' * whiteningMatrix; % 显示循环的进程...
fprintf('迭代 %d 次 \\n', i); break; end
wOld = w;
w = (X * ((X' * w) .^ 3)) / numSamples - 3 * w; % 标准化 w. w = w / norm(w); i = i + 1; end
round = round + 1; end
fprintf('完成!\\n');
% 若结果为复数,则只保留实部 if ~isreal(A)
fprintf('结果为复数,只保留实部\\n'); A = real(A); W = real(W); end
因篇幅问题不能全部显示,请点此查看更多更全内容