GoogLeNet论文阅读,代码实现(Inception系列)

article/2025/9/22 11:03:40

文章目录

  • GoogLeNet(Inception v1)
    • 个人理解
    • 总结
      • 本篇论文主相对于AlexNet和VGG有三处改进(不同)
        • 1、在inception块中引入了1×1卷积
        • 2、将第一层全连接层替换为global-averge-pooling
        • 3、利用inception近似稀疏数据结构
        • 4、引入辅助分类层
      • 代码(GoogeLeNet结构实现)

GoogLeNet(Inception v1)

论文地址:Going deeper with convolutions
------ 隔了两个月再来看这篇论文,不少地方依旧觉得晦涩难懂------

个人理解

理解的不够深,但希望对大家有帮助,有问题的地方也希望大家能指出来
本篇论文由google团队提出,拿到了ILSVRC14图像分类赛道冠军,同年的亚军是VGG。我认为googlenet的提出,相当于给出了一个新的,区别于传统的单纯堆叠卷积层的卷积神经网络结构。其中也借鉴了许多其它经典论文中的idea,比如NIN《Robust object recognition with cortex-like mechanisms》,《Provable Bounds for Learning Some Deep Representations》等,其中第二篇论文的主要结果表明,如果数据集的概率分布可由大的、非常稀疏的深度神经网络表示,通过分析最后一层激活情况的相关统计量,并聚类输出高度相关的神经元,逐层构建最优网络拓扑。,可以逐层构建最佳网络拓扑(这句话是照抄论文用软件翻译过来的)。大致可以认为使用稀疏结构可以让我们找到一个最优的拓扑结构。大家可以看一下原论文,我也打算去看看,似乎涉及到很多数学内容。
令人头疼的是,计算机在稀疏结构上的运算是低效的,即使将算数运算的次数减低100倍,也无法从稀疏结构中得到回报。另外,非均匀稀疏模型需要更复杂的工程和计算基础设施。意思就是说当时的计算机设备不利于稀疏数据结构的运算。于是作者另辟蹊径,希望中间步骤使用稀疏性,然后将稀疏矩阵聚类成相对稠密的子矩阵,最后用当前的计算机对这个稠密的子矩阵做运算。这样即应用了稀疏结构来构建最有结构又避免了计算机在稀疏数据结构上效率低的问题。

这篇论文提出的Inception块就是想要近似论文【2】中的稀疏结构,并通过实验发现有较好的表现。

总结

本篇论文主相对于AlexNet和VGG有三处改进(不同)

1、在inception块中引入了1×1卷积

在最初的Inception快中(结构由下图所述,navies version),应用了多个不同大小的滤波器(filter),随着网络层数的增加,会导致越往后的output feature的通道数越来越大(因为有个池化层,经过池化层后feature map的通道数量不变,每层叠加会导致通道数越来越大),导致参数量猛增,使得计算量也大了起来。
初始Inception块

改进后的Inception结构称作Inception v1,它在原来的基础上添加了1乘1的卷积层用于降维,然后再通过3×3或5×5的卷积核升维,这样大大减少参数量,增加网络层数,激活函变多,使网络非线性表达能力增强。

举个栗子:
5×5filter这条支路举例,假设输入是28×28,256通道的feature map,输出是28×28,32通道的feature map。
navies version所需参数:5×5×256×32≈20万
先降后升version所需参数:1×1×256×16 + 5×5×16×32≈2万
改进后的Inception块

2、将第一层全连接层替换为global-averge-pooling

这一操作根本上地解决了参数量过大的问题,VGG网络过于臃肿的原因就是在卷积层与全连接层之间产生了1亿多个参数。这里保留了一层全连接层(linear层),方便之后的微调(fine-tuning)

3、利用inception近似稀疏数据结构

由直觉,处理视觉信息应该利用不同大小的filter并行处理input feature,然后再集合起来,从而使后面的卷积层可以同时提取不同尺寸的特征。

4、引入辅助分类层

作者发现了一个有趣的现象,相对较浅的网络有更好的表现,表明网络中间层产生的特征应该是非常有判别能力的。通过在网络中间部分加入辅助分类器,增强了分类表现并促进了梯度的反向传播(尽管后面认为这个辅助分类器没什么用)。共有两个辅助分类器和一个主分类器,在训练阶段,对三个分类器的结果进行加权求和得到最后的分类结果(权重分别为0.3、0.3,0.4)。但是在inference阶段,仅通过主分类器进行分类。

代码(GoogeLeNet结构实现)

代码有些长,但好理解

import sys
import numpy as np
import torch
from torch import nn
from torch.autograd import Variable
# 卷积层标配,卷积+relu
def conv_relu(in_channel, out_channel, kernel, stride=1, padding=0):layer = nn.Sequential(nn.Conv2d(in_channel, out_channel, kernel, stride, padding),nn.ReLU(True))return layer# 定义inception块
class inception(nn.Module):def __init__(self, in_channel, out1_1, out2_1, out2_3, out3_1, out3_5, out4_1):super(inception, self).__init__()# 第一条线路,filter大小为1×1self.branch1x1 = conv_relu(in_channel, out1_1, 1)# 第二条线路,filter大小为3×3self.branch3x3 = nn.Sequential( conv_relu(in_channel, out2_1, 1),conv_relu(out2_1, out2_3, 3, padding=1))# 第三条线路,filter大小为5×5self.branch5x5 = nn.Sequential(conv_relu(in_channel, out3_1, 1),conv_relu(out3_1, out3_5, 5, padding=2))# 第四条线路,直接池化层self.branch_pool = nn.Sequential(nn.MaxPool2d(3, stride=1, padding=1),conv_relu(in_channel, out4_1, 1))def forward(self, x):f1 = self.branch1x1(x)f2 = self.branch3x3(x)f3 = self.branch5x5(x)f4 = self.branch_pool(x)output = torch.cat((f1, f2, f3, f4), dim=1)return output# 构建googlenet
class googlenet(nn.Module):def __init__(self, in_channel, num_classes, verbose=False):super(googlenet, self).__init__()self.verbose = verboseself.block1 = nn.Sequential(conv_relu(in_channel, out_channel=64, kernel=7, stride=2, padding=3),nn.MaxPool2d(3, 2))self.block2 = nn.Sequential(conv_relu(64, 64, kernel=1),conv_relu(64, 192, kernel=3, padding=1),nn.MaxPool2d(3, 2))self.block3 = nn.Sequential(inception(192, 64, 96, 128, 16, 32, 32),inception(256, 128, 128, 192, 32, 96, 64),nn.MaxPool2d(3, 2))self.block4 = nn.Sequential(inception(480, 192, 96, 208, 16, 48, 64),inception(512, 160, 112, 224, 24, 64, 64),inception(512, 128, 128, 256, 24, 64, 64),inception(512, 112, 144, 288, 32, 64, 64),inception(528, 256, 160, 320, 32, 128, 128),nn.MaxPool2d(3, 2))self.block5 = nn.Sequential(inception(832, 256, 160, 320, 32, 128, 128),inception(832, 384, 182, 384, 48, 128, 128),nn.AvgPool2d(2))self.classifier = nn.Linear(1024, num_classes)def forward(self, x):x = self.block1(x)if self.verbose:print('block 1 output: {}'.format(x.shape))x = self.block2(x)if self.verbose:print('block 2 output: {}'.format(x.shape))x = self.block3(x)if self.verbose:print('block 3 output: {}'.format(x.shape))x = self.block4(x)if self.verbose:print('block 4 output: {}'.format(x.shape))x = self.block5(x)if self.verbose:print('block 5 output: {}'.format(x.shape))x = x.view(x.shape[0], -1)x = self.classifier(x)return xtest_net = googlenet(3, 10, True) # 3表示输入数据的通道数,10表示分类类别个数

http://chatgpt.dhexx.cn/article/EU9NFgRY.shtml

相关文章

“Python小屋”1300篇历史文章分类速查表

总体说明: 各分类中的文章是按发布时间逆序排列的,动态更新。公众号所有代码均可作为教学案例,转载请注明出处,请勿用作商业用途。 快速查找历史文章的方法:1)单击本文右上角的按钮“...”,然后…

100个数据分析常用指标和术语

大家好,我是辰哥~ 有个朋友是金融行业产品经理,最近在对已有的站内用户做分层与标签分类,需要对用户进行聚类分析。一般从事数据分析行业的朋友对这类词并不陌生,但是像市场运营人员就会把这类些名词概念搞混,导致结果…

TF使用例子-情感分类

北京站 | NVIDIA DLI深度学习培训 2018年1月26日 NVIDIA 深度学习学院 带你快速进入火热的DL领域 阅读全文 正文共10052个字,4张图,预计阅读时间26分钟。 这次改写一下,做一个简单的分类模型和探讨一下hidden layer在聚类的应用场景下会有什…

计算机视觉(五)

Bag of features,简称Bof,中文翻译为“词袋”,是一种用于图像或视频检索的技术。而检索就要进行比对。两幅不同的图像如何比对,比对什么,这就需要提炼出每幅图像中精练的东西出来进行比较。 一、Bag of features算法基…

Eastmount博客导读:专栏系统分类和博客归纳总结

为了更好地帮助博友学习作者的博客,方便作者自己归纳总结专栏,本文详细介绍了作者八年来,在CSDN写的各种专栏,各种系列文章。八年来,作者经历了从本科到硕士,到贵州教书成家,再到现在的博士。八…

Python编程实现用KNN算法对红酒分类功能

一、任务要求 导入红酒数据集(load_wine),编写Python代码,完成以下任务: 1、实现计算平均酒精含量的功能; 2、实现对数据的标准化; 3、使用kNN算法实现红酒分类功能 二、代码实现 from sklearn…

文本挖掘(四万字总结篇:爬虫 - 文本预处理 - 高频词统计 - 聚类 - 情感分析)

1 爬虫 1.1 爬虫原理 这部分内容可以跳过,掌握与否对后面内容的阅读影响并不大,但有兴趣的话可以看看呐~ 实现一个爬虫,一般需要经过两个步骤:处理请求和解析源码/数据。 处理请求方面,我们可以使用Python程序自动发送…

python卷积神经网络代码,python卷积神经网络分类

怎样用python构建一个卷积神经网络模型 上周末利用python简单实现了一个卷积神经网络,只包含一个卷积层和一个maxpooling层,pooling层后面的多层神经网络采用了softmax形式的输出。 实验输入仍然采用MNIST图像使用10个featuremap时,卷积和p…

用python实现基于自媒体数据的人群聚类分析

🍅程序员小王的博客:程序员小王的博客 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 如有编辑错误联系作者,如果有比较好的文章欢迎分享给我,我会取其精华去其糟粕 🍅java自学的学习…

二叉树三种非递归遍历以及代码实现

二叉树三种非递归遍历 1.二叉树前序非递归遍历实现,(采用栈) 思路:(用一个栈) 1.首先用cur标记树的根(root),当cur非空的时候; 2.就直接打印根,并且将cur(也就是root)入栈; 3.接着遍历根的左子…

c++练习(5):二叉树非递归遍历

二叉树遍历 二叉树有三种遍历方法:前序(跟左右)跟节点在前面、中序(左跟右)跟节点在中间、后续(左右跟)跟节点在后面 前序(跟左右):上图的二叉树,第一次跟左右对应ABC…

C++——二叉树OJ|二叉树非递归遍历

目录 二叉树的前序遍历 二叉树的中序遍历 二叉树的后续遍历 二叉树的前序遍历 144. 二叉树的前序遍历 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:vector<int> preorderTraversal(TreeNode* root) { TreeNode* curroot; stack<TreeNode*>…

数据结构与算法_二叉树非递归遍历

记录二叉树的前序&#xff0c;中序&#xff0c;后续&#xff0c;层序等非递归遍历。 1 二叉树非递归前序遍历 用栈实现二叉树非递归前序遍历&#xff0c;按照 V L R顺序进行遍历&#xff1b;每一个都按照V L R方式进行。 上图中&#xff0c;根节点先入栈&#xff0c;出栈并访…

二叉树遍历非递归C++

二叉树遍历非递归C 题目链接二叉树的前序遍历思路分析代码实现 二叉树的中序遍历思路分析代码实现 二叉树的后序遍历思路分析代码实现 一点点题外话 题目链接 二叉树的前序遍历 144. 二叉树的前序遍历 思路分析 既然要使用非递归的方式&#xff0c;那就必须要借助栈来进行处…

二叉树的遍历(非递归)

由于二叉树的递归方法实际上是系统在使用栈进行操作&#xff0c;因此我们的迭代&#xff08;非递归&#xff09;方法也就需要使用栈进行模拟。 一、先序遍历 我们需要明白&#xff0c;进栈的元素都是树的根节点 root。 所以我们需要先访问该节点&#xff0c;再将该节点进栈。…

二叉树非递归遍历算法分析

以前没有学习过树的相关算法&#xff0c;只是了解一些皮毛&#xff0c;最近开始认真学习它。看视频或者网上查资料&#xff0c;可以知道怎么去遍历一棵树&#xff0c;但是算法为什么是这样的呢&#xff1f;少有讲到。如果有一天&#xff0c;我忘记了这个算法&#xff0c;我需要…

c语言和c++实现二叉树非递归遍历

结合栈结构来实现二叉树的非递归遍历&#xff0c;首先将根节点入栈&#xff0c;然后对栈内元素进行循环&#xff0c;弹出栈顶元素&#xff0c;根据链表结点携带的标志位flag来判断是对于结点进行打印还是后续的入栈操作。入栈顺序决定着实际的遍历方式。 main.cpp #include&l…

【数据结构】二叉树的非递归遍历(完整代码)

默认给一棵树前序遍历的结果&#xff0c;按要求创建这棵树&#xff08;#表示空&#xff09;&#xff0c;并用非递归的方法对它进行遍历。 解题思路 1.递归遍历&#xff1a; 则将二叉树的遍历看作是分治问题&#xff0c;将每一棵树都分为根-左子树-右子树三部分&#xff0c;每…

数据结构--二叉树的遍历(非递归)

我们已经对二叉树的基本概念有了一定的了解&#xff0c;也对它的递归版本的前、中、后序遍历掌握的很好了&#xff0c;那么接下来就要介绍二叉树中遍历的非递归版本 >【数据结构】二叉树详解< 先看本篇文章效果更佳哦 目录 1、非递归遍历解析2、前序遍历(非递归)3、中序…

二叉树的非递归遍历 C语言版

文章作者&#xff1a;Slyar 文章来源&#xff1a;Slyar Home (www.slyar.com) 转载请注明&#xff0c;谢谢合作。 上周数据结构课在讲二叉树的遍历&#xff0c;老师只讲递归算法&#xff0c;没有什么技术含量&#xff0c;遂自己琢磨非递归算法实现... 前序遍历:先访问根节点&…