主要来源模式识别课程大作业,本文首先感谢当初的助教和一起完毕作业的队友

matconvnet在matlab下封装了CNN常见算法,网址http://www.vlfeat.org/matconvnet/。本文採用matconvnet-1.0-beta16.tar.gz

第一题: 运用matconvet提供的mnist网络结构。

通过train目录中人脸图片训练网络(训练集)。通过val目录调整网络结构(验证集),最后通过test目录測试网络性能(測试集)

第一题: 设计一个神经网络,并与第一题比較

第一题

1.利用train和val目录进行训练和调參:

    利用matconvnet工具包中对mnist手写数字体设计的cnn结构。识别人脸性别。主程序为“cnn_mnist.m”,而cnn结构初始化在“cnn_mnist_init.m”中完毕。网络结构不须要又一次设计。仅仅须要在cnn_mnist.m中更改数据的输入,在cnn_mnist_init.m更改网络的输出。

    对于本题数据集。“train”中图片为训练集,“val”中为验证集,“test”中为測试集。首先利用“train”和“val”中人脸图片训练cnn网络权重,最后对训练好的网络用“test”中数据进行測试。

    本题主程序所在M文件为“cnn_mnist_new.m”;网络结构文件为“cnn_mnist_init_new.m”;“test_p1.m”为对训练好的网络进行測试的主程序。

   网络激活函数,在缺省情况下,默觉得“sigmoid”。

   首先在“cnn_mnist_init_new.m”中先拷贝“cnn_mnist.m”中代码,然后主要更改当中“getMnistImdb”函数。

因为mnist数据集中的图像数据28*28 。而本次实验中。所用图片大小为100*100 。因此,须要把这些数字图像压缩为28*28 。

   函数“getMnistImdb”中变量“x1”存储训练集中的图片。男性和女性的人脸图片给300张,其前300维存储男性,后300维存储女性;而变量“y1”存储训练集相应的标签。也是其前300维存储男性。后300维存储女性。这里须要注意的是。matconvnet不能把类别标签设置为“0”,否则对其它一些类别不能再识别;而本次作业为二分类问题。这里,男性相应于标签“1”,女性相应于标签“2”。同理,“x2”和“y2”相应于验证集中的数据,当中男性和女性图片各80张。

   作为说明,这里仅仅给出读取训练集数据中女性的演示样例代码:

%x1(:,:,1:300) stores female images in the train set
%x1(:,:,301:600) stores male images in the train set
x1=zeros(28,28,600);
%y1(1:300) stores female labels(1) in the train set
%y1(301:600) stores male labels(2) in the train set
y1=cat(2,ones(1,300),ones(1,300)+1);
%读取训练集图片-female
img_file_path=fullfile(vl_rootnn,'examples\mnist\image\image\new\train\female');
img_dir=dir(img_file_path);
for i=1:length(img_dir)-2 filename=sprintf('%s\\%s\\fy.bmp',img_file_path,img_dir(i+2).name);
I=imread(filename);
I=imresize(I,[28,28]); %将图片压缩为28*28大小
x1(:,:,i)=I;
end

另外,为了防止过拟合,“cnn_mnist_init_new.m”中增加dropout。所谓“dropout”就是在训练过程中,随机让一些节点不參与计算,增加方式为:

net.layers{end+1} = struct('type', 'dropout', 'rate', 0.5);

而且迭代次数设置为300,最重要的是。要把“softmaxloss”前一全连接层中神经元输出节点改2。即:

net.layers{end+1} = struct('type', 'conv', ...
'weights', {{f*randn(1,1,500,2, 'single'), zeros(1,2,'single')}}, ...
'stride', 1, ...
'pad', 0) ;

执行“cnn_mnist_init_new.m”能够得到例如以下结果:

当中。“energy”训练过程中训练集和和验证集的总的误差能量之和;而“error”分别相应训练集和验证机的错误率。“top1err”是“softmax”层输出过程中最高得分项相应错误率,而因为是二分类问题,“top5err”(前5项得分最高项相应错误率)是没有意义的。

这里须要说明一下。因为是二分类问题,最后分类器一般“logistic regression”,而“softmax”是“logistic regression”升级版。支持多分类问题。因为,我们网络最后是全连接到2个神经元上。当中“1”代表女性。“2”代表男性(须要注意的是,运用“softmax”,matconvnet类别标签是不支持0的),而且通过“softmax”进行分类。

2.利用 test目录測试:

“test_p1.m”是对已经训练好的网络測试“test”目录下数据的主程序。

測试集共265张图片,当中男性56张。女性209张。读取数据过程和“cnn_mnist_new.m”类似,这里不再赘述。而载入网络主要过程:

train_imdb_path=fullfile(vl_rootnn,'\examples\mnist\problem1\problem-1-net-epoch\imdb.mat');
load(net_path);
net.layers{end}.type = 'softmax';

当中,“net_path”为网络所在文件路径,而且要主要载入网络之后。要把原来的“softmaxloss”改为“softmax”。

而且处理測试集数据时候。要把測试集的数据减去训练集的均值(因为训练时候。预处理过程含有去均值的过程),当中,均值存储在训练集中的“imdb”结构体中。

演示样例代码例如以下:

test_set=single(test_set);
train_imdb_path=fullfile(vl_rootnn,'\examples\mnist\problem1\problem-1-net-epoch\imdb.mat');
train_imdb=load(train_imdb_path);
train_data_mean=train_imdb.images.data_mean;
test_set=bsxfun(@minus,test_set,train_data_mean);

而这个前向过程的输出主要利用函数“vl_simplenn”,示比例如以下:

err_cnt=0;
best_scores=zeros(1,female_num+male_num);
err_id=zeros(1,female_num+male_num);
for i=1:(female_num+male_num)
res=vl_simplenn(net,test_set(:,:,i));
scores=squeeze(gather(res(end).x));
[best_score, best_id] = max(scores);
best_scores(i)=best_score;
if abs(str2double(net.meta.classes.name{best_id})-test_label(i))>1e-1;
err_cnt=err_cnt+1;
err_id(i)=1;
end end
err_rate=err_cnt/(female_num+male_num);

实验结果。最低错误率为6.79%

执行test_p1.m文件对网络进行測试。本文件共反复10次实验,实验结果分布如上所看到的。

当中平均错误率为8.26%,最低错误率为6.79%。

第二题

1.利用train和val目录进行训练和调參:

与第一题类似。“my_cnn.m”是训练过程的主程序。“my_cnn_init.m”相应网络结构。“test_my_cnn.m” 为对训练好的网络进行測试的主程序。

读取图片数据与第一题类似,这里不再赘述。

而“my_cnn_init.m”中网络结构相应为:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYml6ZXJfY3Nkbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

该网络通过卷积和池化减少维度,而且网络最后全连接到两个神经元上。通过“softmax”进行分类。然后“relu”作为激活函数。训练时候一般须要"batch normalization"

核心代码例如以下:

net.layers = {} ;
%得到96*96
net.layers{end+1} = struct('type', 'conv', ...
'weights', {{f*randn(5,5,1,20, 'single'), zeros(1, 20, 'single')}}, ...
'stride', 1, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'relu') ;
%得到48*48
net.layers{end+1} = struct('type', 'pool', ...
'method', 'avg', ...
'pool', [2 2], ...
'stride', 1, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'dropout', 'rate', 0.2);
%得到44*44
net.layers{end+1} = struct('type', 'conv', ...
'weights', {{f*randn(5,5,10,20, 'single'),zeros(1,20,'single')}}, ...
'stride', 1, ...
'pad', 0) ;
%得到22*22
net.layers{end+1} = struct('type', 'pool', ...
'method', 'avg', ...
'pool', [2 2], ...
'stride', 1, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'dropout', 'rate', 0.2);
%得到18*18
net.layers{end+1} = struct('type', 'conv', ...
'weights', {{f*randn(5,5,20,40, 'single'),zeros(1,40,'single')}}, ...
'stride', 1, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'dropout', 'rate', 0.2);
%得到9*9
net.layers{end+1} = struct('type', 'conv', ...
'weights', {{f*randn(5,5,40,100, 'single'), zeros(1,100,'single')}}, ...
'stride', 1, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'relu') ;
%得到5*5
net.layers{end+1} = struct('type', 'conv', ...
'weights', {{f*randn(5,5,100,100, 'single'), zeros(1,100,'single')}}, ...
'stride', 1, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'relu') ;
%得到1*1
net.layers{end+1} = struct('type', 'conv', ...
'weights', {{f*randn(5,5,100,2, 'single'), zeros(1,2,'single')}}, ...
'stride', 1, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'softmaxloss') ;

执行“my_cnn.m”能够得到例如以下结果:

观察上图可知,当训练次数为第222次时,该网络对val集达到了最低预測错误率,大约为7%。其后有细微的上升趋势。故在下文中选择第222次网络结果进行test集的測试。

2.利用 test目录測试:

“test_p2.m”是对已经训练好的网络測试“test”目录下数据的主程序。測试集共265张图片。当中男性56张,女性209张。

载入网络主要过程:

train_imdb_path=fullfile(vl_rootnn,'\examples\mnist\problem2\problem-2-net-epoch\imdb.mat');
train_imdb=load(train_imdb_path);
net_path=fullfile(vl_rootnn, '\examples\mnist\problem2\problem-2-net-epoch\','net-epoch-222.mat') ;
load(net_path);
net.layers{end}.type = 'softmax';

利用函数“vl_simplenn”进行预測,本部分同问题一,故不再复述。

实验结果,最低错误率为4.53%

执行test_p2.m文件对网络进行測试。本文件共反复10次实验,实验结果分布如上所看到的。当中平均错误率为7.85%,最低错误率为4.53%。

一些思考:

为何不能分块:

在完毕第一题的时候。除了利用imresize函数对图像进行缩放外,我们还试图对图像进行分块处理,如将100*100的图像切割为16张28*28的子图。例如以下所看到的:

然后再对子图进行cnn训练,可是效果并不理想。甚至训练过程都不收敛:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYml6ZXJfY3Nkbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

分析这个现象的原因,我们觉得。人脸图像并不能切割为子块。当切割为子块时。人脸不再是人脸。而仅仅是各个部分离散的多张图片。当中男女图像各个部分高度类似。甚至我们人类在判别的时候也不能分清一个子图属于男还是属于女。

例如以下图第1排的第1张图片,我们非常难推断该子图属于女性。
图像的切割,造成了信息的丢失,部分之和再也不能取代总体。


为何28*28与100*100的精度近似相等

观察下图。左为第一题训练结果。右为第二题训练结果。能够看到,28*28与100*100大小的图片经过cnn训练后,对男女性别的推断,在精度上近似相等。

究其原因。我们觉得,图片大小的改变对人类来说,并不影响推断结果。丢失的信息不足以影响二值化推断。

代码已上传:http://download.csdn.net/detail/bizer_csdn/9827175
使用时候替换安装matconvnet目录下的examples目录

模式识别hw2-------基于matconvnet,用CNN实现人脸图片性别识别的更多相关文章

  1. 基于QT和OpenCV的人脸检測识别系统(2)

    紧接着上一篇博客的讲 第二步是识别部分 人脸识别 把上一阶段检測处理得到的人脸图像与数据库中的已知 人脸进行比对,判定人脸相应的人是谁(此处以白色文本显示). 人脸预处理 如今你已经得到一张人脸,你能 ...

  2. 基于MatConvNet的CNN图像搜索引擎PicSearch

    简介 Picsearch是一种基于卷积神经网络特征的图像搜索引擎. Github:https://github.com/willard-yuan/CNN-for-Image-Retrieval Web ...

  3. 人脸和性别识别(基于OpenCV)

    描写叙述 人脸识别包含四个步骤 人脸检測:定位人脸区域,仅仅关心是不是脸: 人脸预处理:对人脸检測出来的图片进行调整优化. 收集和学习人脸:收集要识别的人的预处理过的人脸,然后通过一些算法去学习怎样识 ...

  4. 基于QT和OpenCV的人脸检測识别系统(1)

    人脸识别分为两大步骤 1.人脸检測 这个是首要实现的.你得实现人脸显示的时候把人脸框出来,当然算法非常多,另一些人眼检測鼻子检測什么的 主要用的是这个 const char *faceCascadeF ...

  5. 基于深度学习的人脸性别识别系统(含UI界面,Python代码)

    摘要:人脸性别识别是人脸识别领域的一个热门方向,本文详细介绍基于深度学习的人脸性别识别系统,在介绍算法原理的同时,给出Python的实现代码以及PyQt的UI界面.在界面中可以选择人脸图片.视频进行检 ...

  6. python手写bp神经网络实现人脸性别识别1.0

    写在前面:本实验用到的图片均来自google图片,侵删! 实验介绍 用python手写一个简单bp神经网络,实现人脸的性别识别.由于本人的机器配置比较差,所以无法使用网上很红的人脸大数据数据集(如lf ...

  7. 转:基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴等)【模式识别中的翘楚】

    文章来自于:http://blog.renren.com/share/246648717/8171467499 基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴 ...

  8. 使用Dlib来运行基于CNN的人脸检测

    检测结果如下 这个示例程序需要使用较大的内存,请保证内存足够.本程序运行速度比较慢,远不及OpenCV中的人脸检测. 注释中提到的几个文件下载地址如下 http://dlib.net/face_det ...

  9. 基于CNN的人脸相似度检测

    人脸相似度检测主要是检测两张图片中人脸的相似度,从而判断这两张图片的对象是不是一个人. 在上一篇文章中,使用CNN提取人脸特征,然后利用提取的特征进行分类.而在人脸相似度检测的工作中,我们也可以利用卷 ...

随机推荐

  1. NetScaler Active-Active模式

    NetScaler Active-Active模式 NetScaler Active-Active模式 (此文档基于版本:NS9.3: Build 55.6 nc) By ShingTan Activ ...

  2. 【距离GDKOI:44天&GDOI:107天】【BZOJ1040】[ZJOI2008] 骑士 (环套树DP)

    其实已经准备退役了,但GDOI之前还是会继续学下去的!!当成兴趣在学,已经对竞赛失去信心了的样子,我还是回去跪跪文化课吧QAQ 第一道环套树DP...其实思想挺简单的,就把环拆开,分类处理.若拆成开的 ...

  3. 旅行规划(travel)

    题目描述 OIVillage 是一个风景秀美的乡村,为了更好的利用当地的旅游资源,吸引游客,推动经济发展,xkszltl 决定修建了一条铁路将当地 nnn 个最著名的经典连接起来,让游客可以通过火车从 ...

  4. testng自定义注解

    在testng中大部分的注解已经可以满足我们测试的需求,但是在测试的时候想要通过注解的方式加入自己测试一些内容,比如 测试项目 测试描述  验证点等信息,可通过自定义注解的方式实现. 具体操作步骤如下 ...

  5. Video for Linux Two API Specification Revision 2.6.32【转】

    转自:https://www.linuxtv.org/downloads/legacy/video4linux/API/V4L2_API/spec-single/v4l2.html Video for ...

  6. hadoop使用supervisord

    #安装 wget https://pypi.python.org/packages/80/37/964c0d53cbd328796b1aeb7abea4c0f7b0e8c7197ea9b0b9967b ...

  7. 数据库--MyBatis的(insert,update,delete)三种批量操作

    转自:http://blog.csdn.net/starywx/article/details/23268465 前段时间由于项目赶期没顾上开发过程中的性能问题,现对部分代码进行优化的过程中发现在数据 ...

  8. python接口自动化4-绕过验证码登录(cookie)【转载】

    本篇转自博客:上海-悠悠 原文地址:http://www.cnblogs.com/yoyoketang/tag/python%E6%8E%A5%E5%8F%A3%E8%87%AA%E5%8A%A8%E ...

  9. 随手看的一本书《java微服务》,测试成功了其中的第一个样例

    静态语言,JAVA应该多了解,结合微服务,DOCKER,再搞搞SPRING CLOUD,就能跟上时代了. 对了,链一个买书的地址: https://item.jd.com/12089180.html ...

  10. [BZOJ1634][Usaco2007 Jan]Protecting the Flowers 护花 贪心

    1634: [Usaco2007 Jan]Protecting the Flowers 护花 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 885  So ...