Functions | |
| darknet_detect (network, image, class_names, threshold) | |
| detections_eq (dets_a, dets_b, atol_conf=0.15, atol_box=0.5, threshold=0.75) | |
| export_onnx (cfg_file, weights_file, fp16=False) | |
| greedy_nearest_match (dets_a, dets_b, atol_conf, atol_box) | |
| load_image (image_path, width, height) | |
| onnx_detect (session, image, class_names, threshold) | |
| single_detection_eq (a, b, atol_conf=0.15, atol_box=0.5) | |
Variables | |
| action | |
| bool | all_eq = True |
| args = parser.parse_args() | |
| atol_box | |
| atol_conf | |
| class_colors = darknet.class_colors(class_names) | |
| class_names = open(args.names).read().splitlines() | |
| default | |
| dets_eq = detections_eq(dn_dets, onnx_dets, atol_conf, atol_box, args.threshold) | |
| dn_dets = darknet_detect(dn_network, image, class_names, args.threshold) | |
| dn_img = darknet.draw_boxes(dn_dets, image.copy(), class_colors) | |
| dn_network | |
| float | |
| height = darknet.network_height(dn_network) | |
| help | |
| image = load_image(image_path, width, height) | |
| nargs | |
| onnx_dets = onnx_detect(onnx_network, image, class_names, args.threshold) | |
| onnx_img = darknet.draw_boxes(onnx_dets, image.copy(), class_colors) | |
| onnx_model = export_onnx(args.cfg, args.weights, fp16=args.fp16) | |
| onnx_network | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| type | |
| width = darknet.network_width(dn_network) | |
Export model to ONNX format and compare outputs to darknet. This tool runs the darknet_onnx_export binary to export a Darknet model to ONNX format, then runs inference using the darknet python bindings and the ONNX runtime to verify that the outputs match. This is useful for testing the implementation of the ONNX exporter. This tool exits with status 0 if all detections match, and non-zero if any detections do not match.
| onnx_export_and_verify.darknet_detect | ( | network, | |
| image, | |||
| class_names, | |||
| threshold | |||
| ) |
Performs inference using the Darknet C library and returns detections.

| onnx_export_and_verify.detections_eq | ( | dets_a, | |
| dets_b, | |||
atol_conf = 0.15, |
|||
atol_box = 0.5, |
|||
threshold = 0.75 |
|||
| ) |
Returns True if the two lists of detections are equivalent, ignoring order. Detections are first matched using `greedy_nearest_match()`, which is a needed to handle floating point differences in the confidence and box coordinates. Any detection left unmatched after that is still allowed, but only if its confidence is within atol_conf of --threshold. This is to account for floating point noise that might put a detection either side of the threshold. This is O(N^2) so only suitable for small numbers of detections.

| onnx_export_and_verify.export_onnx | ( | cfg_file, | |
| weights_file, | |||
fp16 = False |
|||
| ) |
Exports Darknet model to ONNX format and returns path to ONNX file.
| onnx_export_and_verify.greedy_nearest_match | ( | dets_a, | |
| dets_b, | |||
| atol_conf, | |||
| atol_box | |||
| ) |
Greedily matches dets_a against dets_b, returning unmatched detections. Checks if detections are "equal" via `single_detection_eq`, however this is not enough to do the matching, because due to floating point differences there might be multiple candidates. To resolve this, take the nearest detection by distance (computed from the detection box). Returns (unmatched_a, unmatched_b).


| onnx_export_and_verify.load_image | ( | image_path, | |
| width, | |||
| height | |||
| ) |
Loads an image and resizes it to the given width and height.
| onnx_export_and_verify.onnx_detect | ( | session, | |
| image, | |||
| class_names, | |||
| threshold | |||
| ) |
Performs inference using the ONNX model and returns detections.
| onnx_export_and_verify.single_detection_eq | ( | a, | |
| b, | |||
atol_conf = 0.15, |
|||
atol_box = 0.5 |
|||
| ) |
Compares two detections and returns True if they are equivalent. Darknet and ONNX Runtime use different convolution/GEMM implementations, so their float32 summation order differs and results are not bit-identical even when both exporter and runtime are behaving correctly. In practice this shows up as noise on the order of ~0.1 percentage points of confidence and ~0.1px of box position (fp32), and considerably more for fp16, since fp16 has far fewer significant bits to begin with and that quantization error compounds over ~100+ layers. The default tolerances are set loosely enough to absorb fp32 numerical noise while still catching real (much larger) export bugs; pass larger tolerances for fp16 models.

| onnx_export_and_verify.action |
| bool onnx_export_and_verify.all_eq = True |
| onnx_export_and_verify.args = parser.parse_args() |
| onnx_export_and_verify.atol_box |
| onnx_export_and_verify.atol_conf |
| onnx_export_and_verify.class_colors = darknet.class_colors(class_names) |
| onnx_export_and_verify.class_names = open(args.names).read().splitlines() |
| onnx_export_and_verify.default |
| onnx_export_and_verify.dets_eq = detections_eq(dn_dets, onnx_dets, atol_conf, atol_box, args.threshold) |
| onnx_export_and_verify.dn_dets = darknet_detect(dn_network, image, class_names, args.threshold) |
| onnx_export_and_verify.dn_img = darknet.draw_boxes(dn_dets, image.copy(), class_colors) |
| onnx_export_and_verify.dn_network |
| onnx_export_and_verify.float |
| onnx_export_and_verify.height = darknet.network_height(dn_network) |
| onnx_export_and_verify.help |
| onnx_export_and_verify.image = load_image(image_path, width, height) |
| onnx_export_and_verify.nargs |
| onnx_export_and_verify.onnx_dets = onnx_detect(onnx_network, image, class_names, args.threshold) |
| onnx_export_and_verify.onnx_img = darknet.draw_boxes(onnx_dets, image.copy(), class_colors) |
| onnx_export_and_verify.onnx_model = export_onnx(args.cfg, args.weights, fp16=args.fp16) |
| onnx_export_and_verify.onnx_network |
| onnx_export_and_verify.parser = argparse.ArgumentParser(description=__doc__) |
| onnx_export_and_verify.type |
| onnx_export_and_verify.width = darknet.network_width(dn_network) |