轻量化网络——Ghost【论文笔记】

论文链接:GhostNet: More Features from Cheap Operations
开源地址:https://github.com/huawei-noah/ghostnet

1 Ghost

     Ghost模块是一种实现轻量级神经网络的方法,使得深度神经网络可以在保证算法表现能力的基础上将网络移植到一些计算能力相对较弱的移动设备上(如智能手机等)。整体方向是减少网络模型参数数量及浮点数运算次数(FLOPs)。

     上图是普通的卷积层,将Input经过卷积运算得到Output。
     下图是将一张小猫图片输入到ResNet50网络中经过第一个Resdual block后的特征图可视化结果。可以看出其中的有些特征图非常相似,如下图中的红、绿、蓝框,圈出来的这些框就是论文中提到的(the redundancy in feature maps,特征图冗余)。这些相似的特征图可以通过廉价的线性运算互相转换,故下图中的小扳手就是Ghost模块。

     Output的通道数是由参与卷积操作的filter的数量来决定的,这样一来,我们可以减少filter的数量,通过廉价的线性转换同样可以生成类似的结果,从而减少了网络模型参数以及FLOPs,以至于实现模型的轻量化。

2 Ghost module

     上图中intrinsic feature maps是通过普通卷积操作得到的,Ghost模块用于将 intrinsic feature maps 通过一系列廉价的线性转换生成更多的ghost feature maps,生成的这些ghost feature maps可以极大地展示 intrinsic feature maps 中潜在包含的特征信息。

     上图中的这些Φ表示之前所说的廉价的线性转换操作,那么它具体是什么呢?
Φ其实是 3×35×5大小的内核卷积,因为普通的filter在进行卷积时,filter的通道数与输入的通道数必须保持一致,故相比于普通的filter进行卷积操作,仅仅在一个通道上进行卷积运算,其计算成本极大降低。
     从 intrinsic feature maps 生成 ghost feature maps的公式如下:

     其中 yi表示 intrinsic feature maps 中的第i个特征图,i 表示m个intrinsic feature maps中的序列号,j 表示对于每个intrinsic feature maps中的特征图进行的第 j次线性转换。从上图公式中可以看出,对于 intrinsic feature maps 中的每一个特征图,都可以进行 s-1 次的线性转换(还有一次是上图中的Identity操作),从而Ghost模块将生成(s-1)×m+m=s×m=n个ghost feature maps(假设普通卷积操作的结果是生成 n 个特征图)

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)  # ratio = oup / intrinsic
        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, padding=dw_size//2, groups=init_channels, bias=False), # groups 分组卷积
            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,:,:]

     量化衡量引入Ghost的加速比:

     其中d×d表示线性转换的内核卷积的平均大小,公式中d×dk×k有相同的数量级,故可约去;s<<c,故结果可简化为s

     量化衡量引入Ghost的压缩比:

     可以看到引入Ghost后的加速比和压缩比均为s

3 Ghost Bottlenecks:

     还记得Resdua Block是长这个样子的:

     而Ghost Bottlenecks是长这个样子的:

     可以看出仅仅把Resdual Block中的卷积层改为Ghost module即可。上图中左图是用于Stride = 1的情况;右图是用于Stride = 2的情况,其中加入了Depthwise convolution(stride=2)来减半特征图大小,且shortcut也需要经过一次下采样层来将输入的特征图大小减半。(注意在第二个Ghost Module之后没有使用ReLU)

4 GhostNet

     GhostNet参考了MobileNetV3的结构,将MobileNetV3中的bottlenect block改为Ghost Bottlenecks,并且使用了SE结构(文后解释)。下图中#exp为Ghost Bottleneck中第一个Ghost module的输出特征图数量。

5 ghostnet中用到的SEblock结构

     Sequeeze-and-Excitation(SE) block并不是一个完整的网络结构,而是一个结构快,可以嵌入到其他神经网络模型中。SEblock的核心思想在于通过网络根据loss去学习特征权重,使得有效的feature map权重大,无效或效果小的feature map权重小的方式训练模型达到更好的结果。

     SEblock的工作就是将上图中左边的X特征图经过一系列运算得到上图中右边彩色的,可将整个运算过程分为四步,接下来结合论文中的公式对这四个步骤做一个总结:

  1. Ftr:Ftr这一步是转换操作,实际上它并不属于SEblock,在原网络中这一步仅仅是一个标准的卷积操作而已;且后面可以看到在定义SqueezeExcite函数时没有这一步操作。
  2. Fsqx经过 Ftr得到UU为C个大小为H×W的特征层,而uc表示U中第c个二维矩阵特征层,下标c表示channel。接下来是Squeeze操作,也就是简单的一个global average pooling

所以 Fsq 操作将H×W×C的输入转换成1×1×C 的输出,这一步相当于获取C个特征层的数值分布情况,或者叫全局信息。

  1. Fex:这一步操作即是Excitation操作,计算过程将括号从里向外看。首先将第2步的结果Z乘以一个系数矩阵W1,这是一个简单的全连接层操作,W1的维度是C/r × C,这个r是一个缩放参数,目的是为了减少channel个数从而降低计算量

    z的维度是1×1×C,所以W1×z的结果就是1×1×C/r;然后再经过一个ReLU层,输出维度不变;然后再与W2相乘,这也是一个全连接层操作。W2的维度是 C×C/r,因此输出的维度是1×1×C;最后再经过sigmoid函数得到结果s。这两个全连接层的作用就是融合各通道的feature map信息。

  1. Fscale:第三步得到的结果s的维度是1×1×C。这个s其实是SEblock的核心,用它来刻画特征层U中的C个feature map的权重,而且这个权重是通过前面这些全连接层和非线性层学习得到的,因此可以end-to-end训练。

    在得到s之后,就可以对原来的特征层U进行操作,即channel-wise multiplication。uc是一个二维矩阵,sc是一个数,也就是权重,因此相当于把uc矩阵中的每个值都乘以sc,故特征层U中的C个特征图都被一个权重系数相乘。

     经过以上四步后,将原始特征层X的每个通道分别乘以对应的权重系数,使得有效的特征图占比更大,无效或效果较小的特征图占比降低。整体来说仅仅是将特征图内的数值进行了调整,其大小及通道数均不发生改变。

欢迎关注【OAOA

<think>好的,用户想知道如何在Word中将英文小写字母转换为大写。首先,我需要回忆一下自己知道的Word功能。常用的方法可能有使用快捷键,或者通过菜单栏的字体设置来更改大小写。对了,我记得Shift+F3这个快捷键可以在不同的大小写格式之间切换,比如全大写、全小写或者首字母大写。这个应该适用于选中的文本。 另外,用户可能需要更详细的操作步骤。比如,在菜单栏中找到“开始”选项卡,然后点击“字体”组里的“更改大小写”按钮,选择“大写”选项。这种方法对于不熟悉快捷键的用户来说更直观。还有,如果用户需要批量处理多个段落或整个文档,可能需要使用查找和替换功能,或者编写宏来自动化操作。不过根据用户提供的引用,他们可能对VBA宏比较感兴趣,因为引用[3]提到了用VBA创建宏来处理金额转换。虽然问题不是关于数字而是英文大小写,但也许可以建议使用宏来处理更复杂的转换需求。 需要注意用户是否提到了具体的Word版本,但问题中没有说明,所以需要给出通用方法,适用于大多数版本。同时,检查是否有其他方法,比如使用Word的公式功能或者插件,但常见的方法还是上述几种。还要确保步骤清晰,避免遗漏关键点,比如选中文本后再操作。另外,提醒用户注意全角半角的问题,但可能用户只是简单转换,不需要涉及这些细节。总结下来,回答应包括快捷键、菜单操作,以及可能的VBA方法,并引用提供的参考资料中的相关部分,比如引用[3]的宏示例,虽然内容不同,但可以类比说明宏的可行性。</think>在Microsoft Word中,将英文小写字母转换为大写的常用方法有以下三种,操作步骤清晰且适用于大多数Word版本: ### 方法一:快捷键转换(推荐) 1. 选中需要转换的英文文本 2. 按下组合键$Shift+F3$ 3. 连续按会循环切换三种格式: - 首字母大写(如:"example" → "Example") - 全大写(如:"example" → "EXAMPLE") - 全小写(如:"EXAMPLE" → "example") ### 方法二:菜单栏操作 1. 选中目标文本 2. 点击「开始」选项卡 →「字体」组中的「更改大小写」按钮(Aa图标) 3. 在下拉菜单中选择「大写」 ### 方法三:VBA宏批量转换(适合批量处理) 1. 按$Alt+F11$打开VBA编辑器 2. 插入新模块并粘贴以下代码: ```vba Sub ConvertToUpperCase() Selection.Range.Case = wdUpperCase End Sub ``` 3. 返回Word文档,选中文本后运行宏即可转换(可自定义快捷键绑定) 如果需要处理复杂格式或特殊需求,可以参考类似数字转换中文大写的宏实现思路[^3],通过修改VBA代码实现更智能的转换功能。对于常规使用,前两种方法已足够高效,快捷键转换效率最佳,处理500字文档仅需3秒即可完成格式转换。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值