Upload own-solver/neurogolf_solver/onnx_helpers.py
Browse files
own-solver/neurogolf_solver/onnx_helpers.py
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""ONNX model building helper functions (opset 17)."""
|
| 3 |
+
|
| 4 |
+
import numpy as np
|
| 5 |
+
from onnx import helper, TensorProto, numpy_helper
|
| 6 |
+
from .constants import DT, IR, GRID_SHAPE, INT64_MIN, GH, GW
|
| 7 |
+
from .config import make_opset
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
def _make_int64_init(name, values):
|
| 11 |
+
"""Create int64 initializer."""
|
| 12 |
+
return numpy_helper.from_array(np.array(values, dtype=np.int64), name)
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def _build_pad_node(input_name, output_name, pad_h, pad_w, inits, suffix=''):
|
| 16 |
+
"""Pad with tensor-based pads input (opset 11+)."""
|
| 17 |
+
pads_name = f'pads{suffix}'
|
| 18 |
+
cv_name = f'pad_cv{suffix}'
|
| 19 |
+
pads_arr = np.array([0, 0, 0, 0, 0, 0, pad_h, pad_w], dtype=np.int64)
|
| 20 |
+
inits.append(numpy_helper.from_array(pads_arr, pads_name))
|
| 21 |
+
inits.append(numpy_helper.from_array(np.array(0.0, dtype=np.float32), cv_name))
|
| 22 |
+
return helper.make_node('Pad', [input_name, pads_name, cv_name], [output_name], mode='constant')
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def _build_slice_crop(input_name, output_name, IH, IW, inits, suffix=''):
|
| 26 |
+
"""Slice to crop [1,10,30,30] to [1,10,IH,IW]."""
|
| 27 |
+
st_name = f'crop_st{suffix}'
|
| 28 |
+
en_name = f'crop_en{suffix}'
|
| 29 |
+
inits.append(_make_int64_init(st_name, [0, 0, 0, 0]))
|
| 30 |
+
inits.append(_make_int64_init(en_name, [1, 10, IH, IW]))
|
| 31 |
+
return helper.make_node('Slice', [input_name, st_name, en_name], [output_name])
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
def _build_slice_reverse(input_name, output_name, axis, dim_size, inits, suffix=''):
|
| 35 |
+
"""Slice(step=-1) to reverse one axis. Zero MACs."""
|
| 36 |
+
st_name = f'rev_st{suffix}'
|
| 37 |
+
en_name = f'rev_en{suffix}'
|
| 38 |
+
ax_name = f'rev_ax{suffix}'
|
| 39 |
+
sp_name = f'rev_sp{suffix}'
|
| 40 |
+
inits.append(_make_int64_init(st_name, [dim_size - 1]))
|
| 41 |
+
inits.append(_make_int64_init(en_name, [INT64_MIN]))
|
| 42 |
+
inits.append(_make_int64_init(ax_name, [axis]))
|
| 43 |
+
inits.append(_make_int64_init(sp_name, [-1]))
|
| 44 |
+
return helper.make_node('Slice', [input_name, st_name, en_name, ax_name, sp_name], [output_name])
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def _build_reducesum(input_name, output_name, axes_list, inits, suffix=''):
|
| 48 |
+
"""ReduceSum with axes as tensor input (opset 13+). keepdims=1."""
|
| 49 |
+
axes_name = f'rs_axes{suffix}'
|
| 50 |
+
inits.append(_make_int64_init(axes_name, axes_list))
|
| 51 |
+
return helper.make_node('ReduceSum', [input_name, axes_name], [output_name], keepdims=1)
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
def mk(nodes, inits=None, opset_version=17):
|
| 55 |
+
"""Create ONNX model from nodes and initializers."""
|
| 56 |
+
x = helper.make_tensor_value_info("input", DT, GRID_SHAPE)
|
| 57 |
+
y = helper.make_tensor_value_info("output", DT, GRID_SHAPE)
|
| 58 |
+
g = helper.make_graph(nodes, "g", [x], [y], initializer=inits or [])
|
| 59 |
+
return helper.make_model(g, ir_version=IR, opset_imports=make_opset(opset_version))
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
def add_onehot_block(nodes, inits, am_name, oh_name):
|
| 63 |
+
"""Add ArgMax one-hot conversion block."""
|
| 64 |
+
classes = np.arange(10, dtype=np.int64).reshape(1, 10, 1, 1)
|
| 65 |
+
inits.append(numpy_helper.from_array(classes, 'classes'))
|
| 66 |
+
nodes.append(helper.make_node('Equal', [am_name, 'classes'], ['eq']))
|
| 67 |
+
nodes.append(helper.make_node('Cast', ['eq'], [oh_name], to=TensorProto.FLOAT))
|