已关闭
[Requirement|需求建议]: 新增算子decode_bbox_v2的ascend950 实现 #790
zhu-xun创建于  8月24日关闭于  8月25日
zhu-xun
8月24日 创建

Thanks for sending an requirement! Please fill in the following template to help quickly solve your problem.

Backgroud(背景信息)

bounding_box_decode(算子注册名 BoundingBoxDecode,aclnn 函数 aclnnBoundingBoxDecode)是目标检测后处理阶段的
边界框解码算子。anchor-based 检测器(Faster R-CNN、RetinaNet、SSD、YOLOv3 等)的回归分支不直接预测绝对坐标,
而是预测相对锚框的偏移量 deltas = (dx, dy, dw, dh);推理时需要把这组偏移量结合锚框 anchor_box = (x1, y1, x2, y2)
"解码"回图像坐标空间的绝对框 (x1, y1, x2, y2),才能用于后续 NMS、画框或 COCO mAP 评估。该算子是
bounding_box_encode 的严格逆运算,两者共享同一套 (means, stds) 标准化参数与 (x1, y1, x2, y2) 锚框坐标约定,
必须配套使用以保证训练 / 推理编码一致。

Origin(信息来源)

NA

Benefit / Necessity (价值/作用)

bounding_box_decode 是目标检测(two-stage 与 anchor-based one-stage 检测器)后处理阶段的边界框解码算子。
检测网络的回归分支不直接预测绝对坐标,而是预测相对锚框(anchor box)的偏移量 deltas = (dx, dy, dw, dh),
推理时需要把这些偏移量"解码"回图像坐标空间的绝对框 (x1, y1, x2, y2),才能用于后续 NMS、画框或 COCO mAP 评估。

该算子是 bounding_box_encode 的逆运算:encode 把 (anchor, ground_truth) → deltas,decode 把
(anchor, deltas) → decoded box。两者共享同一套 (means, stds) 标准化参数与同一套 (x1, y1, x2, y2)
锚框坐标约定,配套使用才能保证训练 / 推理编码一致。

Design(设计方案)

1.1 算子功能

bounding_box_decode(算子注册名 BoundingBoxDecode,aclnn 函数 aclnnBoundingBoxDecode)是 anchor-based 目标检测后处理阶段的边界框解码算子:把检测网络回归分支预测的相对偏移量 deltas (N, 4) 与锚框 anchor_box (N, 4) 按 Faster R-CNN 范式"解码"回图像坐标空间的绝对框 boxes (N, 4),供后续 NMS / IoU / COCO mAP 评估使用。该算子是同族 bounding_box_encode 的严格逆运算,两者共享同一套 (means, stds) 标准化参数与 (x1, y1, x2, y2) 锚框坐标约定,必须配套使用以保证训练 / 推理编码一致。计算范式为纯 elementwise + 逐行 4 元素解码,无跨元素依赖、无 reduce、无排序,属 Ascend C Vector-bound 场景。

1.2 算子定义(自然语言)

输入两路张量:

  • anchor_box (N, 4):锚框坐标,列含义 (x1, y1, x2, y2),dtype ∈ {float16, float32},Format ND。
  • deltas (N, 4):回归分支预测的偏移量,列含义 (dx', dy', dw', dh'),dtype / shape 必须与 anchor_box 完全一致(无广播)。

属性四项:

  • means(ListFloat,长度 4,默认 (0,0,0,0)):deltas 反标准化的均值,须与训练侧 bounding_box_encode 一致。
  • stds(ListFloat,长度 4,各元素 ≠ 0,默认 (1,1,1,1)):deltas 反标准化的标准差。
  • wh_ratio_clip(Float,> 0,默认 0.016):宽高比裁剪阈值。据 REQUIREMENTS §2.1.3,MindSpore 官方示例在不含 dw/dh 硬裁剪路径下即可逐值复现,wh_ratio_clip 的精确裁剪作用点为待确认项;本设计核心公式不引用该字段(见 §1.3 与 {{DESIGN 缺口:wh_ratio_clip 精确裁剪语义待确认}})。
  • max_shape(ListInt,长度 2 = (H, W)):解码框裁剪上限,x 维度裁到 [0, W]、y 维度裁到 [0, H],下界裁到 0 防止负坐标。aclnn / GEIR 层为必填属性(无运行时默认)。

计算语义(逐 anchor 行独立、行间无依赖):

  1. 由 anchor_box 计算锚框中心 / 宽高(含 +1 偏移,与 encode 对齐,保证宽高至少为 1 防除零):pw = x2 - x1 + 1、ph = y2 - y1 + 1、pcx = (x1 + x2) * 0.5、pcy = (y1 + y2) * 0.5。
  2. 反标准化(decode 侧 deltas * stds + means,与 encode 侧 (raw - means) / stds 互逆):dx = dx' * s0 + m0、dy = dy' * s1 + m1、dw = dw' * s2 + m2、dh = dh' * s3 + m3。
  3. 解码回绝对空间的中心 / 宽高:gw = pw * exp(dw)、gh = ph * exp(dh)、gx = pcx + pw * dx、gy = pcy + ph * dy。
  4. 中心 / 宽高回四角坐标(与 encode 的 +1 偏移严格对齐,+0.5 / -0.5 抵消 +1):x1_out = gx - gw * 0.5 + 0.5、y1_out = gy - gh * 0.5 + 0.5、x2_out = gx + gw * 0.5 - 0.5、y2_out = gy + gh * 0.5 - 0.5。
  5. 按 max_shape = (H, W) 裁剪到合法图像范围:x 维度裁到 [0, W]、y 维度裁到 [0, H]。

输出:

  • boxes (N, 4):解码后的绝对框 (x1, y1, x2, y2),dtype / shape 与 anchor_box 完全一致,Format ND,无 inplace aliasing。

数值稳定性约束(spec.yaml numerical_stability):float16 输入时 exp(dw)/exp(dh) 及后续乘加中间量必须在 fp32 域计算后再回 cast 到 fp16,避免 exp 中间结果溢出 fp16 范围(max 65504,exp(11.1) ≈ 66000)。float32 输入全程 fp32 计算。

1.3 数学公式(LaTeX)

设锚框 anchor_box=(x1,y1,x2,y2)\text{anchor\_box} = (x_1, y_1, x_2, y_2)、偏移量 deltas=(dx′,dy′,dw′,dh′)\text{deltas} = (d_x', d_y', d_w', d_h'),属性 means=(m0,m1,m2,m3)\text{means} = (m_0, m_1, m_2, m_3)、stds=(s0,s1,s2,s3)\text{stds} = (s_0, s_1, s_2, s_3)、max_shape=(H,W)\text{max\_shape} = (H, W)。以下公式对每一行(每个 anchor)独立成立,行间无依赖、无广播。

步骤 1 · 锚框中心 / 宽高(含 +1 偏移,与 encode 对齐,保证宽高至少为 1 防除零):

pw=x2−x1+1,ph=y2−y1+1p_w = x_2 - x_1 + 1,\quad p_h = y_2 - y_1 + 1

pcx=(x1+x2)⋅0.5,pcy=(y1+y2)⋅0.5p_{cx} = (x_1 + x_2) \cdot 0.5,\quad p_{cy} = (y_1 + y_2) \cdot 0.5

步骤 2 · 反标准化(decode 侧 deltas * stds + means,与 encode 侧 (raw - means) / stds 互逆):

dx=dx′⋅s0+m0,dy=dy′⋅s1+m1d_x = d_x' \cdot s_0 + m_0,\quad d_y = d_y' \cdot s_1 + m_1

dw=dw′⋅s2+m2,dh=dh′⋅s3+m3d_w = d_w' \cdot s_2 + m_2,\quad d_h = d_h' \cdot s_3 + m_3

步骤 3 · 解码回绝对空间的中心 / 宽高:

gw=pw⋅exp⁡(dw),gh=ph⋅exp⁡(dh)g_w = p_w \cdot \exp(d_w),\quad g_h = p_h \cdot \exp(d_h)

gx=pcx+pw⋅dx,gy=pcy+ph⋅dyg_x = p_{cx} + p_w \cdot d_x,\quad g_y = p_{cy} + p_h \cdot d_y

步骤 4 · 中心 / 宽高回四角坐标(与 encode 的 +1 偏移严格对齐,+0.5 / -0.5 抵消 +1):

x~1=gx−gw⋅0.5+0.5,y~1=gy−gh⋅0.5+0.5\tilde{x}_1 = g_x - g_w \cdot 0.5 + 0.5,\quad \tilde{y}_1 = g_y - g_h \cdot 0.5 + 0.5

x~2=gx+gw⋅0.5−0.5,y~2=gy+gh⋅0.5−0.5\tilde{x}_2 = g_x + g_w \cdot 0.5 - 0.5,\quad \tilde{y}_2 = g_y + g_h \cdot 0.5 - 0.5

步骤 5 · 按 max_shape = (H, W) 裁剪(下界裁到 0 防止负坐标,x 维度裁到 [0, W]、y 维度裁到 [0, H]):

x1out=clip(x~1, 0, W),y1out=clip(y~1, 0, H)x_1^{out} = \mathrm{clip}(\tilde{x}_1,\, 0,\, W),\quad y_1^{out} = \mathrm{clip}(\tilde{y}_1,\, 0,\, H)

x2out=clip(x~2, 0, W),y2out=clip(y~2, 0, H)x_2^{out} = \mathrm{clip}(\tilde{x}_2,\, 0,\, W),\quad y_2^{out} = \mathrm{clip}(\tilde{y}_2,\, 0,\, H)

输出:

boxes=(x1out, y1out, x2out, y2out)\text{boxes} = (x_1^{out},\, y_1^{out},\, x_2^{out},\, y_2^{out})

关于 wh_ratio_clip:spec.yaml attributes.wh_ratio_clip.semantics 明确"REQUIREMENTS §2.1.3 指出官方示例在不含 dw/dh 硬裁剪路径下复现,其精确裁剪作用点为待确认项,核心 formula 暂不引用"。故本节公式不含 wh_ratio_clip 的硬裁剪项;上游真值(spec.yaml math_semantics.formula)与之完全一致。{{DESIGN 缺口:wh_ratio_clip 精确裁剪语义待确认,本设计公式暂不引用,golden / ST 以"不含 dw/dh 硬裁剪"为基线真值}}

关于精度计算路径:spec.yaml math_semantics.formula 与 numerical_stability 规定,float16 输入时中间 exp / 乘加量升精度到 fp32 计算(a = anchor_box.astype(np.float32)、d = deltas.astype(np.float32)),最终 .astype(anchor_box.dtype) 回 cast。float32 输入全程 fp32。本公式为语义真值,kernel 实现须保证数值等价(详见 §1.4 与 §10)。

真值可追溯性:上述公式已在 MindSpore 官方文档示例(anchor_box=[[4,1,2,1],[2,2,2,3]]、deltas=[[3,1,2,2],[1,2,1,4]]、max_shape=(768,1280)、means=(0,0,0,0)、stds=(1,1,1,1)、wh_ratio_clip=0.016,期望输出 [[4.1953125, 0.0, 0.0, 5.1953125], [2.140625, 0.0, 3.859375, 60.59375]])上逐值复现(详见 REQUIREMENTS §2.1.2)。本节公式即为后续所有分支 Kernel 计算链、以及验证 golden 的唯一语义源。

likedislike
liu-weiliu-wei成员
8月24日 将 zhu-xun 设为负责人
CANN-robotCANN-robot成员
8月25日 关闭了 issue
CANN-robotCANN-robot成员
8月25日 添加了label:resolved