图像分类学习笔记(六)——ResNeXt

一、要点

ResNeXt是ResNet的小幅升级,更新了block

 左边(ResNet的block/50/101/152层):

对于输入通道为256的特征矩阵,首先使用64个1×1的卷积核进行降维,再通过64个3×3的卷积核处理,再通过256个1×1的卷积核升维输出,将输出与输入进行相加,得到最终的输出。

使用右边的结构替代左边的结构:下面解释。

(一)论文中的性能参数指标

 (二)关于ResNet和ResNeXt在ImageNet上top-1 的错误率(计算量相同)

(三)组卷积 (Group Convolution)

当分组的个数与输入特征矩阵的channel是一致的,并且输入特征矩阵的channel也和输出特征矩阵的channel一致的话,就相当于对我们输入特征矩阵的每一个channel分配了一个channel为1的卷积核进行卷积。即DW卷积。

(四)ResNeXt的block结构

(c)(最简形式):输入通道为256维,首先通过128个1×1的卷积核降维处理,再通过group卷积(卷积核3×3,group数为32),得到的特征矩阵的通道是128维,再通过256个1×1的卷积核升维得到输出。再将输出和输入的特征矩阵进行相加得到最终的输出。

(b)和(c)等价

 (a)和(b)等价

 举例:假设path为2,对每个path采用1×1的卷积核来进行卷积

(五) 网络结构

二、使用pytorch搭建

代码是包括ResNet和ResNeXt的

import torch.nn as nn
import torch# 18层/34层 对应的残差结构(既要有实线残差结构的功能,又要有虚线残差结构的功能)
class BasicBlock(nn.Module):expansion = 1  #残差结构的主分支卷积核的个数有无发生变化def __init__(self, in_channel, out_channel, stride=1, downsample=None, **kwargs): # downsample对应残差结构的虚线(shortcut分支)super(BasicBlock, self).__init__()# stride=1,对应着实线的残差结构,因为并没有改变输入特征矩阵的高和宽# output = (input -3 + 2 * 1) / 1 + 1 = input# stride=2,对应着虚线的残差结构,在第一个卷积层需要将特征矩阵的高和宽缩减为原来的一半# output = (input -3 + 2 * 1) / 2 + 1 = input / 2 + 0.5 = input / 2 (向下取整)self.conv1 = nn.Conv2d(in_channels=in_channel, out_channels=out_channel,kernel_size=3, stride=stride, padding=1, bias=False)  # bias=False,不使用偏置项,因为下面用到BatchNormalizationself.bn1 = nn.BatchNorm2d(out_channel)self.relu = nn.ReLU()self.conv2 = nn.Conv2d(in_channels=out_channel, out_channels=out_channel,kernel_size=3, stride=1, padding=1, bias=False)self.bn2 = nn.BatchNorm2d(out_channel)self.downsample = downsampledef forward(self, x):identity = x # shorcut上的输出值if self.downsample is not None:identity = self.downsample(x)out = self.conv1(x)out = self.bn1(out)out = self.relu(out)out = self.conv2(out)out = self.bn2(out)out += identityout = self.relu(out)return out# 50层/101层/152层 对应的残差结构
class Bottleneck(nn.Module):"""注意:原论文中,在虚线残差结构的主分支上,第一个1x1卷积层的步距是2,第二个3x3卷积层步距是1。但在pytorch官方实现过程中是第一个1x1卷积层的步距是1,第二个3x3卷积层步距是2,这么做的好处是能够在top1上提升大概0.5%的准确率。可参考Resnet v1.5 https://ngc.nvidia.com/catalog/model-scripts/nvidia:resnet_50_v1_5_for_pytorch"""expansion = 4  #每个残差结构的最后一层卷积核的个数都是前两层的4倍def __init__(self, in_channel, out_channel, stride=1, downsample=None,groups=1, width_per_group=64):super(Bottleneck, self).__init__()width = int(out_channel * (width_per_group / 64.)) * groupsself.conv1 = nn.Conv2d(in_channels=in_channel, out_channels=width,kernel_size=1, stride=1, bias=False)  # squeeze channelsself.bn1 = nn.BatchNorm2d(width)# -----------------------------------------self.conv2 = nn.Conv2d(in_channels=width, out_channels=width, groups=groups,kernel_size=3, stride=stride, bias=False, padding=1)self.bn2 = nn.BatchNorm2d(width)# -----------------------------------------self.conv3 = nn.Conv2d(in_channels=width, out_channels=out_channel*self.expansion,kernel_size=1, stride=1, bias=False)  # unsqueeze channelsself.bn3 = nn.BatchNorm2d(out_channel*self.expansion)self.relu = nn.ReLU(inplace=True)self.downsample = downsampledef forward(self, x):identity = xif self.downsample is not None:identity = self.downsample(x)out = self.conv1(x)out = self.bn1(out)out = self.relu(out)out = self.conv2(out)out = self.bn2(out)out = self.relu(out)out = self.conv3(out)out = self.bn3(out)out += identityout = self.relu(out)return outclass ResNet(nn.Module):def __init__(self,block, # 对应18/34层或者50/101/152层的残差结构blocks_num, # 残差结构的个数,是个列表,以34层为例,就是[3,4,6,3]num_classes=1000, # 训练集的分类个数include_top=True, # 方便以后在ResNet网络上去搭建更复杂的网络groups=1,width_per_group=64):super(ResNet, self).__init__()self.include_top = include_topself.in_channel = 64self.groups = groupsself.width_per_group = width_per_groupself.conv1 = nn.Conv2d(3, self.in_channel, kernel_size=7, stride=2,padding=3, bias=False)# 为了让特征矩阵的宽和高缩减为原来的一半,所以这里padding=3self.bn1 = nn.BatchNorm2d(self.in_channel)self.relu = nn.ReLU(inplace=True)self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)# 为了让特征矩阵的宽和高缩减为原来的一半,所以这里padding=1self.layer1 = self._make_layer(block, 64, blocks_num[0]) # conv2_x 对于50/101/152层来说,第一个残差结构的第一层只改变特征矩阵的深度,没有改变宽高,所以没有传入stride,默认为1self.layer2 = self._make_layer(block, 128, blocks_num[1], stride=2) # conv3_xself.layer3 = self._make_layer(block, 256, blocks_num[2], stride=2) # conv4_xself.layer4 = self._make_layer(block, 512, blocks_num[3], stride=2) # conv5_xif self.include_top:self.avgpool = nn.AdaptiveAvgPool2d((1, 1))  # output size = (1, 1)self.fc = nn.Linear(512 * block.expansion, num_classes)for m in self.modules():if isinstance(m, nn.Conv2d):nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')def _make_layer(self, block, channel, block_num, stride=1):downsample = None# 对于18/34层第一个残差结构,跳过这句if stride != 1 or self.in_channel != channel * block.expansion:downsample = nn.Sequential(nn.Conv2d(self.in_channel, channel * block.expansion, kernel_size=1, stride=stride, bias=False),nn.BatchNorm2d(channel * block.expansion))layers = []# 残差结构的第一层(虚线残差结构)layers.append(block(self.in_channel,channel,downsample=downsample,stride=stride,groups=self.groups,width_per_group=self.width_per_group))self.in_channel = channel * block.expansionfor _ in range(1, block_num):layers.append(block(self.in_channel,channel,groups=self.groups,width_per_group=self.width_per_group))return nn.Sequential(*layers)def forward(self, x):x = self.conv1(x)x = self.bn1(x)x = self.relu(x)x = self.maxpool(x)x = self.layer1(x)x = self.layer2(x)x = self.layer3(x)x = self.layer4(x)if self.include_top:x = self.avgpool(x)x = torch.flatten(x, 1)x = self.fc(x)return xdef resnet34(num_classes=1000, include_top=True):# https://download.pytorch.org/models/resnet34-333f7ec4.pthreturn ResNet(BasicBlock, [3, 4, 6, 3], num_classes=num_classes, include_top=include_top)def resnet50(num_classes=1000, include_top=True):# https://download.pytorch.org/models/resnet50-19c8e357.pthreturn ResNet(Bottleneck, [3, 4, 6, 3], num_classes=num_classes, include_top=include_top)def resnet101(num_classes=1000, include_top=True):# https://download.pytorch.org/models/resnet101-5d3b4d8f.pthreturn ResNet(Bottleneck, [3, 4, 23, 3], num_classes=num_classes, include_top=include_top)def resnext50_32x4d(num_classes=1000, include_top=True):# https://download.pytorch.org/models/resnext50_32x4d-7cdf4587.pthgroups = 32width_per_group = 4return ResNet(Bottleneck, [3, 4, 6, 3],num_classes=num_classes,include_top=include_top,groups=groups,width_per_group=width_per_group)def resnext101_32x8d(num_classes=1000, include_top=True):# https://download.pytorch.org/models/resnext101_32x8d-8ba56ff5.pthgroups = 32width_per_group = 8return ResNet(Bottleneck, [3, 4, 23, 3],num_classes=num_classes,include_top=include_top,groups=groups,width_per_group=width_per_group)

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

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

相关文章

项目进度与实施计划汇报实践样例模板

一、IT项目实施步骤 项目启动 项目启动 项目启动 项 项目启动 | 需求调研 | 解决方案设计与系统实现 | UAT测试与培训 | 上线与运维支持

nlp大模型课程笔记

自然语言处理基础和应用 👆说明之前的大模型其实有很多都是基于迁移学习的方法。 attention机制的总结,解决了信息瓶颈的问题。 处理词组时BPE的过程 👆pos表示的是token所在的位置 👆技巧是layer normalization。

Nexus2迁移升级到Nexus3

与 Nexus 2.x 相比,Nexus 3.x 为我们提供了更多实用的新特性。SonaType 官方建议我们,使用最新版本 Nexus 2.x 升级到最新版本 Nexus 3.x,并在 Nexus 升级兼容性 一文中为我们提供了各个版本 Nexus 升级到最新版本 Nexus 3.x 的流程&#xff…

Cloudpods 私有云平台有哪些优势?

作为一套完整的私有云管理软件,我们经常会被问到 Cloudpods 和其他的同类产品相比,有哪些优势?我总结了 2 个方面,供大家参考。 功能方面 产品化,开箱即用,易用性较高,基本上都可以傻瓜式的操…

Future

Future Future接口由FutureTask 实现类定义了操作异步任务执行的一些方法,比如异步任务的执行结果、取消任务的执行、判断任务是否被取消、判断任务执行是否完毕等。Future 接口可以为主线程开一个分支任务,专门为主线程处理耗时和费力的业务。 Future…

为什么劝年轻人不要频繁跳槽?

这是一个让很多年轻人犯愁的问题,尤其是在现如今竞争激烈的职场环境中。许多年轻人因为各种原因选择频繁跳槽,但是在我看来,这并不是一个明智的选择。下面就让我们来看看为什么劝年轻人不要频繁跳槽。 1. 错失成长机会 每一个工作都有其独特…

7、Spring_AOP

一、Spring AOP 简介 1.概述 对于spring来说,有三大组件,IOC,ID,AOP aop概述:AOP(Aspect Oriented Programming)面向切面编程。 作用:不改变原有代码设计的基础上实现功能增强 例子 传统打印日志 使用…

基于VHDL语言的汽车测速系统设计_kaic

摘 要 汽车是现代交通工具。车速是一项至关重要的指标。既影响着汽车运输的生产率,又关乎着汽车行驶有没有超速违章,还影响着汽车行驶时人们的人身安全。而伴随着我国国民的安全防范意识的逐步增强,人们也开始越来越关心因为汽车的超速而带来的极其严重…

day 29 柱状图

# 导入柱状图的包 from pyecharts.charts import Bar from pyecharts.options import LabelOpts # 创建柱状图对象 bar Bar()# 添加x轴数据 bar.add_xaxis(["中国", "美国", "英国"])# 添加y轴数据# 设置数值标签在又侧 bar.add_yaxis("G…

使用 docker 搭建 granfana+prometheus 监控平台监控测试服务器资源

互联网发展的今天,人们对互联网产品的用户体验要求也越来越高,企业为了能提供更优质的用户体验,就会绞尽脑汁想尽各种办法。而对于服务器的资源监控,搭建一个资源监控平台,就是一个很好的维护优质服务的保障平台。利用…

LLMs之Code:SQLCoder的简介、安装、使用方法之详细攻略

LLMs之Code:SQLCoder的简介、安装、使用方法之详细攻略 目录 SQLCoder的简介 1、结果 2、按问题类别的结果 SQLCoder的安装 1、硬件要求 2、下载模型权重 3、使用SQLCoder 4、Colab中运行SQLCoder 第一步,配置环境 第二步,测试 第…

Mac Flutter web环境搭建

获取 Flutter SDK 下载以下安装包来获取最新的 stable Flutter SDK将文件解压到目标路径, 比如: cd ~/development $ unzip ~/Downloads/flutter_macos_3.13.0-stable.zip 配置 flutter 的 PATH 环境变量: export PATH"$PATH:pwd/flutter/bin" // 这个命…

【1++的数据结构】之AVL树

👍作者主页:进击的1 🤩 专栏链接:【1的数据结构】 文章目录 一,什么是AVL树二,AVL树的插入三,AVL树的旋转3.1 向左旋转3.2 向右旋转3.3 左右双旋3.4 右左双旋 四,验证AVL树是否平衡 …

LinkedList的顶级理解

目录 1.LinkedList的介绍 LinkedList的结构 2.LinkedList的模拟实现 2.1创建双链表 2.2头插法 2.3尾插法 2.4任意位置插入 2.5查找关键字 2.6链表长度 2.7遍历链表 2.8删除第一次出现关键字为key的节点 2.9删除所有值为key的节点 2.10清空链表 2.11完整代码 3.…

①matlab的命令掌握

目录 输入命令 命名变量 保存和加载变量 使用内置的函数和常量 输入命令 1.您可以通过在命令行窗口中 MATLAB 提示符 (>>) 后输入命令 任务 使用命令 3*5 将数值 3 和 5 相乘。 答案 3*5 2.除非另有指定,否则 MATLAB 会将计算结果存储在一个名为 ans…

POI groupRow 折叠分组,折叠部分不显示问题

折叠组是什么?如图就是用POI 实现的,代码很简单:sheet.groupRow(开始行,结束行)即可 但是万万没想到,最终实现出的结果,合并的组,有一部分并没有渲染出来,如下图: 因为我…

基于蜜獾算法优化的BP神经网络(预测应用) - 附代码

基于蜜獾算法优化的BP神经网络(预测应用) - 附代码 文章目录 基于蜜獾算法优化的BP神经网络(预测应用) - 附代码1.数据介绍2.蜜獾优化BP神经网络2.1 BP神经网络参数设置2.2 蜜獾算法应用 4.测试结果:5.Matlab代码 摘要…

Android——基本控件(下)(十九)

1. 菜单:Menu 1.1 知识点 (1)掌握Android中菜单的使用; (2)掌握选项菜单(OptionsMenu)的使用; (3)掌握上下文菜单(ContextMenu&am…