[基于tensorflow的人脸检测] 基于神经网络的人脸检测5——神经网络的搭建

1.神经网络的基本组成部分

2.tensorflow实现神经网络的框架搭建

3.两个经典的神经网络实例

正文:

1.神经网络的基本组成部分

一个典型的卷积神经网络一般由全连接层卷积层池化层组成。

  • 全连接层是层与层之间所有神经元节点都两两相互连接,所以重要的参数只有两个,输入节点个数和输出节点个数。
  • 卷积层的层与层之间的神经元节点是采用部分连接的方式,采用块状的连接方式(这个块状叫过滤器),其需要定义的参数有
    • 输入以及输入的深度
    • 过滤器尺寸
    • 输出深度(过滤器深度)
    • 过滤的移动步长
  • 池化层的连接方式与卷积层的连接方式一样,由于池化层不改变输入的深度(输出和输入的深度是一样的),所以需要指定的参数是过滤器尺寸和过滤器移动步长。另外根据计算方式的不同,常用的池化层有最大池化和平均池化两种。
2.tensorflow实现神经网络的框架搭建

tensorflow对神经网络的实现有很好的函数支持,下面是实现上面的三种网络层结构的代码。

import tensorflow as tf

def fc(input_, input_deep, out_deep, name): #全连接层
    """参数->输入、输入深度、输出深度、该层的变量名"""
    with tf.compat.v1.variable_scope(name):
        weight = tf.Variable( #权重
            tf.random.truncated_normal([input_deep, out_deep], stddev=0.05),
            name="weights")
        bias = tf.Variable( #偏置
            tf.constant(0.1, dtype=tf.float32, shape=[out_deep]), 
            name="bias")
        net = tf.nn.relu(tf.add(tf.matmul(input_, weight), bias)) #乘加 激活
        
    return net
  
def conv(input_, input_deep, output_deep, ksize, stride, name):#卷积层
    """参数->输入、输入深度、输出深度、过滤器尺寸、过滤器移动步长、该层的变量名"""
    with tf.compat.v1.variable_scope(name):
        conv_weights = tf.compat.v1.get_variable( #权重
            'weight', [ksize, ksize, input_deep, output_deep],
            initializer = tf.truncated_normal_initializer(stddev=0.1))
        conv_biases = tf.compat.v1.get_variable( #偏置
            'biases', [output_deep], initializer = tf.constant_initializer(0.0))

        conv = tf.nn.conv2d( #卷积
            input_, conv_weights, strides=[1,stride,stride,1], padding='SAME')
        relu = tf.nn.relu(tf.nn.bias_add(conv, conv_biases)) #激活
        
    return relu

def maxpool(input_, ksize, stride, name): #最大池化层
    """参数->输入、过滤器尺寸、过滤器移动步长、该层的变量名"""
    with tf.name_scope(name):
        pool = tf.nn.max_pool2d(input_, ksize=[1,ksize,ksize,1], strides=[1,stride,stride,1],
                                padding='VALID') #最大池化
        
    return pool

在卷积和池化时还需要指定填充方式(padding),填充是利用0填充输入矩阵,从而使得输出矩阵的大小不变。padding参数的表示如下。

padding = ‘VALID’ #不使用零填充
padding = ‘SAME’ #使用零填充

填充的方式不同,计算输出矩阵的尺寸也不同。下面是两种方式的计算方法,其中 ⌈ ⌉ \lceil\rceil 表示向上取整。

padding = ‘VALID’ :

输 出 的 高 = ⌈ 输 入 的 高 − 过 滤 器 的 高 + 1 过 滤 器 移 动 步 长 ⌉ 输出的高 = \lceil \frac{输入的高-过滤器的高+1}{过滤器移动步长}\rceil =+1

输 出 的 宽 = ⌈ 输 入 的 宽 − 过 滤 器 的 宽 + 1 过 滤 器 移 动 步 长 ⌉ 输出的宽 = \lceil \frac{输入的宽-过滤器的宽+1}{过滤器移动步长}\rceil =+1

输 出 的 深 度 = 过 滤 器 深 度 输出的深度 = 过滤器深度 =

padding = ‘SAME’:

输 出 的 高 = ⌈ 输 入 的 高 过 滤 器 移 动 步 长 ⌉ 输出的高 = \lceil \frac{输入的高}{过滤器移动步长}\rceil =

输 出 的 宽 = ⌈ 输 入 的 宽 过 滤 器 移 动 步 长 ⌉ 输出的宽 = \lceil \frac{输入的宽}{过滤器移动步长}\rceil =

输 出 的 深 度 = 过 滤 器 深 度 输出的深度 = 过滤器深度 =

3.两个经典的神经网络实例
  1. Alexnet神经网络

    下图为Alexnet的神经网络结构图。
    在这里插入图片描述

    (图片来源于百度百科)
    下面是代码实现:
    def alexnet(input_):
        """alexnet网络结构"""
        conv1 = conv(input_, 3, 96, 11, 4,'layer1_conv1')
        #3为输入到神经网络的维度
        
        lrn1 = tf.nn.lrn(conv1,4,bias=1,alpha=1e-3/9,beta=0.75,name="layer2_lrn1")
        #局部响应归一化
        
        pool1 = maxpool(lrn1, 3, 2,'layer3_pool1')
        
        conv2 = conv(pool1, 96, 256, 5, 1,'layer4_conv2')
    
        lrn2 = tf.nn.lrn(conv2,4,bias=1,alpha=1e-3/9,beta=0.75,name="layer5_lrn2")
    
        pool2 = maxpool(lrn2, 3, 2,'layer6_pool2')
    
        conv3 = conv(pool2, 256, 384, 3, 1,'layer7_conv3')
    
        conv4 = conv(conv3, 384, 384, 3, 1,'layer8_conv4')
    
        conv5 = conv(conv4, 384, 256, 3, 1,'layer9_conv5')
    
        pool3 = maxpool(conv5, 3, 2,'layer10_pool3')
    
        pool_shape = pool3.get_shape().as_list()
        #计算向量长度 长x宽x高(第二、三、四维度,第一维为batch个数)
        nodes = pool_shape[1] * pool_shape[2] * pool_shape[3]
        #通过函数变成向量
        reshaped = tf.reshape(pool3, [pool_shape[0], nodes])
        
        fc1 = fc(reshaped, nodes, 4096, 'layer11_fc1')
        
        fc2 = fc(fc1, 4096, 4096, 'layer12_fc2')
        
        fc3 = fc(fc2, 4096, 2, 'layer13_fc3' )
    
        return fc3
    

神经网络的输出的维度应该等于分类的个数,在人脸检测中,神经网络用于判定输入的图片是否为人脸,是一个二分类任务,所以在最后一层的输出维度中应该是2。

​ 2.vgg神经网络

下表为vgg的神经网络结构图,以表格C列的vgg-16为例搭建神经网络,其中卷积层的过滤器移动步长为1,池化层过滤器的移动步长为2。

在这里插入图片描述

(图片来源于百度百科)

vgg16代码实现:

def vgg_16(input_):
    """vgg16网络结构"""
    conv1 = conv(input_, 3, 64, 3, 1,'layer1_conv1')
    #3为输入到神经网络的维度
    
    conv2 = conv(conv1, 64, 64, 3, 1,'layer2_conv2')
    
    pool1 = maxpool(conv2, 3, 2,'layer3_pool1')
    
    conv3 = conv(pool1, 64, 128, 3, 1,'layer4_conv3')
    
    conv4 = conv(conv3, 128, 128, 3, 1,'layer5_conv4')
    
    pool2 = maxpool(conv4, 3, 2,'layer6_pool2')

    conv5 = conv(pool2, 128, 256, 3, 1,'layer7_conv5')

    conv6 = conv(conv5, 256, 256, 3, 1,'layer8_conv6')

    conv7 = conv(conv6, 256, 256, 1, 1,'layer9_conv7')

    pool3 = maxpool(conv7, 3, 2,'layer10_pool3')
    
    conv8 = conv(pool3, 256, 512, 3, 1,'layer11_conv8')

    conv9 = conv(conv8, 512, 512, 3, 1,'layer12_conv9')

    conv10 = conv(conv9, 512, 512, 1, 1,'layer13_conv10')

    pool4 = maxpool(conv10, 3, 2,'layer14_pool4')
    
    conv11 = conv(pool4, 512, 512, 3, 1,'layer15_conv11')

    conv12 = conv(conv11, 512, 512, 3, 1,'layer16_conv12')

    conv13 = conv(conv12, 512, 512, 1, 1,'layer17_conv13')

    pool5 = maxpool(conv13, 3, 2,'layer18_pool5')
    

    pool_shape = pool5.get_shape().as_list()
    #计算向量长度 长x宽x高(第二、三、四维度,第一维为batch个数)
    nodes = pool_shape[1] * pool_shape[2] * pool_shape[3]
    #通过函数变成向量
    reshaped = tf.reshape(pool5, [pool_shape[0], nodes])
    
    fc1 = fc(reshaped, nodes, 4096, 'layer19_fc1')
    
    fc2 = fc(fc1, 4096, 4096, 'layer20_fc2')
    
    fc3 = fc(fc2, 4096, 2, 'layer21_fc3' )
    
    soft = tf.nn.softmax(fc3)

    return soft

搭建完成网络之后,可以利用图片进行测试,输入一张图片,查看通过神经网络后的输出维度。下面是测试vgg16神经网络的代码以及结果展示。

import tensorflow as tf
import cv2
import numpy as np
path = r"C:\Users\user\Desktop\lena.jpg"
tf.compat.v1.reset_default_graph() #先清空计算图
image = cv2.imread(path, 1)
image_data = tf.image.convert_image_dtype(image,dtype=tf.float32)
with tf.compat.v1.Session() as sess:
    image = sess.run(image_data)
    image = cv2.resize(image,(224,224))
    reshape_xs=np.reshape(image,(1,224,224,3))
    y = vgg_16(reshape_xs)
    print(y)
#输出结果为
#Tensor("Softmax:0", shape=(1, 2), dtype=float32)

结语:
如果对你有帮助,就给我一个赞吧,如何有问题,可以在评论区进行讨论。

上一篇:[基于tensorflow的人脸检测] 基于神经网络的人脸检测4——数据集的标签生成
下一篇:[基于tensorflow的人脸检测] 基于神经网络的人脸检6——数据的存储与加载

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值