chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# pylint: disable=invalid-name
|
||||
"""Multibox location transform (SSD / TFLite DetectionPostProcess decode)."""
|
||||
|
||||
import tvm
|
||||
from tvm import te, topi
|
||||
|
||||
|
||||
def multibox_transform_loc(
|
||||
cls_pred,
|
||||
loc_pred,
|
||||
anchor,
|
||||
variances,
|
||||
clip=False,
|
||||
threshold=0.0,
|
||||
keep_background=True,
|
||||
):
|
||||
"""TFLite ``DecodeCenterSizeBoxes``-style decode + softmax score post-process.
|
||||
|
||||
Inputs must match Relax op contracts: ``cls_pred [B,C,N]``, ``loc_pred [B,4*N]``,
|
||||
``anchor [1,N,4]`` ltrb; per-anchor loc order ``(x,y,w,h)`` after yxhw→xywh reorder.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
cls_pred : te.Tensor
|
||||
``[B, C, N]`` logits.
|
||||
loc_pred : te.Tensor
|
||||
``[B, 4*N]`` encodings ``(x,y,w,h)`` per anchor.
|
||||
anchor : te.Tensor
|
||||
``[1, N, 4]`` ``(left, top, right, bottom)``.
|
||||
variances : tuple of 4 float
|
||||
``(x,y,w,h)`` = ``1/x_scale, 1/y_scale, 1/w_scale, 1/h_scale`` (TFLite).
|
||||
clip : bool
|
||||
Clip ``ymin,xmin,ymax,xmax`` to ``[0,1]``.
|
||||
threshold : float
|
||||
After softmax: ``scores *= (scores >= threshold)``.
|
||||
keep_background : bool
|
||||
If False: ``scores[:,0,:] = 0``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
boxes : te.Tensor
|
||||
``[B, N, 4]`` as ``(ymin,xmin,ymax,xmax)``.
|
||||
scores : te.Tensor
|
||||
``[B, C, N]`` softmax, then threshold mask and optional background zero.
|
||||
"""
|
||||
dtype = cls_pred.dtype
|
||||
B = cls_pred.shape[0]
|
||||
num_anchors = cls_pred.shape[2]
|
||||
loc_reshaped = topi.reshape(loc_pred, [B, num_anchors, 4])
|
||||
|
||||
vx = tvm.tirx.const(float(variances[0]), dtype)
|
||||
vy = tvm.tirx.const(float(variances[1]), dtype)
|
||||
vw = tvm.tirx.const(float(variances[2]), dtype)
|
||||
vh = tvm.tirx.const(float(variances[3]), dtype)
|
||||
half = tvm.tirx.const(0.5, dtype)
|
||||
zero = tvm.tirx.const(0.0, dtype)
|
||||
one = tvm.tirx.const(1.0, dtype)
|
||||
th = tvm.tirx.const(float(threshold), dtype)
|
||||
|
||||
def decode_bbox(b, a, k):
|
||||
left = anchor[0, a, 0]
|
||||
top = anchor[0, a, 1]
|
||||
right = anchor[0, a, 2]
|
||||
bottom = anchor[0, a, 3]
|
||||
ay = (top + bottom) * half
|
||||
ax = (left + right) * half
|
||||
ah = bottom - top
|
||||
aw = right - left
|
||||
ex = loc_reshaped[b, a, 0]
|
||||
ey = loc_reshaped[b, a, 1]
|
||||
ew = loc_reshaped[b, a, 2]
|
||||
eh = loc_reshaped[b, a, 3]
|
||||
ycenter = ey * vy * ah + ay
|
||||
xcenter = ex * vx * aw + ax
|
||||
half_h = half * te.exp(eh * vh) * ah
|
||||
half_w = half * te.exp(ew * vw) * aw
|
||||
ymin = ycenter - half_h
|
||||
xmin = xcenter - half_w
|
||||
ymax = ycenter + half_h
|
||||
xmax = xcenter + half_w
|
||||
if clip:
|
||||
ymin = te.max(zero, te.min(one, ymin))
|
||||
xmin = te.max(zero, te.min(one, xmin))
|
||||
ymax = te.max(zero, te.min(one, ymax))
|
||||
xmax = te.max(zero, te.min(one, xmax))
|
||||
return tvm.tirx.Select(
|
||||
k == 0,
|
||||
ymin,
|
||||
tvm.tirx.Select(k == 1, xmin, tvm.tirx.Select(k == 2, ymax, xmax)),
|
||||
)
|
||||
|
||||
boxes = te.compute((B, num_anchors, 4), decode_bbox, name="multibox_boxes")
|
||||
|
||||
scores = topi.nn.softmax(cls_pred, axis=1)
|
||||
mask = topi.cast(topi.greater_equal(scores, th), dtype)
|
||||
scores = scores * mask
|
||||
if not keep_background:
|
||||
|
||||
def zero_bg(b, c, n):
|
||||
s = scores[b, c, n]
|
||||
return te.if_then_else(c == 0, zero, s)
|
||||
|
||||
scores = te.compute(scores.shape, zero_bg, name="multibox_scores_bg")
|
||||
|
||||
return [boxes, scores]
|
||||
Reference in New Issue
Block a user