1、【代码及说明见第四页】基于三层BP神经网络的人脸识别一、 实验要求采用三层前馈 BP 神经网络实现标准人脸 YALE 数据库的识别。二、BP 神经网络的结构和学习算法实验中建议采用如下最简单的三层 BP 神经网络,输入层为,有 n 个神经元节点,输出层具有 m 个神经元,网络输出为,21xX,隐含层具有 k 个神经元,采用 BP 学习算法训练神经网络。,myYBP 神经网络的结构BP 网络在本质上是一种输入到输出的映射,它能够学习大量的输入与输出之间的映射关系,而不需要任何输入和输出之间的精确的数学表达式,只要用已知的模式对 BP 网络加以训练,网络就具有输入输出对之间的映射能力。BP 网络执
2、行的是有教师训练,其样本集是由形如(输入向量,期望输出向量)的向量对构成的。在开始训练前,所有的权值和阈值都应该用一些不同的小随机数进行初始化。BP 算法主要包括两个阶段:(1) 向前传播阶段从样本集中取一个样本(X p,Yp),将 Xp 输入网络,其中 Xp 为输入向量,Yp 为期望输出向量。计算相应的实际输出 Op。在此阶段,信息从输入层经过逐级的变换,传送到输出层。这个过程也是网络在完成训练后正常运行时执行的过程。在此过程中,网络执行的是下列运算:(1)2)()2(. .npnpFXW(2) 向后传播阶段计算实际输出 Op 与相应的理想输出 Yp 的差;按极小化误差的方法调整权矩阵。这两
3、个阶段的工作一般应受到精度要求的控制,定义(1)21()2mppjjjEyo作为网络关于第 p 个样本的误差测度(误差函数) 。而将网络关于整个样本集的误差测度定义为(2)pE如前所述,将此阶段称为向后传播阶段,也称之为误差传播阶段。为了更清楚地说明本文所使用的 BP 网络的训练过程,首先假设输入层、中间层和输出层的单元数分别是 N、L 和 M。X=(x 0,x1,xN-1)是加到网络的输入矢量,H=(h 0,h1,hL-1)是中间层输出矢量,Y=(y 0,y1,yM-1)是网络的实际输出矢量,并且用 D=(d0,d1,dM-1)来表示训练组中各模式的目标输出矢量。输出单元 i 到隐单元 j
4、的权值是 Vij,而隐单元 j 到输出单元 k 的权值是 Wjk。另外用k 和 j 来分别表示输出单元和隐单元的阈值。于是,中间层各单元的输出为:(3)10()Njijjhfx而输出层各单元的输出是:(4)10()LkjkjyfWh其中 f(*)是激励函数,采用 S 型函数: (5)()1xfe在上述条件下,网络的训练过程如下:(1) 选定训练集。由相应的训练策略选择样本图像作为训练集。(2) 初始化各权值 Vij,W jk 和阈值 j, k,将其设置为接近于 0 的随机值,并初始化精度控制参数 和学习率 。(3) 从训练集中取一个输入向量 X 加到网络,并给定它的目标输出向量 D。(4) 利
5、用式(7)计算出一个中间层输出 H,再用式(8)计算出网络的实际输出 Y。(5) 将输出矢量中的元素 yk 与目标矢量中的元素 dk 进行比较,计算出 M 个输出误差项: 对中间层的隐单元也计算出 L 个误差项:()(1)kd1*0()MJjjkjhW(6) 依次计算出各权值和阈值的调整量:(6)()/(1)*(1)*jk jkkjnLWnh(7)ij ij jiVNVx(8)()/()()k kk(9)*1*1j j jnLn(7) 调整权值和阈值: ,()()()jkjkjkWW)()ijijijVnV,jj(8) 当 k 每经历 1 至 M 后,判断指标是否满足精度要求:E,其中 E 是
6、总误差函数,且 。如果不满足,就返回(3) ,继续迭代。如果满20()2kdy足,就进入下一步。(9) 训练结束,将权值和阈值保存在文件中。这时可以认为各个权值已经达到稳定,分类器形成。再一次进行训练时,直接从文件导出权值和阈值进行训练,不需要进行初始化。开始网络初 始化取 一个 学习样本 ,正向 传入输入计算 各层神经元输入 和输出计算输 出误差调节连 接权值 和阈值样 本结束计 算平均 误差E迭代次 数到达 上限结束精度满足 要求是否是是否否BP 算法流程图YALE 数据库是由耶鲁大学计算视觉与扼制中心创立,包括 15 位志愿者,每个人有 11 张不同姿势、光照和表情的图片,共计 165
7、张图片,图片均为80*100 像素的 BMP 格式图像。我们将整个数据库分为两个部分,每个人的前5 幅图片作为网络的训练使用,后 6 副图片作为测试使用。说明:程序的输入数据可以从这里下载:链接: https:/ 密码: vsfb如果不能下载了, 可以自己找找 YALE 人脸数据库。代码分为 read_can_use.m 和 main_can_ues.m先运行 read_can_use.m 读取图片的像素值,使用奇异值分解的方法得到对应的特征。程序预设了只读取前 5 个人的人脸图片 ,可以自己改成最多 15 个人。然后运行 main_can_use.m ,程序会输出 1 1 2 3 2 3,每
8、个数字代表一张图片最有可能的识别类别(就是人的编号) 。对每个人的 11 张图片,取前 7 张训练网络,后 4 张测试网络,取前 5 个人进行实验。所以共有 35 个训练样本,20 个测试样本。比如输出的结果是 1 1 1 1 2 2 1 2 3 3 3 3 ,因为每 4 个数字是属于同一个人的,前四个都是 1 则都预测正确,第二组的 4 个数字 2 2 1 2 中的那个 1 就是预测错误(本来是 2 预测成了 1) 。由于参数的随机初始化,不保证每次的结果都相同。function main()%clcclear all;%close all;load(date1_5.mat,feature)
9、;warning off allSamNum=35; %输入样本数量TestSamNum=35; %测试样本数量ForcastSamNum=20; %预测样本数量HiddenUnitNum=8; %中间层隐节点数量取 8InDim=40; %网络输入维度OutDim=4; %网络输出维度%inputp=;t=;pnew=;for i=1:55if(mod(i,11)0)p=p;feature(i,:);elsepnew=pnew;feature(i,:);endendp=p;pnew=pnew;%outputs1=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
10、0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ;s2=0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ;s3=0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ;s4=1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 ;t=s1;s2;s3;s4;size(t) %4*35 输出size(p) %40*35 输入
11、SamIn,minp,maxp,tn,mint,maxt=premnmx(p,t); %原始样本对(输入和输出)初始化rand(state,sum(100*clock) %依据系统时钟种子产生随机数SamOut=tn;TestSamIn=SamIn; %这里取输入样本与测试样本相同因为样本容量偏少TestSamOut=SamOut; %也取输出样本与测试样本相同MaxEpochs=50000; %最多训练次数为 50000lr=0.035; %学习速率为 0.035E0=0.65*10(-3); %目标误差为 0.65*10(-3)W1=0.5*rand(HiddenUnitNum,InDim
12、)-0.2; %初始化输入层与隐含层之间的权值B1=0.5*rand(HiddenUnitNum,1)-0.2; %初始化输入层与隐含层之间的阈值W2=0.5*rand(OutDim,HiddenUnitNum)-0.2; %初始化输出层与隐含层之间的权值B2=0.5*rand(OutDim,1)-0.2; %初始化输出层与隐含层之间的阈值ErrHistory=; %给中间变量预先占据内存for i=1:MaxEpochs% HiddenOut=logsig(W1*SamIn+repmat(B1,1,SamNum); % 隐含层网络输出HiddenOut=1./(1+exp(-(W1*SamI
13、n+repmat(B1,1,SamNum); % 隐含层网络输出NetworkOut=W2*HiddenOut+repmat(B2,1,SamNum); % 输出层网络输出Error=SamOut-NetworkOut; % 实际输出与网络输出之差SSE=sumsqr(Error) ; %能量函数(误差平方和)ErrHistory=ErrHistory SSE;if SSEE0,break, end% 调整权值(阈值)Delta2=Error;Delta1=W2*Delta2.*HiddenOut.*(1-HiddenOut);dW2=Delta2*HiddenOut;dB2=Delta2*o
14、nes(SamNum,1);dW1=Delta1*SamIn;dB1=Delta1*ones(SamNum,1);%对输出层与隐含层之间的权值和阈值进行修正W2=W2+lr*dW2;B2=B2+lr*dB2;%对输入层与隐含层之间的权值和阈值进行修正W1=W1+lr*dW1;B1=B1+lr*dB1;endHiddenOut=1./(1+exp(-(W1*SamIn+repmat(B1,1,TestSamNum); % 隐含层输出最终结果NetworkOut=W2*HiddenOut+repmat(B2,1,TestSamNum); % 输出层输出最终结果a=postmnmx(NetworkO
15、ut,mint,maxt); % 还原网络输出层的结果% 利用训练好的网络进行预测pnewn=tramnmx(pnew,minp,maxp); %归一化;HiddenOut=1./(1+exp(-(W1*pnewn+repmat(B1,1,ForcastSamNum);anewn=W2*HiddenOut+repmat(B2,1,ForcastSamNum); % 输出层输出预测结果%把网络预测得到的数据还原为原始的数量级;anew=postmnmx(anewn,mint,maxt);answer=zeros(1,size(anew,2);d=1;for j=1:20for i=4:-1:1a
16、nswer(j)=answer(j)+anew(i,j)*d;d=d*2;endd=1;endanswer=answer+0.5;answer=floor(answer)function feature = read_can_use()clc,clear;%for i=1:5for jj=1:11%s1=YALEsubject0;s2=int2str(i);s22=_;s222=int2str(jj);s3=.bmp;str=strcat(s1,s2);str=strcat(str,s22);str=strcat(str,s222);str=strcat(str,s3);a2=imread(s
17、tr);M=double(a2);%num=1;for j=1:10for k=1:4x=i;%将图片的灰度矩阵划分成 32 块小矩阵temp_num1=size(M,1)./10;%100*80temp_num2=size(M,2)./4;temp=M(j-1)*temp_num1+1:j*temp_num1,(k-1)*temp_num2+1:k*temp_num2);%对每个小矩阵进行 SVD 变换u,temp1,v=svd(temp);%提取最大的 SVD 系数作为特征值temp2=temp1(num,num);%得到所有图片的特征矩阵feature(x-1)*11+jj,(j-1)*4+k)=temp2;endendendendsave(date1_5,feature);