Python----神经网络(《Going deeper with convolutions》论文解读和GoogLeNet网络)

发布于:2025-05-09 ⋅ 阅读:(22) ⋅ 点赞:(0)

一、论文《Going deeper with convolutions》

1.1、 论文基本信息

  • 论文标题: Going deeper with convolutions

  • 作者: Christian Szegedy, Wei Liu, Yangqing Jia, Pierre Sermanet, Scott Reed, Dragomir Anguelov, Dumitru Erhan, Vincent Vanhoucke, Andrew Rabinovich

  • 发表时间: 2014 年 9 月 17 日 (arXiv v1 版本)

  • 所属领域: 计算机视觉 (CV)

  • 主要贡献: 提出 Inception 架构,并在 ImageNet Large-Scale Visual Recognition Challenge 2014 (ILSVRC14) 中取得了领先的分类和检测性能

1.2、作者背景

        论文作者主要来自 Google Inc.,也有部分作者来自 University of North Carolina, Chapel Hill 和 University of Michigan.作者团队在深度学习和计算机视觉领域有着深厚的积累。Christian Szegedy 等人在后续的 Inception 系列工作中继续深入研究了卷积神经网络的架构设计。

1.3、论文主要内容

  • Inception 架构: 论文的核心是提出了一种新的卷积神经网络架构,称为 Inception.

    • Inception 模块通过并行使用不同尺度的卷积核 (1x1, 3x3, 5x5) 和池化操作,能够有效地捕捉图像中的多尺度特征.

    • 1x1 卷积用于降维和增加非线性.

  • GoogLeNet 模型: 论文中提出的一个具体 Inception 架构的实现被称为 GoogLeNet.

    • GoogLeNet 是一个 22 层深的卷积神经网络.

    • GoogLeNet 在 ILSVRC14 比赛中取得了优异的成绩.

  • 性能提升: GoogLeNet 在 ILSVRC14 分类和检测任务中均取得了显著的性能提升,超越了当时的 state-of-the-art 方法.

  • 计算效率: Inception 架构的设计注重计算效率,GoogLeNet 在保持高性能的同时,参数数量和计算量都相对较小.

1.4、论文特点

        多尺度特征提取: Inception 模块是论文的主要创新点,它能够并行地提取图像在不同尺度上的特征,从而提高网络的表示能力.

        计算效率高: 通过 1x1 卷积进行降维,Inception 架构有效地减少了参数数量和计算量,使得更深更宽的网络成为可能.

        设计思想新颖:Inception 架构的设计受到了 Arora 等人关于稀疏网络理论的启发.并通过密集模块来近似稀疏连接.

        工程实现精巧:论文不仅关注模型性能,还注重工程实现上的优化,例如使用辅助分类器来改善梯度传播.使用 Polyak averaging 来提高模型稳定性.

1.5、论文作用

        推动了卷积神经网络的发展: GoogLeNet 提出的 Inception 架构对后续的卷积神经网络设计产生了深远的影响.许多新的网络架构都借鉴了其多尺度特征提取和计算效率高的思想。

        提高了计算机视觉任务的性能: GoogLeNet 在 ILSVRC14 比赛中取得了优异的成绩,证明了 Inception 架构在图像分类和目标检测等任务中的有效性,推动了计算机视觉领域的发展.

        促进了深度学习的工程化: 论文注重计算效率和实际应用,GoogLeNet 的设计使得深度学习模型在资源受限的设备上部署成为可能,促进了深度学习的工程化应用.

1.6、论文影响

        Inception 系列架构: GoogLeNet 是 Inception 系列的开山之作,后续的 Inception v2、v3、Inception-ResNet 等架构都是在其基础上发展而来,不断提升了模型的性能和效率。

        1x1 卷积的广泛应用: 1x1 卷积在 GoogLeNet 中被证明是一种非常有效的降维和特征变换手段,现在已经成为现代卷积神经网络中的标准配置,例如 ResNet 中的瓶颈层.

        网络架构设计的启发: GoogLeNet 的成功启发了人们对网络架构设计的更多思考,例如如何有效地组合不同类型的层,如何平衡模型性能和计算效率等.

        自动化网络架构搜索 (NAS) 的发展: GoogLeNet 中对稀疏连接的探索和对网络拓扑结构的思考,也对后续的自动化网络架构搜索领域的发展产生了一定的影响.

1.7、深入探讨

1.7.1、Inception模块细节

        Inception模块通过1x1卷积实现了多个关键功能。首先,1x1卷积不仅有助于降维和增加网络的非线性性,还能进行跨通道的特征变换,使得网络能够学习复杂的特征组合。此外,不同尺寸的卷积核在Inception中能够有效捕获多尺度特征:小卷积核专注于细节,而大卷积核则捕捉全局结构,从而帮助网络学习最佳特征组合。在稀疏性与效率之间的权衡上,Inception通过采用稀疏连接的设计原则,达成了在保持计算效率的同时,近似稀疏性。

1.7.2、 GoogLeNet架构

        GoogLeNet的结构具有深度和复杂性,其包含22层(参数层)或27层(包括池化层),由约100个模块构成,体现了Inception在构建深度网络时的高效性能。同时,采用辅助分类器的设计,改善了深度网络中的梯度流动,充当了正则化器,增强了训练效果。此外,GoogLeNet中使用平均池化替代全连接层,这一设计灵感源自“Network in Network”,不仅减少了参数量,还提高了对空间平移的鲁棒性。

1.7.3、训练方法

        为了增强模型的泛化能力和鲁棒性,GoogLeNet采用了数据增强技术,如随机裁剪和颜色失真等,以增加训练数据的多样性。在学习率策略方面,通过在训练过程中逐步降低学习率,可以实现更细致的参数调整,从而提高模型的整体性能。此外,应用Polyak平均可以稳定训练过程并改善最终结果,通过对多个模型版本进行平均,提高了结果的可靠性。

1.7.4、实验结果

        在实验中,GoogLeNet展示了其卓越的分类性能,实现了比AlexNet更低的top-5错误率,表明其在参数效率上的优势。在目标检测任务中,通过将R-CNN与GoogLeNet及MultiBox结合,可以显著提升目标检测的准确性和召回率,标志着其在实际应用中的有效性。

1.7.5、GoogLeNet的影响

        GoogLeNet不仅为Inception架构的发展奠定了基础,催生了Inception v2、v3和Inception-ResNet等后续架构,同时也对其他深度学习网络产生了深远影响。例如,ResNet中的1x1卷积瓶颈层受到了GoogLeNet高效设计理念的启发。GoogLeNet在处理多尺度特征方面的创新,极大地影响了后续的卷积神经网络(CNN)架构,推动了现代深度学习的发展。

 二、GoogLeNet网络

2.1、网络的基本介绍

        GoogLeNet是一种流行的神经网络架构,它通常用于图像分类任务。该网络架构是 在2014年ImageNet挑战赛中由Google团队首次提出的,并且在那次分类比赛中获得 了第一名的成绩。

        GoogLeNet的主要特点是采用了一种名为“Inception”模块的结构,该模块可以有效 地捕捉图像中的多尺度特征。 在Inception模块中,网络结构被分成多个并行的分支,每个分支都用于捕捉不同尺 度的特征。这样,GoogLeNet网络就可以更有效地学习图像的特征,并且还可以减 少网络的体积。

        GoogLeNet还采用了一种名为“平均池化”的技术,该技术可以在不改变图像尺寸的情 况下对图像进行降采样。这样,GoogLeNet网络就可以更快地处理图像,并且还可 以提高网络的鲁棒性。

2.2、Inception结构

        Inception结构由谷歌的研究人员在2014年提出,它的名字来源于电影《盗梦空间》,因为它设计时使用了多个并行的卷积神经网络模块,这些模块之间形成了一个 嵌套的结构,就像人在梦中穿梭于不同场景中一样。

        Inception结构的思想和之前的卷积思想不同,LeNet-5模型是将不同的卷积层通过串 联连接起来的,但是Inception结构是通过串联+并联的方式将卷积层连接起来的。 Inception结构是对输入图像并行地执行多个卷积运算或池化操作,并将所有输出结 果拼接为一个非常深的特征图,且不同大小卷积核的卷积运算可以得到图像中的不同 信息,处理获取到的图像中的不同信息可以得到更好的图像特征。

         Inception结构通常用于图像分类和识别任务,因为它能够有效地捕捉图像中的细节 信息。它的主要优势在于能够以高效的方式处理大量的数据,并且模型的参数量相对 较少,这使得它能够在不同的设备上运行。

2.3、1x1卷积核进行降维

        Inception结构的四个分支中,每个分支所得到的特征矩阵的宽和高必 须是相同的,然后再将四个分支的特征矩阵沿着深度方向进行拼接。

        拼接指的是:A分支宽、高、channels为112x112x32的矩阵,B分支宽、高、 channels为112x112x64的矩阵,C分支宽、高、channels为112x112x16的矩阵,D 分支宽、高、channels为112x112x8的矩阵,那么经过拼接后,得到一个 112x112x120的矩阵,120是由32+64+16+8而来。

        卷积有着降维的作用,例如现在有一个输入特征矩阵为n*n*512

        1. 直接经过64个5x5的卷积核进行卷积,那么需要5x5x512x64=819200的参数量;

        2. 经过1x1的卷积再经过64个5x5的卷积,这里1x1的卷积核个数例如是24个,所以 需要的参数量为1x1x512x24+1x1x24x64=50688。

2.4、辅助分类器 

        辅助分类器通常与主要的分类器结合使用,以帮助模型更好地理解图像中的细节和复 杂模式。这种技术可以提高模型的泛化能力,使其更准确地预测未知的图像,在 GoogLeNet中有两个辅助分类器,分别在Inception4a和Inception4d。

        两个辅助分类器的结构式完全一致的:

                1. 平均池化层,池化核大小为5x5,步长为3。

                2. 卷积层,128个卷积核大小是1x1,步长为1。

                3. 全连接层,节点个数为1024个。

                4. 在全连接之后接一个dropout,比例为70%随机失活神经元。

                5. 全连接输出,由于数据集是ImageNet,所以是1000个节点,然后经过 softmax。

注意:辅助分类器在训练的时候使用,在预测的时候不使用。 

2.5、 网络的问题

        尽管GoogLeNet在当时取得了很好的成绩,但它也有一些缺点。

                1. 由于其使用了Inception模块,网络的计算复杂度较高。这使得GoogLeNet的训 练速度较慢,不太适合对实时性要求较高的应用。

                2. GoogLeNet的网络结构相对复杂,不太容易理解,并且由于辅助分类器的存在, 这使得在调试和优化网络时较为困难。

        总之,GoogLeNet的计算复杂度高、网络结构复杂是其主要缺点。

2.6、网络结构

        在上图中,type是每一层的结构,patch size/stride是卷积或者池化的核大小/步长, output size是本层的输出尺寸,depth是这一层的卷积深度,就是卷积层数,param 是本层的参数量,ops是运算量。其它的参数是Inception结构中的对应卷积的的参数。

2.7、设计思路 

import torch
import torch.nn as nn
from torchsummary import summary


class Inception(nn.Module):
    """
    Inception 模块的实现。
    这个模块并行地应用不同尺寸的卷积和池化操作。
    """

    def __init__(self, in_channels, ch1x1, ch3x3red, ch3x3, ch5x5red, ch5x5, pool_proj):
        super(Inception, self).__init__()

        # 1x1 卷积分支
        self.branch1 = nn.Conv2d(in_channels, ch1x1, kernel_size=1)

        # 1x1 卷积 -> 3x3 卷积分支
        self.branch2 = nn.Sequential(
            nn.Conv2d(in_channels, ch3x3red, kernel_size=1),
            nn.ReLU(inplace=True),  # 原地ReLU激活,节省内存
            nn.Conv2d(ch3x3red, ch3x3, kernel_size=3, padding=1),  # padding=1 保持尺寸
            nn.ReLU(inplace=True)
        )

        # 1x1 卷积 -> 5x5 卷积分支
        self.branch3 = nn.Sequential(
            nn.Conv2d(in_channels, ch5x5red, kernel_size=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(ch5x5red, ch5x5, kernel_size=5, padding=2),  # padding=2 保持尺寸
            nn.ReLU(inplace=True)
        )

        # 3x3 池化 -> 1x1 卷积分支
        self.branch4 = nn.Sequential(
            nn.MaxPool2d(kernel_size=3, stride=1, padding=1),  # stride=1, padding=1 保持尺寸
            nn.Conv2d(in_channels, pool_proj, kernel_size=1),
            nn.ReLU(inplace=True)
        )

    def forward(self, x):
        branch1 = self.branch1(x)
        branch2 = self.branch2(x)
        branch3 = self.branch3(x)
        branch4 = self.branch4(x)
        out = torch.cat([branch1, branch2, branch3, branch4], 1)  # 在通道维度上连接
        return out


class GoodNet(nn.Module):
    """
    一个简化的 GoogLeNet 网络实现。
    注意:这并非严格意义上的 GoogLeNet,而是为了演示 Inception 模块的使用。
    """

    def __init__(self, num_classier=1000):
        super().__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3),  # 初始卷积层,padding 保持尺寸
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1),  # 最大池化层,padding 影响输出尺寸

            nn.Conv2d(64, 64, kernel_size=1, stride=1, padding=0),  # 1x1 卷积,减少通道数
            nn.ReLU(inplace=True),

            nn.Conv2d(64, 192, kernel_size=3, stride=1, padding=1),  # 3x3 卷积
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1),

            # Inception modules
            Inception(192, 64, 96, 128, 16, 32, 32),  # Inception 模块,参数来自 GoogLeNet
            Inception(256, 128, 128, 192, 32, 96, 64),  # Inception 模块
            nn.MaxPool2d(kernel_size=3, stride=2, padding=1),  # 添加MaxPool2d
            Inception(480, 192, 96, 208, 16, 48, 64),  # Inception 模块
            Inception(512, 160, 112, 224, 24, 64, 64),  # Inception 模块
            Inception(512, 128, 128, 256, 24, 64, 64),  # Inception 模块
            Inception(512, 112, 144, 288, 32, 64, 64),  # Inception 模块
            Inception(528, 256, 160, 320, 32, 128, 128),  # Inception 模块

            nn.MaxPool2d(kernel_size=3, stride=2, padding=1),  # 最大池化层
            Inception(832, 256, 160, 320, 32, 128, 128),  # Inception 模块
            Inception(832, 384, 192, 384, 48, 128, 128),  # Inception 模块

            nn.AvgPool2d(kernel_size=7, stride=1, padding=0),  # 全局平均池化
            nn.Dropout(0.4)  # Dropout 正则化
        )
        self.fc = nn.Linear(1024, num_classier)  # 全连接层,用于分类

    def forward(self, x):
        x = self.features(x)  # 前向传播通过特征提取器
        # x = x.view(x.size(0), -1)  # 展平特征图,准备输入全连接层
        x=torch.flatten(x,1)
        x = self.fc(x)  # 前向传播通过全连接层
        return x


if __name__ == '__main__':
    model = GoodNet()  # 创建模型实例
    print(summary(model, (3, 224, 224)))  # 打印模型结构和参数信息
----------------------------------------------------------------
        Layer (type)               Output Shape         Param #
================================================================
            Conv2d-1         [-1, 64, 112, 112]           9,472
              ReLU-2         [-1, 64, 112, 112]               0
         MaxPool2d-3           [-1, 64, 56, 56]               0
            Conv2d-4           [-1, 64, 56, 56]           4,160
              ReLU-5           [-1, 64, 56, 56]               0
            Conv2d-6          [-1, 192, 56, 56]         110,784
              ReLU-7          [-1, 192, 56, 56]               0
         MaxPool2d-8          [-1, 192, 28, 28]               0
            Conv2d-9           [-1, 64, 28, 28]          12,352
           Conv2d-10           [-1, 96, 28, 28]          18,528
             ReLU-11           [-1, 96, 28, 28]               0
           Conv2d-12          [-1, 128, 28, 28]         110,720
             ReLU-13          [-1, 128, 28, 28]               0
           Conv2d-14           [-1, 16, 28, 28]           3,088
             ReLU-15           [-1, 16, 28, 28]               0
           Conv2d-16           [-1, 32, 28, 28]          12,832
             ReLU-17           [-1, 32, 28, 28]               0
        MaxPool2d-18          [-1, 192, 28, 28]               0
           Conv2d-19           [-1, 32, 28, 28]           6,176
             ReLU-20           [-1, 32, 28, 28]               0
        Inception-21          [-1, 256, 28, 28]               0
           Conv2d-22          [-1, 128, 28, 28]          32,896
           Conv2d-23          [-1, 128, 28, 28]          32,896
             ReLU-24          [-1, 128, 28, 28]               0
           Conv2d-25          [-1, 192, 28, 28]         221,376
             ReLU-26          [-1, 192, 28, 28]               0
           Conv2d-27           [-1, 32, 28, 28]           8,224
             ReLU-28           [-1, 32, 28, 28]               0
           Conv2d-29           [-1, 96, 28, 28]          76,896
             ReLU-30           [-1, 96, 28, 28]               0
        MaxPool2d-31          [-1, 256, 28, 28]               0
           Conv2d-32           [-1, 64, 28, 28]          16,448
             ReLU-33           [-1, 64, 28, 28]               0
        Inception-34          [-1, 480, 28, 28]               0
        MaxPool2d-35          [-1, 480, 14, 14]               0
           Conv2d-36          [-1, 192, 14, 14]          92,352
           Conv2d-37           [-1, 96, 14, 14]          46,176
             ReLU-38           [-1, 96, 14, 14]               0
           Conv2d-39          [-1, 208, 14, 14]         179,920
             ReLU-40          [-1, 208, 14, 14]               0
           Conv2d-41           [-1, 16, 14, 14]           7,696
             ReLU-42           [-1, 16, 14, 14]               0
           Conv2d-43           [-1, 48, 14, 14]          19,248
             ReLU-44           [-1, 48, 14, 14]               0
        MaxPool2d-45          [-1, 480, 14, 14]               0
           Conv2d-46           [-1, 64, 14, 14]          30,784
             ReLU-47           [-1, 64, 14, 14]               0
        Inception-48          [-1, 512, 14, 14]               0
           Conv2d-49          [-1, 160, 14, 14]          82,080
           Conv2d-50          [-1, 112, 14, 14]          57,456
             ReLU-51          [-1, 112, 14, 14]               0
           Conv2d-52          [-1, 224, 14, 14]         226,016
             ReLU-53          [-1, 224, 14, 14]               0
           Conv2d-54           [-1, 24, 14, 14]          12,312
             ReLU-55           [-1, 24, 14, 14]               0
           Conv2d-56           [-1, 64, 14, 14]          38,464
             ReLU-57           [-1, 64, 14, 14]               0
        MaxPool2d-58          [-1, 512, 14, 14]               0
           Conv2d-59           [-1, 64, 14, 14]          32,832
             ReLU-60           [-1, 64, 14, 14]               0
        Inception-61          [-1, 512, 14, 14]               0
           Conv2d-62          [-1, 128, 14, 14]          65,664
           Conv2d-63          [-1, 128, 14, 14]          65,664
             ReLU-64          [-1, 128, 14, 14]               0
           Conv2d-65          [-1, 256, 14, 14]         295,168
             ReLU-66          [-1, 256, 14, 14]               0
           Conv2d-67           [-1, 24, 14, 14]          12,312
             ReLU-68           [-1, 24, 14, 14]               0
           Conv2d-69           [-1, 64, 14, 14]          38,464
             ReLU-70           [-1, 64, 14, 14]               0
        MaxPool2d-71          [-1, 512, 14, 14]               0
           Conv2d-72           [-1, 64, 14, 14]          32,832
             ReLU-73           [-1, 64, 14, 14]               0
        Inception-74          [-1, 512, 14, 14]               0
           Conv2d-75          [-1, 112, 14, 14]          57,456
           Conv2d-76          [-1, 144, 14, 14]          73,872
             ReLU-77          [-1, 144, 14, 14]               0
           Conv2d-78          [-1, 288, 14, 14]         373,536
             ReLU-79          [-1, 288, 14, 14]               0
           Conv2d-80           [-1, 32, 14, 14]          16,416
             ReLU-81           [-1, 32, 14, 14]               0
           Conv2d-82           [-1, 64, 14, 14]          51,264
             ReLU-83           [-1, 64, 14, 14]               0
        MaxPool2d-84          [-1, 512, 14, 14]               0
           Conv2d-85           [-1, 64, 14, 14]          32,832
             ReLU-86           [-1, 64, 14, 14]               0
        Inception-87          [-1, 528, 14, 14]               0
           Conv2d-88          [-1, 256, 14, 14]         135,424
           Conv2d-89          [-1, 160, 14, 14]          84,640
             ReLU-90          [-1, 160, 14, 14]               0
           Conv2d-91          [-1, 320, 14, 14]         461,120
             ReLU-92          [-1, 320, 14, 14]               0
           Conv2d-93           [-1, 32, 14, 14]          16,928
             ReLU-94           [-1, 32, 14, 14]               0
           Conv2d-95          [-1, 128, 14, 14]         102,528
             ReLU-96          [-1, 128, 14, 14]               0
        MaxPool2d-97          [-1, 528, 14, 14]               0
           Conv2d-98          [-1, 128, 14, 14]          67,712
             ReLU-99          [-1, 128, 14, 14]               0
       Inception-100          [-1, 832, 14, 14]               0
       MaxPool2d-101            [-1, 832, 7, 7]               0
          Conv2d-102            [-1, 256, 7, 7]         213,248
          Conv2d-103            [-1, 160, 7, 7]         133,280
            ReLU-104            [-1, 160, 7, 7]               0
          Conv2d-105            [-1, 320, 7, 7]         461,120
            ReLU-106            [-1, 320, 7, 7]               0
          Conv2d-107             [-1, 32, 7, 7]          26,656
            ReLU-108             [-1, 32, 7, 7]               0
          Conv2d-109            [-1, 128, 7, 7]         102,528
            ReLU-110            [-1, 128, 7, 7]               0
       MaxPool2d-111            [-1, 832, 7, 7]               0
          Conv2d-112            [-1, 128, 7, 7]         106,624
            ReLU-113            [-1, 128, 7, 7]               0
       Inception-114            [-1, 832, 7, 7]               0
          Conv2d-115            [-1, 384, 7, 7]         319,872
          Conv2d-116            [-1, 192, 7, 7]         159,936
            ReLU-117            [-1, 192, 7, 7]               0
          Conv2d-118            [-1, 384, 7, 7]         663,936
            ReLU-119            [-1, 384, 7, 7]               0
          Conv2d-120             [-1, 48, 7, 7]          39,984
            ReLU-121             [-1, 48, 7, 7]               0
          Conv2d-122            [-1, 128, 7, 7]         153,728
            ReLU-123            [-1, 128, 7, 7]               0
       MaxPool2d-124            [-1, 832, 7, 7]               0
          Conv2d-125            [-1, 128, 7, 7]         106,624
            ReLU-126            [-1, 128, 7, 7]               0
       Inception-127           [-1, 1024, 7, 7]               0
       AvgPool2d-128           [-1, 1024, 1, 1]               0
         Dropout-129           [-1, 1024, 1, 1]               0
          Linear-130                 [-1, 1000]       1,025,000
================================================================
Total params: 6,998,552
Trainable params: 6,998,552
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.57
Forward/backward pass size (MB): 66.84
Params size (MB): 26.70
Estimated Total Size (MB): 94.11
----------------------------------------------------------------

网站公告

今日签到

点亮在社区的每一天
去签到