CodexWorkaround
Validate Operations / validate-operations (push) Has been cancelled

This commit is contained in:
ilgeco
2026-06-08 11:33:36 +02:00
parent aec80529ca
commit 75fb70712f
184 changed files with 1127 additions and 7 deletions
+500
View File
@@ -1200,6 +1200,106 @@ def softmax_large_dimension_1024():
save_model(model, "softmax/large_dimension_1024", "softmax_large_dimension_1024.onnx")
# ---------------------------------------------------------------------------
# DFL tests
# ---------------------------------------------------------------------------
def _make_yolo_dfl_initializers(n, include_decode_tail):
shape0 = make_int64_initializer("Shape0", [1, 4, 16, n])
shape1 = make_int64_initializer("Shape1", [1, 16, 4 * n])
shape2 = make_int64_initializer("Shape2", [1, 4, n])
proj = numpy_helper.from_array(np.arange(16, dtype=np.float32).reshape(1, 16), name="Proj")
initializers = [shape0, shape1, shape2, proj]
if include_decode_tail:
starts0 = make_int64_initializer("starts0", [0])
ends0 = make_int64_initializer("ends0", [2])
starts1 = make_int64_initializer("starts1", [2])
ends1 = make_int64_initializer("ends1", [4])
axes = make_int64_initializer("axes", [1])
rng = np.random.default_rng(301)
anchor = numpy_helper.from_array(
rng.uniform(-2.0, 2.0, (1, 2, n)).astype(np.float32), name="Anchor")
half = numpy_helper.from_array(np.asarray([2.0], dtype=np.float32), name="Half")
scale_values = np.full((1, n), 8.0, dtype=np.float32)
scale_values[:, 1::2] = 16.0
scale = numpy_helper.from_array(scale_values, name="Scale")
initializers.extend([starts0, ends0, starts1, ends1, axes, anchor, half, scale])
return initializers
def _build_yolo_dfl_projection_nodes(box_raw_name):
return [
helper.make_node("Reshape", [box_raw_name, "Shape0"], ["R0"]),
helper.make_node("Transpose", ["R0"], ["T0"], perm=[0, 2, 1, 3]),
helper.make_node("Softmax", ["T0"], ["S0"], axis=1),
helper.make_node("Reshape", ["S0", "Shape1"], ["R1"]),
helper.make_node("MatMul", ["Proj", "R1"], ["M0"]),
helper.make_node("Reshape", ["M0", "Shape2"], ["Box4"]),
]
def yolo_dfl_projection_small():
"""YOLO DFL projection path on a small [1,64,128] box tensor."""
box_raw = helper.make_tensor_value_info("BoxRaw", TensorProto.FLOAT, [1, 64, 128])
y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 4, 128])
nodes = _build_yolo_dfl_projection_nodes("BoxRaw")
graph = helper.make_graph(
nodes[:-1] + [helper.make_node("Reshape", ["M0", "Shape2"], ["Y"])],
"yolo_dfl_projection_small",
[box_raw],
[y],
initializer=_make_yolo_dfl_initializers(128, include_decode_tail=False))
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "dfl/yolo_dfl_projection_small", "yolo_dfl_projection_small.onnx")
def yolo_dfl_projection_large():
"""YOLO DFL projection path on a YOLO-scale [1,64,8400] box tensor."""
box_raw = helper.make_tensor_value_info("BoxRaw", TensorProto.FLOAT, [1, 64, 8400])
y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 4, 8400])
nodes = _build_yolo_dfl_projection_nodes("BoxRaw")
graph = helper.make_graph(
nodes[:-1] + [helper.make_node("Reshape", ["M0", "Shape2"], ["Y"])],
"yolo_dfl_projection_large",
[box_raw],
[y],
initializer=_make_yolo_dfl_initializers(8400, include_decode_tail=False))
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "dfl/yolo_dfl_projection_large", "yolo_dfl_projection_large.onnx")
def yolo_dfl_decode_tail_large():
"""YOLO-scale DFL projection followed by box decode, stride scale, score sigmoid, and final concat."""
box_raw = helper.make_tensor_value_info("BoxRaw", TensorProto.FLOAT, [1, 64, 8400])
class_raw = helper.make_tensor_value_info("ClassRaw", TensorProto.FLOAT, [1, 80, 8400])
y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 84, 8400])
nodes = _build_yolo_dfl_projection_nodes("BoxRaw")
nodes.extend([
helper.make_node("Slice", ["Box4", "starts0", "ends0", "axes"], ["L0"]),
helper.make_node("Slice", ["Box4", "starts1", "ends1", "axes"], ["L1"]),
helper.make_node("Sub", ["Anchor", "L0"], ["A"]),
helper.make_node("Add", ["L1", "Anchor"], ["B"]),
helper.make_node("Add", ["A", "B"], ["Sum"]),
helper.make_node("Div", ["Sum", "Half"], ["Center"]),
helper.make_node("Sub", ["B", "A"], ["Size"]),
helper.make_node("Concat", ["Center", "Size"], ["Boxes"], axis=1),
helper.make_node("Mul", ["Boxes", "Scale"], ["BoxesScaled"]),
helper.make_node("Sigmoid", ["ClassRaw"], ["Scores"]),
helper.make_node("Concat", ["BoxesScaled", "Scores"], ["Y"], axis=1),
])
graph = helper.make_graph(
nodes,
"yolo_dfl_decode_tail_large",
[box_raw, class_raw],
[y],
initializer=_make_yolo_dfl_initializers(8400, include_decode_tail=True))
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "dfl/yolo_dfl_decode_tail_large", "yolo_dfl_decode_tail_large.onnx")
# ---------------------------------------------------------------------------
# Resize tests
# ---------------------------------------------------------------------------
@@ -1452,6 +1552,387 @@ def slice_large_channel_1024():
save_model(model, "slice/large_channel_1024", "slice_large_channel_1024.onnx")
def slice_yolo_decode_tail():
"""YOLO-like decode tail where a non-zero-offset channel slice feeds arithmetic and Concat."""
rng = np.random.default_rng(109)
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 4, 32])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 4, 32])
S0 = helper.make_tensor_value_info("S0", TensorProto.FLOAT, [1, 2, 32])
S1 = helper.make_tensor_value_info("S1", TensorProto.FLOAT, [1, 2, 32])
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [1, 2, 32])
B = helper.make_tensor_value_info("B", TensorProto.FLOAT, [1, 2, 32])
Center = helper.make_tensor_value_info("Center", TensorProto.FLOAT, [1, 2, 32])
Size = helper.make_tensor_value_info("Size", TensorProto.FLOAT, [1, 2, 32])
Boxes = helper.make_tensor_value_info("Boxes", TensorProto.FLOAT, [1, 4, 32])
starts0 = make_int64_initializer("starts0", [0])
ends0 = make_int64_initializer("ends0", [2])
starts1 = make_int64_initializer("starts1", [2])
ends1 = make_int64_initializer("ends1", [4])
axes = make_int64_initializer("axes", [1])
anchor = numpy_helper.from_array(rng.uniform(-2.0, 2.0, (1, 2, 32)).astype(np.float32), name="Anchor")
half = numpy_helper.from_array(np.asarray([2.0], dtype=np.float32), name="Half")
scale = numpy_helper.from_array(np.asarray([8.0], dtype=np.float32), name="Scale")
slice0 = helper.make_node("Slice", ["X", "starts0", "ends0", "axes"], ["S0"])
slice1 = helper.make_node("Slice", ["X", "starts1", "ends1", "axes"], ["S1"])
sub_a = helper.make_node("Sub", ["Anchor", "S0"], ["A"])
add_b = helper.make_node("Add", ["S1", "Anchor"], ["B"])
add_sum = helper.make_node("Add", ["A", "B"], ["Sum"])
div_center = helper.make_node("Div", ["Sum", "Half"], ["Center"])
sub_size = helper.make_node("Sub", ["B", "A"], ["Size"])
concat_boxes = helper.make_node("Concat", ["Center", "Size"], ["Boxes"], axis=1)
mul_y = helper.make_node("Mul", ["Boxes", "Scale"], ["Y"])
graph = helper.make_graph(
[slice0, slice1, sub_a, add_b, add_sum, div_center, sub_size, concat_boxes, mul_y],
"slice_yolo_decode_tail",
[X],
[Y, S0, S1, A, B, Center, Size, Boxes],
initializer=[starts0, ends0, starts1, ends1, axes, anchor, half, scale])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "slice/yolo_decode_tail", "slice_yolo_decode_tail.onnx")
def slice_yolo_decode_tail_large_n():
"""Larger YOLO-like decode tail variant to stress non-zero-offset slice address handling."""
rng = np.random.default_rng(110)
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 4, 8400])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 4, 8400])
S0 = helper.make_tensor_value_info("S0", TensorProto.FLOAT, [1, 2, 8400])
S1 = helper.make_tensor_value_info("S1", TensorProto.FLOAT, [1, 2, 8400])
A = helper.make_tensor_value_info("A", TensorProto.FLOAT, [1, 2, 8400])
B = helper.make_tensor_value_info("B", TensorProto.FLOAT, [1, 2, 8400])
Center = helper.make_tensor_value_info("Center", TensorProto.FLOAT, [1, 2, 8400])
Size = helper.make_tensor_value_info("Size", TensorProto.FLOAT, [1, 2, 8400])
Boxes = helper.make_tensor_value_info("Boxes", TensorProto.FLOAT, [1, 4, 8400])
starts0 = make_int64_initializer("starts0", [0])
ends0 = make_int64_initializer("ends0", [2])
starts1 = make_int64_initializer("starts1", [2])
ends1 = make_int64_initializer("ends1", [4])
axes = make_int64_initializer("axes", [1])
anchor = numpy_helper.from_array(rng.uniform(-2.0, 2.0, (1, 2, 8400)).astype(np.float32), name="Anchor")
half = numpy_helper.from_array(np.asarray([2.0], dtype=np.float32), name="Half")
scale = numpy_helper.from_array(np.asarray([8.0], dtype=np.float32), name="Scale")
slice0 = helper.make_node("Slice", ["X", "starts0", "ends0", "axes"], ["S0"])
slice1 = helper.make_node("Slice", ["X", "starts1", "ends1", "axes"], ["S1"])
sub_a = helper.make_node("Sub", ["Anchor", "S0"], ["A"])
add_b = helper.make_node("Add", ["S1", "Anchor"], ["B"])
add_sum = helper.make_node("Add", ["A", "B"], ["Sum"])
div_center = helper.make_node("Div", ["Sum", "Half"], ["Center"])
sub_size = helper.make_node("Sub", ["B", "A"], ["Size"])
concat_boxes = helper.make_node("Concat", ["Center", "Size"], ["Boxes"], axis=1)
mul_y = helper.make_node("Mul", ["Boxes", "Scale"], ["Y"])
graph = helper.make_graph(
[slice0, slice1, sub_a, add_b, add_sum, div_center, sub_size, concat_boxes, mul_y],
"slice_yolo_decode_tail_large_n",
[X],
[Y, S0, S1, A, B, Center, Size, Boxes],
initializer=[starts0, ends0, starts1, ends1, axes, anchor, half, scale])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, "slice/yolo_decode_tail_large_n", "slice_yolo_decode_tail_large_n.onnx")
def _make_yolo_decode_tail_constants(seed, n):
rng = np.random.default_rng(seed)
starts0 = make_int64_initializer("starts0", [0])
ends0 = make_int64_initializer("ends0", [2])
starts1 = make_int64_initializer("starts1", [2])
ends1 = make_int64_initializer("ends1", [4])
axes = make_int64_initializer("axes", [1])
anchor = numpy_helper.from_array(rng.uniform(-2.0, 2.0, (1, 2, n)).astype(np.float32), name="Anchor")
half = numpy_helper.from_array(np.asarray([2.0], dtype=np.float32), name="Half")
scale = numpy_helper.from_array(np.asarray([8.0], dtype=np.float32), name="Scale")
return starts0, ends0, starts1, ends1, axes, anchor, half, scale
def _build_yolo_decode_tail_graph(input_name, slice_source_name, output_name):
slice0 = helper.make_node("Slice", [slice_source_name, "starts0", "ends0", "axes"], ["S0"])
slice1 = helper.make_node("Slice", [slice_source_name, "starts1", "ends1", "axes"], ["S1"])
sub_a = helper.make_node("Sub", ["Anchor", "S0"], ["A"])
add_b = helper.make_node("Add", ["S1", "Anchor"], ["B"])
add_sum = helper.make_node("Add", ["A", "B"], ["Sum"])
div_center = helper.make_node("Div", ["Sum", "Half"], ["Center"])
sub_size = helper.make_node("Sub", ["B", "A"], ["Size"])
concat_boxes = helper.make_node("Concat", ["Center", "Size"], ["Boxes"], axis=1)
mul_y = helper.make_node("Mul", ["Boxes", "Scale"], [output_name])
return [slice0, slice1, sub_a, add_b, add_sum, div_center, sub_size, concat_boxes, mul_y]
def slice_yolo_decode_tail_internal_small():
"""YOLO-like decode tail from an internal tensor with only the final output exposed."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 4, 128])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 4, 128])
zero = numpy_helper.from_array(np.zeros((1, 4, 128), dtype=np.float32), name="Z")
starts0, ends0, starts1, ends1, axes, anchor, half, scale = _make_yolo_decode_tail_constants(111, 128)
preadd = helper.make_node("Add", ["X", "Z"], ["P"])
graph = helper.make_graph(
[preadd] + _build_yolo_decode_tail_graph("X", "P", "Y"),
"slice_yolo_decode_tail_internal_small",
[X],
[Y],
initializer=[zero, starts0, ends0, starts1, ends1, axes, anchor, half, scale])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(
model,
"slice/yolo_decode_tail_internal_small",
"slice_yolo_decode_tail_internal_small.onnx")
def slice_yolo_decode_tail_internal_large():
"""Large YOLO-like decode tail from an internal tensor to stress large non-zero slice offsets."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 4, 8400])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 4, 8400])
zero = numpy_helper.from_array(np.zeros((1, 4, 8400), dtype=np.float32), name="Z")
starts0, ends0, starts1, ends1, axes, anchor, half, scale = _make_yolo_decode_tail_constants(112, 8400)
preadd = helper.make_node("Add", ["X", "Z"], ["P"])
graph = helper.make_graph(
[preadd] + _build_yolo_decode_tail_graph("X", "P", "Y"),
"slice_yolo_decode_tail_internal_large",
[X],
[Y],
initializer=[zero, starts0, ends0, starts1, ends1, axes, anchor, half, scale])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(
model,
"slice/yolo_decode_tail_internal_large",
"slice_yolo_decode_tail_internal_large.onnx")
def slice_yolo_decode_tail_after_transpose():
"""YOLO-like decode tail after a transpose to mirror the final decode-tail producer shape change."""
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 128, 4])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [1, 4, 128])
starts0, ends0, starts1, ends1, axes, anchor, half, scale = _make_yolo_decode_tail_constants(113, 128)
transpose = helper.make_node("Transpose", ["X"], ["T"], perm=[0, 2, 1])
graph = helper.make_graph(
[transpose] + _build_yolo_decode_tail_graph("X", "T", "Y"),
"slice_yolo_decode_tail_after_transpose",
[X],
[Y],
initializer=[starts0, ends0, starts1, ends1, axes, anchor, half, scale])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(
model,
"slice/yolo_decode_tail_after_transpose",
"slice_yolo_decode_tail_after_transpose.onnx")
def _save_yolo_decode_tail_localization_variant(directory, filename, output_name):
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [1, 4, 128])
output_shapes = {
"B": [1, 2, 128],
"Size": [1, 2, 128],
"Boxes": [1, 4, 128],
"Y": [1, 4, 128],
}
output = helper.make_tensor_value_info(output_name, TensorProto.FLOAT, output_shapes[output_name])
zero = numpy_helper.from_array(np.zeros((1, 4, 128), dtype=np.float32), name="Z")
starts0, ends0, starts1, ends1, axes, anchor, half, scale = _make_yolo_decode_tail_constants(114, 128)
preadd = helper.make_node("Add", ["X", "Z"], ["P"])
slice0 = helper.make_node("Slice", ["P", "starts0", "ends0", "axes"], ["S0"])
slice1 = helper.make_node("Slice", ["P", "starts1", "ends1", "axes"], ["S1"])
sub_a = helper.make_node("Sub", ["Anchor", "S0"], ["A"])
add_b = helper.make_node("Add", ["S1", "Anchor"], ["B"])
add_sum = helper.make_node("Add", ["A", "B"], ["Sum"])
div_center = helper.make_node("Div", ["Sum", "Half"], ["Center"])
sub_size = helper.make_node("Sub", ["B", "A"], ["Size"])
concat_boxes = helper.make_node("Concat", ["Center", "Size"], ["Boxes"], axis=1)
nodes = [preadd, slice0, slice1, sub_a, add_b, add_sum, div_center, sub_size, concat_boxes]
if output_name == "Y":
nodes.append(helper.make_node("Mul", ["Boxes", "Scale"], ["Y"]))
graph = helper.make_graph(
nodes,
directory.replace("/", "_"),
[X],
[output],
initializer=[zero, starts0, ends0, starts1, ends1, axes, anchor, half, scale])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
save_model(model, directory, filename)
def slice_yolo_decode_tail_output_b():
"""Localization variant exposing B only."""
_save_yolo_decode_tail_localization_variant(
"slice/yolo_decode_tail_output_b",
"slice_yolo_decode_tail_output_b.onnx",
"B")
def slice_yolo_decode_tail_output_size():
"""Localization variant exposing Size only."""
_save_yolo_decode_tail_localization_variant(
"slice/yolo_decode_tail_output_size",
"slice_yolo_decode_tail_output_size.onnx",
"Size")
def slice_yolo_decode_tail_output_boxes():
"""Localization variant exposing Boxes only."""
_save_yolo_decode_tail_localization_variant(
"slice/yolo_decode_tail_output_boxes",
"slice_yolo_decode_tail_output_boxes.onnx",
"Boxes")
def slice_yolo_decode_tail_output_y():
"""Localization variant exposing Y only."""
_save_yolo_decode_tail_localization_variant(
"slice/yolo_decode_tail_output_y",
"slice_yolo_decode_tail_output_y.onnx",
"Y")
def _build_yolo_head_final_concat_graph(lengths, output_name):
total_n = sum(lengths)
h0 = helper.make_tensor_value_info("H0", TensorProto.FLOAT, [1, 144, lengths[0]])
h1 = helper.make_tensor_value_info("H1", TensorProto.FLOAT, [1, 144, lengths[1]])
h2 = helper.make_tensor_value_info("H2", TensorProto.FLOAT, [1, 144, lengths[2]])
y = helper.make_tensor_value_info(output_name, TensorProto.FLOAT, [1, 84, total_n])
starts_box = make_int64_initializer("starts_box", [0])
ends_box = make_int64_initializer("ends_box", [4])
starts0 = make_int64_initializer("starts0", [0])
ends0 = make_int64_initializer("ends0", [2])
starts1 = make_int64_initializer("starts1", [2])
ends1 = make_int64_initializer("ends1", [4])
axes = make_int64_initializer("axes", [1])
split = make_int64_initializer("split", [64, 80])
rng = np.random.default_rng(115 + total_n)
anchor = numpy_helper.from_array(rng.uniform(-2.0, 2.0, (1, 2, total_n)).astype(np.float32), name="Anchor")
half = numpy_helper.from_array(np.asarray([2.0], dtype=np.float32), name="Half")
scale_values = np.full((1, total_n), 8.0, dtype=np.float32)
scale_values[:, 1::2] = 16.0
scale = numpy_helper.from_array(scale_values, name="Scale")
head = helper.make_node("Concat", ["H0", "H1", "H2"], ["Head"], axis=2)
split_node = helper.make_node("Split", ["Head", "split"], ["BoxRaw", "ClassRaw"], axis=1)
box4 = helper.make_node("Slice", ["BoxRaw", "starts_box", "ends_box", "axes"], ["Box4"])
slice0 = helper.make_node("Slice", ["Box4", "starts0", "ends0", "axes"], ["S0"])
slice1 = helper.make_node("Slice", ["Box4", "starts1", "ends1", "axes"], ["S1"])
sub_a = helper.make_node("Sub", ["Anchor", "S0"], ["A"])
add_b = helper.make_node("Add", ["S1", "Anchor"], ["B"])
add_sum = helper.make_node("Add", ["A", "B"], ["Sum"])
div_center = helper.make_node("Div", ["Sum", "Half"], ["Center"])
sub_size = helper.make_node("Sub", ["B", "A"], ["Size"])
concat_boxes = helper.make_node("Concat", ["Center", "Size"], ["Boxes"], axis=1)
mul_boxes = helper.make_node("Mul", ["Boxes", "Scale"], ["BoxesScaled"])
scores = helper.make_node("Sigmoid", ["ClassRaw"], ["Scores"])
final = helper.make_node("Concat", ["BoxesScaled", "Scores"], [output_name], axis=1)
graph = helper.make_graph(
[head, split_node, box4, slice0, slice1, sub_a, add_b, add_sum, div_center, sub_size, concat_boxes,
mul_boxes, scores, final],
f"{output_name}_graph",
[h0, h1, h2],
[y],
initializer=[starts_box, ends_box, starts0, ends0, starts1, ends1, axes, split, anchor, half, scale])
return helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
def slice_yolo_head_final_concat_small():
"""YOLO head/final-output structure with [1,144,N] head, split, decode, and final [1,84,N] concat."""
model = _build_yolo_head_final_concat_graph([96, 24, 8], "Y")
save_model(
model,
"slice/yolo_head_final_concat_small",
"slice_yolo_head_final_concat_small.onnx")
def slice_yolo_head_final_concat_large():
"""YOLO-scale final-head concat reproducer with head lengths 6400, 1600, and 400."""
model = _build_yolo_head_final_concat_graph([6400, 1600, 400], "Y")
save_model(
model,
"slice/yolo_head_final_concat_large",
"slice_yolo_head_final_concat_large.onnx")
def _build_yolo_head_localization_graph(output_name):
lengths = [96, 24, 8]
total_n = sum(lengths)
h0 = helper.make_tensor_value_info("H0", TensorProto.FLOAT, [1, 144, lengths[0]])
h1 = helper.make_tensor_value_info("H1", TensorProto.FLOAT, [1, 144, lengths[1]])
h2 = helper.make_tensor_value_info("H2", TensorProto.FLOAT, [1, 144, lengths[2]])
output_shapes = {
"BoxesScaled": [1, 4, total_n],
"Scores": [1, 80, total_n],
"Y": [1, 84, total_n],
}
output = helper.make_tensor_value_info(output_name, TensorProto.FLOAT, output_shapes[output_name])
starts_box = make_int64_initializer("starts_box", [0])
ends_box = make_int64_initializer("ends_box", [4])
starts0 = make_int64_initializer("starts0", [0])
ends0 = make_int64_initializer("ends0", [2])
starts1 = make_int64_initializer("starts1", [2])
ends1 = make_int64_initializer("ends1", [4])
axes = make_int64_initializer("axes", [1])
split = make_int64_initializer("split", [64, 80])
rng = np.random.default_rng(244)
anchor = numpy_helper.from_array(rng.uniform(-2.0, 2.0, (1, 2, total_n)).astype(np.float32), name="Anchor")
half = numpy_helper.from_array(np.asarray([2.0], dtype=np.float32), name="Half")
scale_values = np.full((1, total_n), 8.0, dtype=np.float32)
scale_values[:, 1::2] = 16.0
scale = numpy_helper.from_array(scale_values, name="Scale")
nodes = [
helper.make_node("Concat", ["H0", "H1", "H2"], ["Head"], axis=2),
helper.make_node("Split", ["Head", "split"], ["BoxRaw", "ClassRaw"], axis=1),
helper.make_node("Slice", ["BoxRaw", "starts_box", "ends_box", "axes"], ["Box4"]),
helper.make_node("Slice", ["Box4", "starts0", "ends0", "axes"], ["S0"]),
helper.make_node("Slice", ["Box4", "starts1", "ends1", "axes"], ["S1"]),
helper.make_node("Sub", ["Anchor", "S0"], ["A"]),
helper.make_node("Add", ["S1", "Anchor"], ["B"]),
helper.make_node("Add", ["A", "B"], ["Sum"]),
helper.make_node("Div", ["Sum", "Half"], ["Center"]),
helper.make_node("Sub", ["B", "A"], ["Size"]),
helper.make_node("Concat", ["Center", "Size"], ["Boxes"], axis=1),
helper.make_node("Mul", ["Boxes", "Scale"], ["BoxesScaled"]),
helper.make_node("Sigmoid", ["ClassRaw"], ["Scores"]),
]
if output_name == "Y":
nodes.append(helper.make_node("Concat", ["BoxesScaled", "Scores"], ["Y"], axis=1))
graph = helper.make_graph(
nodes,
f"yolo_head_{output_name.lower()}_graph",
[h0, h1, h2],
[output],
initializer=[starts_box, ends_box, starts0, ends0, starts1, ends1, axes, split, anchor, half, scale])
return helper.make_model(graph, opset_imports=[helper.make_opsetid("", 13)])
def slice_yolo_head_output_boxes_scaled():
"""Localization variant exposing only BoxesScaled."""
model = _build_yolo_head_localization_graph("BoxesScaled")
save_model(
model,
"slice/yolo_head_output_boxes_scaled",
"slice_yolo_head_output_boxes_scaled.onnx")
def slice_yolo_head_output_scores():
"""Localization variant exposing only Scores."""
model = _build_yolo_head_localization_graph("Scores")
save_model(
model,
"slice/yolo_head_output_scores",
"slice_yolo_head_output_scores.onnx")
def slice_yolo_head_output_y():
"""Localization variant exposing only final Y."""
model = _build_yolo_head_localization_graph("Y")
save_model(
model,
"slice/yolo_head_output_y",
"slice_yolo_head_output_y.onnx")
# ---------------------------------------------------------------------------
# Gather tests
# ---------------------------------------------------------------------------
@@ -2001,6 +2482,20 @@ if __name__ == "__main__":
slice_nchw_spatial_crop()
slice_after_conv()
slice_large_channel_1024()
slice_yolo_decode_tail()
slice_yolo_decode_tail_large_n()
slice_yolo_decode_tail_internal_small()
slice_yolo_decode_tail_internal_large()
slice_yolo_decode_tail_after_transpose()
slice_yolo_decode_tail_output_b()
slice_yolo_decode_tail_output_size()
slice_yolo_decode_tail_output_boxes()
slice_yolo_decode_tail_output_y()
slice_yolo_head_final_concat_small()
slice_yolo_head_final_concat_large()
slice_yolo_head_output_boxes_scaled()
slice_yolo_head_output_scores()
slice_yolo_head_output_y()
print("\nGenerating Softmax tests:")
softmax_basic()
@@ -2009,6 +2504,11 @@ if __name__ == "__main__":
softmax_negative_axis()
softmax_large_dimension_1024()
print("\nGenerating DFL tests:")
yolo_dfl_projection_small()
yolo_dfl_projection_large()
yolo_dfl_decode_tail_large()
print("\nGenerating Resize tests:")
resize_nearest_2x()
resize_nearest_non_uniform()