深度学习之路=====10=====>>Resnext(tensorflow2)

news2025/7/27 3:55:57

简介

类型:2017CVPR 作者: Kaiming He组

和其他轻量级网络特点一样,Resnext也是通过降低参数量来改进模型,提高模型精度的。该模型基于Inception的split-transform-merge范式和VGG堆叠网络,将Resnet的单路卷积变成多路卷积(分组卷积),与Inception的区别是该模块的所有支路采用相同的拓扑结果。

作者认为split-transform-merge是通用的神经网络标准范式,
用如下公式表示:
在这里插入图片描述
作者引入Resnext后的表达式为:
在这里插入图片描述
x表示short-cut, C表示cardinality,即分组个数-独立且相同的拓扑结构, τ ( x ) \tau \left( x \right) τ(x)表示任意变换,最后进行merge。

特点

  • 增加 cardinality 比增加深度和宽度更有效;
  • 采用 VGG 堆叠的思想和 Inception 的 split-transform-merge 思想,可扩展性比较强;
  • 101 层的 ResNeXt 比 200 层的 ResNet 更好;
  • 用一种平行堆叠相同拓扑结构的blocks代替原来 ResNet 的三层卷积的block,在不明显增加参数量级的情况下提升了模型的准确率,同时由于拓扑结构相同,超参数也减少了,便于模型移植。

创新点

  • 采用相同拓扑结构的分组卷积,引入cardinality用来表示对通道的分组数
  • 降低参数量和计算量

下图左右分别为Resnet和Resnext的基本block,其中Resnext-block符合作者提到的split-transform-merge范式
在这里插入图片描述

ResNext的BottleNeck结构:

下图中的三种结构为等价结构,其中©结构较前两种实现简单,文中使用©结构。
在这里插入图片描述

网络结构

方括号内容表示Block中的网络设置
在这里插入图片描述

容易忽略的点:

  • Resnext中相邻间Repeat stage中的第二块stage中的第一个block中的GC(分组卷积)的步长为2,也就是上表中conv3,conv4,conv5的第一个block中的分组卷积步长为2,这样,相邻间Repeat stage的输出尺寸差2倍(28->14->7)。
  • 上面的步长变化导致对应块中的short-cut层的卷积步长也要对应为2,这样经过各自的卷积计算后,他们的尺寸仍然一致,可以进行“+”计算。

代码

import tensorflow as tf
import numpy as np
from tensorflow.keras.layers import *
from tensorflow.keras import Model
class Conv(Model):
    def __init__(self,filters,kernel_size=1,strides=1):
        super().__init__()
        self.layers_list=[]
        self.layers_list.append(Conv2D(filters,kernel_size=kernel_size,strides=strides,padding='same'))
        self.layers_list.append(BatchNormalization())
        self.layers_list.append(Activation('relu'))
    def call(self,x):
        for layer in self.layers_list:
            x=layer(x)
        return x
class Group_Conv(Model):
    def __init__(self,strides,cardinality,in_channels):
        super().__init__()
        self.cardinality=cardinality
        self.channels_per_group=in_channels//cardinality
        assert self.channels_per_group>0 ,"erro!!,the channels of per group is less 0"
        self.gc_list=[]
        for i in range(cardinality):
            self.gc_list.append(Conv2D(self.channels_per_group,kernel_size=3,strides=strides,padding='same'))
        self.b=BatchNormalization()
        self.a=Activation('relu')
    def call(self,input):
        x_list=tf.split(input,self.cardinality,axis=-1)
        for i,group_conv in enumerate(self.gc_list):
            x_list[i]=group_conv(x_list[i])
        x=tf.concat(x_list,axis=-1)
        x=self.b(x)
        output=self.a(x)
        return output          
            
class Resnext_block(Model):
    def __init__(self,in_channels,strides,cardinality):
        super().__init__()
        
        self.residual=[]
        self.residual.append(Conv2D(filters=in_channels*2,kernel_size=1,strides=strides,padding='same'))
        self.residual.append(Activation('relu'))
        self.out_channels=in_channels*2
        self.layers_list=[]
        self.layers_list.append(Conv(in_channels))
        self.layers_list.append(Group_Conv(strides,cardinality,in_channels))
        self.layers_list.append(Conv(self.out_channels))
    def call(self,x):
        #print(x.shape)
        input=x
        for residual_layer in self.residual:
            input=residual_layer(input)
        residual=input
        #print(residual.shape)
        for layer in self.layers_list:
            
            x=layer(x)
            
        
        y=x+residual
        #print(y.shape)
        return y
class Resnext(Model):
    def __init__(self,repeat_list,filters=64,cardinality=32):
        super().__init__()
        self.in_channels=filters
        self.layers_list=[]
        self.layers_list.append(Conv(self.in_channels,kernel_size=7,strides=2))
        self.layers_list.append(MaxPooling2D(pool_size=(3,3),strides=2,padding='same'))
        for j,repeat in enumerate(repeat_list):
            self.in_channels=self.in_channels*2
           #print(self.in_channels)
            for i in range(repeat):
                if j!=0 and i==0:
                    strides=2
                else:
                    strides=1
                self.layers_list.append(Resnext_block(self.in_channels,strides,cardinality))
        self.layers_list.append(GlobalAveragePooling2D())
        self.layers_list.append(Dense(1000,activation='softmax'))
    def call(self,x):
        for layer in self.layers_list:
            x=layer(x)
            #print(x.shape)
        return x
##用一个数据验证模型正确性
model = Resnext(repeat_list=[3,4,6,3])
inputs = np.zeros((1, 224, 224, 3), np.float32)
model(inputs).shape
model.summary()
##模型结构和图中提到的一致,但是最终的参数量和比论文中多几乎一半,不解。
#这是每个block输出的shape,与表中一致
(1, 112, 112, 64)
(1, 56, 56, 64)
(1, 56, 56, 256)
(1, 56, 56, 256)
(1, 56, 56, 256)
(1, 28, 28, 512)
(1, 28, 28, 512)
(1, 28, 28, 512)
(1, 28, 28, 512)
(1, 14, 14, 1024)
(1, 14, 14, 1024)
(1, 14, 14, 1024)
(1, 14, 14, 1024)
(1, 14, 14, 1024)
(1, 14, 14, 1024)
(1, 7, 7, 2048)
(1, 7, 7, 2048)
(1, 7, 7, 2048)
(1, 2048)
(1, 1000)

Model: "resnext_16"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv_498 (Conv)              multiple                  9728      
_________________________________________________________________
max_pooling2d_11 (MaxPooling multiple                  0         
_________________________________________________________________
resnext_block_243 (Resnext_b multiple                  64768     
_________________________________________________________________
resnext_block_244 (Resnext_b multiple                  138496    
_________________________________________________________________
resnext_block_245 (Resnext_b multiple                  138496    
_________________________________________________________________
resnext_block_246 (Resnext_b multiple                  351744    
_________________________________________________________________
resnext_block_247 (Resnext_b multiple                  548352    
_________________________________________________________________
resnext_block_248 (Resnext_b multiple                  548352    
_________________________________________________________________
resnext_block_249 (Resnext_b multiple                  548352    
_________________________________________________________________
resnext_block_250 (Resnext_b multiple                  1395712   
_________________________________________________________________
resnext_block_251 (Resnext_b multiple                  2182144   
_________________________________________________________________
resnext_block_252 (Resnext_b multiple                  2182144   
_________________________________________________________________
resnext_block_253 (Resnext_b multiple                  2182144   
_________________________________________________________________
resnext_block_254 (Resnext_b multiple                  2182144   
_________________________________________________________________
resnext_block_255 (Resnext_b multiple                  2182144   
_________________________________________________________________
resnext_block_256 (Resnext_b multiple                  5560320   
_________________________________________________________________
resnext_block_257 (Resnext_b multiple                  8706048   
_________________________________________________________________
resnext_block_258 (Resnext_b multiple                  8706048   
_________________________________________________________________
global_average_pooling2d_13  multiple                  0         
_________________________________________________________________
dense_13 (Dense)             multiple                  2049000   
=================================================================
Total params: 39,676,136
Trainable params: 39,615,592
Non-trainable params: 60,544

参考

深度学习——分类之ResNeXt
ResNeXt算法详解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/35344.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

程序员注意!35岁前,别靠死工资过日子

《2022程序员职场洞察报告》显示,六成受访者的职级和薪酬原地踏步,仅38.3%程序员群体的工作发生过变动,升职加薪、搞副业、自由工作等。 近两年,伴随疫情及行业发展的不确定性,企业招聘以及人才求职双方都变得谨慎。越…

MFC程序设计——用button更改静态文本+显示内容并弹出新内容+静态文本动态打开位图

目录 一、新建基于对话框的MFC编程项目 二、设计界面 2.设置启动项 2.找到资源视图和Dialog 3.拖入控件 三、创建变量(关联对话框与静态文本) 四、写入控件代码 1.在文本上的应用 2.在图像上的应用 2.1初始化的方法 2.2控件导入的方法 3.控件…

TSC TTP244Pro 打码机出现的问题及解决方案

背景: 最近在使用TSC的TTP 244 Pro 打码机的过程中,出现了几个小问题,最后请教了专业的人员才解决了问题,现把需要注意的点记录如下: 准备: 先去TSC的** 官网 **上找关于适用于你的打码机和使用环境的驱…

数据结构(高阶)—— AVL树

目录 一、AVL树的基本概念 二、AVL树的结点定义 三、AVL树的插入 四、AVL树的旋转 1. 右单旋 2. 左单旋 3. 右左双旋 4. 左右双旋 五、AVL树的验证 六、AVL树的性能 七、源代码 一、AVL树的基本概念 二叉搜索树虽可以缩短查找的效率,但如果数据有序或…

CXL 2.0 Device配置空间寄存器组成

目录 1 配置空间 1.1 PCI Power Management Capability Structure 1.2 PCI Express Capability Structure 2 扩展配置空间 2.1 PCIe DVSEC for CXL Device 2.2 GPF DVSEC for CXL Devices 2.3 PCIe DVSEC for Flex Bus Port 2.4 Register Locator DVSEC CXL设备配置空间…

ThinkPHP架构

文章目录一、架构总览1.1、有关常用的一些概念入口文件应用模块控制器操作模型视图驱动行为命名空间【全限定类名】1.补充二、生命周期三、入口文件四、URL访问五、模块设计六、命明空间七、自动加载八、Traits引入九、API友好一、架构总览 ThinkPHP5.0应用基于MVC(…

前后端分页插件

PageHelper 是一个 MyBatis 的分页插件,支持多种数据库,可查看官网&#xff0c;负责将已经写好的 SQL 语句&#xff0c;进行SQL分页加工。无需你自己去封装以及关心 SQL 分页等问题&#xff0c;支持多种分页方式,如从第0或第一页开始, 使用很方便。 添加依赖 <dependency&…

线代 | 【提神醒脑】自用笔记串联二 —— 向量组 · 线性方程组 · 特征值与特征向量

本文总结参考于 kira 2023 线代提神醒脑技巧班。 笔记均为自用整理。加油!ヾ(◍∇◍)ノ゙ 四、向量组 4.1、向量组的线性相关性 ----------------------------------------------------------------------------------------------------------…

Linux 软链接 与 硬链接 的区别

Linux 软链接 与 硬链接 的区别 1、概念 ​  链接文件&#xff1a;是 Linux 操作系统中的一种文件&#xff0c;主要用于解决文件的共享使用问题&#xff0c;而链接的方式分为两种——软链接和硬链接。 ​  inode&#xff1a;是文件系统中存储文件元信息&#xff08;文件的…

Auddly Music Server的编译和安装

本文始于 2021 年 11 月&#xff0c;已经忘记了是什么原因一直没发&#xff0c;这次基本上全部重写了一遍&#xff0c;除了官方的图&#xff0c;所有图片都是重新截取的&#xff1b; 什么是 auddly &#xff1f; auddly 是一款自托管音乐流应用程序。 什么是 auddly-server &am…

模拟实现ATM系统——Java

目录 一、内容简介 二、基本流程 三、具体步骤 1.定义Account类 2.菜单栏 3.账户注册 (1)根据卡号查询账户信息 (2)生成随机卡号 (3)注册账户 4.账户登录 (1)验证码 (2)登录 5.账户展示界面 6.用户操作 (1)查询账户 (2)存款 (3)取款 (4)转账 (5)修改密码 …

旋转的骰子(二)

1.动画——旋转的骰子 上一次我们做了一个旋转的骰子(参看第2讲),这次我们想要点击按钮,让骰子旋转到特定的点数停下来! 2.分析需求——庖丁解牛 a.立方体特定的朝向

LiveData源码分析

先放整理流程图&#xff1a; 1.postValue调2次只触发1次&#xff1f; postValue本质是把新值保存到LiveData的mPendingData成员变量里&#xff0c;版本号1&#xff0c;把执行Runnable post到主线程&#xff0c;在主线程setValue。 多次调用会更新mPendingData的值&#xff0c…

opencv的极线几何

一、理论介绍 当我们使用针孔相机拍摄图像时&#xff0c;我们会丢失一个重要的信息&#xff0c;即图像的深度。一个解决方案如我们的眼睛的方式使用两个相机&#xff08;两只眼睛&#xff09;&#xff0c;这就是所谓的立体视觉。 PO1O2为极平面&#xff0c;l1和l2为极线,e1和…

基于webrtc的数据传输研究总结

什么是webrtc WebRTC (Web Real-Time Communications) 是一项实时通讯技术&#xff0c;它允许网络应用或者站点&#xff0c;在不借助中间媒介的情况下&#xff0c;建立浏览器之间点对点&#xff08;Peer-to-Peer&#xff09;的连接&#xff0c;实现视频流和&#xff08;或&…

最新阿里云ECS服务器S6/C6/G6/N4/R6/sn2ne/sn1ne/se1ne处理器CPU性能详解

阿里云ECS服务器S6/C6/G6/N4/R6/sn2ne/sn1ne/se1ne处理器CPU性能怎么样&#xff1f;阿里云服务器优惠活动机型有云服务器S6、计算型C6、通用型G6、内存型R6、云服务器N4、云服务器sn2ne、云服务器sn1ne、云服务器se1ne处理器CPU性能详解及使用场景说明。 1、阿里云服务器活动机…

全局唯一ID

文章目录前言MongoDB ObjectIdTwitter SnowflakeUUID前言 基于数据库设置其实初始值&#xff0c;以及增量步长。基于ZK,Redis,改良雪花集中式服务生成&#xff0c;远程调用获取id。基于并行空间划分&#xff0c;Snowflake&#xff08;8Byte字节64bit位&#xff09;&#xff0c…

供应化学试剂mPEG-Azide,mPEG-N3,甲氧基-聚乙二醇-叠氮,CAS:89485-61-0

1、名称 英文&#xff1a;mPEG-Azide&#xff0c;mPEG-N3 中文&#xff1a;甲氧基-聚乙二醇-叠氮 2、CAS编号&#xff1a;89485-61-0 3、所属分类&#xff1a;Azide PEG Methoxy PEG 4、分子量&#xff1a;可定制&#xff0c;甲氧基-聚乙二醇-叠氮 5k、甲氧基-PEG-叠氮 10…

Higress 实战: 30行代码写一个 Wasm Go 插件

前言 在11月15号的直播 《Higress 开源背后的发展历程和上手 Demo 演示》中&#xff0c;为大家演示了 Higress 的 Wasm 插件如何面向 Ingress 资源进行配置生效&#xff0c;本文对当天的 Demo 进行一个回顾&#xff0c;并说明背后的原理机制。 本文中 Demo 运行的前提&#x…

PPOCR车牌定位模型推理后处理优化研究

综述 最近在研究基于PPOCR算法的车牌识别&#xff08;LPR&#xff09;&#xff0c;部署模型后发现之前关于OCR文本定位的后处理策略在车牌识别中存在定位精度不够高&#xff0c;文本框偏移的问题&#xff0c;如&#xff1a; 经分析发现是之前的OCR后处理策略存在一定局限&am…