服务粉丝

我们一直在努力
当前位置:首页 > 财经 >

CeiT:训练更快的多层特征抽取ViT

日期: 来源:GiantPandaCV收集编辑:pprp



【GiantPandaCV导语】

来自商汤和南洋理工的工作,也是使用卷积来增强模型提出low-level特征的能力,增强模型获取局部性的能力,核心贡献是LCA模块,可以用于捕获多层特征表示。相比DeiT,训练速度更快。




引言

针对先前Transformer架构需要大量额外数据或者额外的监督(Deit),才能获得与卷积神经网络结构相当的性能,为了克服这种缺陷,提出结合CNN来弥补Transformer的缺陷,提出了CeiT:

(1)设计Image-to-Tokens模块来从low-level特征中得到embedding。

(2)将Transformer中的Feed Forward模块替换为Locally-enhanced Feed-Forward(LeFF)模块,增加了相邻token之间的相关性。

(3)使用Layer-wise Class Token Attention(LCA)捕获多层的特征表示。

经过以上修改,可以发现模型效率方面以及泛化能力得到了提升,收敛性也有所改善,如下图所示:

方法

1. Image-to-Tokens

使用卷积+池化来取代原先ViT中7x7的大型patch。

2. LeFF

将tokens重新拼成feature map,然后使用深度可分离卷积添加局部性的处理,然后再使用一个Linear层映射至tokens。

3. LCA

前两个都比较常规,最后一个比较有特色,经过所有Transformer层以后使用的Layer-wise Class-token Attention,如下图所示:

LCA模块会将所有Transformer Block中得到的class token作为输入,然后再在其基础上使用一个MSA+FFN得到最终的logits输出。作者认为这样可以获取多尺度的表征。

实验

SOTA比较:

I2T消融实验:

LeFF消融实验:

LCA有效性比较:

收敛速度比较:

代码

模块1:I2T Image-to-Token

  # IoT
  self.conv = nn.Sequential(
      nn.Conv2d(in_channels, out_channels, conv_kernel, stride, 4),
      nn.BatchNorm2d(out_channels),
      nn.MaxPool2d(pool_kernel, stride)    
  )
  
  feature_size = image_size // 4

  assert feature_size % patch_size == 0, 'Image dimensions must be divisible by the patch size.'
  num_patches = (feature_size // patch_size) ** 2
  patch_dim = out_channels * patch_size ** 2
  self.to_patch_embedding = nn.Sequential(
      Rearrange('b c (h p1) (w p2) -> b (h w) (p1 p2 c)', p1 = patch_size, p2 = patch_size),
      nn.Linear(patch_dim, dim),
  )

模块2:LeFF

class LeFF(nn.Module):
    
    def __init__(self, dim = 192, scale = 4, depth_kernel = 3):
        super().__init__()
        
        scale_dim = dim*scale
        self.up_proj = nn.Sequential(nn.Linear(dim, scale_dim),
                                    Rearrange('b n c -> b c n'),
                                    nn.BatchNorm1d(scale_dim),
                                    nn.GELU(),
                                    Rearrange('b c (h w) -> b c h w', h=14, w=14)
                                    )
        
        self.depth_conv =  nn.Sequential(nn.Conv2d(scale_dim, scale_dim, kernel_size=depth_kernel, padding=1, groups=scale_dim, bias=False),
                          nn.BatchNorm2d(scale_dim),
                          nn.GELU(),
                          Rearrange('b c h w -> b (h w) c', h=14, w=14)
                          )
        
        self.down_proj = nn.Sequential(nn.Linear(scale_dim, dim),
                                    Rearrange('b n c -> b c n'),
                                    nn.BatchNorm1d(dim),
                                    nn.GELU(),
                                    Rearrange('b c n -> b n c')
                                    )
        
    def forward(self, x):
        x = self.up_proj(x)
        x = self.depth_conv(x)
        x = self.down_proj(x)
        return x
        
class TransformerLeFF(nn.Module):
    def __init__(self, dim, depth, heads, dim_head, scale = 4, depth_kernel = 3, dropout = 0.):
        super().__init__()
        self.layers = nn.ModuleList([])
        for _ in range(depth):
            self.layers.append(nn.ModuleList([
                Residual(PreNorm(dim, Attention(dim, heads = heads, dim_head = dim_head, dropout = dropout))),
                Residual(PreNorm(dim, LeFF(dim, scale, depth_kernel)))
            ]))
    def forward(self, x):
        c = list()
        for attn, leff in self.layers:
            x = attn(x)
            cls_tokens = x[:, 0]
            c.append(cls_tokens)
            x = leff(x[:, 1:])
            x = torch.cat((cls_tokens.unsqueeze(1), x), dim=1) 
        return x, torch.stack(c).transpose(0, 1)

模块3:LCA

class LCAttention(nn.Module):
    def __init__(self, dim, heads = 8, dim_head = 64, dropout = 0.):
        super().__init__()
        inner_dim = dim_head *  heads
        project_out = not (heads == 1 and dim_head == dim)

        self.heads = heads
        self.scale = dim_head ** -0.5

        self.to_qkv = nn.Linear(dim, inner_dim * 3, bias = False)

        self.to_out = nn.Sequential(
            nn.Linear(inner_dim, dim),
            nn.Dropout(dropout)
        ) if project_out else nn.Identity()

    def forward(self, x):
        b, n, _, h = *x.shape, self.heads
        qkv = self.to_qkv(x).chunk(3, dim = -1)
        q, k, v = map(lambda t: rearrange(t, 'b n (h d) -> b h n d', h = h), qkv)
        q = q[:, :, -1, :].unsqueeze(2) # Only Lth element use as query

        dots = einsum('b h i d, b h j d -> b h i j', q, k) * self.scale

        attn = dots.softmax(dim=-1)

        out = einsum('b h i j, b h j d -> b h i d', attn, v)
        out = rearrange(out, 'b h n d -> b n (h d)')
        out =  self.to_out(out)
        return out

class LCA(nn.Module):
    # I remove Residual connection from here, in paper author didn't explicitly mentioned to use Residual connection, 
    # so I removed it, althougth with Residual connection also this code will work.
    def __init__(self, dim, heads, dim_head, mlp_dim, dropout = 0.):
        super().__init__()
        self.layers = nn.ModuleList([])
        self.layers.append(nn.ModuleList([
                PreNorm(dim, LCAttention(dim, heads = heads, dim_head = dim_head, dropout = dropout)),
                PreNorm(dim, FeedForward(dim, mlp_dim, dropout = dropout))
            ]))
    def forward(self, x):
        for attn, ff in self.layers:
            x = attn(x) + x[:, -1].unsqueeze(1)
            x = x[:, -1].unsqueeze(1) + ff(x)
        return x

参考

https://arxiv.org/abs/2103.11816

https://github.com/rishikksh20/CeiT-pytorch/blob/master/ceit.py



为了感谢读者的长期支持,今天我们将送出三本由 机械工业出版社 提供的:《从零开始构建深度前馈神经网络》 。点击下方抽奖助手参与抽奖。没抽到并且对本书有兴趣的也可以使用下方链接进行购买。

《从零开始构建深度前馈神经网络》抽奖链接


本书通过Python+NumPy从零开始构建神经网络模型,强化读者对算法思想的理解,并通过TensorFlow构建模型来验证读者亲手从零构建的版本。前馈神经网络是深度学习的重要知识,其核心思想是反向传播与梯度下降。本书从极易理解的示例开始,逐渐深入,帮助读者充分理解并熟练掌握反向传播与梯度下降算法,为后续学习打下坚实的基础。


END



相关阅读

  • GPT4 VS Claude In MLIR

  • 本文构造了20个MLIR基础概念的问题以及使用OneFlow IR转换为Tosa IR的5个代码段来评测GPT4和Claude对于MLIR的掌握能力,我的结论是对于基础概念的理解Claude整体上和GPT4持平
  • 罕见!此地确诊1例!

  • 来源:河南共青团综合自南方新闻网、深圳市疾控中心、西安疾控中心日前深圳大学总医院确诊一例罕见的黑热病连白血病都查了最终确诊为黑热病“刚开始以为是感冒后来新冠、甲流
  • 关键时刻,一杯奶茶立功了!

  • 近日云南昭通消防救援部门接报有女生在楼顶处欲跳楼轻生‍消防员们紧急前往现场处置
    ‍‍试了多种方法最后用一杯奶茶救下了女生
    消防员们到达现场后看到女生在天台上情绪
  • 周六19点直播预告 | 系统0day安全-apache fuzz

  • 快来预约*声明:针对未购课用户,观看视频号完整直播均需付费系统0day安全:《apache fuzz》时间:4月22日(周六)19点联系助教,报名立享限时优惠球分享球点赞球在看
  • 4月,白鹭与安远的约定

  • ----广告热线:13766331200----漠漠水田飞白鹭去年四月记者拍摄过嬉戏、觅食的白鹭给春耕时节增添了一道美丽的风景线(白鹭为安远生态“代言”)又是一年四月天白鹭如约而至我县
  • 安远县蔡坊、高云山乡大坝管护人员招聘公告

  • ----广告热线:13766331200----一、招聘名额因蔡坊、高云山乡内三座大坝、厂房管理需要,需聘请大坝、厂房管护人员6人。二、资格条件(一)安远县户籍;(二)男性,年龄应在50周岁以下,高中
  • 4月29日 一场惊艳全城的活动即将开启!

  • ----广告热线:13766331200----免责声明本文仅为分享交流,相关内容不排除因政府相关规划、规定及开发商未能控制的原因而发生变化。以上图文仅为要约邀请,本公司保留对其修改的

热门文章

  • “复活”半年后 京东拍拍二手杀入公益事业

  • 京东拍拍二手“复活”半年后,杀入公益事业,试图让企业捐的赠品、家庭闲置品变成实实在在的“爱心”。 把“闲置品”变爱心 6月12日,“益心一益·守护梦想每一步”2018年四
  • 美国对华2000亿关税清单,到底影响有多大?

  • 1 今天A股大跌,上证最大跌幅超过2%。直接导火索是美国证实计划对华2000亿美元产品加征25%关税。 听起来,2000亿美元数目巨大,我们来算笔账。 2000亿美元,按现在人民币汇率

最新文章

  • CeiT:训练更快的多层特征抽取ViT

  • 【GiantPandaCV导语】来自商汤和南洋理工的工作,也是使用卷积来增强模型提出low-level特征的能力,增强模型获取局部性的能力,核心贡献是LCA模块,可以用于捕获多层特征表示。相比
  • GPT4 VS Claude In MLIR

  • 本文构造了20个MLIR基础概念的问题以及使用OneFlow IR转换为Tosa IR的5个代码段来评测GPT4和Claude对于MLIR的掌握能力,我的结论是对于基础概念的理解Claude整体上和GPT4持平