基于神经网络的人脸识别(附代码)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

【代码及说明见第四页】
基于三层BP 神经网络的人脸识别
一、 实验要求
采用三层前馈BP 神经网络实现标准人脸YALE 数据库的识别。

二、BP 神经网络的结构和学习算法
实验中建议采用如下最简单的三层BP 神经网络,输入层为],,,[21n x x x X ,有n 个神经元节点,输出层具有m 个神经元,网络输出为],,,[21m y y y Y ,隐含层具有k 个神经元,采用BP 学习算法训练神经网络。

BP 神经网络的结构
BP 网络在本质上是一种输入到输出的映射,它能够学习大量的输入与输出之间的映射关系,而不需要任何输入和输出之间的精确的数学表达式,只要用已知的模式对BP 网络加以训练,网络就具有输入输出对之间的映射能力。

BP 网络执行的是有教师训练,其样本集是由形如(输入向量,期望输出向量)的向量对构成的。

在开始训练前,所有的权值和阈值都应该用一些不同的小随机数进行初始化。

BP 算法主要包括两个阶段: (1) 向前传播阶段
①从样本集中取一个样本(X p ,Y p ),将X p 输入网络,其中X p 为输入向量,Y p 为期望输出向量。

②计算相应的实际输出O p 。

在此阶段,信息从输入层经过逐级的变换,传送到输出层。

这个过程也是网络在完成训练后正常运行时执行的过程。

在此过程中,网络执行的是下列运算: (1)(2)()21(...((())...))n p n p O F F F X W W W
(2) 向后传播阶段
①计算实际输出O p 与相应的理想输出Y p 的差; ②按极小化误差的方法调整权矩阵。

这两个阶段的工作一般应受到精度要求的控制,定义
21
1()2m
p pj pj j E y o (1)
作为网络关于第p 个样本的误差测度(误差函数)。

而将网络关于整个样本集的误差测度定义为
p E E (2)
如前所述,将此阶段称为向后传播阶段,也称之为误差传播阶段。

为了更清楚地说明本文所使用的BP 网络的训练过程,首先假设输入层、中间层和输出层的单元数分别是N 、L 和M 。

X=(x 0,x 1,…,x N-1)是加到网络的输入矢量,H=(h 0,h 1,…,h L-1)是中间层输出矢量,Y=(y 0,y 1,…,y M-1)是网络的实际输出矢量,并且用D=(d 0,d 1,…,d M-1)来表示训练组中各模式的目标输出矢量。

输出单元i 到隐单元j 的权值是V ij ,而隐单元j 到输出单元k 的权值是W jk 。

另外用θk 和Φj 来分别表示输出单元和隐单元的阈值。

于是,中间层各单元的输出为:
1
0()N j ij i j i h f V x (3)
而输出层各单元的输出是:
1
0()L k jk j k j y f W h (4)
其中f(*)是激励函数,采用S 型函数:
1
()1x
f x e (5)
在上述条件下,网络的训练过程如下:
(1) 选定训练集。

由相应的训练策略选择样本图像作为训练集。

(2) 初始化各权值V ij ,W jk 和阈值Φj ,θk ,将其设置为接近于0的随机值,并初始化精度控制参数ε和学习率α。

(3) 从训练集中取一个输入向量X 加到网络,并给定它的目标输出向量D 。

(4) 利用式(7)计算出一个中间层输出H ,再用式(8)计算出网络的实际输出Y 。

(5) 将输出矢量中的元素y k 与目标矢量中的元素d k 进行比较,计算出M 个输出误差项:()(1)k k k k k d y y y 对中间层的隐单元也计算出L 个误差项:
1
*0(1)M J
j j k jk k h h W
(6) 依次计算出各权值和阈值的调整量:
()(/(1))*((1)1)**jk jk k j W n L W n h (6)
*()(/(1))*((1)1)**ij ij j i
V n N V n x (7) ()(/(1))*((1)1)*k k k n L n (8)
*()(/(1))*((1)1)*j j j
n L n (9) (7) 调整权值和阈值:(1)()()jk jk jk W n W n W n ,(1)()()ij ij ij V n V n V n
(1)()()k k k n n n ,(1)()()j j n n n
(8) 当k 每经历1至M 后,判断指标是否满足精度要求:E ≤ε,其中E 是总误
差函数,且1
20
1()2M k k k E d y 。

如果不满足,就返回(3),继续迭代。

如果满足,
就进入下一步。

(9) 训练结束,将权值和阈值保存在文件中。

这时可以认为各个权值已经达到稳定,分类器形成。

再一次进行训练时,直接从文件导出权值和阈值进行训练,不需要进行初始化。

BP 算法流程图
YALE 数据库是由耶鲁大学计算视觉与扼制中心创立,包括15位志愿者,每个人有11张不同姿势、光照和表情的图片,共计165张图片,图片均为80*100像素的BMP 格式图像。

我们将整个数据库分为两个部分,每个人的前5幅图片作
为网络的训练使用,后6副图片作为测试使用。

说明:
程序的输入数据可以从这里下载:
链接: https:///s/1aAHGyg0sFH1PYdY4XekyTQ 密码: 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,每个数字代表一张图片最有可能的识别类别(就是人的编号)。

对每个人的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()
%%
clc
clear all;
%close all;
load('date1_5.mat','feature');
warning off all
SamNum=35; %输入样本数量
TestSamNum=35; %测试样本数量
ForcastSamNum=20; %预测样本数量
HiddenUnitNum=8; %中间层隐节点数量取8
InDim=40; %网络输入维度
OutDim=4; %网络输出维度
%%input
p=[];t=[];pnew=[];
for i=1:55
if(mod(i,11)<=7&&mod(i,11)>0)
p=[p;feature(i,:)];
else
pnew=[pnew;feature(i,:)];
end
end
p=p';pnew=pnew';
%%output
s1=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 输入
[SamIn,minp,maxp,tn,mint,maxt]=premnmx(p,t); %原始样本对(输入和输出)初始化
rand('state',sum(100*clock)) %依据系统时钟种子产生随机数
SamOut=tn;
TestSamIn=SamIn; %这里取输入样本与测试样本相同因为样本容量偏少
TestSamOut=SamOut; %也取输出样本与测试样本相同
MaxEpochs=50000; %最多训练次数为50000
lr=0.035; %学习速率为0.035
E0=0.65*10^(-3); %目标误差为0.65*10^(-3)
W1=0.5*rand(HiddenUnitNum,InDim)-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*SamIn+repmat(B1,1,SamNum)))); % 隐含层网络输出
NetworkOut=W2*HiddenOut+repmat(B2,1,SamNum); % 输出层网络输出
Error=SamOut-NetworkOut; % 实际输出与网络输出之差SSE=sumsqr(Error) ; %能量函数(误差平方和)
ErrHistory=[ErrHistory SSE];
if SSE<E0,break, end
% 调整权值(阈值)
Delta2=Error;
Delta1=W2'*Delta2.*HiddenOut.*(1-HiddenOut);
dW2=Delta2*HiddenOut';
dB2=Delta2*ones(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;
end
HiddenOut=1./(1+exp(-((W1*SamIn+repmat(B1,1,TestSamNum))))); % 隐含层输出最终结果
NetworkOut=W2*HiddenOut+repmat(B2,1,TestSamNum); % 输出层输出最终结果
a=postmnmx(NetworkOut,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:20
for i=4:-1:1
answer(j)=answer(j)+anew(i,j)*d;
d=d*2;
end
d=1;
end
answer=answer+0.5;
answer=floor(answer)
function [feature] = read_can_use()
clc,clear;
%%
for i=1:5
for jj=1:11
%%
s1='YALE\subject0';
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(str);
M=double(a2);
%%
num=1;
for j=1:10
for k=1:4
x=i;
%将图片的灰度矩阵划分成32块小矩阵
temp_num1=size(M,1)./10;%100*80
temp_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;
end
end
end
end
save('date1_5','feature');。

相关文档
最新文档