美文网首页人脸识别
深度学习—PNet模型实践

深度学习—PNet模型实践

作者: 90000Tank | 来源:发表于2020-11-07 18:56 被阅读0次

在AI的培训学习期间,常常能听到老师的叮嘱:不动手,是绝对学不好AI的。正好今天学习了一些经典的深度学习网络模型,这次就以PNet为主说下自己的学习心得和编码实践。

知识铺垫

很多深度学习网络模型的基础,就是卷积神经网络(CNN)

CNN概述

很多图形,可以在通过特定的变换(在计算机中可以表示为矩阵运算)后,仍旧保持原有的一些重要特征,如下图所示:

图中的用来相乘的3×3小矩阵,就是一个过滤器(filter)。而所谓CNN(convolutional neural network),就是通过一个个的filter,不断地提取特征,从局部的特征到总体的特征,从而进行图像识别功能。那么怎么去设计这些各种各样的filter呢?首先,我们都不一定清楚对于一大推图片,我们需要识别哪些特征,其次,就算知道了有哪些特征,想真的去设计出对应的filter,恐怕也并非易事,要知道,特征的数量可能是成千上万的。

不用着急,在神经网络里,这些filter中的每个数字,其实就是参数。我们可以通过大量的数据,来让计算机自己去“学习”这些参数(即深度学习),这就是CNN的基本原理。

CNN结构组成

CNN的整体结构包含了3种层(layer):

  • Convolutional layer(卷积层--CONV)
  • Pooling layer(池化层--POOL)
  • Fully Connected layer(全连接层--FC)
CNN过程演示

从图可以看出,在经过数次卷积和池化之后,我们最后会先将多维的图片数据进行“扁平化”,也就是把 (height,width,channel)的数据压缩成长度为 height × width × channel的一维数组,然后再与FC层连接,使其变为普通的神经网络。

感受野

在卷积神经网络中,感受野(Receptive Field)是指卷积神经网络每一层输出的特征图(feature map)上的像素点在输入图片上映射的区域大小。再通俗点的解释是,特征图上的一个点对应输入图上的区域,如下图所示:

选择适合的filter,从而达到理想的感受野,是一个好的神经网络的体现。

模型描述

PNet网络模型图

这个模型图来自于论文《Joint Face Detection and Alignment using
Multi-task Cascaded Convolutional Networks》,从图中可以看出:PNet输入是一个12×12大小的图片,所以训练前需要把生成的训练数据(通过生成bounding box,然后把该bounding box 剪切成12×12大小的图片),转换成12×12×3的结构。

  1. 通过10个3×3×3的卷积核,2×2的Max Pooling(stride=2)操作,生成10个5×5的特征图
  2. 通过16个3×3×10的卷积核,生成16个3×3的特征图
  3. 通过32个3×3×16的卷积核,生成32个1×1的特征图。
  4. 针对32个1×1的特征图,可以通过2个1×1×32的卷积核,生成2个1×1的特征图用于分类【是否人脸】;4个1×1×32的卷积核,生成4个1×1的特征图用于回归框判断【人脸位置的4个特征】;10个1×1×32的卷积核,生成10个1×1的特征图用于人脸轮廓点的判断【左右眼、鼻子、左右嘴角位置】。

编码实践

为了简单模拟网络模型,使用了Python的TensorFlow库,所涉及的两个主要函数如下:

  • tf.layers.conv2d——用于构造CNN结构中的卷积层
  • tf.layers.max_pooling2d——用于构造CNN结构中的池化层

以下是模拟PNet网络模型的代码(不涉及到模型训练)

import tensorflow as tf
import numpy as np

inputs = tf.placeholder(tf.float32, [32, 12, 12, 3])  ## 假设一开始有32个图片,图片大小12*12
'''
这些维数(filter、channel等),都是根据论文《Joint Face Detection and Alignment using 
Multi-task Cascaded Convolutional Networks》 中的图来照葫芦画瓢的~
'''
### 卷积(convolution)后图片数量变为10,说明filter数量为10【即生成10个特征】;
### kernel_size为3(因为描述是“Conv: 3*3”);
### padding默认为valid
net = tf.layers.conv2d(inputs, 10, 3, activation=tf.nn.relu)  

### 论文中MP(max pooling)为3*3(指窗口大小);
### 另外可看出图片边长从12变为5(缩小2倍多),说明步长(stride)很可能为2
net = tf.layers.max_pooling2d(net, 3, 2, padding="same") 
net = tf.layers.conv2d(net, 16, 3, padding="valid", activation=tf.nn.relu)
net = tf.layers.conv2d(net, 32, 3, padding="valid", activation=tf.nn.relu)

# 是否人脸(二分类问题)
logits = tf.layers.conv2d(net, 2, 1, padding='valid', activation=tf.nn.relu)
## 人脸位置,Box【4个特征:】
boxes = tf.layers.conv2d(net, 4, 1, padding='valid', activation=tf.nn.relu)
### 人脸关键点 【10个特征:左眼、右眼、鼻子、左嘴角、右嘴角】
landmark = tf.layers.conv2d(net, 10, 1, padding='valid', activation=tf.nn.relu)

print(net.shape)

运行后可以看到,最后的输出结果为“(32, 1, 1, 32)”,与PNet的模型说明最后的输出维度一致,说明代码已可以简单模拟PNet网络模型。

  参考:
*【DL笔记6】从此明白了卷积神经网络(CNN)(https://zhuanlan.zhihu.com/p/42559190)

相关文章

网友评论

    本文标题:深度学习—PNet模型实践

    本文链接:https://www.haomeiwen.com/subject/bqlqbktx.html