轻量化网络——ghostnet代码讲解

[目标检测]-cv常用模块ghostbottleneck原理讲解与pytorch实现 1.ghostnet简介 Ghostnet是华为诺亚方舟实验室今年在CVPR2020上新发表的文章《GhostNet: More Features from Cheap Operations》中提出的一种新型的网络结构,他的核心思想就是设计一种分阶段的卷积计算模块,在少量的非线性的卷积得到的特征图基础上,在进行一次线性卷积,从而获取更多的特征图,而新的到的特征图,就被叫做之前特征图的‘ghost’,以此来实现消除冗余特征,获取更加轻量的模型。 论文题名:《GhostNet: More Features fr 阅读详情

背景

神经网络在移动设备上的应用还亟待解决,主要原因是现有模型又大又慢。因而,一些研究提出了模型的压缩方法,比如剪枝、量化、知识蒸馏等;还有一些则着重于高效的网络结构设计,比如MobileNet,ShuffleNet等。本文就设计了一种全新的神经网络基本单元Ghost模块,从而搭建出轻量级神经网络架构GhostNet。
在一个训练好的深度神经网络中,通常会包含丰富甚至冗余的特征图,以保证对输入数据有全面的理解。如下图所示,在ResNet-50中,将经过第一个残差块处理后的特征图拿出来,三个相似的特征图对示例用相同颜色的框注释。 该对中的一个特征图可以通过廉价操作(用扳手表示)将另一特征图变换而获得,可以认为其中一个特征图是另一个的“幻影”。因为,本文提出并非所有特征图都要用卷积操作来得到,“幻影”特征图可以用更廉价的操作来生成。

在这里插入图片描述

Ghost Module

在这里插入图片描述

如上图左边是传统卷积,右边是Ghost模块,作者认为深度卷积神经网络通常引用由大量卷积组成的卷积神经网络,导致大量的计算成本。尽管最近的工作,例如MobileNet和ShuffleNet引入了深度卷积或混洗操作,以使用较小的卷积核(浮点运算)来构建有效的CNN,其余 1x1 卷积层仍将占用大量内存和FLOPs。
代码实现

class GhostModule(nn.Module):
    def __init__(self, inp, oup, kernel_size=1, ratio=2, dw_size=3, stride=1, relu=True):
        super(GhostModule, self).__init__()
        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, bias=False),
            nn.BatchNorm2d(init_channels),
            nn.ReLU(inplace=True) if relu else nn.Sequential(),
        )

        self.cheap_operation = nn.Sequential(
            nn.Conv2d(init_channels, new_channels, dw_size, 1, dw_size//2, groups=init_channels, bias=False),
            nn.BatchNorm2d(new_channels),
            nn.ReLU(inplace=True) if relu else nn.Sequential(),
        )

    def forward(self, x):
        x1 = self.primary_conv(x)
        x2 = self.cheap_operation(x1)
        out = torch.cat([x1,x2], dim=1)
        return out[:,:self.oup,:,:]

通过分析代码可以看出,self.primary_conv先对输入进行1x1卷积,得到x1,x1的通道数是原来的一半,之后在进行深度可分离卷积,输出值为x2,输出通道数同样是x的通道数的一半,然后x1和x2 在通道上进行堆叠。
什么是深度可分离呢?
在这里插入图片描述

Ghost Bottleneck

Ghost Bottleneck:利用Ghost模块的优势,作者介绍了专门为小型CNN设计的Ghost bottleneck(G-bneck)。如下图所示,Ghost bottleneck似乎类似于ResNet中的基本残差块(Basic Residual Block),其中集成了多个卷积层和shortcut。Ghost bottleneck主要由两个堆叠的Ghost模块组成。第一个Ghost模块用作扩展层,增加了通道数。这里将输出通道数与输入通道数之比称为expansion ratio。第二个Ghost模块减少通道数,以与shortcut路径匹配。然后,使用shortcut连接这两个Ghost模块的输入和输出。这里借鉴了MobileNetV2,第二个Ghost模块之后不使用ReLU,其他层在每层之后都应用了批量归一化(BN)和ReLU非线性激活。上述Ghost bottleneck适用于stride= 1,对于stride = 2的情况,shortcut路径由下采样层和stride = 2的深度卷积(Depthwise Convolution)来实现。出于效率考虑,Ghost模块中的初始卷积是点(1x1)卷积(Pointwise Convolution)。

在这里插入图片描述

代码实现

class GhostNet(nn.Module):
    def __init__(self, cfgs, num_classes=1000, width=1.0, dropout=0.2):
        super(GhostNet, self).__init__()
        # setting of inverted residual blocks
        self.cfgs = cfgs
        self.dropout = dropout

        # building first layer
        output_channel = _make_divisible(16 * width, 4)
        self.conv_stem = nn.Conv2d(3, output_channel, 3, 2, 1, bias=False)
        self.bn1 = nn.BatchNorm2d(output_channel)
        self.act1 = nn.ReLU(inplace=True)
        input_channel = output_channel

        # building inverted residual blocks
        stages = []
        block = GhostBottleneck
        for cfg in self.cfgs:
            layers = []
            for k, exp_size, c, se_ratio, s in cfg:
                output_channel = _make_divisible(c * width, 4)
                hidden_channel = _make_divisible(exp_size * width, 4)
                layers.append(block(input_channel, hidden_channel, output_channel, k, s,
                              se_ratio=se_ratio))
                input_channel = output_channel
            stages.append(nn.Sequential(*layers))

        output_channel = _make_divisible(exp_size * width, 4)
        stages.append(nn.Sequential(ConvBnAct(input_channel, output_channel, 1)))
        input_channel = output_channel
        
        self.blocks = nn.Sequential(*stages)        

        # building last several layers
        output_channel = 1280
        self.global_pool = nn.AdaptiveAvgPool2d((1, 1))
        self.conv_head = nn.Conv2d(input_channel, output_channel, 1, 1, 0, bias=True)
        self.act2 = nn.ReLU(inplace=True)
        self.classifier = nn.Linear(output_channel, num_classes)

    def forward(self, x):
        x = self.conv_stem(x)
        x = self.bn1(x)
        x = self.act1(x)
        x = self.blocks(x)
        x = self.global_pool(x)
        x = self.conv_head(x)
        x = self.act2(x)
        x = x.view(x.size(0), -1)
        if self.dropout > 0.:
            x = F.dropout(x, p=self.dropout, training=self.training)
        x = self.classifier(x)
        return x


def ghostnet(**kwargs):
    """
    Constructs a GhostNet model
    """
    cfgs = [
        # k, t, c, SE, s 
        # stage1
        [[3,  16,  16, 0, 1]],
        # stage2
        [[3,  48,  24, 0, 2]],
        [[3,  72,  24, 0, 1]],
        # stage3
        [[5,  72,  40, 0.25, 2]],
        [[5, 120,  40, 0.25, 1]],
        # stage4
        [[3, 240,  80, 0, 2]],
        [[3, 200,  80, 0, 1],
         [3, 184,  80, 0, 1],
         [3, 184,  80, 0, 1],
         [3, 480, 112, 0.25, 1],
         [3, 672, 112, 0.25, 1]
        ],
        # stage5
        [[5, 672, 160, 0.25, 2]],
        [[5, 960, 160, 0, 1],
         [5, 960, 160, 0.25, 1],
         [5, 960, 160, 0, 1],
         [5, 960, 160, 0.25, 1]
        ]
    ]
    return GhostNet(cfgs, **kwargs)
class GhostBottleneck(nn.Module):
    """ Ghost bottleneck w/ optional SE"""

    def __init__(self, in_chs, mid_chs, out_chs, dw_kernel_size=3,
                 stride=1, act_layer=nn.ReLU, se_ratio=0.):
        super(GhostBottleneck, self).__init__()
        has_se = se_ratio is not None and se_ratio > 0.
        self.stride = stride

        # Point-wise expansion (1x1)
        self.ghost1 = GhostModule(in_chs, mid_chs, relu=True)

        # Depth-wise convolution
        if self.stride > 1:
            self.conv_dw = nn.Conv2d(mid_chs, mid_chs, dw_kernel_size, stride=stride,
                             padding=(dw_kernel_size-1)//2,
                             groups=mid_chs, bias=False)
            self.bn_dw = nn.BatchNorm2d(mid_chs)

        # Squeeze-and-excitation
        if has_se:
            self.se = SqueezeExcite(mid_chs, se_ratio=se_ratio)
        else:
            self.se = None

        # Point-wise linear projection
        self.ghost2 = GhostModule(mid_chs, out_chs, relu=False)
        
        # 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, stride=stride,
                       padding=(dw_kernel_size-1)//2, groups=in_chs, bias=False),
                nn.BatchNorm2d(in_chs),
                nn.Conv2d(in_chs, out_chs, 1, stride=1, padding=0, bias=False),
                nn.BatchNorm2d(out_chs),
            )


    def forward(self, x):
        residual = x

        # 1st ghost bottleneck
        x = self.ghost1(x)

        # Depth-wise convolution
        if self.stride > 1:
            x = self.conv_dw(x)
            x = self.bn_dw(x)
            
        # Squeeze-and-excitation
        if self.se is not None:
            x = self.se(x)

        # 2nd ghost bottleneck
        x = self.ghost2(x)
        
        x += self.shortcut(residual)
        return x

其实引用将所有的内容说明了一切,里面的信息量很大 !

GhostNet

基于Ghost bottleneck,作者提出GhostNet。作者遵循MobileNetV3的基本体系结构的优势,然后使用Ghost bottleneck替换MobileNetV3中的bottleneck。GhostNet主要由一堆Ghost bottleneck组成,其中Ghost bottleneck以Ghost模块为构建基础。第一层是具有16个卷积核的标准卷积层,然后是一系列Ghost bottleneck,通道逐渐增加。这些Ghost bottleneck根据其输入特征图的大小分为不同的阶段。除了每个阶段的最后一个Ghost bottleneck是stride = 2,其他所有Ghost bottleneck都以stride = 1进行应用。最后,利用全局平均池和卷积层将特征图转换为1280维特征向量以进行最终分类。SE模块也用在了某些Ghost bottleneck中的残留层,如表1中所示。与MobileNetV3相比,这里用ReLU换掉了Hard-swish激活函数。尽管进一步的超参数调整或基于自动架构搜索的Ghost模块将进一步提高性能,但表1所提供的架构提供了一个基本设计参考。

在这里插入图片描述

下面是mobileNet V3网络
在这里插入图片描述

实验效果

在这里插入图片描述
总结

为了减少最新的深度神经网络的计算成本,本文提出了一种用于构建高效的神经网络结构的新型Ghost模块。Ghost模块将原始卷积层分为两部分,首先使用较少的卷积核来生成原始特征图,然后,进一步使用廉价变换操作以高效生产更多幻影特征图。在基准模型和数据集上进行的实验表明,该方法是一个即插即用的模块,能够将原始模型转换为更紧凑的模型,同时保持可比的性能。此外,在效率和准确性方面,使用提出的新模块构建的GhostNet均优于最新的轻量神经网络,如MobileNetV3。

代码地址:
论文地址
官方代码地址

模型官方讲解

GhostNet网络详解 1. GhostNet网络 一张图片经过神经网络进行特征提取后,能够得到很多特征图。 在特征图中会有一些相似性很高,这就是神经网络中存在的特征图冗杂的情况(如图中扳手相连的两幅特征图)。 作者认为可以对其中的一个特征图进行(Cheap Operations)简单的线性运算从而生成更多相似特征图,从而可以使用更少的参数生成更多的特征图,将相似的特征图认为是彼此的Ghost。 2. Ghost Module 作者用Ghost Module代替传统卷积,首先采用普通的1x1卷积对输入图片进行通道数的压缩,然后 阅读详情

相关推荐

GhostNet原理与代码实例讲解

GhostNet原理与代码实例讲解 作者:禅与计算机程序设计艺术 1. 背景介绍 1.1 GhostNet的起源与发展 GhostNet是一种新型的轻量级卷积神经网络架构,由华为诺亚方舟实验室在2020年提出。

AI天才研究院 1074

GhostNet(CVPR 2020)学习笔记 (附代码)

GhostNet(CVPR 2020)学习笔记 (附代码)

PLANTTHESON的博客 3881

从YOLOv8到华为移动端模型YOLOv8-GhostNet | 提升特征提取的轻量化策略【附涨点保姆级代码】

GhostNet由华为提出,作为一种轻量级网络,其核心思想是在保留神经网络模型表达能力的前提下,通过减少冗余计算,实现模型的轻量化。GhostNet的基本单元是通过一组廉价操作生成“ghost”特征图,从而代替传统卷积操作中较为昂贵的计算过程。这一改进使得GhostNet非常适合部署在资源有限的移动端设备上。本文探讨了YOLOv8模型结合GhostNetv1的改进,提出了一种新的轻量化特征提取网络——YOLOv8-GhostNet。

一键难忘的博客 3520

轻量级网络Ghostnet(GhostConv(幻影卷积)、Ghost BottleNeck)详解

该论文提供了一个全新的Ghost模块,旨在通过廉价操作生成更多的特征图。基于一组原始的特征图,作者应用一系列线性变换,以很小的代价生成许多能从原始特征发掘所需信息的“Ghost”特征图(Ghost feature maps)。该Ghost模块即插即用,通过堆叠Ghost模块得出Ghost bottleneck,进而搭建轻量级神经网络——GhostNet。

weixin_43960370的博客 4万+

YOLOv5算法改进(4)— 主干网络介绍(MobileNetV3、ShuffleNetV2和GhostNet)

YOLOv5算法中的主干网络可以有多种替换方案,为了后面讲解的方便,本篇文章就给大家介绍MobileNetV3、ShuffleNetV2和GhostNet主干网络!

小哥谈 2239

YOLOv10轻量化改进:Ghostnet、G_ghost、Ghostnetv2家族大作战(一):华为Ghostnet,超越谷歌MobileNet | CVPR2020

1)引入了一个新的 Ghost 模块,通过使用更少的参数来生成更多的特征; 2)基于 Ghost 模块,建立了一个高效的神经架构,即 GhostNet。

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 865

YOLOv5改进系列(二)结合轻量化网络GhostNet

此文的Ghost Module、Ghost Bottleneck主要针对官方提供的YOLOv5源码中的实现作讲解,与原生的华为官方提供的源码简化了很多。在我的数据集上跑10个epoch的结果(没有使用预训练权重),可以看到虽然计算量和参数量降低了很多,但是精度也掉了很多。这些特征图是由卷积操作得到,又输入到下一个卷积层进行运算,这个过程包含大量的网络参数,消耗了大量的计算资源。的源码实现,不过需要注意的是相比于华为的源码是简化版本。中的冗余信息可能是一个成功模型的重要组成部分,中的结构的模型训练结果。

m0_55908255的博客 1545

【轻量化篇】YOLOv8改进实战 | 更换主干网络 Backbone 之 GhostnetV2

w94ghz的博客 1730

notepad-- 轻量文本编辑|macOS 安装与上手完整指南

notepad-- 是一个用 C++/Qt 编写的轻量级跨平台文本编辑器,定位是国产 Notepad 类编辑器的替代品。本文覆盖预编译包安装、源码编译两条路线和三个核心使用场景,不涉及插件开发。做完最后一步,你手上的 Mac 里就有能开文件、做差异对比、随时切编码且中文不乱码的编辑器。 ## 动手前 30 秒:先判断你走哪条路 先自问三个问题:你的 Mac 装过 Xcode 命令行工具吗、平时

gitblog_00041的博客 173

YOLOv5改进系列(三) 本文(7万字) | 更换主干backbone | MobileNetV3 | ShuffleNetV2 | EfficientNetv2 | GhostNet | 等 |

《人工智能专栏》 Python与Python | 机器学习 | 深度学习 | 目标检测 | YOLOv5及其改进 | YOLOv8及其改进 | 关键知识点 | 各种工具教程MobileNetV3,是谷歌在2019年3月21日提出的轻量化网络架构,在前两个版本的基础上,加入神经网络架构搜索(NAS)和h-swish激活函数,并引入SE通道注意力机制,性能和速度都表现优异,受到学术界和工业界的追捧。引用大佬的描述:MobileNet V3 = MobileNet v2 + SE结构 + hard

专注于人工智能学习,总结 4763

ghostnet.pytorch:[CVPR2020] GhostNet

此仓库仅实现GhostNet的演示代码。 请移至以获取更多详细信息。 幽灵网 此存储库提供了CVPR 2020论文Pytorch演示实现。 带有预训练模型的TensorFlow / PyTorch实现可在。 要求 该代码已在Python3 PyTorch 1.0+上进行了验证。 用法 用法示例: import torch from ghost_net import ghost_net model = ghost_net(width_mult=1.0) input = torch.randn(32,3,224,224) y = model(input) print(y) GhostNet简介 GhostNet:廉价运营带来的更多功能。 CVPR2020。 韩开,王云和,田琦,郭建元,徐春景,徐昌。 方法 表现 GhostNet击败了其他SOTA轻量级CNN,例如MobileNetV

移动端轻量级卷积网络近三年进展(MobileNet V3, Blaze, GhostNet)- 附源码讲解

CNN 在图像分类,分割检测等领域获得广泛应用,在 PC 端运行模型虽然精度高,但参数量和算力都不是移动端的设备可以承受的,为了让深度学习模型可以在移动端高效的运行,目前业界主流的解决手段有三种。 网络架构设计:思想在于设计能在移动端高效运行的轻量化网络架构(本文讲的算法都属于此手段) 通道剪枝:对网络中的通道层进行重要性分析,裁剪重要程度低的层来降低网络的计算量 模型搜索:给定搜索空间,使用强化,遗传等算法在搜索空间中找到满足给定计算量的模型架构 这里主要介绍近三年比较出名的移动端轻量级网

Edvard的专栏 2767

安装破解IAR EWARM 8.2,提供注册机

IAR Embedded Workbench for ARM(IAR for ARM)是一款微处理器的集成开发环境软件,该集成开发环境中包含了IAR的C/C++编译器、 汇编工具、链接器、库管理器、文本编辑器、工程管理器和C-SPY调试器,支持ARM,AVR,MSP430等芯片。   一、安装 双击运行安装程序,点击Install IAR Embedded Workbench for ARM...

睿思派克 4万+

PaddleHub 轻量级图像分类实战:ghostnet_x1_3_imagenet 模块的安装、推理、Fine-tune 与 Serving 部署全指南

本文以 PaddleFormers 仓库中的 `ghostnet_x1_3_imagenet` 图像分类模块为主线,系统讲解 GhostNet 轻量级网络的模块结构、环境安装、命令行与 Python API 预测、基于 Flowers 数据集的 Fine-tune 全流程,以及 PaddleHub Serving 在线服务化部署。读完本文,你将能够独立完成从模型安装、单张图片分类预测,到自定义数据

gitblog_00525的博客 755

移动端UI自动化测试新框架Maestro:声明式语法与实战指南

UI自动化测试是保障移动应用质量的关键环节,其核心原理是通过脚本模拟用户操作,对应用界面进行自动验证。传统命令式框架(如基于Selenium WebDriver的Appium)虽然控制粒度细,但脚本编写和维护成本较高。声明式测试框架则通过描述“做什么”而非“怎么做”,显著降低了技术门槛和维护复杂度,其技术价值在于提升测试脚本的可读性、编写效率与跨团队协作能力。在移动端测试领域,这尤其适用于需要快速验证核心业务流程、进行冒烟测试和回归测试的场景。本文聚焦的**Maestro框架**,正是这一理念的杰出实践。它

weixin_32921023的博客 711

【SABRE 3D, SABRE 3DxT,LAM设备】2025年9月10日

前文:SABRE 3D系列机台简介本章节详细阐述了在维护期间锁定电气、机械、热力学及重力组件以及化学管线输入的锁定操作流程,旨在降低人员受伤风险。p42~p55。

weixin_46735260的博客 1598

(C1-1)MobileNet、ShuffleNet、GhostNet

轻量化网络模型

木槿qwer的博客 591

VC Spyglass调试秘籍:从Lint报错到代码修复的完整工作流

本文详细介绍了VC Spyglass调试的完整工作流,重点解析了如何高效定位和修复Lint检查中常见的XMRE-L跨模块引用错误。通过对比GUI与命令行(vc_static_shell)双模式调试技巧,并结合TCL脚本实现批量处理与规则豁免,帮助数字设计工程师系统化地提升代码调试效率与质量。

weixin_29246195的博客 571

《剑指 Offer》面试题 05「替换空格」全解析:三种解法与多语言实现

本文围绕《剑指 Offer(第 2 版)》面试题 05「替换空格」展开,以 doocs/leetcode 开源仓库中 [lcof/面试题05. 替换空格/README.md](https://link.gitcode.com/i/b2e178c159d0da989f7da483b4d28823) 为骨架,完整覆盖题目描述、限制条件、三种解题思路,并结合仓库内 16 个多语言 Solution 源码

gitblog_00745的博客 634

IOS APP上架被拒 4.3(a) - Design - Spam,成功

成功解决IOS APP上架被拒 4.3(a) - Design - Spam,本篇博客记录了详细过程

qq_40147106的博客 6890

国科大学习资料--人工智能原理与算法-2021年期末考试题解析(学长整理)

国科大学习资料–人工智能原理与算法-2021年期末考试题解析(学长整理) 国科大学习资料–人工智能原理与算法-2021年期末考试题解析(学长整理) 国科大学习资料–人工智能原理与算法-2021年期末考试题解析(学长整理) 根据学弟的反馈,该年的期末题只有5道,且均是作业题(所以大家一定要积极完成作业,考前多做几遍!!!!) 下面解析: 3.25 由于该题,我没有做过,所以只能给你英文版的答案。答案如下,其他的题目答案都是中文版。 5.9 8.10 12.20 15.13 ...

无名何许人的博客 3962

PaddleSeg MobileSeg 轻量化语义分割模型全解析:架构、配置与移动端部署实战

MobileSeg 是 PaddleSeg 中面向移动端与边缘设备的语义分割模型系列,采用「轻量骨干 + 编解码」架构,能够在 X86 CPU、ARM CPU 等低算力硬件上运行,同时保持可观的分割精度。本文以 QualityInspector 工业质检方案中 MobileSeg 的模型卡片与配置文件为骨架,结合仓库源码深入讲解其架构设计、五种轻量骨干、Cityscapes 精度与推理速度实测数据

gitblog_00640的博客 453

AutoSAR系列讲解(入门篇)1.2-AutoSAR概述

这里主要说明了AutoSAR是个什么,还有其工具链

雪云飞星的博客 5万+

YOLOv8如何更换主干网络?自定义backbone教程

在资源受限设备上部署YOLOv8时,可通过替换主干网络提升效率。只要满足输入尺寸、多尺度特征图输出和通道匹配三项条件,就能自定义backbone并集成到Ultralytics框架中。结合YAML配置文件,可灵活使用MobileNet、GhostNet等轻量结构,或自行设计适用于小目标检测与边缘推理的专用骨干网络。

weixin_42348783的博客 1587

《Python全栈系列教程》专栏介绍及文章汇总

《Python全栈系列教程》专栏介绍及文章汇总

孤寒者的博客 71万+

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

上一篇: matplotlib读取ndarry格式图片并进行不失真的resize
apodxxx
博客等级 码龄7年 17粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值