
文档教程人工智能【免费下载链接】AISystemAISystem 主要是指AI系统包括AI芯片、AI编译器、AI推理和训练框架等AI全栈底层技术项目地址https://gitcode.com/GitHub_Trending/ai/AISystem点击查看免费下载本篇文章围绕 AISystem 仓库中模型轻量化主题下的 GhostNet 系列展开深入讲解 GhostNet V1 的 Ghost Module、Ghost bottleneck 与网络结构设计以及 GhostNet V2 引入的解耦全连接注意力DFC attention如何在不明显增加计算量的前提下增强轻量模型的表达能力。读完本文你将掌握 GhostNet 两代模型的数学原理、复杂度推导、完整 PyTorch 代码实现以及它在移动端/端侧推理场景中比传统卷积更省算力的设计动机并能在现有 CNN 中直接复用 Ghost Module 做即插即用的轻量化改造。GhostNet V1用廉价线性变换生成冗余特征图GhostNet V1的核心贡献是提出了一个全新的Ghost Module通过一组原始特征图应用一系列廉价的线性变换cheap linear operations以很小的代价生成许多能从原始特征中发掘所需信息的 Ghost 特征图。该模块即插即用通过堆叠 Ghost Module 构成 Ghost bottleneck进而搭建出轻量级神经网络 GhostNet。在 ImageNet 分类任务中GhostNet 在相似计算量情况下 Top-1 正确率达到 75.7%高于 MobileNetV3 的 75.2%——需要说明的是该数据来自原论文与本文档的陈述实际部署效果以具体训练配置与硬件环境为准。这一设计的出发点在于深度卷积神经网络通常由大量卷积层组成导致巨大的计算成本。尽管 MobileNet、ShuffleNet 等早期工作引入了深度卷积DWConv或混洗操作来构建更高效的 CNN但其余的 1×1 卷积层仍然占用大量内存和 FLOPs。更重要的是主流 CNN 计算出的中间特征图存在大量冗余其中许多特征彼此相似。既然这些冗余特征不需要一一生成那么就没有必要为它们付出同等的计算代价——这正是 Ghost Module 的核心思想。卷积的数学表达与冗余现象给定输入数据 $X∈R^{c \times h \times w}$其中 c 是输入通道数h 和 w 是输入的高度与宽度用于生成 n 个特征图的任意卷积层运算可表示为$$ YX*fb $$其中 $*$ 是卷积运算$b$ 是偏差项$Y∈R^{h\times w\times n}$ 是具有 n 个通道的输出特征图$f∈R^{c\times k\times k\times n}$ 是这一层的卷积核$h$ 和 $w$ 是输出特征图的高度和宽度$k\times k$ 是卷积核 f 的内核大小。在此卷积过程中由于卷积核数量 n 和通道数 c 通常非常大例如 256 或 512所需的 FLOPs 数量高达 $n \cdot h \cdot w \cdot c \cdot k \cdot k$。从公式可以看出需要优化的参数量f 和 b 中的参数由输入和输出特征图的尺寸共同决定。而实际观察卷积层的输出特征图可以发现其中包含大量冗余部分特征之间彼此相似。因此作者提出没有必要使用大量的 FLOPs 和参数一一生成这些冗余特征图——这些原始特征图通常尺寸较小可以由普通卷积核先生成再通过廉价操作派生出其余特征图。Ghost Module 的两阶段生成过程具体来说首先用一次普通卷积生成 $m$ 个原始特征图 $Y∈R^{h\times w\times m}$$$ YX*f $$其中 $f∈R^{c\times k\times k\times m}$ 是使用的卷积核且 $m\leq n$为简单起见省略了偏差项。这里的超参数卷积核大小、stride、padding与普通卷积保持一致以维持输出特征图的空间尺寸即 $h$ 和 $w$不变。为了进一步获得所需的 n 个特征图作者对 $Y$ 中的每个原始特征图应用一系列廉价的线性运算以生成 s 个 Ghost 特征图$$ y_{ij}\Phi_{i,j}(y_{i}),\ \forall i1,...,m,\ j1,...,s $$其中 $y{i}$ 是 $Y$ 中第 i 个原始特征图$\Phi{i,j}$ 是生成第 j 个特征图 $y_{ij}$ 的第 j 个线性运算也就是说 $y{i}$ 可以产生一个或多个特征图 ${y{i,j}}^{s}{j1}$。最后一个 $\Phi{i,s}$ 是恒等映射用于保留原始特征图。通过该操作我们可以获得 $nm\cdot s$ 个特征图 $Y[y_{11},y_{12},...,y_{ms}]$ 作为 Ghost Module 的输出。注意线性运算 $\Phi$ 在每个通道上独立运行其计算量比普通卷积少得多。实践中一个 Ghost Module 内可以容纳多种不同的线性运算。整个流程可以归纳为三步普通卷积primary conv先用常规卷积生成少量原始特征图廉价操作cheap operation对原始特征图做线性变换代码实现中采用 DW 卷积生成冗余特征图拼接concat将普通卷积生成的特征图与廉价操作生成的特征图沿通道维拼接得到最终输出。如结构对比图08Ghostnet01.png所示普通卷积直接由输入特征图卷积得到输出特征图而 Ghost Module 先做一次常规卷积得到少量特征再通过线性变换生成其余特征并合并。利用 Ghost Module 生成与普通卷积层相同数量的特征图就可以轻松地将 Ghost Module 替换任意卷积层集成到现有设计好的神经网络结构中从而减少计算成本。复杂度分析理论加速比与参数压缩比Ghost Module 包含一个恒等映射和 $m\cdot(s-1)\frac{n}{s}\cdot(s-1)$ 个线性运算每个线性运算的平均内核大小为 $d\times d$。理想情况下这些线性运算可以拥有不同的形状和参数但考虑到 CPU/GPU 的在线推理实用性作者建议在一个 Ghost Module 中采用相同大小的线性运算以便高效实现。使用 Ghost Module 升级普通卷积的理论加速比为$$ r_{s}\frac{n\cdot h\cdot w\cdot c\cdot k\cdot k}{\frac{n}{s}\cdot h\cdot w\cdot c\cdot k\cdot k (s-1)\cdot \frac{n}{s}\cdot h\cdot w\cdot d\cdot d} $$$$ \frac{c\cdot k\cdot k}{\frac{1}{s}\cdot c\cdot k\cdot k\frac{s-1}{s}\cdot d\cdot d}\approx\frac{s\cdot c}{sc-1}\approx s $$其中 $d\times d$ 的幅度与 $k\times k$ 相似且 $s\ll c$。同理参数压缩比可计算为$$ r_{c}\frac{n\cdot c\cdot k\cdot k}{\frac{n}{s}\cdot c\cdot k\cdot k(s-1)\cdot \frac{n}{s}\cdot d\cdot d}\approx\frac{s\cdot c}{sc-1}\approx s $$从推导结果看当 s 远小于通道数 c 时理论加速比和参数压缩比都近似等于 s例如 s2 时理论上可压缩约一半。值得注意的是GhostNet 的方法本身并不复杂——本质上是将原本的一次大卷积拆成一次小卷积 一次廉价线性变换两次乘法相加而代码实现中第二个变换正是用 depthwise conv 完成的。作者在论文中也提到前面的卷积使用 pointwise 卷积效率更高因此整个网络的结构类似一个 MobileNet 的反转版本只不过 GhostNet 采用拼接concat的方式进一步减少了计算量。Ghost Module 的 PyTorch 实现下面给出本文档对应的 Ghost Module 实现。核心要点是先将输出通道拆分为intrinsic_channels out_channels // s和ghost_channels intrinsic_channels * (s - 1)前者由普通卷积kernel_size1 的 pointwise生成后者由分组数等于输入通道数的 DW 卷积生成最后沿通道维拼接。# Ghost 模块以普通卷积和 DW 卷积组合而成 class GhostModule(nn.Module): def __init__(self, in_channels, out_channels, s2, kernel_size1, stride1, use_reluTrue): super(GhostModule, self).__init__() intrinsic_channels out_channels // s ghost_channels intrinsic_channels * (s - 1) self.primary_conv nn.Sequential( nn.Conv2d(in_channelsin_channels, out_channelsintrinsic_channels, kernel_sizekernel_size, stridestride, paddingkernel_size // 2, biasFalse), nn.BatchNorm2d(intrinsic_channels), nn.ReLU(inplaceTrue) if use_relu else nn.Sequential() ) self.cheap_op DW_Conv3x3BNReLU(in_channelsintrinsic_channels, out_channelsghost_channels, stridestride, groupsintrinsic_channels) def forward(self, x): y self.primary_conv(x) z self.cheap_op(y) out torch.cat([y, z], dim1) return out从实现可见s即论文中的 s默认 2直接决定了通道拆分比例是控制 Ghost Module 压缩强度的核心超参数kernel_size默认取 1即 primary conv 采用 pointwise 卷积这也是作者强调的前面用 pointwise 效率比较高的体现cheap_op使用 3×3、groupsintrinsic_channels的 DWConv对应论文中在每个通道上运行、计算量远小于普通卷积的线性运算描述。理解这一点后可以顺带回顾仓库中 MobileNet 系列文档 对 DW/PW 卷积的拆分讲解——Ghost Module 正是在深度可分离卷积思路上进一步剪掉冗余特征生成开销的演进。Ghost bottleneck轻量级残差瓶颈块Ghost bottleneck 与 ResNet 中的基本残差块Basic Residual Block结构相似可以理解为将 Basic Residual Block 中的卷积操作替换为 Ghost Module 得到的变体。它主要由两个堆叠的 Ghost Module 组成第一个 Ghost Module 用于增加通道数第二个 Ghost Module 用于减少通道数以与 shortcut 路径匹配然后使用 shortcut 连接这两个 Ghost Module 的输入与输出。设计细节上这里借鉴了 MobileNetV2 的实践第二个 Ghost Module 之后不使用 ReLU 激活函数其他层在每层之后都应用批量归一化BN和 ReLU 非线性激活。作者设计了两种 Ghost bottleneck分别对应 stride1 与 stride2 两种情况其结构如 08Ghostnet02.png 所示。stride1 的 Ghost bottleneck左图主干通路由两个 Ghost Module 串联组成其中第一个 Ghost Module 扩大通道数第二个 Ghost Module 将通道数降低到与输入通道数一致残差边部分与 ResNet 一样直接相加。由于 stride1不会压缩输入特征图的高和宽其功能是加深网络深度。stride2 的 Ghost bottleneck右图主干通路的两个 Ghost Module 之间加入一个 stride2 的 DWConv将特征图的高和宽压缩为输入的 1/2残差边部分也添加一个步长为 2 的 DWConv 和 1×1 的 PWConv以保证 Add 操作时两侧尺寸对齐。该模块可以用来替换其他 CNN 中的下采样层步长 2。出于效率考虑Ghost Module 中的所有标准卷积都用 PWConv 代替。# Ghost 瓶颈层实现 class GhostBottleneck(nn.Module): def __init__(self, in_channels, mid_channels, out_channels, kernel_size, stride, use_se, se_kernel_size1): super(GhostBottleneck, self).__init__() self.stride stride self.bottleneck nn.Sequential( GhostModule(in_channelsin_channels, out_channelsmid_channels, kernel_size1, use_reluTrue), DW_Conv3x3BNReLU(in_channelsmid_channels, out_channelsmid_channels, stridestride, groupsmid_channels) if self.stride 1 else nn.Sequential(), SqueezeAndExcite(mid_channels, mid_channels, se_kernel_size) if use_se else nn.Sequential(), GhostModule(in_channelsmid_channels, out_channelsout_channels, kernel_size1, use_reluFalse) ) if self.stride 1: self.shortcut DW_Conv3x3BNReLU(in_channelsin_channels, out_channelsout_channels, stridestride) else: self.shortcut nn.Conv2d(in_channelsin_channels, out_channelsout_channels, kernel_size1, stride1) def forward(self, x): out self.bottleneck(x) residual self.shortcut(x) out residual return out实现中的几个关键点mid_channels是 bottleneck 中间层的通道数对应论文中第一个 Ghost Module 扩通道、第二个 Ghost Module 降通道的职责划分stride 1时主干中间插入带 stride 的 DWConv 完成下采样shortcut 侧同样用带 stride 的 DWConv BN 对齐尺寸use_se开关用于决定是否在瓶颈中间插入 Squeeze-and-Excitation 模块对应原论文中SE 模块用在某些 Ghost bottleneck 的残留层。GhostNet 网络整体结构GhostNet 主要由一堆 Ghost bottleneck 堆叠而成其中 Ghost bottleneck 以 Ghost Module 为构建基础。其网络结构要点如下第一层是带有 16 个卷积核的标准卷积层然后接一系列 Ghost bottleneck通道数逐渐增加这些 Ghost bottleneck 根据其输入特征图的大小分为不同阶段除每个阶段最后一个 Ghost bottleneck 采用 stride2 外其余 Ghost bottleneck 均以 stride1 应用最后利用全局平均池化和卷积层将特征图转换为 1280 维特征向量用于最终分类SE 模块也用在了某些 Ghost bottleneck 的残留层中与 MobileNetV3 相比这里用 ReLU 换掉了 Hard-swish 激活函数。作者也指出进一步的超参数调整或基于自动架构搜索NAS的 Ghost 模块有望进一步提升性能。对于端侧推理引擎而言仓库 推理系统概述 中将其归入轻量网络课程模块GhostNet 这种标准卷积 DW 卷积拼接的结构对 TFLite、ncnn、MNN 等移动端推理框架天然友好易于在低算力设备上获得更好的延迟表现。GhostNet V2引入解耦全连接注意力DFC AttentionGhostNet V2的主要工作是在 Ghost Module 的基础上添加了一个改进的注意力块——DFCDecoupled Fully Connected解耦全连接注意力。它不仅在普通硬件上可以快速执行还能捕获远程像素之间的依赖关系。大量实验表明 GhostNetV2 优于现有体系结构。例如它在 167M FLOPs 计算量下于 ImageNet 上实现了 75.3% 的 Top-1 精度显著高于 GhostNetV1 的 74.5%而计算成本相似数据来自原论文与本文档陈述。需要特别强调的是GhostNet V1/V2 的演进方向与本仓库模型小型化主题一脉相承V1 解决如何用更少计算生成同等数量特征图V2 解决在轻量前提下如何恢复被压缩掉的空间表达力。从自注意力到 DFC复杂度从 O(H²W²) 降到 O(H²WHW²)虽然自注意力操作可以很好地建模长距离依赖但其部署效率低。相比自注意力机制具有固定权重的 FC 层更简单、更容易实现也可以用于生成具有全局感受野的 attention maps。给定特征图 $Z∈R^{H\times W\times C}$它可以看作 hw 个 tokens记作 $z_{i}\in R^{C}$即 $Z{z_{11},z_{12},...,z_{hw}}$。FC 层生成 attention map 的公式表达如下$$ a_{hw}\sum_{h,w}F_{h,w,h,w}\odot z_{h,w} \tag{1} $$其中 $\odot$ 表示 element-wise multiplicationF 是 FC 层中可学习的权重$A{a_{11},a_{12},...,a_{HW}}$。根据上述公式将所有 tokens 与可学习权重聚合以提取全局信息该过程比经典自注意力简单得多。然而该过程的计算复杂度仍然是二次方的特征图大小的复杂度为 $\mathcal{O}(H^{2}W^{2})$在实际场景中不可接受尤其是当输入图像为高分辨率时。例如对于一个 4 层的 GhostNet 网络特征图具有 313656×56个 tokens这使得 attention maps 的计算异常复杂。实际上CNN 中的特征图通常是低秩的并不需要将不同空间位置的所有输入和输出 tokens 密集连接。特征的 2D 尺寸很自然地提供了一个视角来减少 FC 层的计算量将上述公式分解为两个 FC 层分别沿水平方向和垂直方向聚合特征公式表达如下$$ a{hw}\sum{h1}^{H}F^{H}{h,h,w}\odot z{h,w},\quad h1,2,...,H,\ w1,2,...,W \tag{2} $$$$ a_{hw}\sum_{w1}^{W}F^{W}{w,h,w}\odot z{h,w},\quad h1,2,...,H,\ w1,2,...,W \tag{3} $$其中 $F^{H}$ 和 $F^{W}$ 是变换的权重。输入原始特征 Z依次应用公式 (2) 和公式 (3)分别提取沿两个方向的长距离依赖关系。作者将此操作称为解耦全连接注意力DFC attention其信息流如 08Ghostnet03.png 所示输入特征经下采样后先经过垂直方向全连接Vertical FC聚合垂直上下文再经过水平方向全连接Horizontal FC聚合水平上下文最终上采样得到注意力图。由于水平和垂直方向变换的解耦注意力模块的计算复杂度可以降低到 $\mathcal{O}(H^{2}WHW^{2})$。对于 full attention公式 1正方形区域内的所有 patches 直接参与被聚合 patch 的计算而在 DFC attention 中一个 patch 直接由其垂直方向和水平方向上的 patches 聚合其他 patch 则参与垂直线/水平线上的 patch 的生成与被聚合的 token 构成间接关系。因此一个 patch 的计算最终也涉及正方形区域内的所有 patches。公式 (2) 和公式 (3) 是 DFC attention 的一般表示分别沿水平和垂直方向聚合像素。通过共享部分变换权重可以方便地使用卷积操作实现从而省去影响实际推理速度的耗时张量 reshape 和 transpose 操作。为了处理不同分辨率的输入图像卷积核的大小可以与特征图的大小解耦——即在输入特征上依次进行两个大小分别为 $1\times K_{H}$ 和 $K_{W}\times 1$ 的 DWConv 操作。当用卷积实现时DFC attention 的理论计算复杂度为 $\mathcal{O}(K_{H}HWK_{W}HW)$。这种策略得到了 TFLite 和 ONNX 等工具的良好支持可以在移动设备上进行快速推理。Ghost Module V2在廉价变换之外增加注意力旁路下面给出 GhostModuleV2 的实现。与 V1 相比它在modeattn分支中新增了short_conv注意力旁路该旁路先用 1×1 卷积把输入变换到输出通道数再做两组分组卷积(1,5)与(5,1)的条形核分别聚合水平与垂直方向上下文这正是 DFC attention 的卷积化实现前向时注意力旁路在 2×2 平均池化降采样后的特征上计算门控信号再上采样回原分辨率与主分支输出逐元素相乘。class GhostModuleV2(nn.Module): def __init__(self, inp, oup, kernel_size1, ratio2, dw_size3, stride1, reluTrue, modeNone, argsNone): super(GhostModuleV2, self).__init__() self.mode mode self.gate_fn nn.Sigmoid() if self.mode in [original]: self.oup oup init_channels math.ceil(oup / ratio) new_channels init_channels * (ratio - 1) self.primary_conv nn.Sequential( nn.Conv2d(inp, init_channels, kernel_size, stride, kernel_size // 2, biasFalse), nn.BatchNorm2d(init_channels), nn.ReLU(inplaceTrue) if relu else nn.Sequential(), ) self.cheap_operation nn.Sequential( nn.Conv2d(init_channels, new_channels, dw_size, 1, dw_size // 2, groupsinit_channels, biasFalse), nn.BatchNorm2d(new_channels), nn.ReLU(inplaceTrue) if relu else nn.Sequential(), ) elif self.mode in [attn]: self.oup oup init_channels math.ceil(oup / ratio) new_channels init_channels * (ratio - 1) self.primary_conv nn.Sequential( nn.Conv2d(inp, init_channels, kernel_size, stride, kernel_size // 2, biasFalse), nn.BatchNorm2d(init_channels), nn.ReLU(inplaceTrue) if relu else nn.Sequential(), ) self.cheap_operation nn.Sequential( nn.Conv2d(init_channels, new_channels, dw_size, 1, dw_size // 2, groupsinit_channels, biasFalse), nn.BatchNorm2d(new_channels), nn.ReLU(inplaceTrue) if relu else nn.Sequential(), ) self.short_conv nn.Sequential( nn.Conv2d(inp, oup, kernel_size, stride, kernel_size // 2, biasFalse), nn.BatchNorm2d(oup), nn.Conv2d(oup, oup, kernel_size(1, 5), stride1, padding(0, 2), groupsoup, biasFalse), nn.BatchNorm2d(oup), nn.Conv2d(oup, oup, kernel_size(5, 1), stride1, padding(2, 0), groupsoup, biasFalse), nn.BatchNorm2d(oup), ) def forward(self, x): if self.mode in [original]: x1 self.primary_conv(x) x2 self.cheap_operation(x1) out torch.cat([x1, x2], dim1) return out[:, :self.oup, :, :] elif self.mode in [attn]: res self.short_conv(F.avg_pool2d(x, kernel_size2, stride2)) x1 self.primary_conv(x) x2 self.cheap_operation(x1) out torch.cat([x1, x2], dim1) return out[:, :self.oup, :, :] * F.interpolate(self.gate_fn(res), size(out.shape[-2], out.shape[-1]), modenearest)实现细节说明ratio对应 V1 中的s控制通道拆分modeoriginal与 V1 的 Ghost Module 行为一致modeattn时short_conv中kernel_size(1,5)与(5,1)的条形卷积即 $1\times K_{H}$ 与 $K_{W}\times 1$ 两个 DWConv 的落点注意力旁路在 2×2 池化降采样的小特征图上计算再最近邻上采样回原尺寸与对 DFC 支路特征下采样以减小计算量的设计一致最终通过 Sigmoid 门控与主分支逐元素相乘输出。增强 Ghost Module双分支并行信息聚合Ghost Module 中只有 m 个特征与其他像素交互这影响了 Ghost Module 提取空间信息spatial information的能力。因此作者使用 DFC attention 来增强 Ghost Module 的输出特征 Y从而捕获不同空间像素之间的长距离依赖关系。输入特征 $X∈R^{h\times w\times c}$ 被送入两个分支一个是 Ghost Module 分支用于输出特征 Y另一个是 DFC attention Module 分支用于生成 attention map A。回顾经典自注意力中线性变换层将输入特征图转换为计算 attention maps 的 query 和 key的做法作者也实现一个 1×1 卷积将 Ghost Module 分支的输入 X 变换为 DFC Module 分支的输入 Z。两个分支输出的乘积即为最终输出 $O∈R^{H\times W\times C}$可以表示为$$ O Sigmoid(A)\odot V(X) $$其中 $\odot$ 表示 element-wise multiplicationA 是 attention mapSigmoid 是归一化函数用于将注意力值缩放到 (0, 1) 范围$V()$ 表示 Ghost ModuleX 为输入特征。信息聚合过程如 08Ghostnet04.png 所示输入特征分为两个并行分支——Ghost 分支与注意力分支两个分支的对应特征做逐元素乘法Multiply最终融合得到输出特征。使用相同的输入特征Ghost Module 和 DFC attention 是两个从不同角度提取信息的并行分支。输出特征是它们的逐元素乘积其中既包含来自 Ghost Module 的特征也包含来自 DFC attention 的信息。每个 attention value 都涉及大范围的 patches因此输出特征能够包含这些 patches 的信息轻量模型的表达能力因此得到显著增强。GhostBottleneck V2增强逆 bottleneck 的中间表达为了减小 DFC attention 模块所消耗的计算量本文对 DFC 这条支路上的特征进行下采样在更小的特征图上执行一系列变换。同时作者发现对逆 bottleneckinverted bottleneck结构而言增强expressivenessbottleneck 中间层比增强capacitybottleneck 输出层更加有效因此 GhostNetV2 只对中间特征做了增强。GhostNetV2 的 bottleneck 结构如 08Ghostnet05.png 所示——图中对比展示了 GhostNetV1 与 GhostNetV2 在 stride1 与 stride2 两种情形下的 bottleneckV2 版本在 Ghost 模块基础上并联 DFC attention 分支并对 DFC 支路做下采样以控制开销。class GhostBottleneckV2(nn.Module): def __init__(self, in_chs, mid_chs, out_chs, dw_kernel_size3, stride1, act_layernn.ReLU, se_ratio0., layer_idNone, argsNone): super(GhostBottleneckV2, self).__init__() has_se se_ratio is not None and se_ratio 0. self.stride stride # Point-wise expansion if layer_id 1: self.ghost1 GhostModuleV2(in_chs, mid_chs, reluTrue, modeoriginal, argsargs) else: self.ghost1 GhostModuleV2(in_chs, mid_chs, reluTrue, modeattn, argsargs) # Depth-wise convolution if self.stride 1: self.conv_dw nn.Conv2d(mid_chs, mid_chs, dw_kernel_size, stridestride, padding(dw_kernel_size - 1) // 2, groupsmid_chs, biasFalse) self.bn_dw nn.BatchNorm2d(mid_chs) # Squeeze-and-excitation if has_se: self.se SqueezeExcite(mid_chs, se_ratiose_ratio) else: self.se None self.ghost2 GhostModuleV2(mid_chs, out_chs, reluFalse, modeoriginal, argsargs) # shortcut if (in_chs out_chs and self.stride 1): self.shortcut nn.Sequential() else: self.shortcut nn.Sequential( nn.Conv2d(in_chs, in_chs, dw_kernel_size, stridestride, padding(dw_kernel_size - 1) // 2, groupsin_chs, biasFalse), nn.BatchNorm2d(in_chs), nn.Conv2d(in_chs, out_chs, 1, stride1, padding0, biasFalse), nn.BatchNorm2d(out_chs), ) def forward(self, x): residual x x self.ghost1(x) if self.stride 1: x self.conv_dw(x) x self.bn_dw(x) if self.se is not None: x self.se(x) x self.ghost2(x) x self.shortcut(residual) return x实现要点layer_id 1的前两层使用不带注意力的modeoriginal的 Ghost Module更深的层layer_id 1则使用modeattn的增强版本——这正是只对中间特征做增强、控制 DFC 计算量的策略在代码层面的体现mid_chs是逆 bottleneck 的中间通道数增强发生在这一层ghost1输出的中间表达上stride 1时在中间插入 stride2 的 DWConv 完成下采样shortcut 侧则用 DWConv 1×1 卷积对齐尺寸se_ratio控制是否插入 SE 模块。小结与思考GhostNetV1 提出了一个即插即用的模块能将原始模型转为更轻量的模型GhostNetV2 在此基础上更关注硬件友好性并提出了一种新的适用于移动应用的架构。GhostNetV2 提出的 DFC 注意力方法可以捕捉长距离空间位置中像素之间的相关性这显著增强了轻量级模型的表达能力以较低的计算成本实现了较高的性能。从仓库模型小型化课程的整体脉络看见 02Mobilenet READMEGhostNet 与 SqueezeNet、ShuffleNet、MobileNet、EfficientNet 等构成完整的 CNN 轻量化演进谱系GhostNet 的普通卷积 DW 卷积拼接结构与 MobileNet 的深度可分离卷积一脉相承而 V2 的 DFC attention 又为轻量网络如何低成本引入全局上下文提供了新的设计范式对后续移动端视觉模型的工程实现具有直接参考价值。赞分享文档教程人工智能【免费下载链接】AISystemAISystem 主要是指AI系统包括AI芯片、AI编译器、AI推理和训练框架等AI全栈底层技术项目地址https://gitcode.com/GitHub_Trending/ai/AISystem点击查看免费下载相关推荐BrewUI FakeBrew 深入假 brew 测试替身的 4 个设计亮点让 UI 测试彻底确定化BrewUI FakeBrew 深入假 brew 测试替身的 4 个设计亮点让 UI 测试彻底确定化 BrewUI 是 Homebrew 的官方 macOS文档教程人工智能AISystem 轻量级 CNN 模型小型化实战指南SqueezeNet、ShuffleNet 与 MobileNet 架构解析AISystem 轻量级 CNN 模型小型化实战指南SqueezeNet、ShuffleNet 与 MobileNet 架构解析 本篇技术指南以 AISyst文档教程人工智能轻量级网络浅析MobileNet、GhostNet等高效模型在L0CV中的实现轻量级网络浅析MobileNet、GhostNet等高效模型在L0CV中的实现 在当今移动设备和边缘计算蓬勃发展的时代轻量级神经网络已成为计算机视觉领域的关计算机视觉深度学习机器学习教程示例工程上一篇智慧树刷课插件终极指南3步实现自动化学习效率提升40%下一篇终极智慧树刷课插件5分钟实现视频自动播放与智能学习加速创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考