onnx / models

A collection of pre-trained, state-of-the-art models in the ONNX format
http://onnx.ai/models/
Apache License 2.0
7.89k stars 1.4k forks source link

Tiny YOLOv3 , Yolov3 in ONNXRuntime C API vs Python #440

Open dk-teknologisk-mlnn opened 3 years ago

dk-teknologisk-mlnn commented 3 years ago

These two models have unknown dimensions, so the input and output shapes have -1 in them in C api. and in python yolov3 has variable names in their place. I can fix those using "addfreedimensionbyname" in session_options. Then it recomputes the input and output sizes.

// debug info from my code: input dims before add free dims: -1 3 -1 -1 input dims after add free dims: 1 3 416 416

Outputs 0-1 also gets computed automatically, but output 2 is still unknown:

output 0: len 3 dims 1 10647 4 output 1: len 3 dims 1 80 10647 output 2: len 2 dims -1 -1

I can still use the output as I know its sets of 3 int32 and I check the indices being in range and not (0,0,0), and I good good results.

In python I get out3.shape = (N_goodmatches,3) just fine.

Now, tiny yolov3 is another matter. there the dims are ["N",3,None,None] and I add a free dimension by name to "N" = 1, and I get [1,3,None,None]. Outputs are [1,None,4] [1,80,None] [1,None,None]

I tried to set dimension by designation DATA_FEATURE, but no luck. In python it will work out just fine that None is 2535. So I hardcode this value in my C api....

Output2 (index lists) I still need to guess a size and test the index ranges.

How can I push ORT to recompute the output shapes, like python does?

  > out1,out2,out3 = z.run(None, {name: input.astype(np.float32),name2: input2.astype(np.float32)})
  > out1.shape
  (1, 2535, 4)
  > out2.shape
  (1, 80, 2535)
  > out3.shape
  (1, 0, 3)

NOTE: I see some questions about solving these unknowns. When they have a string name do this:

g_ort->AddFreeDimensionOverrideByName(session_options, "N", 1);
g_ort->AddFreeDimensionOverrideByName(session_options, "unk__576", 1);
g_ort->AddFreeDimensionOverrideByName(session_options, "unk__579", 1);
   g_ort->AddFreeDimensionOverrideByName(session_options, "unk__577", 416);
  g_ort->AddFreeDimensionOverrideByName(session_options, "unk__578", 416);

In C it is just -1, but in python you can see the names:

_>>> z.get_inputs()[0].shape ['unk576', 3, 'unk577', 'unk_578']

dk-teknologisk-mlnn commented 3 years ago

OK, so I fixed one of the issues: I installed keras and keras2onnx, and ocnverted both models with opset =10 Now both models function exactly the same: The batch parameter is "N" and I can add free dimension override by name =1 Image size is M1 and M2, I can override to 416. It now computes the 10647 / 2535 automatically for both models output, so I need not hardcode that. But the last index output is still not updated. so I don't know exactly how many selected boxes it has.

  output 0: len 3 dims 1 10647 4
  output 1: len 3 dims 1 80 10647
  output 2: len 3 dims 1 -1 3