Как вы находите, что параметр квантования внутри модели ONNX привел к преобразованию уже квантованной модели tflite в ONNX?
то, что я пытался сделать, это преобразовать квантованный tflite в ONNX и запустить его напрямую с помощью ORT с помощью tf2onnx. Сеть, которую я пытаюсь преобразовать, представляет собой YOLOv5, предварительно обученную с моим собственным набором данных + COCO, и модель была успешно преобразована. Я уверен в этом, потому что я только что попытался загрузить как модель ONNX (через PRT), так и модель tflite, сохранить параметры квантования из входных и выходных данных интерпретатора tflite, фактически запустить сеанс модели ONNX с этими параметры квантования, и он фактически показывает идентичный результат при запуске модели tflite/исходной модели pt, которую я обучал с помощью API Ultratycs.
Проблема в том, что в случае с tflite можно найти параметры квантования, такие как масштабный коэффициент и нулевые точки, вне входных или выходных данных, но я понятия не имею, как найти эти точные числа из преобразованной модели ONNX.
В случае ORT get_inputs() и get_outputs() показывают только имя тензора ввода/вывода, их тип и размерность для них. В случае с ONNX API я не копал так глубоко.
Любое понимание проблемы будет оценено. Заранее спасибо и хорошего дня.
1 ответ
Итак, я нашел способ и решил опубликовать свой собственный ответ для людей, которым может быть интересно решение.
Что я сделал, так это импортировал onnx, загрузил модель и из члена графа этой указанной модели попытался сослаться на самый первый и самый последний узлы в этом графе. Внутри этих узлов попытался извлечь имя 2-го и 3-го элементов на вкладке «ввод», потому что дано, что первый будет фактическим входным тензором.
А затем, с помощью инициализаторов этого графа, попытался найти те, что с тем же именем, и как только я их нашел, преобразовать их в фактическое значение с помощью onnx.numpy_helper.to_array() вот фрагмент кода
factors = onnx_model.graph.initializer
for idx, init in enumerate(factors):
if factors[idx].name == nodes[0].input[1]:
array_test = onnx.numpy_helper.to_array(factors[idx])
self.scale_input = array_test
elif factors[idx].name == nodes[0].input[2]:
array_test = onnx.numpy_helper.to_array(factors[idx])
self.zero_point_input = array_test
elif factors[idx].name == nodes[len(nodes) - 1].input[1]:
array_test = onnx.numpy_helper.to_array(factors[idx])
self.scale_output = array_test
elif factors[idx].name == nodes[len(nodes) - 1].input[2]:
array_test = onnx.numpy_helper.to_array(factors[idx])
self.zero_point_output = array_test
print(self.scale_input, self.scale_output)
print(self.zero_point_input, self.zero_point_output)
del onnx_model
Проблема в том, что фактическая операционная среда представляет собой встроенный ECU, который по какой-то причине не поддерживает onnx, поэтому я попытался найти решение, доступное с onnxruntime, но на данный момент это все, что у меня есть.