IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> Residual Attention Network for Image Classification -> 正文阅读

[人工智能]Residual Attention Network for Image Classification

Residual Attention Network for Image Classification

参考

个人理解

  • 这篇,怎么说呢,效果很好但是提出的这个Mask Branch部分多少有点宣兵夺主的感觉(指层数,这个会在文章末尾说明)。
  • 基本思想就是利用Mask Branch来将背景过滤掉,然后使模型更加专注于图片中的主要信息。
  • 主要贡献呢,1是上面的这个思想,2是采用ResidualBlock避免直接堆叠带来的性能退化。

Attention Module

  • 大致结构示意图如下:
    • image-20211014200404850
    • 上面的部分是Trunk Branch,即主干部分,就是几个ResidualBlock的堆叠,作用是提取Feature Map。
    • 下面的部分是Mask Branch,即Mask分支,其结构下文会说(Soft Mask Branch部分),作用是遮挡住无效的背景信息。
    • 文中给出{p = 1, t = 2, r = 1},代表前面有p个ResidualBlock,以此类推,后面一节也会用到这个
Soft Mask Branch
  • image-20211014201212296
  • 结构长这样,就是一堆上下采样加残差单元的组合,实际上的实现也差不多,然后文中给出了r=1,即代表121的组合。
  • 需要注意的是中间这段加了个大号残差,有点像CSPDarknet的那个味道(话说回来,这玩意是在这篇后面提出来的~)
  • 值得关注的是这里有多次上/下采样(表现为maxpooling/interpolation),这种操作加上多层conv的叠加会使得感受野增大(conv的叠加增加感受野在VGG这篇里面曾经提到过,记得是3个3x3的感受野=1个7x7,而且又可以减少参数量啥的)
Spatial Attention and Channel Attention
  • 这个部分略微有点诡异,我试着讲讲个人理解,首先这段讲的应该是下图中的这个函数选什么的问题(Mask Branch尾部)
    • image-20211014202552457
  • f1f2f3分别代表着混合注意力通道注意力空间注意力
    • f1是sigmoid,f2是L2正则,f3是不知道啥东西,文中说是归一化+sigmoid(exp里面是归一化,类似BN,然后整体就是个sigmoid这样)
    • 然后我的理解是,f1仅仅将每个像素点用sigmoid映射到[0,1],f2就是指考虑考虑通道的L2正则,即可以看成将某个像素点在channel维度上的比重算出来,f3同理,只不过算的是HxW维度的这样
    • 然后效果是第一个最好~
    • image-20211014203153817

感觉宣兵夺主的原因

  • 这里我先给两张图,第一张是Attention-56/92的结构图,第二张是在imageNet上的效果图

  • 首先Attention-56的命名是怎么来的?56是Trunk层数,看起来很合理是吧?因为Trunk,主干嘛,而且56层,也不多。然后看看第二张图,和Attention-56对比的是ResNet-152,为什么呢?因为的性能强劲,56就足以和152匹敌?其实不是的~

  • 我找了份代码实现**ResidualAttentionNetwork-pytorch**,研究了下里面的Attention结构是咋回事,取的是这部分代码

    • class AttentionModule_pre(nn.Module):
      
          def __init__(self, in_channels, out_channels, size1, size2, size3):
              super(AttentionModule_pre, self).__init__()
              self.first_residual_blocks = ResidualBlock(in_channels, out_channels)
      
              self.trunk_branches = nn.Sequential(
                  ResidualBlock(in_channels, out_channels),
                  ResidualBlock(in_channels, out_channels)
               )
              
              self.mpool1 = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
              self.softmax1_blocks = ResidualBlock(in_channels, out_channels)
              self.skip1_connection_residual_block = ResidualBlock(in_channels, out_channels)
              self.mpool2 = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
              self.softmax2_blocks = ResidualBlock(in_channels, out_channels)
              self.skip2_connection_residual_block = ResidualBlock(in_channels, out_channels)
              self.mpool3 = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
              self.softmax3_blocks = nn.Sequential(
                  ResidualBlock(in_channels, out_channels),
                  ResidualBlock(in_channels, out_channels)
              )
      
              self.interpolation3 = nn.UpsamplingBilinear2d(size=size3)
              self.softmax4_blocks = ResidualBlock(in_channels, out_channels)
              self.interpolation2 = nn.UpsamplingBilinear2d(size=size2)
              self.softmax5_blocks = ResidualBlock(in_channels, out_channels)
              self.interpolation1 = nn.UpsamplingBilinear2d(size=size1)
              self.softmax6_blocks = nn.Sequential(
                  nn.BatchNorm2d(out_channels),
                  nn.ReLU(inplace=True),
                  nn.Conv2d(out_channels, out_channels , kernel_size = 1, stride = 1, bias = False),
                  nn.BatchNorm2d(out_channels),
                  nn.ReLU(inplace=True),
                  nn.Conv2d(out_channels, out_channels , kernel_size = 1, stride = 1, bias = False),
                  nn.Sigmoid()
              )
              self.last_blocks = ResidualBlock(in_channels, out_channels)
      
          def forward(self, x):
              x = self.first_residual_blocks(x)
              out_trunk = self.trunk_branches(x)
              out_mpool1 = self.mpool1(x)
              out_softmax1 = self.softmax1_blocks(out_mpool1)
              out_skip1_connection = self.skip1_connection_residual_block(out_softmax1)
              out_mpool2 = self.mpool2(out_softmax1)
              out_softmax2 = self.softmax2_blocks(out_mpool2)
              out_skip2_connection = self.skip2_connection_residual_block(out_softmax2)
              out_mpool3 = self.mpool3(out_softmax2)
              out_softmax3 = self.softmax3_blocks(out_mpool3)
              #
              out_interp3 = self.interpolation3(out_softmax3)
              # print(out_skip2_connection.data)
              # print(out_interp3.data)
              out = out_interp3 + out_skip2_connection
              out_softmax4 = self.softmax4_blocks(out)
              out_interp2 = self.interpolation2(out_softmax4)
              out = out_interp2 + out_skip1_connection
              out_softmax5 = self.softmax5_blocks(out)
              out_interp1 = self.interpolation1(out_softmax5)
              out_softmax6 = self.softmax6_blocks(out_interp1)
              out = (1 + out_softmax6) * out_trunk
              out_last = self.last_blocks(out)
      
              return out_last
      
      
  • 光看代码可能看不出来,我根据forward画了图,如下所示:

    • 可以看出,Trunk Branch仅仅2个ResidualBlock就完事了(左边),而Mask Branch就不是这么简单了,足足6个(按照文中的描述,也应该有4个这样子)
    • image-20211014205444874
    • 然后再回到第一张表格,Attention-56是怎么算的呢?
      • 首先有1+1+1+3=6个Residual unit,即6个ResidualBlock =>18层conv
      • 然后Attention Module部分的Trunk是1+2+1=4个ResidualBlock,一共1+1+1=3个Attention Module,故有12个ResidualBlock=>36层conv
      • 然后加上刚开始的conv和最后的fc,刚好就是56层~
    • 那么实际上应该是多少层呢?
      • 我们不按上面的图算,就按照文中的比例算,即用这个{p = 1, t = 2, r = 1}算,那么可以得到Soft Mask Branch部分一共是4个ResidualBlock+2个conv=14层conv,然后加上左右两个p=1个的ResidualBlock的话就是14+2*3=20层,远大于Trunk Branch的12层吼
      • Attention-56实际上最深应该是20*3+18+2 = 80层,当然远小于152,效果还是有的,只是觉得有些宣兵夺主

总结

  • 不管Mask 的设计有多么诡异,这都不妨碍这是一片优秀的论文,为CNN的注意力机制作出了巨大的贡献
  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-10-15 11:47:53  更:2021-10-15 11:50:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 10:18:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码