LVQ神经网络的预测——人脸识别的一些笔记

一、LVQ神经网络

LVQ神经网络由三层组成,即输入层、隐含层和输出层,网络在输入层与隐含层间为完全连接,而在隐含层与输出层间为部分连接,每个输出层神经元与隐含层神经元的不同组相连接。隐含层和输出层神经元之间的连接权值固定为1。输入层和隐含层神经元间连接的权值建立参考矢量的分量(对每个隐含神经元指定一个参考矢量)。在网络训练过程中,这些权值被修改。隐含层神经元(又称为Kohnen神经元)和输出神经元都具有二进制输出值。当某个输入模式被送至网络时,参考矢量最接近输入模式的隐含神经元因获得激发而赢得竞争,因而允许它产生一个“1”,而其它隐含层神经元都被迫产生“0”。与包含获胜神经元的隐含层神经元组相连接的输出神经元也发出“1”,而其它输出神经元均发出“0”。产生“1”的输出神经元给出输入模式的类,由此可见,每个输出神经元被用于表示不同的类。

 二, LVQ神经网络的预测——人脸识别的实验设计

实验设计过程

  •  人脸特征提取-------当人脸朝向不同时,眼睛在图像中的位置会有明显的差别。因此,只需要将描述人眼位置信息的特征向量提取出来即可。方法是将采集到的50幅图像先进行预处理,将图片按420*420的尺寸对人脸部位进行裁剪,然后将裁剪得到的图像按“人员编号_人脸朝向”的格式进行命名,再将其转换成二值灰度图像,接着将图像划分成6行8列,人眼的位置信息可以用第2行的8个子矩阵来描述,用Sobel边缘算子进行边缘检测后8个子矩阵中的值为“1”的像素点个数与人脸朝向有直接关系,只要分别统计出第2行的8个子矩阵中的值为“1”的像素点即可。

%% 清除环境变量
clear all
clc

%% 人脸特征向量提取 
% 人数
M = 10;
% 人脸朝向类别数
N = 5; 
% 特征向量提取
pixel_value = feature_extraction(M,N);



        
% 特征提取子函数
function pixel_value = feature_extraction(m,n)
pixel_value = zeros(50,8);
sample_number = 0;
for i = 1:m
    for j = 1:n %%m=10,n=5;
        str = strcat('Images\',num2str(i),'_',num2str(j),'.bmp'); %strcat串联输入,连接图片的名字
        img = imread(str);  %读取图像
        [rows cols] = size(img);%420*420,图像的尺寸
        img_edge = edge(img,'Sobel');%使用sobel边缘检测算法检测图像 I 中的边缘。
        sub_rows = floor(rows/6);%最接近的最小整数,分成6行
        sub_cols = floor(cols/8);%最接近的最小整数,分成8列
        sample_number = sample_number + 1;
        for subblock_i = 1:8   %最后得到总和。
            for ii = sub_rows+1:2*sub_rows  %:,第二行(扫描眼睛的部分)
                for jj = (subblock_i-1)*sub_cols+1:subblock_i*sub_cols  %每一块
                    pixel_value(sample_number,subblock_i) = ...  %sample_number是图像的张数,
                        pixel_value(sample_number,subblock_i) + img_edge(ii,jj); %图像里每一个最小单位扫过去,重复叠加。   
                end
            end     
        end  
     end
end

  •  训练集/测试集产生

% 产生图像序号的随机序列
rand_label = randperm(M*N);  
% 人脸朝向标号
direction_label = repmat(1:N,1,M);%1行M列向量,数值是1到N ;
% 训练集
train_label = rand_label(1:30);
P_train = pixel_value(train_label,:)';
Tc_train = direction_label(train_label);%训练集的方向参数集;
T_train = ind2vec(Tc_train);%通过数字找出1的所在的行数。
% 测试集
test_label = rand_label(31:end);
P_test = pixel_value(test_label,:)';
Tc_test = direction_label(test_label);

  • 创建LVQ网络

for i = 1:5
    rate{i} = length(find(Tc_train == i))/30;%find查找Tc_train等于i的值,length最大长度
end
net = newlvq(minmax(P_train),20,cell2mat(rate),0.01,'learnlv1');%cell2mat将元胞数组转化为普通数组,20为竞争层神经元个数,0.01是学习速率,由于训练集数据是随机产生的,所以参数PC的设置需要事先计算得出
% 设置训练参数
net.trainParam.epochs = 100;
net.trainParam.goal = 0.001;
net.trainParam.lr = 0.1;

  • 训练网络

net = train(net,P_train,T_train);

  • 人脸识别测试

T_sim = sim(net,P_test);%T_sim 是一个5行20列矩阵。
Tc_sim = vec2ind(T_sim);%显示T_sim每列的非零元素所在的行数;
result = [Tc_test;Tc_sim]%第一行为测试集图像的标准人脸朝向类别,第二行为测试集图像的预测人脸朝向类别。

  •  结果显示

% 训练集人脸标号
strain_label = sort(train_label);%对数组元素进行排序
htrain_label = ceil(strain_label/N);%ceil朝正无穷大四舍五入,显示这个图像的排号
% 训练集人脸朝向标号
dtrain_label = strain_label - floor(strain_label/N)*N;
dtrain_label(dtrain_label == 0) = N;
% 显示训练集图像序号
disp('训练集图像为:' );
for i = 1:30 
    str_train = [num2str(htrain_label(i)) '_'...
               num2str(dtrain_label(i)) '  '];
    fprintf('%s',str_train)
    if mod(i,5) == 0
        fprintf('\n');%五个一行五个一行
    end
end
% 测试集人脸标号
stest_label = sort(test_label);
htest_label = ceil(stest_label/N);
% 测试集人脸朝向标号
dtest_label = stest_label - floor(stest_label/N)*N;
dtest_label(dtest_label == 0) = N;
% 显示测试集图像序号
disp('测试集图像为:');
for i = 1:20 
    str_test = [num2str(htest_label(i)) '_'...
              num2str(dtest_label(i)) '  '];
    fprintf('%s',str_test)
    if mod(i,5) == 0
        fprintf('\n');
    end
end
% 显示识别出错图像
error = Tc_sim - Tc_test;
location = {'左方' '左前方' '前方' '右前方' '右方'};
for i = 1:length(error)
    if error(i) ~= 0
        % 识别出错图像人脸标号
        herror_label = ceil(test_label(i)/N);
        % 识别出错图像人脸朝向标号
        derror_label = test_label(i) - floor(test_label(i)/N)*N;
        derror_label(derror_label == 0) = N;
        % 图像原始朝向
        standard = location{Tc_test(i)};
        % 图像识别结果朝向
        identify = location{Tc_sim(i)};
        str_err = strcat(['图像' num2str(herror_label) '_'...
                        num2str(derror_label) '识别出错.']);
        disp([str_err '(正确结果:朝向' standard...
                      ';识别结果:朝向' identify ')']);
    end
end
% 显示识别率
disp(['识别率为:' num2str(length(find(error == 0))/20*100) '%']);

        
 

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值