文章目录
文章目录
1. AlexNet介绍
2. 使用TensorFlow2 实现 Alexnet
1. AlexNet介绍
AlexNet是2012年ImageNet竞赛冠军获得者Hinton和他的学生Alex Krizhevsky设计的。其模型的top5错误率(即正确的类不是测试中排名前五的类的百分率)为15.3%,第二名错误率则达到26.2%,足足比第二名提高了 10.9%,在当时引起了不少轰动。Alexnet一站成名,让深度学习和卷积网络也快速的火了起来。
我们从Alexnet论文《ImageNet Classification with Deep Convolutional Neural Networks》中 找到其网络结构,如下图所示

其网络结构整体上跟Lenet5差不多,但是使用了一些对训练网络十分有效的技巧:
使用Relu激活函数,加速模型收敛 使用两块GPU并行运算,提高训练速度,且能帮助训练更大的网络 采用最大池化 使用随机丢弃(Drop Out),每次利用训练样本更新参数时,随机“丢弃”一定比例的神经元,被丢弃的神经元不参加训练,也不更新相关参数。Drop Out能有效减缓过拟合,也能加快网络收敛速度 数据增强(Data Augmentation),通过训练样本生成更多样本,如图像水平翻转,以及将256*256的图像随机选取224*224的片段作为输入图像。通过这两种方式处理,可以将一张图变成2048张图像。这样可以较大规模的增加训练样本,避免由于训练样本不够造成的性能损失。
接下来,我们来具体看下网络结构,我们需要先明确以下几点
结构分上下两部分,是因为采用了两块GPU进行训练
原图没有单独画出Max pooling层,而是将Max pooling层以文本形式标注在卷积层的右下角(事实上,由于池化层没有要学习的参数,因此在计算神经网络层数时一般不将池化层计算在内),我们在讲解的时候,结构按照原图进行讲解,即将卷积层和Max pooling层作为一个层来看待,则按照这种说明规定,Alexnet网络除了输入层外,共有8层(论文中也叫作权重层),其中5个卷积层和3个全连接层。
5个卷积层中,只有第三层,是两块GPU进行融合计算,其余层均是分开计算的。3个全连接层,则均是两个GPU进行融合计算,为了更清晰的说明网络结构,我们将假设只使用一个GPU进行计算。
根据论文描述,池化大小为 ,池化步长为
在第二层和第三层卷积之后,进行了局部响应归一化(Local Response Normalization)处理即LRN层,后续被许多学者发现并不能起太大作用,现在几乎不用这种处理方式,因此不在单独介绍。
依然是先给出卷积特征图大小计算公式:
接下来,我们逐层介绍
输入层
输入大小为 的彩色图像,参数量为。
第一层
输入为的图像, 使用个大小为的卷积核 ,卷积步长为,我们利用特征图大小计算公式计算发现得到的特征图大小为,并不是原图标注的,这里有两种处理方式,可以将输入图像大小调整为,或设定 , 则此时特征图大小也为 ,后续代码实现时,我将使用第一种方式,即将图像大小设置为
卷积层使用的激活函数为Relu。卷积之后,有一个LRN层,之后是最大池化层,经过池化之后,特征图大小从 变为。
该层的待学习参数数量为 个
第二层
输入大小为的特征图,使用 256个大小为的卷积核,卷积步长为1 ,并设定,输出大小为的特征图。
卷积层使用的激活函数为Relu。卷积之后,有一个LRN层,之后是最大池化层,经过池化之后,特征图大小从 变为
该层的待学习参数数量为
第三层
输入大小为的特征图,使用 384个大小为的卷积核,卷积步长为1 ,并设定 ,输出大小为的特征图。
卷积层使用的激活函数为Relu。卷积之后,无LRN层,无最大池化层。
该层的待学习参数数量为
第四层
输入大小为的特征图,使用 384个大小为的卷积核,卷积步长为1 ,并设定,输出大小为的特征图。
卷积层使用的激活函数为Relu。卷积之后,无LRN层,无最大池化层。
该层的待学习参数数量为
第五层
输入大小为的特征图,使用 256个大小为的卷积核,卷积步长为1 ,并设定,输出大小为的特征图。
卷积层使用的激活函数为Relu。卷积之后,无LRN层,有最大池化层,池化后的特征图大小为
该层的待学习参数数量为
第六层
全连接层,输入参数 个,使用 4096个神经元,使用Relu激活函数,使用Drop Out。
该层的待学习参数数量为
第七层
全连接层,输入参数 个,使用 4096个神经元,使用Relu激活函数,使用Drop Out。
该层的待学习参数数量为
第八层
全连接层,输入参数 个,使用 1000个神经元,使用softmax激活函数。
该层的待学习参数数量为
我们使表格来总结下各个层所执行的操作

2. 使用TensorFlow2 实现 Alexnet
#!/usr/bin/python3
# @Time : 2021/2/26 10:07
# @Author :
# @File :
# @Software: PyCharm
# @Description : 使用TensorFlow实现AlexNet网络结构
import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Conv2D,MaxPool2D,Dropout,BatchNormalization,Activation,Flatten,Dense
from tensorflow.keras import Model,models
def AlexNet8():
# 第一层:卷积--> 激活 --> 归一化 --> 最大池化
x = Conv2D(filters=96,kernel_size=11,strides=4,name='Conv2D_1')(inputs)
x = Activation('relu',name='Activation_1')(x)
x = BatchNormalization(name='BN_1')(x) # 使用 BatchNormalization 代替LRN
x = MaxPool2D(pool_size=(3,3),strides=2,name='MaxPool2D_1')(x)
# 第二层:卷积--> 激活 --> 归一化 --> 最大池化
x = Conv2D(filters=256,kernel_size=5,strides=1,padding='same',name='Conv2D_2')(x)
x = Activation('relu',name='Activation_2')(x)
x = BatchNormalization(name='BN_2')(x)
x = MaxPool2D(pool_size=(3,3),strides=2,name='MaxPool2D_2')(x)
# 第三层:卷积--> 激活
x = Conv2D(filters=384,kernel_size=3,strides=1,padding='same',name='Conv2D_3')(x)
x = Activation('relu',name='Activation_3')(x)
# 第四层:卷积--> 激活
x = Conv2D(filters=384,kernel_size=3,strides=1,padding='same',name='Conv2D_4')(x)
x = Activation('relu',name='Activation_4')(x)
# 第五层:卷积--> 激活 --> 最大池化
x = Conv2D(filters=256,kernel_size=3,strides=1,padding='same',name='Conv2D_5')(x)
x = Activation('relu',name='Activation_5')(x)
x = MaxPool2D(pool_size=(3,3),strides=2,name='MaxPool2D_5')(x)
# 第六层 拉直 --> Drop out --> 激活
x = Flatten()(x)
x = Dense(units=4096,activation='relu',name='Dense_6')(x)
x = Dropout(0.5,name='Dropout_6')(x)
# 第七层 全连接 --> Drop out
x = Dense(units=4096,activation='relu',name='Dense_7')(x)
x = Dropout(0.5,name='Dropout_7')(x)
# 第八层 全连接
outputs = Dense(units=1000,activation='softmax',name='Output_8')(x)
return outputs
# 第零层,输入层
inputs = tf.keras.Input(shape=(227,227,3))
model = Model(inputs=inputs,outputs=AlexNet8(),name='AlexNet8')
model.summary()
模型摘要如下
Model: "AlexNet8"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_6 (InputLayer) [(None, 227, 227, 3)] 0
_________________________________________________________________
Conv2D_1 (Conv2D) (None, 55, 55, 96) 34944
_________________________________________________________________
Activation_1 (Activation) (None, 55, 55, 96) 0
_________________________________________________________________
BN_1 (BatchNormalization) (None, 55, 55, 96) 384
_________________________________________________________________
MaxPool2D_1 (MaxPooling2D) (None, 27, 27, 96) 0
_________________________________________________________________
Conv2D_2 (Conv2D) (None, 27, 27, 256) 614656
_________________________________________________________________
Activation_2 (Activation) (None, 27, 27, 256) 0
_________________________________________________________________
BN_2 (BatchNormalization) (None, 27, 27, 256) 1024
_________________________________________________________________
MaxPool2D_2 (MaxPooling2D) (None, 13, 13, 256) 0
_________________________________________________________________
Conv2D_3 (Conv2D) (None, 13, 13, 384) 885120
_________________________________________________________________
Activation_3 (Activation) (None, 13, 13, 384) 0
_________________________________________________________________
Conv2D_4 (Conv2D) (None, 13, 13, 384) 1327488
_________________________________________________________________
Activation_4 (Activation) (None, 13, 13, 384) 0
_________________________________________________________________
Conv2D_5 (Conv2D) (None, 13, 13, 256) 884992
_________________________________________________________________
Activation_5 (Activation) (None, 13, 13, 256) 0
_________________________________________________________________
MaxPool2D_5 (MaxPooling2D) (None, 6, 6, 256) 0
_________________________________________________________________
flatten_7 (Flatten) (None, 9216) 0
_________________________________________________________________
Dense_6 (Dense) (None, 4096) 37752832
_________________________________________________________________
Dropout_6 (Dropout) (None, 4096) 0
_________________________________________________________________
Dense_7 (Dense) (None, 4096) 16781312
_________________________________________________________________
Dropout_7 (Dropout) (None, 4096) 0
_________________________________________________________________
Output_8 (Dense) (None, 1000) 4097000
=================================================================
Total params: 62,379,752
Trainable params: 62,379,048
Non-trainable params: 704




