基于神经网络的人脸识别附代码Word文件下载.docx
《基于神经网络的人脸识别附代码Word文件下载.docx》由会员分享,可在线阅读,更多相关《基于神经网络的人脸识别附代码Word文件下载.docx(9页珍藏版)》请在冰豆网上搜索。
(2)向后传播阶段
①计算实际输出Op与相应的理想输出Yp的差;
②按极小化误差的方法调整权矩阵。
这两个阶段的工作一般应受到精度要求的控制,定义
(1)
作为网络关于第p个样本的误差测度(误差函数)。
而将网络关于整个样本集的误差测度定义为
(2)
如前所述,将此阶段称为向后传播阶段,也称之为误差传播阶段。
为了更清楚地说明本文所使用的BP网络的训练过程,首先假设输入层、中间层和输出层的单元数分别是N、L和M。
X=(x0,x1,…,xN-1)是加到网络的输入矢量,H=(h0,h1,…,hL-1)是中间层输出矢量,Y=(y0,y1,…,yM-1)是网络的实际输出矢量,并且用D=(d0,d1,…,dM-1)来表示训练组中各模式的目标输出矢量。
输出单元i到隐单元j的权值是Vij,而隐单元j到输出单元k的权值是Wjk。
另外用θk和Φj来分别表示输出单元和隐单元的阈值。
于是,中间层各单元的输出为:
(3)
而输出层各单元的输出是:
(4)
其中f(*)是激励函数,采用S型函数:
(5)
在上述条件下,网络的训练过程如下:
(1)选定训练集。
由相应的训练策略选择样本图像作为训练集。
(2)初始化各权值Vij,Wjk和阈值Φj,θk,将其设置为接近于0的随机值,并初始化精度控制参数ε和学习率α。
(3)从训练集中取一个输入向量X加到网络,并给定它的目标输出向量D。
(4)利用式(7)计算出一个中间层输出H,再用式(8)计算出网络的实际输出Y。
(5)将输出矢量中的元素yk与目标矢量中的元素dk进行比较,计算出M个输出误差项:
对中间层的隐单元也计算出L个误差项:
(6)依次计算出各权值和阈值的调整量:
(6)
(7)
(8)
(9)
(7)调整权值和阈值:
,
(8)当k每经历1至M后,判断指标是否满足精度要求:
E≤ε,其中E是总误差函数,且
。
如果不满足,就返回(3),继续迭代。
如果满足,就进入下一步。
(9)训练结束,将权值和阈值保存在文件中。
这时可以认为各个权值已经达到稳定,分类器形成。
再一次进行训练时,直接从文件导出权值和阈值进行训练,不需要进行初始化。
BP算法流程图
YALE数据库是由耶鲁大学计算视觉与扼制中心创立,包括15位志愿者,每个人有11张不同姿势、光照和表情的图片,共计165张图片,图片均为80*100像素的BMP格式图像。
我们将整个数据库分为两个部分,每个人的前5幅图片作为网络的训练使用,后6副图片作为测试使用。
说明:
程序的输入数据可以从这里下载:
链接:
密码:
vsfb
如果不能下载了,可以自己找找YALE人脸数据库。
代码分为read_can_use.m和main_can_ues.m
先运行read_can_use.m读取图片的像素值,使用奇异值分解的方法得到对应的特征。
程序预设了只读取前5个人的人脸图片,可以自己改成最多15个人。
然后运行main_can_use.m,程序会输出112323,每个数字代表一张图片最有可能的识别类别(就是人的编号)。
对每个人的11张图片,取前7张训练网络,后4张测试网络,取前5个人进行实验。
所以共有35个训练样本,20个测试样本。
比如输出的结果是111122123333…..,因为每4个数字是属于同一个人的,前四个都是1则都预测正确,第二组的4个数字2212中的那个1就是预测错误(本来是2预测成了1)。
由于参数的随机初始化,不保证每次的结果都相同。
functionmain()
%%
clc
clearall;
%closeall;
load('
date1_5.mat'
'
feature'
);
warningoffall
SamNum=35;
%输入样本数量
TestSamNum=35;
%测试样本数量
ForcastSamNum=20;
%预测样本数量
HiddenUnitNum=8;
%中间层隐节点数量取8
InDim=40;
%网络输入维度
OutDim=4;
%网络输出维度
%%input
p=[];
t=[];
pnew=[];
fori=1:
55
if(mod(i,11)<
=7&
&
mod(i,11)>
0)
p=[p;
feature(i,:
)];
else
pnew=[pnew;
end
end
p=p'
;
pnew=pnew'
%%output
s1=[00000000000000000000000000000000000];
s2=[00000000000000000000011111111111111];
s3=[00000001111111111111100000000000000];
s4=[11111110000000111111100000001111111];
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=[];
%给中间变量预先占据内存
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=[ErrHistorySSE];
ifSSE<
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;
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;
forj=1:
20
fori=4:
-1:
1
answer(j)=answer(j)+anew(i,j)*d;
d=d*2;
d=1;
answer=answer+0.5;
answer=floor(answer)
function[feature]=read_can_use()
clc,clear;
5
forjj=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;
forj=1:
10
fork=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;
save('
date1_5'