惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
GRAHAM CLULEY
V
V2EX
WordPress大学
WordPress大学
博客园 - Franky
Last Week in AI
Last Week in AI
博客园 - 司徒正美
有赞技术团队
有赞技术团队
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 【当耐特】
V
Visual Studio Blog
C
CERT Recently Published Vulnerability Notes
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Jina AI
Jina AI
Attack and Defense Labs
Attack and Defense Labs
腾讯CDC
The Hacker News
The Hacker News
Hugging Face - Blog
Hugging Face - Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
J
Java Code Geeks
人人都是产品经理
人人都是产品经理
阮一峰的网络日志
阮一峰的网络日志
T
Tailwind CSS Blog
S
SegmentFault 最新的问题
大猫的无限游戏
大猫的无限游戏
小众软件
小众软件
A
Arctic Wolf
量子位
博客园 - 聂微东
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
N
News and Events Feed by Topic
雷峰网
雷峰网
博客园_首页
Google Online Security Blog
Google Online Security Blog
Spread Privacy
Spread Privacy
罗磊的独立博客
H
Hacker News: Front Page
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
月光博客
月光博客
TaoSecurity Blog
TaoSecurity Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
博客园 - 三生石上(FineUI控件)
宝玉的分享
宝玉的分享
IT之家
IT之家
The Cloudflare Blog
爱范儿
爱范儿
博客园 - 叶小钗
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Apple Machine Learning Research
Apple Machine Learning Research
酷 壳 – CoolShell
酷 壳 – CoolShell

博客园 - 无左无右

mmdetection3d-1.0.0rc0 安裝 左乘和右乘,行向量和列向量 grep -rl "math\.tan" /media/data_1/everyday/2025_down --include="*.py" - 无左无右 已知相机到车的rt 4x4矩阵,求pitch和yaw角度 torch.where(condition, x, y) 是一个三元运算符:如果条件为真,取 x 的值;如果条件为假,保持 y(即原本的 weights)不变。 for decoder_idx, (cls, reg) in enumerate(zip(cls_scores, reg_preds)): log_str += ', '.join(log_items) 左乘与右乘 GridMask--随机用“网格状”的遮挡去盖住图片的一部分,迫使模型学习更鲁棒的特征。 obtain_sensor2top函数, sensor → ego_s → global → ego_lidar → lidar assert osp.exists(self.table_root), 'Database version not found: {}'.format(self.table_root) Deformable-DETR 网页绘图,无需注册 value = value.masked_fill(input_padding_mask[..., None], float(0)) 点云绕不同的轴旋转可视化,roll,pitch,yaw 相机坐标系转车辆坐标系以及相反, RT矩阵,旋转变换P_cam = rot_car2cam * P_car + trans_car2cam; P_cam = rot * (P_car - trans) 连续200帧的ego的RT矩阵R_prevel2wld,shape是[200,4,4],目标的rt矩阵的R_curpt2curvels的shape是[87, 200, 4, 4], 87是目标数量, 把t11时刻的目标对齐到t0, numpy实现 vscode launch.json debug 带caffe库的工程代码 标注工具--抹除目标 ubuntu1804安装 mmdet3d 0.17.1 报错与解决 np.stack(a,axis=x), x=0,1,2 外参扰动 car_noise2cam = car2cam @ car_noise2car BEVDet-net部分 TP, FP, precision, recall bevdepth- 数据处理部分 ubuntu 硬盘挂载,重启后硬盘掉了 create_frustum 分析 (frustum = torch.stack((x_coords, y_coords, d_coords, paddings), -1)) sweep_lidar_depth = sweep_lidar_depth.reshape(batch_size * num_cams, *sweep_lidar_depth.shape[2:]) torch.where(condition, x, y) 自动驾驶,单目3D中的alpha角度
DETR
无左无右 · 2026-02-25 · via 博客园 - 无左无右

Image


CNN Backbone


Feature Map


Flatten + Position Encoding


Transformer Encoder


Transformer Decoder (object queries)


MLP Head

├── Class
└── Box

位置编码

class PositionEmbeddingSine(nn.Module):
    """
    This is a more standard version of the position embedding, very similar to the one
    used by the Attention is all you need paper, generalized to work on images.
    """
    def __init__(self, num_pos_feats=64, temperature=10000, normalize=False, scale=None):
        super().__init__()
        self.num_pos_feats = num_pos_feats
        self.temperature = temperature
        self.normalize = normalize
        if scale is not None and normalize is False:
            raise ValueError("normalize should be True if scale is passed")
        if scale is None:
            scale = 2 * math.pi
        self.scale = scale

    def forward(self, tensor_list: NestedTensor):
        x = tensor_list.tensors #torch.Size([2, 2048, 27, 32])
        mask = tensor_list.mask #torch.Size([2, 27, 32])
        assert mask is not None
        not_mask = ~mask
        y_embed = not_mask.cumsum(1, dtype=torch.float32) #torch.Size([2, 27, 32])
        x_embed = not_mask.cumsum(2, dtype=torch.float32) #torch.Size([2, 27, 32])
        if self.normalize:
            eps = 1e-6
            y_embed = y_embed / (y_embed[:, -1:, :] + eps) * self.scale
            x_embed = x_embed / (x_embed[:, :, -1:] + eps) * self.scale

        dim_t = torch.arange(self.num_pos_feats, dtype=torch.float32, device=x.device) #[128]
        dim_t = self.temperature ** (2 * (dim_t // 2) / self.num_pos_feats) #[128]

        pos_x = x_embed[:, :, :, None] / dim_t #torch.Size([2, 27, 32, 128])  # x_embed[:, :, :, None]torch.Size([2, 27, 32, 1]) 
        pos_y = y_embed[:, :, :, None] / dim_t #torch.Size([2, 27, 32, 128])
        
        #pos_x[:, :, :, 0::2] torch.Size([2, 27, 32, 64])  
        #torch.stack((pos_x[:, :, :, 0::2].sin(), pos_x[:, :, :, 1::2].cos()), dim=4) torch.Size([2, 27, 32, 64, 2])
        pos_x = torch.stack((pos_x[:, :, :, 0::2].sin(), pos_x[:, :, :, 1::2].cos()), dim=4).flatten(3) #torch.Size([2, 27, 32, 128])      
        pos_y = torch.stack((pos_y[:, :, :, 0::2].sin(), pos_y[:, :, :, 1::2].cos()), dim=4).flatten(3)#torch.Size([2, 27, 32, 128]) 
        #torch.cat((pos_y, pos_x), dim=3) torch.Size([2, 27, 32, 256])
        pos = torch.cat((pos_y, pos_x), dim=3).permute(0, 3, 1, 2) #pos torch.Size([2, 256, 27, 32])      
        return pos

这里mask是同一个batch图像大小不一样,把同一个batch里面图像统一成一样,小的图pad补充1,原图区域是0。 not_mask = ~mask是原图区域。
图片

ENCODE

图片

#src [h*w, b, 256]   mask[b, h*w]  pos_embed [h*w, b, 256]  
memory = self.encoder(src, src_key_padding_mask=mask, pos=pos_embed) #[672, b, 256]
 def with_pos_embed(self, tensor, pos: Optional[Tensor]):
        return tensor if pos is None else tensor + pos

	self.self_attn = nn.MultiheadAttention(d_model, nhead, dropout=dropout)

    def forward_post(self,
                     src,
                     src_mask: Optional[Tensor] = None,
                     src_key_padding_mask: Optional[Tensor] = None,
                     pos: Optional[Tensor] = None):
        q = k = self.with_pos_embed(src, pos) #src pos [h*w, b, 256]
        src2 = self.self_attn(q, k, value=src, attn_mask=src_mask,
                              key_padding_mask=src_key_padding_mask)[0] #src_key_padding_mask[b, h*w]
        src = src + self.dropout1(src2)
        src = self.norm1(src)
        src2 = self.linear2(self.dropout(self.activation(self.linear1(src))))
        src = src + self.dropout2(src2)
        src = self.norm2(src)
        return src #[h*w, b, 256]
        
        
        
class TransformerEncoder(nn.Module):

    def __init__(self, encoder_layer, num_layers, norm=None):
        super().__init__()
        self.layers = _get_clones(encoder_layer, num_layers)
        self.num_layers = num_layers
        self.norm = norm

    def forward(self, src,
                mask: Optional[Tensor] = None,
                src_key_padding_mask: Optional[Tensor] = None,
                pos: Optional[Tensor] = None):
        output = src

        for layer in self.layers: #layer 就是 forward_post
            output = layer(output, src_mask=mask,
                           src_key_padding_mask=src_key_padding_mask, pos=pos)

        if self.norm is not None:
            output = self.norm(output)

        return output   

DECODE

self.query_embed = nn.Embedding(num_queries, hidden_dim) #100, 256
query_embed = self.query_embed.weight  #[100, 256]

query_embed = query_embed.unsqueeze(1).repeat(1, bs, 1) #[100, b, 256]     query_embed[100,256]
mask = mask.flatten(1) #[b, h*w]

tgt = torch.zeros_like(query_embed) #[100, b, 256]
memory = self.encoder(src, src_key_padding_mask=mask, pos=pos_embed) #[h*w, b, 256]

#tgt [100, b, 256]  memory[h*w, b, 256] mask[b, h*w]  pos_embed[h*w, b, 256]  query_embed[100, b, 256]
hs = self.decoder(tgt, memory, memory_key_padding_mask=mask,
                  pos=pos_embed, query_pos=query_embed)




def forward_post(self, tgt, memory,
                 tgt_mask: Optional[Tensor] = None,
                 memory_mask: Optional[Tensor] = None,
                 tgt_key_padding_mask: Optional[Tensor] = None,
                 memory_key_padding_mask: Optional[Tensor] = None,
                 pos: Optional[Tensor] = None,
                 query_pos: Optional[Tensor] = None):
    q = k = self.with_pos_embed(tgt, query_pos) #tgt, query_pos [100, b, 256]
    tgt2 = self.self_attn(q, k, value=tgt, attn_mask=tgt_mask,
                          key_padding_mask=tgt_key_padding_mask)[0] #[100, b, 256]
    tgt = tgt + self.dropout1(tgt2)
    tgt = self.norm1(tgt) #[100, b, 256]
    
    #tgt query_pos [100, b, 256]
    #memory  pos [h*w, b, 256]
    #memory_mask None
    #memory_key_padding_mask[b, h*w]
    #self.multihead_attn = nn.MultiheadAttention(d_model, nhead, dropout=dropout)
    tgt2 = self.multihead_attn(query=self.with_pos_embed(tgt, query_pos),
                               key=self.with_pos_embed(memory, pos),
                               value=memory, attn_mask=memory_mask,
                               key_padding_mask=memory_key_padding_mask)[0] # [100, b, 256]
    tgt = tgt + self.dropout2(tgt2) # [100, b, 256]
    tgt = self.norm2(tgt)
    tgt2 = self.linear2(self.dropout(self.activation(self.linear1(tgt))))
    tgt = tgt + self.dropout3(tgt2)
    tgt = self.norm3(tgt)
    return tgt

图片

图片

在 decoder layer 里通常是:

# 1. self-attention (query ↔ query)
tgt = self.self_attn(tgt + query_pos)

# 2. cross-attention (query ↔ image)
tgt = self.multihead_attn(tgt + query_pos, memory + pos, memory)

# 3. FFN
tgt = self.ffn(tgt)

out

#[6, b, 100, 256]
hs = self.transformer(self.input_proj(src), mask, self.query_embed.weight, pos[-1])[0] 
#[6, b, 100, 92]
outputs_class = self.class_embed(hs)
#[6, b, 100, 4]
outputs_coord = self.bbox_embed(hs).sigmoid()

LOSS

图片

class HungarianMatcher(nn.Module):
    """This class computes an assignment between the targets and the predictions of the network

    For efficiency reasons, the targets don't include the no_object. Because of this, in general,
    there are more predictions than targets. In this case, we do a 1-to-1 matching of the best predictions,
    while the others are un-matched (and thus treated as non-objects).
    """

    def __init__(self, cost_class: float = 1, cost_bbox: float = 1, cost_giou: float = 1):
        """Creates the matcher

        Params:
            cost_class: This is the relative weight of the classification error in the matching cost
            cost_bbox: This is the relative weight of the L1 error of the bounding box coordinates in the matching cost
            cost_giou: This is the relative weight of the giou loss of the bounding box in the matching cost
        """
        super().__init__()
        self.cost_class = cost_class
        self.cost_bbox = cost_bbox
        self.cost_giou = cost_giou
        assert cost_class != 0 or cost_bbox != 0 or cost_giou != 0, "all costs cant be 0"

    @torch.no_grad()
    def forward(self, outputs, targets):
        """ Performs the matching

        Params:
            outputs: This is a dict that contains at least these entries:
                 "pred_logits": Tensor of dim [batch_size, num_queries, num_classes] with the classification logits
                 "pred_boxes": Tensor of dim [batch_size, num_queries, 4] with the predicted box coordinates

            targets: This is a list of targets (len(targets) = batch_size), where each target is a dict containing:
                 "labels": Tensor of dim [num_target_boxes] (where num_target_boxes is the number of ground-truth
                           objects in the target) containing the class labels
                 "boxes": Tensor of dim [num_target_boxes, 4] containing the target box coordinates
        Returns:
            A list of size batch_size, containing tuples of (index_i, index_j) where:
                - index_i is the indices of the selected predictions (in order)
                - index_j is the indices of the corresponding selected targets (in order)
            For each batch element, it holds:
                len(index_i) = len(index_j) = min(num_queries, num_target_boxes)
        """
        bs, num_queries = outputs["pred_logits"].shape[:2]
        #outputs["pred_logits"] [b, 100, 92]   flatten(0, 1) [100*b, 92]
        #outputs["pred_boxes"] [b, 100, 4] flatten(0, 1)  [100*b, 4]
        # We flatten to compute the cost matrices in a batch
        out_prob = outputs["pred_logits"].flatten(0, 1).softmax(-1)  # [batch_size * num_queries, num_classes]
        out_bbox = outputs["pred_boxes"].flatten(0, 1)  # [batch_size * num_queries, 4]

        # Also concat the target labels and boxes
        tgt_ids = torch.cat([v["labels"] for v in targets]) #[num_objs]
        tgt_bbox = torch.cat([v["boxes"] for v in targets]) #[num_objs, 4]

        # Compute the classification cost. Contrary to the loss, we don't use the NLL,
        # but approximate it in 1 - proba[target class].
        # The 1 is a constant that doesn't change the matching, it can be ommitted.
        cost_class = -out_prob[:, tgt_ids] #[100*b, num_objs]

        # Compute the L1 cost between boxes
        cost_bbox = torch.cdist(out_bbox, tgt_bbox, p=1)    #[100*b, num_objs]

        # #[100*b, num_objs] Compute the giou cost betwen boxes
        cost_giou = -generalized_box_iou(box_cxcywh_to_xyxy(out_bbox), box_cxcywh_to_xyxy(tgt_bbox))

        # Final cost matrix
        C = self.cost_bbox * cost_bbox + self.cost_class * cost_class + self.cost_giou * cost_giou
        C = C.view(bs, num_queries, -1).cpu() #[b, 100, num_objs]

        sizes = [len(v["boxes"]) for v in targets] #[2, 1,...] b个
        indices = [linear_sum_assignment(c[i]) for i, c in enumerate(C.split(sizes, -1))] #[[[49, 62], [1, 0]], [[35], [0]]]
        #这里就代表batch0的有2个目标,用id49去匹配gt1, 用id62去匹配gt0
        return [(torch.as_tensor(i, dtype=torch.int64), torch.as_tensor(j, dtype=torch.int64)) for i, j in indices]

然后就拿匹配到的idx去计算loss

 def get_loss(self, loss, outputs, targets, indices, num_boxes, **kwargs):
        loss_map = {
            'labels': self.loss_labels,
            'cardinality': self.loss_cardinality,
            'boxes': self.loss_boxes,
            'masks': self.loss_masks
        }
        assert loss in loss_map, f'do you really want to compute {loss} loss?'
        return loss_map[loss](outputs, targets, indices, num_boxes, **kwargs)
       
   self.get_loss(loss, outputs, targets, indices, num_boxes)
   
    def loss_labels(self, outputs, targets, indices, num_boxes, log=True):
        """Classification loss (NLL)
        targets dicts must contain the key "labels" containing a tensor of dim [nb_target_boxes]
        """
        assert 'pred_logits' in outputs
        src_logits = outputs['pred_logits']

        idx = self._get_src_permutation_idx(indices)
        target_classes_o = torch.cat([t["labels"][J] for t, (_, J) in zip(targets, indices)])
        target_classes = torch.full(src_logits.shape[:2], self.num_classes,
                                    dtype=torch.int64, device=src_logits.device)
        target_classes[idx] = target_classes_o

        loss_ce = F.cross_entropy(src_logits.transpose(1, 2), target_classes, self.empty_weight)
        losses = {'loss_ce': loss_ce}

        if log:
            # TODO this should probably be a separate loss, not hacked in this one here
            losses['class_error'] = 100 - accuracy(src_logits[idx], target_classes_o)[0]
        return losses   

问题1:detr为什么不能用很大的分辨率?

detr用的下采样32倍去计算,计算量与大小成平方关系
图片

图片

图片

图片

问题2:transform如何每个元素与其他元素都有联系的

图片