项目实战2:TF2.0+AlexNet构建Fasion MNSIT分类器

Table of Contents

1.1 AlexNet 简介

1.2 tensorflow2.0利用keras搭建AlexNet网络结构

1.3 AlexNet实现Fasion MNIST分类

参考文献及链接:


一、前言

在构建了LetNet网络实现对Fasion MNSIT的分类后,熟悉了深度学习在图像分类应用的大致流程,但精度不佳,于是决定搭建深度学习发展历程中经典的网络模型,对Fasion MNIST数据集进行进一步分析,了解各个网络模型的闪光点,也通过对网络模型的分析学习深度学习的知识点,秉承“实践出真理”的实干注意真谛,为后期在实际项目中的模型优化打好基础。

学习记录:

1. tensorflow2.0深度学习开发环境搭建(ubuntu/win10)

2. 项目实战1:TF2.0+LetNet-5构建Fasion MNSIT分类器

3. 项目实战2:TF2.0+AlexNet构建Fasion MNSIT分类器

4. 项目实战3:TF2.0+VGG-16构建Fasion MNIST分类器

5. 项目实战4:TF2.0+ResNet构建Fasion MNIST分类器

5. 项目实战5:TF2.0+mobilieNet构建Fasion MNIST分类器

1.1 AlexNet 简介

AlexNet是2012年ImageNet竞赛冠军获得者Hinton和他的学生Alex Krizhevsky设计的。也是在那年之后,更多的更深的神经网路被提出,比如优秀的VGG,GoogleLeNet。其官方提供的数据模型,准确率达到57.1%,top 1-5 达到80.2%. 这项对于传统的机器学习分类算法而言,已经相当的出色,其网络结构如图1所示。

AlexNet网络结构图

AlexNet中包含了几个比较新的技术点如下:

  • (1)成功使用ReLU作为CNN的激活函数,并验证其效果在较深的网络超过了Sigmoid,成功解决了Sigmoid在网络较深时的梯度弥散问题。虽然ReLU激活函数在很久之前就被提出了,但是直到AlexNet的出现才将其发扬光大。
  • (2)训练时使用Dropout随机忽略一部分神经元,以避免模型过拟合。Dropout虽有单独的论文论述,但是AlexNet将其实用化,通过实践证实了它的效果。在AlexNet中主要是最后几个全连接层使用了Dropout。

Dropout的作用及原理简介:Dropout可以作为训练深度神经网络的一种trick供选择。在每个训练批次中,通过忽略一半的特征检测器(让一半的隐层节点值为0),可以明显地减少过拟合现象。这种方式可以减少特征检测器(隐层节点)间的相互作用,检测器相互作用是指某些检测器依赖其他检测器才能发挥作用。即:在前向传播的时候,让某个神经元的激活值以一定的概率p停止工作,这样可以使模型泛化性更强,因为它不会太依赖某些局部的特征,示意图如图所示:

论文链接:Dropout: A Simple Way to Prevent Neural Networks from Overfitting

  • (3)在CNN中使用重叠的最大池化。此前CNN中普遍使用平均池化,AlexNet全部使用最大池化,避免平均池化的模糊化效果。并且AlexNet中提出让步长比池化核的尺寸小,这样池化层的输出之间会有重叠和覆盖,提升了特征的丰富性。
  • (4)提出了LRN层,对局部神经元的活动创建竞争机制,使得其中响应比较大的值变得相对更大,并抑制其他反馈较小的神经元,增强了模型的泛化能力。
  • (5)使用CUDA加速深度卷积网络的训练,利用GPU强大的并行计算能力,处理神经网络训练时大量的矩阵运算。AlexNet使用了两块GTX 580 GPU进行训练,单个GTX 580只有3GB显存,这限制了可训练的网络的最大规模。因此作者将AlexNet分布在两个GPU上,在每个GPU的显存中储存一半的神经元的参数。因为GPU之间通信方便,可以互相访问显存,而不需要通过主机内存,所以同时使用多块GPU也是非常高效的。同时,AlexNet的设计让GPU之间的通信只在网络的某些层进行,控制了通信的性能损耗。 
  • (6)数据增强,随机地从256*256的原始图像中截取224*224大小的区域(以及水平翻转的镜像),相当于增加了2*(256-224)^2=2048倍的数据量。如果没有数据增强,仅靠原始的数据量,参数众多的CNN会陷入过拟合中,使用了数据增强后可以大大减轻过拟合,提升泛化能力。进行预测时,则是取图片的四个角加中间共5个位置,并进行左右翻转,一共获得10张图片,对他们进行预测并对10次结果求均值。同时,AlexNet论文中提到了会对图像的RGB数据进行PCA处理,并对主成分做一个标准差为0.1的高斯扰动,增加一些噪声,这个Trick可以让错误率再下降1%。

1.2 tensorflow2.0利用keras搭建AlexNet网络结构

在AlexNet论文里由于采用了两块GUP进行训练,而当时深度学习框架也不想现在tensorflow这么人性化,所以看似挺复杂,这里我们将网络进行简化为单gpu版本,后期需要进行多gpu训练,可利用tensorflow的多gpu训练api进行改善,网络结构如图所示:(图片来自:详解深度学习之经典网络架构(二):AlexNet)

注:AlexNet原始输入图像尺寸为227x227x3大小的1000分类,而Fasion MNIST图像尺寸为28x28x1的10分类,输入尺寸太小不足以完成网络的下采样过程,故需要对网络进行简单的修改:

(1)卷积层1:卷积核步长设为:2

(2)输出层:输出向量长度设为:10

在networks文件夹中创建AlexNet.py,添加以下内容:

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

def AlexNet_inference(in_shape):

    model = keras.Sequential(name='AlexNet')  

    # model.add(layers.Conv2D(96,(11,11),strides=(4,4),input_shape=(in_shape[1],in_shape[2],in_shape[3]),
                # padding='same',activation='relu',kernel_initializer='uniform')) 
                
    model.add(layers.Conv2D(96,(11,11),strides=(2,2),input_shape=(in_shape[1],in_shape[2],in_shape[3]),
                padding='same',activation='relu',kernel_initializer='uniform'))  
    model.add(layers.MaxPooling2D(pool_size=(3,3),strides=(2,2)))  
    model.add(layers.Conv2D(256,(5,5),strides=(1,1),padding='same',activation='relu',kernel_initializer='uniform'))  
    model.add(layers.MaxPooling2D(pool_size=(3,3),strides=(2,2)))  
    model.add(layers.Conv2D(384,(3,3),strides=(1,1),padding='same',activation='relu',kernel_initializer='uniform'))  
    model.add(layers.Conv2D(384,(3,3),strides=(1,1),padding='same',activation='relu',kernel_initializer='uniform'))  
    model.add(layers.Conv2D(256,(3,3),strides=(1,1),padding='same',activation='relu',kernel_initializer='uniform'))  
    model.add(layers.MaxPooling2D(pool_size=(2,2),strides=(2,2)))  
    model.add(layers.Flatten())  
    model.add(layers.Dense(2048,activation='relu'))  
    model.add(layers.Dropout(0.5))  
    model.add(layers.Dense(2048,activation='relu'))  
    model.add(layers.Dropout(0.5))  
    model.add(layers.Dense(10,activation='softmax'))  
    model.compile(optimizer=keras.optimizers.Adam(),
                loss='sparse_categorical_crossentropy', #不能直接用函数,否则在与测试加载模型不成功!
                metrics=['accuracy'])
    model.summary()  

    return model

1.3 AlexNet实现Fasion MNIST分类

利用上一节构建的LetNet-5对Fasion MNIST数据集分类的工程,将推理模型更换为本次建立的AlexNet,进行训练,代码如下:

import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
print(tf.__version__)

from utils import mnist_reader 
from networks import LetNet_5
from networks import AlexNet

MODEL_DIR = "models/"
DataSetPath = "dataSets/fashion/"
# DataSetPath = "dataSets/mnist/"
x_train, y_train = mnist_reader.load_mnist(DataSetPath, 'train')
x_test, y_test = mnist_reader.load_mnist(DataSetPath, 't10k')

x_train = x_train.reshape((-1,28,28,1))
x_test = x_test.reshape((-1,28,28,1))

print(x_train.shape[1], x_train.shape[2], x_train.shape[3])

x_shape  = x_train.shape

def AlexNet_train():
    
    # 加载与训练权重
    # AlexNet_model = keras.models.load_model(PRE_MODEL_DIR)

    AlexNet_model = AlexNet.AlexNet_inference(x_shape)
    totall_epochs = 0
    epochs = 10
    
    while(True):

        history = AlexNet_model.fit(x_train, y_train, batch_size=64, epochs=epochs, validation_split=0.1)

        plt.plot(history.history['accuracy'])
        plt.plot(history.history['val_accuracy'])
        plt.legend(['training', 'valivation'], loc='upper left')
        plt.show()

        res = AlexNet_model.evaluate(x_test, y_test)
        print(res)
        
        totall_epochs += epochs
        model_save_dir = MODEL_DIR+'AlexNet_model_'+str(totall_epochs)+'.h5'
        AlexNet_model.save( model_save_dir )

        keyVal = input('please enter your command!(0:quite, 1>:continue!)')
        keyVal = int(keyVal)
        if 0==keyVal:
            break
        elif 0<=keyVal and 10>=keyVal:
            epochs = keyVal

在训练5个epochs后效果如下图所示:

最后在测试集得到87.67%的精度,不到200us(>5000fps)的推理时间,精度并没有比LetNet-5高?(论调参侠的重要性!)。

参考文献及链接:

(1)AlexNet: ImageNet Classification with Deep ConvolutionalNeural Networks

(2)Dropout: A Simple Way to Prevent Neural Networks from Overfitting

(3)深入理解AlexNet网络(一篇讲解很棒的文章)

 

 

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值