当前位置: 首页 > news >正文

广东住房和城乡建设厅官方网站通辽市北京网站建设

广东住房和城乡建设厅官方网站,通辽市北京网站建设,怎么恶意点击对手竞价,网站备案期间临时网页Detr源码解读(mmdetection) 1、原理简要介绍 整体流程#xff1a; 在给定一张输入图像后#xff0c;1#xff09;特征向量提取#xff1a; 首先经过ResNet提取图像的最后一层特征图F。注意此处仅仅用了一层特征图#xff0c;是因为后续计算复杂度原因#xff0c;另外 在给定一张输入图像后1特征向量提取 首先经过ResNet提取图像的最后一层特征图F。注意此处仅仅用了一层特征图是因为后续计算复杂度原因另外由于仅用最后一层特征图故对小目标检测不友好这也是后续deformable detr改进的原因。 2添加位置编码信息 经F拉平成一维张量并添加上位置编码信息得到I。3Transformer中encoder部分4Transformer中decoder部分学习位置嵌入object queries。5FFN部分6后续匈牙利匹配损失计算。 2、mmdetection中源码介绍 2.1. 整体逻辑 Detr的内部逻辑如下在mmdet/models/detector/single_stage.py。即首先提取图像特征向量之后经过DetrHead来计算最终的损失。img[b,3,224,224] x[b,2048,7,7] def forward_train(self,img,img_metas,gt_bboxes,gt_labels,gt_bboxes_ignoreNone):super(SingleStageDetector, self).forward_train(img, img_metas)# img[b,3,224,224] x[b,2048,7,7]x self.extract_feat(img) # 提取图像特征向量 # 经过DetrHead得到loss losses self.bbox_head.forward_train(x, img_metas, gt_bboxes,gt_labels, gt_bboxes_ignore)return lossesforward_train 跟其他的检测头差不多先是调用自己也就是自身的 forward 函数得到输出的 class label 和 reg coordinate再调用自身的 loss 函数不过这里是重载了一下将 img_meta 传输进了 forward 函数的参数。执行完outs self(x, img_metas)跳转到forward的num_levels len(feats) def forward_train(self,x,img_metas,gt_bboxes,gt_labelsNone,gt_bboxes_ignoreNone,proposal_cfgNone,**kwargs):Forward function for training mode.Args:x (list[Tensor]): Features from backbone.img_metas (list[dict]): Meta information of each image每个图像的元信息, e.g.,image size, scaling factor, etc.gt_bboxes (Tensor): Ground truth bboxes of the image,图像的地面真相框shape (num_gts, 4).gt_labels (Tensor): Ground truth labels of each box,shape (num_gts,).gt_bboxes_ignore (Tensor): Ground truth bboxes to be ignored,要忽略的基本事实框shape (num_ignored_gts, 4).proposal_cfg (mmcv.Config): Test / postprocessing configuration,测试/后处理配置if None, test_cfg would be used.Returns:dict[str, Tensor]: A dictionary of loss components.损失成分词典。assert proposal_cfg is None, proposal_cfg must be Noneouts self(x, img_metas) #x[b,2048,7,7]if gt_labels is None:loss_inputs outs (gt_bboxes, img_metas)else:loss_inputs outs (gt_bboxes, gt_labels, img_metas)losses self.loss(*loss_inputs, gt_bboxes_ignoregt_bboxes_ignore)return losses执行完outs self(x, img_metas)跳转到forward的num_levels len(feats)。feats[b,2048,7,7] def forward(self, feats, img_metas):#这里默认为1因为DETR默认用最后一层特征图num_levels len(feats)img_metas_list [img_metas for _ in range(num_levels)]return multi_apply(self.forward_single, feats, img_metas_list)执行完return multi_apply(self.forward_single, feats, img_metas_list)跳转到forward_single函数 2.2. 图像特征向量提取 mmdet中提取图像特征向量的config配置文件如下可以发现用ResNet50并只提取了最后一层特征层即out_indices(3,)。骨干网络会输出特征图的1/32输入为【23224224】。通过backbone后得到图像大小为【2, 2048, 7, 7】和mask大小为【277】 backbonedict(typeResNet,depth50,num_stages4,out_indices(3, ), # detr仅要resnet50的最后一层特征图并不需要FPNfrozen_stages1,norm_cfgdict(typeBN, requires_gradFalse),norm_evalTrue,stylepytorch,init_cfgdict(typePretrained, checkpointtorchvision://resnet50))2.3. 给图像特征向量添加位置编码信息forward_single函数里面是 head 前向的逻辑。 本部分代码来自mmdet/models/dense_heads/detr_head.py的 forward_single函数中。   mmdet中生成位置编码信息借助的是mask矩阵所谓的mask就是为了统一批次大小而对图像进行了pad被填充的部分在后续计算多头注意力时应该舍弃故需要一个mask矩阵遮挡住具体形状为[batch, h,w]这里先贴下生成mask的过程 batch_size x.size(0) input_img_h, input_img_w img_metas[0][batch_input_shape]# 一个批次图像大小 # 先将 mask 设置为全 1 masks x.new_ones((batch_size, input_img_h, input_img_w)) # [b,224,224] # 对每一张图来说在原来图片有像素的地方把 mask 置 0 # 因此 mask 中 padding 的地方才是 1 for img_id in range(batch_size):img_h, img_w, _ img_metas[img_id][img_shape] # 创建了一个mask非0代表无效区域 0 代表有效区域masks[img_id, :img_h, :img_w] 0 # 将pad部分置为1非pad部分置为0.输入图像的经过resnet50下采样后hw已经变了所以还需进一步将mask下采样成和图像特征向量一样的shape。代码如下 # 将每一层的特征图先投影到指定的特征维度,2048通道太多了转成256通道 x self.input_proj(x) #Conv2d(self.in_channels, self.embed_dims, kernel_size1)#[b,256,7,7] # interpolate masks to have the same spatial shape with x masks F.interpolate( #masks[b,7,7]masks.unsqueeze(1), sizex.shape[-2:]).to(torch.bool).squeeze(1) # masks和x的shape一样[b,2,2]后续便可以生成位置编码部分mmdet/models/utils/position_encoding.py代码里采用了sine位置编码该函数给masks的每个像素位置生成了一个256维的唯一的位置向量。shape[B, 256, 7, 7] # position encoding pos_embed self.positional_encoding(masks)2.4 送入Transformer 4.1. 整体逻辑 在得到图像特征向量x[b,256,7,7]、masks[b,7,7]矩阵以及位置编码pos_embed[b,256,7,7]后便可送入Transformer。进入transformer的之前四个变量维度分别为, x-[2, 256, 7, 7],mask-[2, 7, 7],query_embed-[100, 256],pos_embed-[2, 256, 7, 7] # outs_dec: [nb_nb_decdec, bs, num_query, embed_dim] outs_dec, _ self.transformer(x, masks, self.query_embedding.weight,pos_embed)在进入transformer之前定义了一个query_embed(就是后边的object query),其第一个维度为num_queries原文解释为一张图片里的最大检测数量第二个维度为hidden_dim就是256。 self.query_embedding nn.Embedding(self.num_query, self.embed_dims)关键是理清encoder和decoder的QKV分别指啥 本部分代码来自mmdet\models\utils\transformer.py的 Transformer函数中。看代码 bs, c, h, w x.shape# use view instead of flatten for dynamically exporting to ONNXx x.view(bs, c, -1).permute(2, 0, 1) # [bs, c, h, w] - [h*w, bs, c] [49,2,256]pos_embed pos_embed.view(bs, c, -1).permute(2, 0, 1) # [49,2,256]query_embed query_embed.unsqueeze(1).repeat( #[100,b,256]1, bs, 1) # [num_query, dim] - [num_query, bs, dim]mask mask.view(bs, -1) # [bs, h, w] - [bs, h*w] [2,49]经过变换后的四个变量维度分别为, img-[49, 2, 256],mask-[2, 49],query_embed-[100, 2, 256],pos_embed-[49, 2, 256]memory self.encoder(queryx, # [49,b,256]keyNone,valueNone,query_pospos_embed, # [49,b,256]query_key_padding_maskmask) # [b,49]target torch.zeros_like(query_embed) # decoder初始化全0# out_dec: [num_layers, num_query, bs, dim]out_dec self.decoder(querytarget, # 全0的target, 后续在MultiHeadAttn中执行了keymemory, # query query query_pos又加回去了。valuememory,key_pospos_embed,query_posquery_embed, # [num_query, bs, dim]key_padding_maskmask)# outs_dec: [nb_nb_decdec, bs, num_query, embed_dim] [6,2,100,256]out_dec out_dec.transpose(1, 2)memory memory.permute(1, 2, 0).reshape(bs, c, h, w)return out_dec, memory其中encoder中q就是xkv分别为Nonequery_pos代表位置编码而query_key_padding_mask就是mask。decoder的q是全0的target后续decoder会迭代更新q而kv则 是memory即encoder的输出key_pos依旧是k的位置信息query_embed即论文中Object query可学习位置信息key_padding_mask依然是mask。 4.2. encoder部分 先看下encoder初始化部分内部循环调用了6次BaseTransformerLayer因此只需讲解一层EncoderLayer即可。将img,mask,pos_embed送入transformer encoder中进行注意力操作。得到[49, 2, 256]的输出 encoderdict(typeDetrTransformerEncoder,num_layers6, # 经过6层Layertransformerlayersdict( # 每层layer内部使用多头注意力typeBaseTransformerLayer,attn_cfgs[dict(typeMultiheadAttention,embed_dims256, num_heads8,dropout0.1)],feedforward_channels2048, # FFN中间层的维度 ffn_dropout0.1,operation_order(self_attn, norm, ffn, norm))), # 定义运算流程先跳转到mmdet\models\utils\transformer.py的DetrTransformerEncoder函数。再来看下BaseTransformerLayer的forward部分。该部分可以损失detr的核心部分了因为本质上mmdet内部只是封装了pytorch现有的nn.MultiHeadAtten函数。所以需要理解nn.MultiHeadAttn中两种mask参数的含义限于篇幅原因这里可参考nn.Transformer来理解这两个mask。 不过简单理解就是attn_mask在detr中没用到仅用key_padding_mask。attn_mask是为了遮挡未来文本信息用的而图像可以看到全部的信息因此不需要用attn_mask。 def forward(self,query,keyNone,valueNone,query_posNone,key_posNone,attn_masksNone,query_key_padding_maskNone,key_padding_maskNone,**kwargs):#Forward function for TransformerDecoderLayer.norm_index 0attn_index 0ffn_index 0identity queryif attn_masks is None:attn_masks [None for _ in range(self.num_attn)]elif isinstance(attn_masks, torch.Tensor):attn_masks [copy.deepcopy(attn_masks) for _ in range(self.num_attn)]warnings.warn(fUse same attn_mask in all attentions in f{self.__class__.__name__} )else:assert len(attn_masks) self.num_attn, fThe length of \fattn_masks {len(attn_masks)} must be equal \fto the number of attention in \foperation_order {self.num_attn}for layer in self.operation_order: # 遍历config文件的顺序if layer self_attn:temp_key temp_value query query self.attentions[attn_index]( # 内部调用nn.MultiHeadAttnquery,temp_key,temp_value,identity if self.pre_norm else None,query_posquery_pos, # 若有位置编码信息则和query相加 key_posquery_pos, # 若有位置编码信息则和key相加 attn_maskattn_masks[attn_index],key_padding_maskquery_key_padding_mask,**kwargs)attn_index 1identity queryelif layer norm:query self.norms[norm_index](query) # 层归一化norm_index 1elif layer cross_attn: # decoder用到query self.attentions[attn_index]( query,key,value,identity if self.pre_norm else None,query_posquery_pos, # 若有位置编码信息则和query相加 key_poskey_pos, # 若有位置编码信息则和key相加 attn_maskattn_masks[attn_index],key_padding_maskkey_padding_mask,**kwargs)attn_index 1identity queryelif layer ffn: # 残差连接加全连接层query self.ffns[ffn_index](query, identity if self.pre_norm else None)ffn_index 1return querydecoder部分和encoder流程类似只是多了交叉注意力。decoder部分将[49,2,256]的输出和query_embed[100,2,256]输入到transformer decoder中得到[6, 2, 100, 256]的输出。这里是合并了6个不同层级解码层的输出其实只需要最后一层即可。 decoder这里其实是将query_embed和feature做了注意力机制q为query_embed[100, 2, 256]k为memory也就是feature[49, 2, 256],v也是memory[49, 2, 256]。 ** 总结 ** decoder的输出经过Prediction feed-forward networks (FFNs)生成最终的预测。即[6,2,100,256]经过线性层生成[6,2,100,92]的类别预测经过线性层生成[6, 2, 100, 4]的框坐标预测。 由于后续在detr上改进的论文对匈牙利算法以及loss计算改动不大因此这部分代码就不讲解了。
http://www.lakalapos1.cn/news/19741/

相关文章:

  • 国内包装设计网站百度一对一解答
  • 网站建设策划基本流程图顺德微网站建设
  • 手机端的网站首页该怎么做wordpress 安装教程
  • 什么是门户类型的网站图书馆网站建设情况
  • 全椒做网站网站建设招标评分
  • 长沙做网站优化wordpress好用的空间
  • 广告公司网站建设策划书如何发布视频赚钱
  • 互联网网站名字网站建设及运行情况介绍
  • 唐山建讯网站微信公众平台号申请注册入口
  • 网站上传文件夹鞍山58同城招聘网最新招聘
  • 深圳有做网站的公司python微信小程序开发教程
  • 石家庄网站建设推广公司哪家好百度权重网站排名
  • 企业网站怎么做推广比较好服装公司网站建设
  • 唐河永琚建筑公司网站国内十大旅游网站排名
  • 龙禧网站建设手机网卡
  • 做网站不用tomcat行吗南京软件网站建设公司
  • jsp网站开发实训报告做请柬的网站
  • 国外专业做集装箱别墅网站王野摩托车是什么牌子
  • 微信网站对接做网站必须开厂吗
  • 网站从域名网站详情一般是什么公司做
  • 站群管理系统苏州seo
  • 人力资源网站模板免费申请电信卡
  • 怎么做资源类网站网站开发实用技术第2版课后答案
  • 网站建设软件免费被官方认可赚钱游戏
  • 个人能建什么样的网站网站用excel做数据库
  • 中资源 网站域名解析seo是什么的简称
  • 网站软件定制开发制作外贸销售渠道
  • 歌手投票网站怎么做长清做网站
  • 网站改版 合同保定网站制作公司
  • 网站制作模板代码html免费如何做网站淘客推广