Zhangzhe's Blog

The projection of my life.

0%

URL

TL;DR

  • 本文介绍了一种 BEV 视角下的 3D 障碍物检测算法,该算法的输入是由多张(6张)图片组成的车身环视视角,输出为车身周围障碍物的 3D bbox

  • LSS(lift-splat-shoot) 算法较为相似,但任务不同,LSS 想要解决的是 BEV 视角下的分割问题,BEVDet 想要解决的是 3D 障碍物检测问题

  • FCOS3D 等单目 3D 障碍物检测的任务类型相似,区别在于:单目 3D 障碍物检测对每个视角做 3D 障碍物检测后,需要使用后处理融合跨视角的物体,BEVDet 可以将跨视角融合问题内嵌到模型中(BEV

Algorithm

总体结构

BevDet.png

由上图可以看出,模型主要由四个部分组成,分别是:

  • Image-view Encoder:图像特征提取(backbone + neck),6个视角分别做特征提取,不做视角间特征融合
  • View Transformer:视角变换(同时也实现了图像间信息融合),从图像视角转换为 BEV 视角,使用的方法和 LSS 方法一样,输出为 BEV feature
  • BEV Encoder:对 BEV feature 用一个较小的 BEV backbone 做特征提取
  • Head:任务头,预测 3D bbox 等,本文使用了 CenterPoint Head

算法流程的伪代码表示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 定义输入,shape: (8, 6, 256, 704, 3) [batch, camera, H, W, C]
input_images = get_input_images()

# 图像视图编码器,输出shape: (8, 6, 16, 44, 256) [batch, camera, H//16, W//16, C]
image_view_features = image_view_encoder(input_images)

# 视图变换器,输出shape: (8, 64, 128, 128) [batch, C, Bev_H, Bev_W]
transformed_features = view_transformer(image_view_features)

# BEV编码器,输出shape: (8, 256, 64, 64) [batch, C, Bev_H//2, Bev_W//2]
encoded_bev_features = bev_encoder(transformed_features)

# 任务特定头部进行3D物体检测,输出shape: (8, num_objects, object_info)
detection_results = task_specific_head(encoded_bev_features)

# 返回3D物体检测结果
return detection_results

数据增广方法

  • 独立图片空间数据增广:图片的翻转、裁剪和旋转可以用 3x3 矩阵表示,在 View Transformer 的时候需要做对应逆变换,即 同时更改图片和 View Transformer 过程

  • BEV视角下的数据增广:在BEV空间的学习中,数据量少于图像视图空间,因为每个样本包含多个摄像机图像,所以更容易过拟合;该增广方法遵循常见的 LiDAR 方法,采用了 2D 空间中的常见数据增广操作,如翻转、缩放和旋转,需要对应修改目标 3D bbox,即 同时更改 BEV Feature 和 3D bbox GT

Scale-NMS

  • 由于 BEV 空间中不同类别的空间分布与图像视图空间中的分布非常不同,所以作者提出了 Scale-NMS,在执行经典的 NMS 算法之前根据每个对象的类别来缩放每个对象的大小,可显著提高了对小面积类别(如行人和交通锥)的预测性能

Thought

  • 从模型结构和数据增广方式看 BEVDet 本质是一个二阶段算法:

    • image Encode + View Transformer:环视图像编码到 BEV 空间

    • BEV Encoder + Task HeadBEV 空间下的 3D 障碍物检测

  • 但第一阶段输出的 BEV Feature 没有用 LiDAR 点云监督就有点怪….(后续的改进算法加了)

URL

TL;DR

  • 提出了一个完全端到端的多目标跟踪框架

  • 将多目标跟踪问题形式化为一组序列预测问题

  • 引入了跟踪感知的标签分配

  • 提出了用于时间建模的集体平均损失和时间聚合网络方法

Algorithm

MOTR 整体流程

MOTR.png

  1. 特征提取:用 CNN backbone 提取连续帧中每一帧的特征(上图中的 Enc

  2. 查询生成:用 Deformable Transformer 对第一步提取的特征进行查询(上图中的 Dec

    • 对于视频第一帧,只解码 object detection query (上图中的 $q_d$ )得到 hidden state

    • 对于非第一帧,将 object detection query (上图中的 $q_d$ )和上一帧的 tracking query (上图中的 $q_{tr}$ )先 concat 再进行解码得到 hidden state

  3. 预测结果生成:用一个简单的结构将上一步得到的 hidden state 映射到任务空间,预测结果包含 object detection resultstracking results

  4. 得到下一帧的 tracking query:用 QIM (Query Interaction Module, 查询交互模块) 将上一步得到的预测结果映射为下一帧的 tracking query

  5. 计算损失 / 输出预测结果:对于训练,计算集体平均损失(CAL, Collective Average Loss);对于预测,直接输出第 3 步得到的结果

  • 描述 MOTR 过程的伪代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
def process_frame(frame, detect_queries, track_queries=None, ground_truths=None):
# 使用CNN提取帧特征
# frame shape: (height, width, channels)
frame_features = extract_frame_features(frame) # Shape: (height, width, channels)

if track_queries is None:
# 使用Deformable DETR解码器生成隐藏状态
# detect_queries shape: (num_queries, query_dim)
# frame_features shape: (height, width, channels)
hidden_states = deformable_detr_decoder(detect_queries, frame_features) # Shape: (num_queries, hidden_dim)
else:
queries = concatenate(track_queries, detect_queries) # Shape: (num_queries + num_tracks, query_dim)
hidden_states = deformable_detr_decoder(queries, frame_features) # Shape: (num_queries + num_tracks, hidden_dim)

# 生成预测
# hidden_states shape: (num_queries, hidden_dim)
predictions = predict(hidden_states) # Shape: (num_queries + num_tracks, num_classes + 4)

# 使用Query Interaction Module (QIM)生成下一帧的跟踪查询
# hidden_states shape: (num_queries, hidden_dim)
track_queries = qim(hidden_states) # Shape: (num_tracks, query_dim)

if ground_truths is not None:
# 使用Collective Average Loss (CAL)进行训练
# predictions shape: (num_queries, num_classes + 4)
# ground_truths shape: (num_objects, num_classes + 4)
loss = cal(predictions, ground_truths)
backpropagate(loss)

return predictions, track_queries # Shape: (num_queries + num_tracks, num_classes + 4), (num_tracks, query_dim)

def process_video(video, ground_truths=None):
# 初始化检测查询
# 返回形状:(num_queries, query_dim)
detect_queries = initialize_detect_queries()
track_queries = None # Shape: (num_tracks, query_dim)

for frame in video:
predictions, track_queries = process_frame(frame, detect_queries, track_queries, ground_truths)
if ground_truths is None:
yield predictions

查询交互模块

  • 查询交互模块 Query Interaction Module (QIM)MOTR 中的一个关键组件,它负责处理物体的进入和退出,以及增强长期的时间关系建模

  • QIM 的输入是当前帧预测的 detection resulttracking result,输出是下一帧的 tacking query

  • 通俗来说,QIM 是根据当前帧预测的结果,给出下一帧的 “提问”

  • QIM 过程的伪代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def query_interaction_module(hidden_states, scores, tau_en, tau_ex, M):
# hidden_states shape: (num_queries, hidden_dim)
# scores shape: (num_queries, num_classes)
# tau_en, tau_ex: entrance and exit thresholds
# M: number of consecutive frames for exit threshold

# Object Entrance
entrance_mask = scores.max(dim=1) > tau_en # Shape: (num_queries,)
hidden_states = hidden_states[entrance_mask] # Shape: (num_entrance_queries, hidden_dim)

# Temporal Aggregation Network (TAN),主要目的是融合时序信息,本文是用了一个 Multi-Head Self-Attention 实现
hidden_states = temporal_aggregation_network(hidden_states) # Shape: (num_entrance_queries, hidden_dim)

# Object Exit
exit_mask = scores.max(dim=1) < tau_ex # Shape: (num_entrance_queries,)
exit_mask = exit_mask.rolling(window=M).sum() > 0 # Shape: (num_entrance_queries,)
hidden_states = hidden_states[~exit_mask] # Shape: (num_track_queries, hidden_dim)

return hidden_states # Shape: (num_track_queries, hidden_dim)

集体平均损失

  • 集体平均损失(Collective Average Loss,CAL)是 MOTR 算法中用于训练的损失函数。不同于传统的逐帧计算损失,CAL 收集整个视频剪辑的所有预测,然后基于整个视频剪辑计算总体损失

  • 集体平均损失的代码描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def collective_average_loss(predictions, ground_truths, matching_results):
total_loss = 0
total_objects = 0

for i in range(len(predictions)):
pred_tracked = predictions[i]['tracked']
pred_detected = predictions[i]['detected']
gt_tracked = ground_truths[i]['tracked']
gt_detected = ground_truths[i]['detected']
match_tracked = matching_results[i]['tracked']
match_detected = matching_results[i]['detected']

total_loss += single_frame_loss(pred_tracked, match_tracked, gt_tracked)
total_loss += single_frame_loss(pred_detected, match_detected, gt_detected)

total_objects += len(gt_tracked) + len(gt_detected)

return total_loss / total_objects

Thought

  • 以一种非常优雅的方式解决了端到端多目标追踪的任务,打破了之前 NN detection + Hard logic code trackingtracking 范式

  • 这种非黑盒的(显式监督 detecion bbox)复杂任务端到端训练,启发了后续的许多更复杂的端到端任务,例如 UniAD

URL

TL;DR

  • 提出了 Deformable DETR:这是一种新的目标检测模型,解决了现有 DETR 模型的收敛速度慢和特征空间分辨率有限的问题。

  • 使用可变形的注意力模块:这些模块只关注参考点周围的一小部分关键采样点,从而在更少的训练周期内提高了性能,尤其是对小对象的检测。

  • 结合了可变形卷积的稀疏空间采样和 Transformer 的关系建模能力:这使得模型能够在处理大规模数据时保持高效,同时还能捕捉到复杂的上下文关系。

  • 引入了一种两阶段的变体:在这个变体中,区域提议由 Deformable DETR 生成,然后进行迭代的细化。这使得模型能够更精确地定位和识别目标。

Algorithm

deformable_detr.png

Deformable DETR 整体结构图

Deformabel Attention Block

deformable_attention.png

  • Multi-Head Attention:
    $MultiHeadAtten(z_q, x) = \sum_{m=1}^MW_m[\sum_{k\in\Omega_k}A_{mqk}\cdot W_m’x_k]$

    • 输入为一个 query 的表征 $z_q$ ,以及总特征 x,输出为 query 查询结果向量

    • M 表示 number of head

    • $A_{mqk}$ 表示 $softmax(\frac{QK^T}{\sqrt{d}})$

    • $W_m’x_k$ 实际上就是 self-attention 中的 $V$

  • Deformable Attention:
    $DeformableAtten(z_q,p_q,x) = \sum_{m=1}^MW_m[\sum_{k=1}^KA_{mqk}\cdot W_m’x(p_q + \Delta p_{mqk})]$

    • 输入为一个 query 的表征 $z_q$ ,总特征 x,以及 query 对应的 预设采样位置,输出为 query 查询结果向量

    • $\Delta p_{mqk}$ 表示由 $z_q$ 计算得到的 基于预设查询位置的横纵偏移

    • $A_{mqk} = softmax(z_qW_a)\ \ ,W_a\in\mathbb{R}^{dim\times num\_points}\ \ ,z_q\in\mathbb{R}^{dim}$ ,即 point position attention 是由 query 线性映射得到的 ,因此 Deformable Attention 没有 Key 的存在,只有 QueryValue

    • K 表示 number of points,即采样点个数

  • Multi-Scale Deformable Attention
    $MSDeformableAtten(z_q,\hat{p}_q,\{x\}_{l=1}^L) = \sum_{m=1}^MW_m[\sum_{l=1}^L\sum_{k=1}^KA_{mlqk}\cdot W_m’x^l(\phi_l(\hat{p}_q) + \Delta p_{mlqk})]$

    • Deformable Attention 不同的是,输入的 x 变成了多尺度特征(例如 backbone 不同深度的特征),更贴近实际视觉工程化应用场景

    • point 采样范围是所有 levelfeature map,即 MSDefromableAttention 有全局 attention 信息

  • Deformable AttentionSelf Attention 对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import torch
import torch.nn.functional as F
import math


def attention(query, key, value):
# query, key, value shapes: (batch_size, sequence_length, embedding_dim)
scores = torch.matmul(query, key.transpose(-2, -1)) / math.sqrt(query.size(-1))
# scores shape: (batch_size, sequence_length, sequence_length)
probs = F.softmax(scores, dim=-1)
# probs shape: (batch_size, sequence_length, sequence_length)
output = torch.matmul(probs, value)
# output shape: (batch_size, sequence_length, embedding_dim)
return output

def deformable_attention(query, value, reference_points, num_sampling_points, atten_linear, offset_linear):
# query shape: (batch_size, sequence_length, embedding_dim)
# value shape: (batch_size, sequence_length, embedding_dim)
# reference_points shape: (batch_size, sequence_length, 2)
# num_sampling_points: integer, number of points to sample around each reference point

batch_size, seq_len, embed_dim = query.size()

# Calculate offsets
# offset_linear is a linear layer that predicts the offsets
offsets = offset_linear(reference_points).view(batch_size, seq_len, num_sampling_points, 2)
# offsets shape: (batch_size, sequence_length, num_sampling_points, 2)

# Calculate sampling positions based on reference points
sampling_positions = reference_points.unsqueeze(2) + offsets
# sampling_positions shape: (batch_size, sequence_length, num_sampling_points, 2)

# Sample values (this is simplified; you might need interpolation)
# Here, we assume value and reference_points are in the same space for simplicity
sampling_values = value.gather(1, sampling_positions.long())
# sampling_values shape: (batch_size, sequence_length, num_sampling_points, embedding_dim)

# Calculate scores
# atten_linear is a linear layer that transforms the query for calculating attention scores
scores = atten_linear(query).view(batch_size, seq_len, num_sampling_points)
# scores shape: (batch_size, sequence_length, num_sampling_points)

# Softmax to get attention probabilities
probs = F.softmax(scores, dim=-1)
# probs shape: (batch_size, sequence_length, num_sampling_points)

# Calculate output
output = torch.matmul(probs, sampling_values)
# output shape: (batch_size, sequence_length, embedding_dim)

return output

Thought

  • query 线性映射代替 querykey 外积做 attention 数学上可解释性会变差,计算复杂度会降低

  • Deformable Conv 是典型的对 NPU 不友好,Deformable Attention 会更复杂,被代季峰支配的恐惧

  • Multi-scale 做各特征尺度上的信息融合,开创了一个 CNN 做 backbone + Deformable Transformer 做 head 的计算机视觉任务模型新范式,甚至省去了 FPN

  • 总之是用各种便宜的计算来近似复杂的全局 attention,复杂度从 H*W —> K,即 $O(n^2) -> O(K)$

TL;DR

  • 本文介绍了 YOLO 系列几种高效的 backbone 设计,主要包括:VoVNetPRNCSPNetELANE-ELAN

Algorithm

1. VoVNet

vovnet.png

  • 作者认为 densenet 存在问题:每一层 Conv 都使用之前所有层的输出,因此会导致当前 Convinput channel 很大,输出到 output channel 却较小

  • 因此,作者只在 VoVNet Block 的最后一个 Conv 才用之前所有层的输出

  • 相同计算量下,效果优于 ResnetDenseNet

2. PRN

prn.png

3. CSPNet(YOLOV5)

CSPNet.png

  • CPSNet 的全称是 Cross Stage Partial Networks, 本质是把模型分成两部分,其中一部分经过计算(几层 Conv)后和另外一部分合起来,相当于第二部分和第一部分模型深度不同

4. ELAN

elan.png

  • ELAN 全称是 Efficient Layer Aggregation Network, 作者以 VoVNetResNet 做对比,VoVNet 在叠加更多 block 时表现要比 ResNet 更差,作者分析是因为 VoVNet 结构中存在过多的 transition layers,这导致在叠加 block 时最短梯度路径( the shortest gradient path )不断增加,从而使得 block 增加时训练难度上升

  • PRN 相比 ResNet,使用 mask 让输入只有部分 channel 通过 identity connection,丰富了梯度来源;

  • CSPNet 通过将 channel split,一方面增加了梯度信息(同 PRN),另一方面减少了 computational block 中的计算量;

  • ELAN 的思想是:搭建网络时需要考虑每一层的最短最长梯度路径,还要考虑整个网络的最长梯度路径。

5. E-ELAN(YOLOV7)

eelan.png

  • E-ELANextended ELAN,在不改变 gradient path 的情况下,加入了 Group ConvShuffle and merge Conv 等操作,极大的提高了模型表现能力,成就了 YOLOV7 又快又好的效果!

URL

TL;DR

  • 本文提出一种以自动驾驶规划为目的的神经网络架构,该架构对每个感知子任务显式监督,合理的将子任务连接起来,增加了子任务之间的协调性,并增加了模型的可解释性

URL

TL;DR

  • 使用预测下一个词(语言建模 language modeling)任务进行自监督预训练
  • 预训练的模型需要使用 reinforement learning with human feedback(RLHF) 进行对齐(align),这个过程不会在测试数据集上提高模型表现,但可以更好的对齐人类的意图和三观
  • 模型输入可以是图片和文本,输出为文本

Details

  • 使用了很强大的基建,可以做到准确预测模型训练的最终效果(scaling),可以以较小的代价和较快的时间找到最合适的模型架构和超参数设置

  • 为模型引入了 steerability(操纵性),可以在模型的 prompt 中加入一些 System message,让模型回复风格拥有某种特质(比如老师、政客等)

  • GPT-4 使用了很多机制提高了模型的安全性

Thought

  • 这篇技术报告更多是对模型效果的分析,基本没有模型细节的描述
  • 大模型逐渐变成大厂垄断,普通研究者能摸到的最后只剩下一个 API

URL

TL;DR

  • 作者团队训练了一个 96Transformer1750 亿参数的超大模型(GPT2 只有约 15 亿参数),在下游任务上无需 fine-tuning 即可得到很好的效果。
  • 本质是 GPT2 的放大版(参数量放大了一百多倍)

Algorithm

  • 在下游任务上,可以使用 Zero ShotOne ShotFew Shot 三种方式推理模型,下图以英语翻译法语的例子介绍三者的区别:

GPT3.png

  • GPT3 系列模型详细设置:

GP3_1.png

  • GPT3 自监督训练数据:

GP3_2.png

使用了 common crawl 数据集,由于 common crawl 数据集很脏,所以训练是数据采样率并不高

  • 下图是在几个下游任务上和 SOTA 算法的比较:

GPT3_3.png

GPT3_5.png

GPT3_4.png

从普遍表现看,GPT3 few shot 效果 > one shot > zero shot,不一定比 SOTA 点高(SOTA 普遍使用了 fine tuning,直接比较不公平)

Thought

  • 在某些任务上,GPT3 few shot 效果可媲美 fine tuning SOTA,可以说明 GPT3 还是非常强大的

  • 比上一代参数量提高一百多倍,开启了大模型时代…

URL

TL;DR

  • 本文提出一种类似 chatGPT 的交互式 Zero-shot 分割算法,用户给出一个 prompt(支持 point / box / mask / text),模型会根据 Prompt 语义完成分割,无需在特定分割任务数据上 fine-tuning(类似于 GPT2 和之后的系列模型)
  • 本文一个非常重要的理念是 Data Centric,即以数据为中心而不是以模型为中心,这一点和 GPT 系列也不谋而合
    • 传统视觉算法是在固定的数据集上修改模型结构实现模型效果的提升,实际是以模型为中心
    • 数据为中心的算法通常固定模型结构,通过例如 RLHF(reinforcement learning from human feedback) 的方法,使用模型辅助标注员高效标注大量数据(11 亿个 mask 区域),重复迭代提高效果
  • 模型本身由三部分组成:
    • image_encoder:提取图片特征,使用的是 ViT 模型,在交互过程中只需要推理一次
    • prompt_encoder: 提取 prompt 特征,将人的输入(例如点或框)编码到特征空间
    • mask_decoder: 输入为图片特征和 prompt 特征,融合后输出分割 mask

Algorithm

任务定义

sam3.png

理论上支持 point / box / mask / text,但 demo 和 code 都只包含了 point / box / mask

模型结构

sam4.png

image encoder 是 VIT
prompt encoder 对于 box / point prompt 只是简单的位置编码;对于 mask 是几层简单的卷积
lightweight mask decoder 是轻量级 transformer

Data centric

sam2.png

模型为中心和数据为中心的对比

使用效果

sam1.png

图中的框为用户输入的 prompt,模型会根据 prompt 输出分割结果

Thought

  • Data centric 感觉一定是未来,但形式一定不会以 RLHF 形式存在,而更多的以自监督形式存在
  • prompt 未来会取代 fine-tuning 这个词

URL

TL;DR

  • Bert 全方位打败 GPT 之后,OpenAI 推出了参数量更大的 GPT2
  • GPT2 与之前所有的 NLP 预训练模型使用的 自监督预训练 + 任务相关 fine-tuning 范式不同,GPT2 不再需要任何数据相关 fine-tuning,而是使用 prompt(提示词)
  • prompt(提示词) 是一段在模型推理阶段用于描述任务的文本,通常加在问题之前,起到提示模型的作用

Algorithm

GPT2 很大程度上只是 GPT 的放大版,所引入的创新并不多

  • 使用了 Byte Pair Encoding(BPE) 分词算法,本质是一种贪心算法

  • 由于自回归(auto-regression)模型推理容易出现死循环,所以本文提出一种 top-k 输出按 softmax 概率采样的 trick,增加模型的随机性

Thought

  • GPT2 最重要的作用是提出了使用 Prompt 替代 fine-tuning 的范式,为之后的 AIGC 大面积推广扫平了障碍

URL

TL;DR

  • 本文基于 FCOS 论文提出一种架构简单的 Anchor Free 的单目 3D 检测算法 FCOS3D,在 NeurIPS 2020nuScenes 3D 检测比赛纯视觉赛道上取得了第一名。

Algorithm

问题定义

  • 本文提出的 FCOS3D 要解决的核心问题是一个 图片到 7-DoF 属性(x, y, z, w, l, h, yaw+dir)的预测

    • DoF 是指 degree of freedom(自由度)。

    • (x, y, z, w, l, h, yaw+dir) 分别表示物体在相机坐标系下的 3 维坐标和长宽高(单位都是米),和偏航角(俯视图角度,单位是弧度)和方向 2 分类共同构成朝向。

  • 对于 nuScenes 3D 检测比赛,还需要解决的非核心问题包括:

    • 预测出的 3D 框物体的类别(10类物体)

    • 预测出的 3D 框物体的属性(9种属性)

    • 预测出的 3D 框物体的 x, y 轴速度(不是 “病态” 问题了,已经属于癌症问题了….)

网络结构

fcos3d.png

  • backboneFPN 比较常规

  • decode headFCOS 一样,使用了不同 level feature 的参数共享(反正是全卷积,不存在 shape 问题)

  • decode head 中包括:

    • 分类分支:

      • class: output_shape = (N, 10, H, W),使用 FocalLoss

      • attribute: output_shape = (N, 9, H, W),使用 CrossEntropyLoss

    • 回归分支:

      • box: output_shape = (N, 9, H, W)(dx, dy, log(z), log(w), log(l), log(h), yaw, vx, vy),使用 SmoothL1Loss

      • centerness: output_shape = (N, 1, H, W),使用 BCEWithLogitsLoss

      • direction: output_shape = (N, 2, H, W),使用 CrossEntropyLoss

target 设置

  • target 设置中使用了很多 2D 引导 3D 的思想。

(x, y, z) target 设置

  • 由于是 3D 检测,所以 GT 的 3D 框坐标(x, y, z, w, l, h)单位都是米,这对神经网络是不友好的(因为神经网络看到的是像素,预测以像素为单位更容易)。

  • 因此,本文实际是一个 2.5D 的预测(xy 2D, z 3D),实际预测的 x, y 是像素坐标系下相对于 feature map 每一个点的偏移量(由相机坐标系和相机内参可计算得到像素坐标系),z, w, l, h 的预测是相机坐标系下的米为单位的真值取 log

centerness target 设置

  • FCOS 不同,FCOS3D centerness: $c = e^{-\alpha((\Delta x)^2+(\Delta y)^2)}$ ,$\alpha=2.5$

yaw target 设置

  • 本文将 yaw (0 ~ $2\pi$)编码成 yaw (0 ~ $\pi$)和方向

正样本选择

  • FCOS 是将 feature map 上的每个位置到 GT 中心点的距离小于 1.5 * stride 的点作为正样本。

  • FCOS3D3D 检测,没办法直接使用 FCOS 提出的方法;解决方法和 x, y 坐标回归方法类似,如果 2.5D 坐标下的 x, yfeature map 位置距离小于 1.5 * stride,则算作正例。

GT 尺度分配

  • FCOS 思想一样

不同尺度 feature map 缩放

  • FCOS 思想一样,只是更丰富 scale.shape == (num_of_level, 3),分别表示 scale_offset(for xy) / scale_depth(for z) / scale_size(for wlh)

Thought

  • 本文极大程度的借鉴了 FCOS,相当于 FCOS2.5D

  • 加入了很多 trick: log(z), centerness target 定义,encode yaw 等,很 work