AIGC探索之GoogLeNet(含并行连接的网络)_卷积

引言

随着计算能力的提升和海量数据的积累,深度学习在计算机视觉领域取得了显著进展。2014 年,Google 团队提出了 GoogLeNet 模型,并在 ILSVRC-2014 中取得了冠军。该模型的创新设计不仅提升了准确率,还显著减少了计算资源的消耗。GoogLeNet吸收了NiN中串联网络的思想,并在此基础上做了改进。

1. GoogLeNet 简介


AIGC探索之GoogLeNet(含并行连接的网络)_tensorflow_02

GoogLeNet 是一种深度卷积神经网络,包含 22 层,因其使用了一种名为 Inception 的模块而闻名。与传统的卷积网络不同,GoogLeNet 在提高准确性的同时有效降低了计算成本。

2. GoogLeNet 架构解析


GoogLeNet 的核心在于其 Inception 模块。每个模块通过并行的卷积操作来捕获不同尺度的特征。Inception 模块包含:

  • 1x1 卷积:用于减少特征图的维度。
  • 3x3 卷积:捕获中尺度特征。
  • 5x5 卷积:捕获大尺度特征。
  • 3x3 最大池化:通过池化操作保留关键信息。

通过堆叠多个 Inception 模块,GoogLeNet 能够在较深的网络中高效提取不同层次的特征。

2.1 Inception块

GoogLeNet中最重要的是Inception块,在这个块中抽取了不同的通道,不同的通道有不同的设计,如下图所示,Inception块通过四条路经从不同的层面抽取信息,然后在输出通道维合并: 前三条路径使用窗口大小为1 * 1、3 * 3、5 * 5的卷积层,从不同的空间大小中提取信息 中间两条路径在输入上执行1 * 1卷积,以减少通道数,从而降低模型的复杂性 第四条路经使用3 * 3最大汇聚层,然后使用1 * 1卷积层来改变通道数 四条路径都是用合适的填充来使输入和输出的高宽一致 最后每条线路的输出在通道维度上连结,得到Inception块的输出 在Inception块中,通常调整的超参数是每层输出通道数

AIGC探索之GoogLeNet(含并行连接的网络)_卷积_03

① 白色的卷积用来改变通道数,蓝色的卷积用来抽取信息。

② 最左边一条1X1卷积是用来抽取通道信息,其他的3X3卷积用来抽取空间信息。

具体过程:

首先,输入被复制成了四块(之前所遇到的都是一条路直接到最后):

  • 第一条路先进入一个1 *1的卷积层再输出
  • 第二条路先通过一个1 * 1的卷积层对通道做变换,再通过一个pad为1的3 * 3的卷积层,使得输入和输出的高宽相同
  • 第三条路先通过一个1 * 1的卷积层对通道数做变换,不改变高宽,但是再通过一个pad为2的5 * 5的卷积层提取空间信息特征,输入和输出还是等高等宽的
  • 第四条路先通过一个pad为1的3 * 3的最大池化层,再通过一个1 * 1的卷积层 因为这四条路都没有改变高宽,最后用一个contact的操作将它们的输出合并起来(不是将四张图片放在一起形成一张更大的图片,而是在输出的通道数上做合并,最终的输出和输入等同高宽,但是输出的通道数更多,因为是四条路输出的通道数合并在一起的),因此,输出的高宽是不变的,改变的只有它的通道数

在这个结构中,基本上各种形状的卷积层和最大池化层等都有了,所以就不用过多地纠结于卷积层尺寸的选择

2.2 最好的卷积层超参数?

AIGC探索之GoogLeNet(含并行连接的网络)_tensorflow_04

2.3 网络层次结构

GoogLeNet的整体结构如下:

  • 输入层
  • 9个Inception模块
  • 全局平均池化层
  • 全连接层
  • Softmax输出层

GoogLeNet的总深度为22层,其中包括多个Inception模块和辅助分类器,辅助分类器的目的是增强梯度传播,帮助网络更快收敛。

AIGC探索之GoogLeNet(含并行连接的网络)_卷积_05

3. 关键创新点


  • Inception 模块: 通过并行路径设计,实现了多尺度的特征提取。
  • 1x1 卷积: 用于维度减少和计算效率提升。
  • 全局平均池化: 替代传统的全连接层,减少参数,防止过拟合。

4. GoogLeNet的优点


  • 参数效率:通过1x1卷积减少参数数量,提高了模型的计算效率。
  • 多尺度特征提取:不同大小的卷积核能够捕捉不同层次的特征,使得模型具有更强的表达能力。
  • 深度与宽度:通过堆叠多个Inception模块,GoogLeNet在保持深度的同时,能够有效增加网络的宽度。

5. 实验与结果


在 ILSVRC-2014 中,GoogLeNet 以 6.67% 的 top-5 错误率赢得比赛,相比于传统模型,其参数量仅为 AlexNet 的 1/12,但精度更高。

6. 示例代码

接下来,我们将通过TensorFlow和Keras实现一个简单的GoogLeNet模型,用于图像分类任务。

6.1 数据准备

我们将使用CIFAR-10数据集作为示例数据集,该数据集包含10个类别的32x32彩色图像。

import tensorflow as tf
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.utils import to_categorical

# 加载CIFAR-10数据集
(x_train, y_train), (x_test, y_test) = cifar10.load_data()

# 数据归一化
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0

# 类别标签转为one-hot编码
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)

6.2 模型构建

下面是GoogLeNet模型的实现,包含Inception模块的定义。

from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, AveragePooling2D, Flatten, Dense, Dropout, Concatenate
from tensorflow.keras.models import Model

def inception_module(x, filters):
    # 1x1卷积
    conv1x1 = Conv2D(filters[0], (1, 1), padding='same', activation='relu')(x)

    # 1x1卷积 + 3x3卷积
    conv3x3 = Conv2D(filters[1], (1, 1), padding='same', activation='relu')(x)
    conv3x3 = Conv2D(filters[2], (3, 3), padding='same', activation='relu')(conv3x3)

    # 1x1卷积 + 5x5卷积
    conv5x5 = Conv2D(filters[3], (1, 1), padding='same', activation='relu')(x)
    conv5x5 = Conv2D(filters[4], (5, 5), padding='same', activation='relu')(conv5x5)

    # 3x3最大池化 + 1x1卷积
    maxpool = MaxPooling2D((3, 3), strides=(1, 1), padding='same')(x)
    maxpool = Conv2D(filters[5], (1, 1), padding='same', activation='relu')(maxpool)

    # 拼接所有卷积结果
    return Concatenate(axis=-1)([conv1x1, conv3x3, conv5x5, maxpool])

# 构建GoogLeNet模型
def build_googlenet(input_shape=(32, 32, 3)):
    inputs = Input(shape=input_shape)
    
    # 初始卷积层
    x = Conv2D(32, (3, 3), padding='same', activation='relu')(inputs)
    x = Conv2D(32, (3, 3), padding='same', activation='relu')(x)
    x = MaxPooling2D(pool_size=(2, 2))(x)
    
    x = Conv2D(64, (3, 3), padding='same', activation='relu')(x)
    x = MaxPooling2D(pool_size=(2, 2))(x)

    # Inception模块
    x = inception_module(x, [32, 32, 32, 16, 16, 32])
    x = inception_module(x, [32, 32, 32, 16, 16, 32])
    
    # 全局平均池化
    x = AveragePooling2D(pool_size=(8, 8))(x)
    x = Flatten()(x)
    x = Dense(10, activation='softmax')(x)

    return Model(inputs, x)

model = build_googlenet()
model.summary()

6.3 模型训练

model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# 训练模型
model.fit(x_train, y_train, validation_data=(x_test, y_test), epochs=10, batch_size=64)

6.4 评估模型

# 评估模型
test_loss, test_accuracy = model.evaluate(x_test, y_test)
print(f'Test Accuracy: {test_accuracy:.4f}')

7. 总结


GoogLeNet 的成功在于其创新的架构设计,通过 Inception 模块实现了计算效率与模型性能的平衡。它引领了深度神经网络的发展方向,影响了后续一系列网络架构的设计。


参考: 含并行连结的网络(GoogLeNet)