AlexNet模型简介

2012年AlexNet在ImageNet竞赛中以超过第二名10.9个百分点的绝对优势一举夺冠,自此,深度学习和卷积神经网络一举成名,一直火到了今天。

模型组成

  • 输入层
  • 5个卷积层
  • 3个全链接层

从上图还可以看到网络有两个分支,这是因为当时硬件条件有限,一块GPU显存不够所以使用了两块GPU分别训练,在最后的全连接层进行特征融合得到最后的结果。

因为网络上比较流行上面这个图,但其实我个人更喜欢下面这个图,在逻辑和过程上更加清楚。

AlexNet 各层的详细描述

输入层: 输入大小为224 x 224的3通道图像,实际上会经过预处理变为227X227X3

第1层:卷积层(卷积、池化)

    使用96个大小为11 x 11 x 3的卷积核,分两组(每组48个),按步长4个像素对输入层进行卷积运算,得到两组55 x 55 x48 的卷积结果。

    对卷积结果使用ReLu激活函数,得到激活结果。

    对激活结果使用窗口为3 x 3、步长为2个像素的重叠最大池化,得到27 x 27 x 48的池化结果。

    对池化结果使用局部响应归一化操作,得到27 x 27 x 48的归一化结果。

第2层:卷积层(卷积、池化)

    使用256个大小为27 x 27 x 48的卷积核,分两组(每组128个),按步长1个像素对第2层的归一化结果进行卷积运算,得到两组27 x 27 x 128 的卷积结果。

    对卷积结果使用ReLu激活函数,得到激活结果。

    对两组 27 x 27 x 128的激活结果使用窗口为3 x 3、步长为2个像素的重叠最大池化,得到两组13 x 13 x 128的池化结果。

    对池化结果使用局部响应归一化操作,得到两组13 x 13 x128 的归一化结果。

第3层:卷积层

    使用384个大小为13 x 13 x 256的卷集核,分两组,按步长为1个像素对上一层归一化结果卷积运算,得到两组13 x 13 x 192的卷积结果。

    对卷积结果使用ReLu激活函数,得到激活结果。

第4层:卷积层

    使用384个大小为13 x 13 x 192的卷集核,分两组,按步长为1个像素对上一层的激活结果进行卷积运算,得到两组两组 13 x 13 x 192 的卷积结果。

    对卷积结果使用ReLu激活函数,得到激活结果

第5层:卷积层(卷积、池化)

    使用256个大小为13 x 13 x 192的卷积核分两组,按步长为1个像素,对上一层的激活结果卷积运算,得到两组 13 x 13 x128卷积结果。

    对卷积结果使用ReLu激活函数,得到激活结果。

    对激活结果,进行窗口为3 x 3,步长为2个像素的重叠最大池化,得到两组13 x 3 x 128的池化结果。

第6层: 全链接层

    使用4096个神经元分两组,对上一层的池化结果全链接处理。

    对全链接结果使用ReLu激活函数。

    对激活结果使用概率为0.5的dropout操作,得到dropout结果。

第7层: 全链接层

    使用4096个神经元分两组,对上一层的池化结果全链接处理。

    对全链接结果使用ReLu激活函数。

    对激活结果使用概率为0.5的dropout操作,得到dropout结果。

第8层: 输出层

    1000路的软最大输出层,用来覆盖1000类的标签分布。

AlexNet 的贡献

  • ReLU激活函数

  • Dropout

  • LRN

  • 数据增强

代码实现

from tensorflow.keras import layers, models, Model, Sequential


def AlexNet_v1(im_height=224, im_width=224, class_num=1000):
    # tensorflow中的tensor通道排序是NHWC
    # 使用函数形式构建模型,必须加上输入层
    input_image = layers.Input(shape=(im_height, im_width, 3), dtype="float32")  # output(None, 224, 224, 3)
    x = layers.ZeroPadding2D(((1, 2), (1, 2)))(input_image)                      # output(None, 227, 227, 3)
    x = layers.Conv2D(48, kernel_size=11, strides=4, activation="relu")(x)       # output(None, 55, 55, 48)
    x = layers.MaxPool2D(pool_size=3, strides=2)(x)                              # output(None, 27, 27, 48)
    x = layers.Conv2D(128, kernel_size=5, padding="same", activation="relu")(x)  # output(None, 27, 27, 128)
    x = layers.MaxPool2D(pool_size=3, strides=2)(x)                              # output(None, 13, 13, 128)
    x = layers.Conv2D(192, kernel_size=3, padding="same", activation="relu")(x)  # output(None, 13, 13, 192)
    x = layers.Conv2D(192, kernel_size=3, padding="same", activation="relu")(x)  # output(None, 13, 13, 192)
    x = layers.Conv2D(128, kernel_size=3, padding="same", activation="relu")(x)  # output(None, 13, 13, 128)
    x = layers.MaxPool2D(pool_size=3, strides=2)(x)                              # output(None, 6, 6, 128)

    x = layers.Flatten()(x)                         # output(None, 6*6*128)
    x = layers.Dropout(0.2)(x)                      # 为下一层的Dense层加入dropout
    x = layers.Dense(2048, activation="relu")(x)    # output(None, 2048)
    x = layers.Dropout(0.2)(x)
    x = layers.Dense(2048, activation="relu")(x)    # output(None, 2048)
    x = layers.Dense(class_num)(x)                  # output(None, 5), 在这里是可以用layers.Dense(10, activation="softmax"),从而省略后面的softmax层
    predict = layers.Softmax()(x)

    model = models.Model(inputs=input_image, outputs=predict)
    return model








class AlexNet_v2(Model):
    def __init__(self, class_num=1000):
        super(AlexNet_v2, self).__init__()
        self.features = Sequential([
            layers.ZeroPadding2D(((1, 2), (1, 2))),                                 # output(None, 227, 227, 3)
            layers.Conv2D(48, kernel_size=11, strides=4, activation="relu"),        # output(None, 55, 55, 48)
            layers.MaxPool2D(pool_size=3, strides=2),                               # output(None, 27, 27, 48)
            layers.Conv2D(128, kernel_size=5, padding="same", activation="relu"),   # output(None, 27, 27, 128)
            layers.MaxPool2D(pool_size=3, strides=2),                               # output(None, 13, 13, 128)
            layers.Conv2D(192, kernel_size=3, padding="same", activation="relu"),   # output(None, 13, 13, 192)
            layers.Conv2D(192, kernel_size=3, padding="same", activation="relu"),   # output(None, 13, 13, 192)
            layers.Conv2D(128, kernel_size=3, padding="same", activation="relu"),   # output(None, 13, 13, 128)
            layers.MaxPool2D(pool_size=3, strides=2)])                              # output(None, 6, 6, 128)

        self.flatten = layers.Flatten()
        self.classifier = Sequential([
            layers.Dropout(0.2),
            layers.Dense(1024, activation="relu"),                                  # output(None, 2048)
            layers.Dropout(0.2),
            layers.Dense(128, activation="relu"),                                   # output(None, 2048)
            layers.Dense(class_num),                                                # output(None, 5)
            layers.Softmax()
        ])

    def call(self, inputs, **kwargs):
        x = self.features(inputs)
        x = self.flatten(x)
        x = self.classifier(x)
        return x

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值