ResNeXt学习

news/2024/9/22 2:38:50/

1. 模型介绍

ResNeXt是由何凯明团队在2017年CVPR会议上提出来的新型图像分类网络。ResNeXt是ResNet的升级版,在ResNet的基础上,引入了cardinality的概念,类似于ResNet,ResNeXt也有ResNeXt-50,ResNeXt-101的版本。那么相较于ResNet,ResNeXt的创新点在哪里?既然是分类网络,那么在ImageNet数据集上的指标相较于ResNet有何变化?之后的ResNeXt_WSL又是什么东西?下面我和大家一起分享一下这些知识。

2. 模型结构

在ResNeXt的论文中,作者提出了当时普遍存在的一个问题,如果要提高模型的准确率,往往采取加深网络或者加宽网络的方法。虽然这种方法是有效的,但是随之而来的,是网络设计的难度和计算开销的增加。为了一点精度的提升往往需要付出更大的代价。因此,需要一个更好的策略,在不额外增加计算代价的情况下,提升网络的精度。由此,何等人提出了cardinality的概念。

下图是ResNet(左)与ResNeXt(右)block的差异。在ResNet中,输入的具有256个通道的特征经过1×1卷积压缩4倍到64个通道,之后3×3的卷积核用于处理特征,经1×1卷积扩大通道数与原特征残差连接后输出。ResNeXt也是相同的处理策略,但在ResNeXt中,输入的具有256个通道的特征被分为32个组,每组被压缩64倍到4个通道后进行处理。32个组相加后与原特征残差连接后输出。这里cardinatity指的是一个block中所具有的相同分支的数目。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
下图是InceptionNet的两种inception module结构,左边是inception module的naive版本,右边是使用了降维方法的inception module。相较于右边,左边很明显的缺点就是参数大,计算量巨大。使用不同大小的卷积核目的是为了提取不同尺度的特征信息,对于图像而言,多尺度的信息有助于网络更好地对图像信息进行选择,并且使得网络对于不同尺寸的图像输入有更好的适应能力,但多尺度带来的问题就是计算量的增加。因此在右边的模型中,InceptionNet很好地解决了这个问题,首先是1×1的卷积用于特征降维,减小特征的通道数后再采取多尺度的结构提取特征信息,在降低参数量的同时捕获到多尺度的特征信息。

ResNeXt正是借鉴了这种“分割-变换-聚合”的策略,但用相同的拓扑结构组建ResNeXt模块。每个结构都是相同的卷积核,保持了结构的简洁,使得模型在编程上更方便更容易,而InceptionNet则需要更为复杂的设计。

在这里插入图片描述

3. 模型实现

ResNeXt与ResNet的模型结构一致,主要差别在于block的搭建,因此这里用paddle框架来实现block的代码

class ConvBNLayer(nn.Layer):def __init__(self, num_channels, num_filters, filter_size, stride=1,groups=1, act=None, name=None, data_format="NCHW"):super(ConvBNLayer, self).__init__()self._conv = Conv2D(in_channels=num_channels, out_channels=num_filters,kernel_size=filter_size, stride=stride,padding=(filter_size - 1) // 2, groups=groups,weight_attr=ParamAttr(name=name + "_weights"), bias_attr=False,data_format=data_format)if name == "conv1":bn_name = "bn_" + nameelse:bn_name = "bn" + name[3:]self._batch_norm = BatchNorm(num_filters, act=act, param_attr=ParamAttr(name=bn_name + '_scale'),bias_attr=ParamAttr(bn_name + '_offset'), moving_mean_name=bn_name + '_mean',moving_variance_name=bn_name + '_variance', data_layout=data_format)def forward(self, inputs):y = self._conv(inputs)y = self._batch_norm(y)return yclass BottleneckBlock(nn.Layer):def __init__(self, num_channels, num_filters, stride, cardinality, shortcut=True,name=None, data_format="NCHW"):super(BottleneckBlock, self).__init__()self.conv0 = ConvBNLayer(num_channels=num_channels, num_filters=num_filters,filter_size=1, act='relu', name=name + "_branch2a",data_format=data_format)self.conv1 = ConvBNLayer(num_channels=num_filters, num_filters=num_filters,filter_size=3, groups=cardinality,stride=stride, act='relu', name=name + "_branch2b",data_format=data_format)self.conv2 = ConvBNLayer(num_channels=num_filters,num_filters=num_filters * 2 if cardinality == 32 else num_filters,filter_size=1, act=None,name=name + "_branch2c",data_format=data_format)if not shortcut:self.short = ConvBNLayer(num_channels=num_channels, num_filters=num_filters * 2if cardinality == 32 else num_filters,filter_size=1, stride=stride,name=name + "_branch1", data_format=data_format)self.shortcut = shortcutdef forward(self, inputs):y = self.conv0(inputs)conv1 = self.conv1(y)conv2 = self.conv2(conv1)if self.shortcut:short = inputselse:short = self.short(inputs)y = paddle.add(x=short, y=conv2)y = F.relu(y)return y

4. 模型特点

ResNeXt通过控制cardinality的数量,使得ResNeXt的参数量和GFLOPs与ResNet几乎相同。

通过cardinality的分支结构,为网络提供更多的非线性,从而获得更精确的分类效果。

5. 模型指标

在这里插入图片描述

上图是ResNet与ResNeXt的参数对比,可以看出,ResNeXt与ResNet几乎是一模一样的参数量和计算量,然而两者在ImageNet上的表现却不一样。 result 从图中可以看出,ResNeXt除了可以增加block中3×3卷积核的通道数,还可以增加cardinality的分支数来提升模型的精度。ResNeXt-50和ResNeXt-101都大大降低了对应ResNet的错误率。图中,ResNeXt-101从32×4d变为64×4d,虽然增加了两倍的计算量,但也能有效地降低分类错误率。
在这里插入图片描述

在2019年何凯明团队开源了ResNeXt_WSL,ResNeXt_WSL是何凯明团队使用弱监督学习训练的ResNeXt,ResNeXt_WSL中的WSL就表示Weakly Supervised Learning(弱监督学习)。

ResNeXt101_32×48d_WSL有8亿+的参数,是通过弱监督学习预训练的方法在Instagram数据集上训练,然后用ImageNet数据集做微调,Instagram有9.4亿张图片,没有经过特别的标注,只带着用户自己加的话题标签。 ResNeXt_WSL与ResNeXt是一样的结构,只是训练方式有所改变。下图是ResNeXt_WSL的训练效果。
在这里插入图片描述

6. 参考文献

  • ResNet
  • ResNeXt
  • GoogLeNet

http://www.ppmy.cn/news/1528660.html

相关文章

武汉凯迪正大—变压器空负载特性参数测试仪 变压器容量及损耗参数测试仪

KDBR-N 变压器容量测试仪具有体积小巧、操作简单、使用方便等优点,并升级了内部处理器、数据采集系统、国标数据,使仪器可用范围更宽,测试精度更高。 KDBR-N 变压器容量测试仪包含了变压器容量、变压器空载损耗、变压器负载损耗及其代号水平…

JVM堆介绍

堆 堆是Java虚拟机中用于存储对象实例和数组的内存区域,它是Java程序运行时数据区的核心部分,负责存储和管理几乎所有的对象数据。 一、JVM堆介绍 今天,我们将深入探索Java堆的奥秘。它是Java虚拟机中一个非常关键的内存区域。让我们一起揭…

Windows系统通过部署wsl + Goland进行跨平台开发

1.背景 近期项目中因为用到了 Golang库中的 "log/syslog" 包,而这个包是禁止在windows平台上编译的. 并且在windows环境上开发也会有诸多不便,如执行makefile文件的make命令,本地开发环境中docker,etcd,redis的搭建等等,而这些通过部署wsl去搭建一个linux环境就很可以…

[数据集][目标检测]智慧养殖场肉鸡目标检测数据集VOC+YOLO格式3548张1类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):3548 标注数量(xml文件个数):3548 标注数量(txt文件个数):3548 标注…

linux-网络相关概念

一、tcp/ip网络模型 tcp/ip网络模型包含4层(应用、传输、internet、链路),描述不同协议如何进行互操作,以便计算机通过互联网将流量从一台计算机发送到另一台计算机 应用applicationo层: 应用程序,常见应用包括ssh、https、nfs或cifs、smtp等 传输tr…

吉首大学--23级题目讲解

7-1 单链表基本操作 在 C/C 中,.(点)和 ->(箭头)运算符用于访问结构体或类的成员,但它们的使用场景不同。 1. . 运算符 . 运算符用于访问结构体或类的成员,通过对象或结构体变量直接访问。…

嵌入式Linux学习笔记(6)-线程处理、线程同步、线程池(c语言实现)

一、概述 线程是一种轻量级的并发执行的机制。线程是进程中的一个实体,它执行在同一进程的上下文中,共享同一内存空间,但拥有独立的栈空间。 C语言的线程使用pthread库实现,通过包含头文件 pthread.h 来使用相关的函数和数据类型 …

Bugku---密码学---乐谱密码

题目出处:首页 - Bugku CTF ✨打开后发现是一张乐符图 ✨一般我们所熟悉的「Do Re Mi Fa Sol La Si」,若写成音名,即是「C D E F G A B」。不过德国人习惯使用的音名则是「C D E F G A H」,「B」代表 音名B♭ 。 C也就是后面的4&…