• VIT、Swim-trans、DETR最全流程讲解


    一:VIT

    整体流程:

    • 2D卷积进行patch_embed
    • 加入一维的类别编码
    • 进行位置编码,完成这一套流程变成了[B, N, C]
    • 输入进encorder的block模块中
    • block中进行了multi-attention,mlp,drop,shortcut等操作,此时输出的还是[B, N, C]
    • 最后只提取[:,0]输入进Head层,经过两层fc,最终网络输出为[B, 1, num_classes]
    • 后面就是softmax,交叉熵损失,完成任务!

    二:Swim-trans

    整体流程:

    • 2D卷积进行patch_embed,变形为[B Ph*Pw C],然后再进入一个[hidden_dim, hidden_dim]的fc层
    • 进行位置编码 nn.Parameter(torch.zeros(1, num_patches, embed_dim))
    • 下面进入多个basicLayer层中,每个Layer层主要由多对SwinTransformerBlock层组成
    • 对输出的[B L C]变形为[B C L],然后平均池化,变为[B C 1],最后flatten(1),最后输出结果[B, C]

    Block中的处理流程:

    • 将[B Ph*Pw C]变为[B, H, W, C]
    • 偶数Block层进行W-MSA,奇数层SW-MSA,这里主要对奇数层讲解
    • 进行torch.roll操作,整合分散窗口
    • 进行window_partition,[B, H, W, C]变为[nW*B, window_size, window_size, C]
    • 再变形为[nWB, window_sizewindow_size, C]输入进self.attn,对每个窗口进行自注意力运算,注意!!对于SW,需要对attention矩阵加入mask掩码,这样才是对每个分裂的小窗口真正的注意力运算。其中还有一处细节,就是对于每个窗口都加入了位置编码。最后输出[nWB, window_sizewindow_size, C]
    • 对输出还原成[nW*B, window_size, window_size, C],然后进行window_reverse,还原成[B H’ W’ C]
    • 如果是SW层,需要进行torch.roll,再进行特征图还原
    • 最后变形为[B Ph*Pw C],进行MLP、shortcut等操作并输出

    Layer中的处理流程:

    • 经过多层Block后,将[B Ph*Pw C]输入下采样层
    • 将[B Ph*Pw C]变形为[B, H, W, C],然后下采样
    • 下采样方式是间隔着取出四个特征层,然后对通道层进行拼接,成为[B, H//2, W//2, 4*C]
    • 变形为[B, H//2*W//2, 4×C]输入进fc层,缩减C通道维度为2C
    • 最后输出结果[B, H//2*W//2, 2C]

    三:DETR

    整体流程:

    • 对原图[B C H W]进行几层resnet50,取最后一层,并通过1×1卷积层将通道数变为hidden_dim,生成src特征图
    • 通过nn.embedding设位置编码pos_embed,提前存[50, hidden_dim]组备用,这种方法和VIT、Swim-Trans的有差别,原因就是这里允许不同大小的输入图像。将src和pos_embed输入进transformer中
    • transformer模块中, 将src和pos_embed先变形为[H*W B hidden_dim],然后先输入Encoder层,再出入Decoder层中。注意!!设置一个tgt,和预先设置的query_pos的大小相同( tgt = torch.zeros_like(query_embed)),query_embed = nn.Embedding(num_queries, hidden_dim),一般num_queries=100,代指最多100个预测框

    Encoder中的处理流程:

    • Encoder中包含多层encoderLayer层
    • Layer层主要做自注意力运算。Q、K的生成和以往不同,没有再创建Q、K生成矩阵,而是直接对src加上pos_embed,作为q、k(q = k = self.with_pos_embed(src, pos)),而v = src
    • 接下来,直接调用了nn.MultiheadAttention进行self-atention计算,生成了新src2,后面就是常规的mlp、shortcut、dropout等
    • 经过多层Layer后,norm()后得到Encoder最终输出memory ,大小为[H*W B hidden_dim]

    Decoder中的处理流程

    • Decoder中包括多层DncoderLayer
    • Layer层主要用来不断更新tgt,从刚开始的[0, 0, …, 0]变为具有一定含义的新特征。做法就是先对tgt自注意力,q = k = self.with_pos_embed(tgt, query_pos),v=tgt,然后nn.MultiheadAttention进行self-atention计算,生成了新的tgt。接着,进行交叉注意力,(tgt + query_embed)作为q,而K和V都来自memory+ pos_embed和memory,最后进行基本的mlp、dropout、norm操作,最后输出tgt,形状为[num_queries B hidden_dim]
    • Decoder在经过一系列的layer后,会将每次的layer输出的临时tgt存储,便于后期对每一层都计算loss,最终输出hs为
      [layer_num,num_queries ,B,hidden_dim]

    经过了Encoder-Decoder后,对输出的hs进行self.class_embed和self.bbox_embed,将通道数变为指定维度,用于后面计算损失。将hs[-1]取出作为最终预测值。最后对preds和tagets进行匈牙利匹配,找出哪儿几个query是负责预测的,然后才能计算损失。

  • 相关阅读:
    第四篇Android--TextView使用详解
    基于深度神经网络的社交媒体用户级心理压力检测
    基础算法C++讲解(目前更新至:双指针)
    全平台数据(数据库)管理工具 DataCap 管理 Rainbond 上的所有数据库
    CAN YOU UNDERSTAND YOUR CUSTOMER SENTIMENT?
    Andoird使用Room实现持久化及使用Room进行增删查改
    软件测试之集成测试
    “前端”工匠系列(一):合格的工匠,究竟该搞什么 | 京东云技术团队
    【小程序项目开发-- 京东商城】uni-app开发之轮播图
    CMOS IC功耗类型及其影响因素
  • 原文地址:https://blog.csdn.net/weixin_43702653/article/details/126069377