【TensorFlow2.0】(可写入简历项目) 基于CNN卷积神经网络的图像识别—从搭建模型到模型部署完整过程

以CNN为基础完成一个CIFAR-10图像识别应用。

一、CNN相关理论

CNN(Convolutional Neural Network,卷积神经网络)是DNN(深度神经网络,泛指全连接层)中一个非常重要的并且应用广泛的分支,CNN自从被提出在图像处理领域得到了大量应用。

卷积神经网络按照层级可以分为5层:数据输入层卷积层激活层池化层全连接层

1.1 数据输入层

数据输入层主要是对原始图像数据进行预处理。

1.2 卷积层 Conv

卷积层通过卷积计算将样本数据进行降维采样,以获取具有空间关系特征的数据。

1.3 激活层

激活层对数据进行非线性变换处理,目的是对数据维度进行扭曲来获得更多连续的概率密度空间。在CNN中,激活层一般采用的激活函数是ReLU,它具有收敛快、求梯度简单等特点。

1.4 失活层 Dropout

失活层d1 : Dropout极大简化了训练时神经网络的复杂度,加快了神经网络的训练速度; Dropout的主要作用是防止神经网络的过拟合,提高了神经网络的泛化性。

1.5 池化层 Pool

池化层夹在连续的卷积层中间,用于压缩数据的维度以减少过拟合。当采用最大池化策略时,可以采用最大值来代替一个区域的像素特征,这样就相当于忽略了这个区域的其他像素值,大幅度降低了数据采样维度。

1.6 Flatten层

Flatten层将图片矩阵拉平:经过卷积和池化完成特征提取,紧接着是全连接层,需要将图片的三个维度长宽数据压平成一个维度,可以减少参数。

1.7 批量池化层 BatchNormalization

批量池化层 BatchNormalization 进行归一化处理,是一个用于优化训练神经网络的技巧,让数据在训练过程中保持同一分布,在每一个隐藏层进行批量归一化。对于每一个batch,计算该batch的均值与方差,在将线性计算结果送入激活函数之前,先对计算结果进行批量归一化处理,即减均值、除标准差,保证计算结果符合均值为0,方差为1的标准正态分布,然后再将计算结果作为激活函数的输入值进行计算。

1.8 全连接层 DNN

全连接层在所有的神经网络层级之间都有权重连接,最终连接到输出层。在进行模型训练时,神经网络会自动调整层级之间的权重以达到拟合数据的目的。

源码:

# 导入需要的依赖包
import tensorflow as tf
import getConfig

# 初始化一个字典,用于存放配置获取函数返回的配置参数
gConfig = {}
gConfig = getConfig.get_config(config_file='config.ini')

'''
	在cnnModel实现上我们采用了tf.keras这个高阶API类,
	定义了四层卷积神经网络,输出维度分别是32、64、128和256,
	最后在输出层定义了四层全连接神经网络,输出维度分别是256、128、64和10。
	在定义卷积神经网络过程中,按照一个卷积神经网络标准的结构进行定义,
	使用最大池化(maxpooling)策略进行降维特征提取,使用Dropout防止过拟合。
'''

# 定义cnnModel方法类,在执行器中可以世界实例化一个CNN进行训练
class cnnModel(object):
    def __init__(self, rate):
        # 初始化Dropout神经元失效的概率
        self.rate = rate

    def createModel(self):
        # 创建Sequential序列对象,通过add添加所需的网络层
        model = tf.keras.Sequential()
        '''
            tf.keras.layers.Conv2D: 使用Conv2D可以创建一个卷积核来对输入数据进行卷积计算,
                                    然后输出结果,其创建的卷积核可以处理二维数据。
        '''
        # 卷积层conv1: 输出数据维度为64,卷积核维度为3x3,输入数据维度为:[32,32,3]
        model.add(tf.keras.layers.Conv2D(64, 3,
                                       kernel_initializer='he_normal',
                                       strides=1,
                                       activation='relu',
                                       padding='same',
                                       input_shape=(32, 32, 3),
                                       name="conv1"))

        # 卷积层conv2: 输出数据维度为64,卷积核维度为3x3
        model.add(tf.keras.layers.Conv2D(64, 3,
                                         kernel_initializer='he_normal',
                                         strides=1,
                                         activation='relu',
                                         padding='same',
                                         name="conv2"))

        # 池化层pool1: 在一个2×2的像素区域内取一个像素最大值作为该区域的像素特征
        model.add(tf.keras.layers.MaxPool2D((2, 2),
                                            strides=2,
                                            padding='valid',
                                            name="pool1"))
        # 失活层d1 : Dropout极大简化了训练时神经网络的复杂度,加快了神经网络的训练速度;
        #           Dropout的主要作用是防止神经网络的过拟合,提高了神经网络的泛化性。
        model.add(tf.keras.layers.Dropout(rate=self.rate,
                                          name="d1"))

        # 批量池化层BatchNormalization
        model.add(tf.keras.layers.BatchNormalization())

        # 卷积层conv3
        model.add(tf.keras.layers.Conv2D(128, 3,
                                         kernel_initializer='he_normal',
                                         strides=1,
                                         activation='relu',
                                         padding='same',
                                         name="conv3"))
        # 卷积层conv4
        model.add(tf.keras.layers.Conv2D(128, 3,
                                         kernel_initializer='he_normal',
                                         strides=1,
                                         activation='relu',
                                         padding='same',
                                         name="conv4"))

        # 池化层pool2: 在一个2×2的像素区域内取一个像素最大值作为该区域的像素特征
        model.add(tf.keras.layers.MaxPool2D((2, 2),
                                            strides=2,
                                            padding='valid',
                                            name="pool2"))
        # 失活层d2
        model.add(tf.keras.layers.Dropout(rate=self.rate,
                                          name="d2"))
        # 批量池化层BatchNormalization
        model.add(tf.keras.layers.BatchNormalization())

        # 卷积层conv5
        model.add(tf.keras.layers.Conv2D(256, 3,
                                         kernel_initializer='he_normal',
                                         strides=1,
                                         activation='relu',
                                         padding='same',
                                         name="conv5"))
        # 卷积层conv6
        model.add(tf.keras.layers.Conv2D(256, 3,
                                         kernel_initializer='he_normal',
                                         strides=1,
                                         activation='relu',
                                         padding='same',
                                         name="conv6"))

        # 池化层pool3: 在一个2×2的像素区域内取一个像素最大值作为该区域的像素特征
        model.add(tf.keras.layers.MaxPool2D((2, 2),
                                            strides=2,
                                            padding='valid',
                                            name="pool3"))
        # 失活层d3
        model.add(tf.keras.layers.Dropout(rate=self.rate,
                                          name="d3"))
        # 批量池化层BatchNormalization
        model.add(tf.keras.layers.BatchNormalization())

        # Flatten层将图片矩阵拉平:
        # 经过卷积和池化完成特征提取,紧接着是全连接层,需要将图片的三个维度长宽数据压平成一个维度,可以减少参数
        model.add(tf.keras.layers.Flatten(name="flatten"))

        # Dropout层d4
        model.add(tf.keras.layers.Dropout(rate=self.rate,
                                          name="d4"))
        # 全连接层
        model.add(tf.keras.layers.Dense(128,
                                        activation='relu',
                                        kernel_initializer='he_normal'))
        # Dropout层d5
        model.add(tf.keras.layers.Dropout(rate=self.rate,
                                          name="d5"))
        # 最后的输出层,项目是进行图像10分类,输出的维度是10;
        # 使用softmax作为激活函数,softmax是一个在多分类问题上使用的激活函数
        model.add(tf.keras.layers.Dense(10,
                                        activation='softmax',
                                        kernel_initializer='he_normal'))

        # 设计完神经网络后,需要对网络模型进行编译、生成可以训练的模型;
        # 进行编译时,需要定义损失函数loss、优化器optimizer、模型评价标准metrics
        model.compile(loss='categorical_crossentropy',
                      optimizer='adam',
                      metrics=['accuracy'])

        return model

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
乘风的头像乘风管理团队
上一篇 2022年5月24日
下一篇 2022年5月24日

相关推荐