Introduction(介绍)
这一篇文章是“ST25R3916 Discovery Board 人脸识别+NFC双重认证的安全门禁系统”的第二篇。
在上一篇文章里面,我们介绍了这个小工程的整体框架和开发板侧的具体工作,这一篇我们会着重介绍PC侧的开发工作。这篇文章是基于“Arnaldo P. Castaño”在codeproject的基础上进行的二次开发,非常幸运有大牛在前面淌水。


Technical Background(技术背景)
什么是CNN?这是一种特别的神经网络(卷积网络),专门用于图像分类。它的输入是一个立体矩阵数据,一般用于存储一个图片,图片一般都有长宽和深度组成,灰阶的深度是1,而彩色图片深度是3 (RGB)。卷积矩阵由多个卷积层组成;卷积层最重要的功能是利用提供kernel来做图片的卷积运算,这在图像处理中使用非常的广泛。如果你学过图像处理算法,你应该对dither和sharper算法相当熟悉,Kernel就是类似的算法。但是在卷积网络中,这些算法可不是为了进行单纯的图像处理,特定的kernel算法可以用来寻找图片中的特征向量,水平或者垂直的线,边角甚至是圆。具体的算法和公式我就不在这里展示了,免得搞得大家都失去了看下去的兴趣。大家需要记住的是,卷积网络是通过kernel算法寻找特征向量,并在多个卷积层之间使用权重来互相关联。而这些权重的分配就是我们所重点关心的东西。


Face Recognition(人脸识别)
在开始我们的工作之前,我们需要准备以下工具:
1. Python3.0 (我们的代码将主要遵循Python的语法)
2. TensorFlow(TF) 这是Google的开源代码,目前已经集成在Python里面作为一个库使用。我之前有自己从0开始开发过一个小型的NN网络,花费了不少时间,而如果直接使用TF,也许就只有3行代码的工作量。不过自己从无到有开发的好处是你可以方便的移植到各种平台中发挥作用
3. Keras 机器学习的Python API
4. Numpy Python带的包,用于复杂的数学计算
5. SK-Image 用以处理图形图像
6. TK 用来开发界面程序
如果你这些都准备好了,我们就开始开发CNN。 我会在github上公开代码,如果你在使用这些代码的过程中,发现有一些包缺失,可以使用pip安装对应的包。
我们的CNN包含以下属性:
1. 输入层,由于我们处理的是灰阶图像,我们的深度选择是1
2. Conv2D layer – 32 filters, filter size of 3
3. Activation layer – must use a nonlinear function for learning, in this case, the function is ReLU
4. Conv2D layer – 32 filters, filter size of 3, stride of 3
5. MaxPooling2D layer – applies the (2, 2) pooling window
6. DropOut layer, at 25% – prevents overfitting by randomly dropping some of the values from the previous layer (setting them to 0); a.k.a. the dilution technique
7. Conv2D layer – 64 filters, filter size of 3
8. Conv2D layer – 64 filters, filter size of 3 and, stride of 3
9. MaxPooling2D layer – applies the (2, 2) pooling window
10. DropOut layer, at 25%
11. Flatten layer – transforms the data to be used in the next layer
12. Dense layer – represents a fully connected traditional NN
13. Dense layer, with the number of nodes matching the number of classes in the problem – 15 for the Yale dataset
看上去可能很麻烦,其实只是各种属性的初始化而已。代码如下图:
code3.jpg
我们使用的样本图片来自于Yale,15个非常友善的小伙子贡献了165个灰阶的表情包供大家使用。非常有爱。
face.png
OK,下面的图片展示了使用CNN对这165张图片进行学习,这15个人就是我们的分类,我们的目标是当Camera读到其中的任何一个人的头像时,不管他是什么样的表情,都能正确的识别他,并能和他对应的NFC TAG ID进行正确的关联。
我开发了一个TK的GUI来方便的处理和用户的交互:
train.jpg
Training 60 次结束了,我们得到的正确率是91.3%,貌似还可以。
train2.jpg
下面我们来识别一张图片,Open File Button模拟的是Camera,我并没有太多时间来开发Camera模块,我的目的主要是为了展示整个项目的核心概念。
predict.jpg
我随机选择的是第6个小伙,而CNN网络也正确的识别出了第六个小伙,看下面的浮点数,显示的是在16个分类中各个分类的可能性,我们可以很清楚的看到,分类6中的可能性是最高的。

代码我放在了: https://github.com/imwangwang/face-recognition

在下面一节里面,我会向大家展示如何把PC的识别和NFC的识别集成起来(integration),来Demo我们在第一节里面提及的功能。