Alexnet详细介绍与TensorFlow实现

本文详细解读了AlexNet在ImageNet竞赛中的突破,包括其结构、优化技巧(如ReLU、DropOut和Data Augmentation)及关键层参数。TensorFlow2实现详解,带你领略深度学习的兴起之始。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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差不多,但是使用了一些对训练网络十分有效的技巧:

  1. 使用Relu激活函数,加速模型收敛
  2. 使用两块GPU并行运算,提高训练速度,且能帮助训练更大的网络
  3. 采用最大池化
  4. 使用随机丢弃(Drop Out),每次利用训练样本更新参数时,随机“丢弃”一定比例的神经元,被丢弃的神经元不参加训练,也不更新相关参数。Drop Out能有效减缓过拟合,也能加快网络收敛速度
  5. 数据增强(Data Augmentation),通过训练样本生成更多样本,如图像水平翻转,以及将256X256的图像随机选取224X224的片段作为输入图像。通过这两种方式处理,可以将一张图变成2048张图像。这样可以较大规模的增加训练样本,避免由于训练样本不够造成的性能损失。

接下来,我们来具体看下网络结构,我们需要先明确以下几点

  1. 结构分上下两部分,是因为采用了两块GPU进行训练

  2. 原图没有单独画出Max pooling层,而是将Max pooling层以文本形式标注在卷积层的右下角(事实上,由于池化层没有要学习的参数,因此在计算神经网络层数时一般不将池化层计算在内),我们在讲解的时候,结构按照原图进行讲解,即将卷积层和Max pooling层作为一个层来看待,则按照这种说明规定,Alexnet网络除了输入层外,共有8层(论文中叫做有8个权重层),其中5个卷积层和3个全连接层。

  3. 5个卷积层中,只有第三层,是两块GPU进行融合计算,其余层均是分开计算的。3个全连接层,则均是两个GPU进行融合计算,为了更清晰的说明网络结构,我们将假设只使用一个GPU进行计算。

  4. 根据论文描述,池化大小为 3 ∗ 3 3*3 33 ,池化步长为 2 2 2

  5. 在第二层和第三层卷积之后,进行了局部响应归一化(Local Response Normalization)处理即LRN层,后续被许多学者发现并不能起太大作用,现在几乎不用这种处理方式,因此不在单独介绍。

  6. 依然是先给出卷积特征图大小计算公式:

    O w = { f l o o r ( W − 1 S w ) + 1 , p a d d i n g = " S A M E " f l o o r ( W − F w S w ) + 1 , p a d d i n g = " V A L I D " O h = { f l o o r ( H − 1 S h ) + 1 , p a d d i n g = " S A M E " f l o o r ( H − F h S h ) + 1 , p a d d i n g = " V A L I D " \begin{aligned}O_w &= \begin{cases} floor(\frac{W-1}{S_w})+1 ,padding="SAME"\\ \\ floor\bigg(\frac{W-F_w}{S_w} \bigg)+1 ,padding="VALID"\end{cases}\\\\ O_h &= \begin{cases}floor(\frac{H-1}{S_h})+1,padding="SAME"\\\\ floor\bigg(\frac{H-F_h}{S_h} \bigg)+1,padding="VALID" \end{cases}\end{aligned} OwOh=floor(SwW1)+1,padding="SAME"floor(SwWFw)+1,padding="VALID"=floor(ShH1)+1,padding="SAME"floor(ShHFh)+1,padding="VALID"

接下来,我们逐层介绍

  • 输入层

    输入大小为 224 ∗ 224 ∗ 3 224*224*3 2242243的彩色图像,参数量为 224 ∗ 224 ∗ 3 = 150528 224*224*3 = 150528 2242243=150528

  • 第一层

    输入为 224 ∗ 224 ∗ 3 224*224*3 2242243的图像, 使用 96 96 96个大小为 11 ∗ 11 ∗ 3 11*11*3 11113的卷积核 ,卷积步长为 4 4 4,我们利用特征图大小计算公式计算发现得到的特征图大小为 54 ∗ 54 ∗ 96 54*54*96 545496,并不是原图标注的 55 ∗ 55 ∗ 96 55*55*96 555596,这里有两种处理方式,可以将输入图像大小调整为 227 ∗ 227 ∗ 3 227*227*3 2272273,或设定 p a d d i n g = 2 padding=2 padding=2 , 则此时特征图大小也为 55 ∗ 55 ∗ 96 55*55*96 555596 ,后续代码实现时,我将使用设定 p a d d i n g = 2 padding=2 padding=2 这种方式。

    卷积层使用的激活函数为Relu。卷积之后,有一个LRN层,之后是最大池化层,经过池化之后,特征图大小从 55 ∗ 55 ∗ 96 55*55*96 555596 变为 27 ∗ 27 ∗ 96 27*27*96 272796

    该层的待学习参数数量为 11 ∗ 11 ∗ 3 ∗ 96 + 96 = 34944 11*11*3*96+96 = 34944 1111396+96=34944

  • 第二层

    输入大小为 27 ∗ 27 ∗ 96 27*27*96 272796的特征图,使用 256个大小为 5 ∗ 5 ∗ 96 5*5*96 5596的卷积核,卷积步长为1 ,并设定 p a d d i n g = ′ s a m e ′ padding='same' padding=same,输出大小为 27 ∗ 27 ∗ 256 27*27*256 2727256的特征图。

    卷积层使用的激活函数为Relu。卷积之后,有一个LRN层,之后是最大池化层,经过池化之后,特征图大小从 27 ∗ 27 ∗ 256 27*27*256 2727256 变为 13 ∗ 13 ∗ 256 13*13*256 1313256

    该层的待学习参数数量为 5 ∗ 5 ∗ 96 ∗ 256 + 256 = 614656 5*5*96*256+256=614656 5596256+256=614656

  • 第三层

    输入大小为 13 ∗ 13 ∗ 256 13*13*256 1313256的特征图,使用 384个大小为 3 ∗ 3 ∗ 256 3*3*256 33256的卷积核,卷积步长为1 ,并设定 p a d d i n g = ′ s a m e ′ padding='same' padding=same ,输出大小为 13 ∗ 13 ∗ 384 13*13*384 1313384的特征图。

    卷积层使用的激活函数为Relu。卷积之后,无LRN层,无最大池化层。

    该层的待学习参数数量为 3 ∗ 3 ∗ 256 ∗ 384 + 384 = 885120 3*3*256*384+384=885120 33256384+384=885120

  • 第四层

    输入大小为 3 ∗ 3 ∗ 384 3*3*384 33384的特征图,使用 384个大小为 3 ∗ 3 ∗ 384 3*3*384 33384的卷积核,卷积步长为1 ,并设定 p a d d i n g = ′ s a m e ′ padding='same' padding=same,输出大小为 13 ∗ 13 ∗ 384 13*13*384 1313384的特征图。

    卷积层使用的激活函数为Relu。卷积之后,无LRN层,无最大池化层。

    该层的待学习参数数量为 3 ∗ 3 ∗ 384 ∗ 384 + 384 = 1327488 3*3*384*384+384=1327488 33384384+384=1327488

  • 第五层

    输入大小为 3 ∗ 3 ∗ 384 3*3*384 33384的特征图,使用 256个大小为 3 ∗ 3 ∗ 384 3*3*384 33384的卷积核,卷积步长为1 ,并设定 p a d d i n g = ′ s a m e ′ padding='same' padding=same,输出大小为 13 ∗ 13 ∗ 256 13*13*256 1313256的特征图。

    卷积层使用的激活函数为Relu。卷积之后,无LRN层,有最大池化层,池化后的特征图大小为 6 ∗ 6 ∗ 256 6*6*256 66256

    该层的待学习参数数量为 3 ∗ 3 ∗ 384 ∗ 256 + 256 = 884992 3*3*384*256+256=884992 33384256+256=884992

  • 第六层

    全连接层,输入参数 6 ∗ 6 ∗ 256 = 9216 6*6*256=9216 66256=9216个,使用 4096个神经元,使用Relu激活函数,使用Drop Out。

    该层的待学习参数数量为 9216 ∗ 4096 + 4096 = 37752832 9216*4096+4096=37752832 92164096+4096=37752832

  • 第七层

    全连接层,输入参数 4096 4096 4096个,使用 4096个神经元,使用Relu激活函数,使用Drop Out。

    该层的待学习参数数量为 4096 ∗ 4096 + 4096 = 16781312 4096*4096+4096=16781312 40964096+4096=16781312

  • 第八层

    全连接层,输入参数 4096 4096 4096个,使用 1000个神经元,使用softmax激活函数。

    该层的待学习参数数量为 4096 ∗ 1000 + 1000 = 4097000 4096*1000+1000=4097000 40961000+1000=4097000

我们使表格来总结下各个层所执行的操作

在这里插入图片描述

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

积跬步以至千里。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值