onnx2tf 1.29.16__py3-none-any.whl → 1.29.17__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
onnx2tf/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from onnx2tf.onnx2tf import convert, main
2
2
 
3
- __version__ = '1.29.16'
3
+ __version__ = '1.29.17'
onnx2tf/ops/Add.py CHANGED
@@ -21,6 +21,7 @@ from onnx2tf.utils.common_functions import (
21
21
  disable_unnecessary_transpose,
22
22
  shape_unmatched_special_avoidance_workaround,
23
23
  merge_two_consecutive_identical_ops_into_one,
24
+ transpose_with_flexing_deterrence,
24
25
  deterring_shape_corruption_due_to_broadcast,
25
26
  acquisition_of_validation_data,
26
27
  onnx_tf_tensor_validation,
@@ -297,6 +298,117 @@ def make_node(
297
298
  )
298
299
  tf_type = tf.identity
299
300
 
301
+ def _normalize_dim(dim):
302
+ return int(dim) if isinstance(dim, (int, np.integer)) else None
303
+
304
+ def _get_static_shape(tensor):
305
+ shape = getattr(tensor, 'shape', None)
306
+ if shape is None or shape == tf.TensorShape(None):
307
+ return None
308
+ return [_normalize_dim(dim) for dim in list(shape)]
309
+
310
+ def _shape_match_with_none(expected, actual):
311
+ if expected is None or actual is None:
312
+ return False
313
+ if len(expected) != len(actual):
314
+ return False
315
+ for e_dim, a_dim in zip(expected, actual):
316
+ e_dim = _normalize_dim(e_dim)
317
+ a_dim = _normalize_dim(a_dim)
318
+ if e_dim is None or a_dim is None:
319
+ continue
320
+ if e_dim != a_dim:
321
+ return False
322
+ return True
323
+
324
+ def _perm_shape(shape, perm):
325
+ return [shape[i] for i in perm] if shape is not None else None
326
+
327
+ def _limited_perms(rank):
328
+ identity = list(range(rank))
329
+ perms = [identity]
330
+ if rank == 3:
331
+ perms.append([0, 2, 1])
332
+ elif rank == 4:
333
+ perms.extend([[0, 2, 3, 1], [0, 3, 1, 2]])
334
+ elif rank == 5:
335
+ perms.extend([[0, 2, 3, 4, 1], [0, 4, 1, 2, 3]])
336
+ return perms
337
+
338
+ def _ranked_perms(perms, input_shape, onnx_shape):
339
+ if input_shape is None or onnx_shape is None:
340
+ return perms
341
+ scored = []
342
+ for perm in perms:
343
+ score = 0
344
+ for out_idx, in_idx in enumerate(perm):
345
+ if out_idx >= len(onnx_shape) or in_idx >= len(input_shape):
346
+ continue
347
+ o_dim = _normalize_dim(onnx_shape[out_idx])
348
+ i_dim = input_shape[in_idx]
349
+ if isinstance(o_dim, int) and isinstance(i_dim, int) and o_dim == i_dim:
350
+ score += o_dim
351
+ scored.append((score, 1 if perm == list(range(len(perm))) else 0, perm))
352
+ scored.sort(key=lambda x: (x[0], x[1]), reverse=True)
353
+ return [p for _, _, p in scored]
354
+
355
+ # Rescue guard for unexpected broadcasted shapes
356
+ if not enable_gelu:
357
+ expected_shape = None
358
+ if graph_node_output_shape is not None:
359
+ expected_shape = [_normalize_dim(dim) for dim in list(graph_node_output_shape)]
360
+ output_shape = _get_static_shape(tf_layers_dict[graph_node_output.name]['tf_node'])
361
+ input_shape_1 = _get_static_shape(input_tensor_1)
362
+ input_shape_2 = _get_static_shape(input_tensor_2)
363
+ if expected_shape is not None \
364
+ and output_shape is not None \
365
+ and not _shape_match_with_none(expected_shape, output_shape) \
366
+ and input_shape_1 is not None \
367
+ and input_shape_2 is not None \
368
+ and len(input_shape_1) == len(expected_shape) \
369
+ and len(input_shape_2) == len(expected_shape):
370
+
371
+ rank = len(expected_shape)
372
+ perms = _limited_perms(rank)
373
+ perm_list_1 = _ranked_perms(perms, input_shape_1, expected_shape)
374
+ perm_list_2 = _ranked_perms(perms, input_shape_2, expected_shape)
375
+ rescue_done = False
376
+ for perm_1 in perm_list_1:
377
+ for perm_2 in perm_list_2:
378
+ try_input_1 = transpose_with_flexing_deterrence(
379
+ input_tensor=input_tensor_1,
380
+ perm=perm_1,
381
+ **kwargs,
382
+ )
383
+ try_input_2 = transpose_with_flexing_deterrence(
384
+ input_tensor=input_tensor_2,
385
+ perm=perm_2,
386
+ **kwargs,
387
+ )
388
+ try:
389
+ rescue_tensor = tf.math.add(
390
+ x=try_input_1 \
391
+ if not isinstance(try_input_1, np.ndarray) \
392
+ else tf.convert_to_tensor(try_input_1),
393
+ y=try_input_2 \
394
+ if not isinstance(try_input_2, np.ndarray) \
395
+ else tf.convert_to_tensor(try_input_2),
396
+ name=graph_node.name,
397
+ )
398
+ except Exception as ex:
399
+ continue
400
+
401
+ rescue_shape = _get_static_shape(rescue_tensor)
402
+ if _shape_match_with_none(expected_shape, rescue_shape):
403
+ input_tensor_1 = try_input_1
404
+ input_tensor_2 = try_input_2
405
+ tf_layers_dict[graph_node_output.name]['tf_node'] = rescue_tensor
406
+ tf_type = tf.math.add
407
+ rescue_done = True
408
+ break
409
+ if rescue_done:
410
+ break
411
+
300
412
  # Post-process transpose
301
413
  tf_layers_dict[graph_node_output.name]['tf_node'] = \
302
414
  post_process_transpose(
onnx2tf/ops/Concat.py CHANGED
@@ -291,6 +291,78 @@ def make_node(
291
291
  tf_type = tf.constant
292
292
 
293
293
  else:
294
+ def _normalize_dim(dim):
295
+ return int(dim) if isinstance(dim, (int, np.integer)) else None
296
+
297
+ def _get_static_shape(tensor):
298
+ shape = getattr(tensor, 'shape', None)
299
+ if shape is None or shape == tf.TensorShape(None):
300
+ return None
301
+ return [_normalize_dim(dim) for dim in list(shape)]
302
+
303
+ def _shape_match_with_none(onnx_shape, tf_shape):
304
+ if onnx_shape is None or tf_shape is None:
305
+ return False
306
+ if len(onnx_shape) != len(tf_shape):
307
+ return False
308
+ for o_dim, t_dim in zip(onnx_shape, tf_shape):
309
+ o_dim = _normalize_dim(o_dim)
310
+ t_dim = _normalize_dim(t_dim)
311
+ if o_dim is None or t_dim is None:
312
+ continue
313
+ if o_dim != t_dim:
314
+ return False
315
+ return True
316
+
317
+ def _can_concat_shapes(shapes, axis):
318
+ if shapes is None or any(s is None for s in shapes):
319
+ return True
320
+ rank = len(shapes[0])
321
+ for idx in range(rank):
322
+ if idx == axis:
323
+ continue
324
+ dims = [s[idx] for s in shapes]
325
+ known = [d for d in dims if isinstance(d, int)]
326
+ if len(known) >= 2 and len(set(known)) != 1:
327
+ return False
328
+ return True
329
+
330
+ def _perm_shape(shape, perm):
331
+ return [shape[i] for i in perm] if shape is not None else None
332
+
333
+ def _limited_perms(rank):
334
+ identity = list(range(rank))
335
+ perms = [identity]
336
+ if rank == 3:
337
+ perms.append([0, 2, 1])
338
+ elif rank == 4:
339
+ perms.extend([[0, 2, 3, 1], [0, 3, 1, 2]])
340
+ elif rank == 5:
341
+ perms.extend([[0, 2, 3, 4, 1], [0, 4, 1, 2, 3]])
342
+ return perms
343
+
344
+ def _base_perms(rank):
345
+ if rank <= 1:
346
+ return [list(range(rank))]
347
+ return [list(p) for p in itertools.permutations(range(rank))]
348
+
349
+ def _ranked_perms(perms, input_shape, axis, onnx_shape):
350
+ identity = list(range(len(perms[0]))) if perms else []
351
+ scored = []
352
+ for perm in perms:
353
+ score = 0
354
+ if input_shape is not None and onnx_shape is not None:
355
+ for out_idx, in_idx in enumerate(perm):
356
+ if out_idx == axis:
357
+ continue
358
+ o_dim = _normalize_dim(onnx_shape[out_idx]) if out_idx < len(onnx_shape) else None
359
+ i_dim = input_shape[in_idx] if in_idx < len(input_shape) else None
360
+ if isinstance(o_dim, int) and isinstance(i_dim, int) and o_dim == i_dim:
361
+ score += o_dim
362
+ scored.append((score, 1 if perm == identity else 0, perm))
363
+ scored.sort(key=lambda x: (x[0], x[1]), reverse=True)
364
+ return [p for _, _, p in scored]
365
+
294
366
  try:
295
367
  # normal concat attempt
296
368
  tf_layers_dict[graph_node_output.name]['tf_node'] = \
@@ -301,35 +373,109 @@ def make_node(
301
373
  )
302
374
  except:
303
375
  # Workaround to reduce error rate when merging tensors with undefined dimensions
304
- try:
305
- # Attempts to bind with the axis specified in ONNX
306
- tf_layers_dict[graph_node_output.name]['tf_node'] = \
307
- tf.concat(
308
- values=values,
309
- axis=int(graph_node.attrs.get('axis', 0)),
310
- name=graph_node.name,
311
- )
312
- axis = int(graph_node.attrs.get('axis', 0))
313
- except:
314
- # If not successful with the same axis as ONNX, try to combine by other axes
315
- # Trial in reverse order from the axis at the end
316
- value_rank = len(values[0].shape)
317
- succeed = False
318
- for idx in reversed(range(value_rank)):
376
+ original_values = values
377
+ original_shapes = [_get_static_shape(v) for v in original_values]
378
+ value_rank = getattr(original_values[0].shape, 'rank', None)
379
+ if value_rank is None:
380
+ value_rank = len(original_values[0].shape)
381
+
382
+ onnx_shape_list = None
383
+ if onnx_output_shape is not None:
384
+ onnx_shape_list = [_normalize_dim(dim) for dim in list(onnx_output_shape)]
385
+
386
+ onnx_axis = int(graph_node.attrs.get('axis', 0))
387
+ onnx_axis = onnx_axis + value_rank if onnx_axis < 0 else onnx_axis
388
+
389
+ def _axis_score(axis_idx):
390
+ if onnx_shape_list is not None and axis_idx < len(onnx_shape_list):
391
+ onnx_dim = onnx_shape_list[axis_idx]
392
+ if isinstance(onnx_dim, int):
393
+ return onnx_dim
394
+ score = 0
395
+ for shape in original_shapes:
396
+ if shape is None or axis_idx >= len(shape):
397
+ continue
398
+ dim = shape[axis_idx]
399
+ if isinstance(dim, int):
400
+ score += dim
401
+ return score
402
+
403
+ axis_candidates = list(range(value_rank))
404
+ axis_candidates.sort(
405
+ key=lambda a: (_axis_score(a), 1 if a == onnx_axis else 0),
406
+ reverse=True,
407
+ )
408
+
409
+ base_perms = _base_perms(value_rank)
410
+ max_combo = 20000
411
+ if len(base_perms) ** len(original_values) > max_combo:
412
+ base_perms = _limited_perms(value_rank)
413
+
414
+ succeed = False
415
+ matched = False
416
+ chosen_axis = None
417
+ chosen_values = None
418
+ chosen_tensor = None
419
+
420
+ for axis_idx in axis_candidates:
421
+ perm_lists = [
422
+ _ranked_perms(base_perms, shape, axis_idx, onnx_shape_list)
423
+ for shape in original_shapes
424
+ ]
425
+ for perm_combo in itertools.product(*perm_lists):
426
+ permuted_shapes = [
427
+ _perm_shape(shape, perm) for shape, perm in zip(original_shapes, perm_combo)
428
+ ]
429
+ if not _can_concat_shapes(permuted_shapes, axis_idx):
430
+ continue
431
+ try_values = [
432
+ value if perm == list(range(value_rank)) else
433
+ transpose_with_flexing_deterrence(
434
+ input_tensor=value,
435
+ perm=perm,
436
+ **kwargs,
437
+ )
438
+ for value, perm in zip(original_values, perm_combo)
439
+ ]
319
440
  try:
320
- tf_layers_dict[graph_node_output.name]['tf_node'] = \
441
+ concat_tensor = \
321
442
  tf.concat(
322
- values=values,
323
- axis=idx,
443
+ values=try_values,
444
+ axis=axis_idx,
324
445
  name=graph_node.name,
325
446
  )
326
- axis = idx
447
+ except:
448
+ continue
449
+
450
+ if not succeed:
327
451
  succeed = True
452
+ chosen_axis = axis_idx
453
+ chosen_values = try_values
454
+ chosen_tensor = concat_tensor
455
+
456
+ if onnx_shape_list is None:
457
+ matched = True
458
+ chosen_axis = axis_idx
459
+ chosen_values = try_values
460
+ chosen_tensor = concat_tensor
328
461
  break
329
- except:
330
- pass
331
- if not succeed:
332
- raise
462
+
463
+ output_shape = _get_static_shape(concat_tensor)
464
+ if _shape_match_with_none(onnx_shape_list, output_shape):
465
+ matched = True
466
+ chosen_axis = axis_idx
467
+ chosen_values = try_values
468
+ chosen_tensor = concat_tensor
469
+ break
470
+ if matched:
471
+ break
472
+
473
+ if succeed:
474
+ tf_layers_dict[graph_node_output.name]['tf_node'] = chosen_tensor
475
+ axis = chosen_axis
476
+ values = chosen_values
477
+ else:
478
+ raise
333
479
 
334
480
  # Attempts to force axis correction when the number of axes in the combined tensor do not exactly match.
335
481
  # However, if more than 2 patterns of correct answers exist, give up the correction.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: onnx2tf
3
- Version: 1.29.16
3
+ Version: 1.29.17
4
4
  Summary: Self-Created Tools to convert ONNX files (NCHW) to TensorFlow/TFLite/Keras format (NHWC). The purpose of this tool is to solve the massive Transpose extrapolation problem in onnx-tensorflow (onnx-tf).
5
5
  Keywords: onnx,tensorflow,tflite,keras,deep-learning,machine-learning
6
6
  Author: Katsuya Hyodo
@@ -364,7 +364,7 @@ Video speed is adjusted approximately 50 times slower than actual speed.
364
364
  docker run --rm -it \
365
365
  -v `pwd`:/workdir \
366
366
  -w /workdir \
367
- ghcr.io/pinto0309/onnx2tf:1.29.16
367
+ ghcr.io/pinto0309/onnx2tf:1.29.17
368
368
 
369
369
  or
370
370
 
@@ -372,7 +372,7 @@ Video speed is adjusted approximately 50 times slower than actual speed.
372
372
  docker run --rm -it \
373
373
  -v `pwd`:/workdir \
374
374
  -w /workdir \
375
- docker.io/pinto0309/onnx2tf:1.29.16
375
+ docker.io/pinto0309/onnx2tf:1.29.17
376
376
 
377
377
  or
378
378
 
@@ -1,10 +1,10 @@
1
- onnx2tf/__init__.py,sha256=eUTDHQ-QolqzjE7OAU5EnMP1epQf_1sc4vD2dRt8Bj4,67
1
+ onnx2tf/__init__.py,sha256=lBriMyNyUvk8PZzSUDHztzVxIWdVqefvM7BTdwwGAGU,67
2
2
  onnx2tf/__main__.py,sha256=2RSCQ7d4lc6CwD-rlGn9UicPFg-P5du7ZD_yh-kuBEU,57
3
3
  onnx2tf/onnx2tf.py,sha256=y8FewjpNYAFnUs0cjq6JzdYkiXQSm1o_sZ3PXLJzK64,161921
4
4
  onnx2tf/ops/Abs.py,sha256=V7btmCG_ZvK_qJovUsguq0ZMJ349mhNQ4FHSgzP_Yuo,4029
5
5
  onnx2tf/ops/Acos.py,sha256=Fo8YkFKuWq8Fi2xUrBdKcAH1yJ8r5pjSD0wgLttTNdk,4003
6
6
  onnx2tf/ops/Acosh.py,sha256=ATQj2cT5JS_mTfXi0kXqJ1yzSZu5J0zHA5VjV3j7uKY,3588
7
- onnx2tf/ops/Add.py,sha256=pgJTnV1wZZk3mRaVxxezVkArfmlqlk74DCMZDm6VRJc,12295
7
+ onnx2tf/ops/Add.py,sha256=oSEAuUCPT7lju3R873OH_CDchU4RTDuF8ALJuHyydVc,17106
8
8
  onnx2tf/ops/AffineGrid.py,sha256=j_Q0gRoWpQhep7xHQVqyEBiCbe4yiNelIYSsvq0MPXg,6281
9
9
  onnx2tf/ops/And.py,sha256=_ubtWa0r8-60x__pS7MEMil1DfBqxiUsk66yRCYS4KY,4591
10
10
  onnx2tf/ops/ArgMax.py,sha256=F3PV4EchYQgH1GATJybVGnmY9sGvZkgxCHbNCue9Qns,7278
@@ -29,7 +29,7 @@ onnx2tf/ops/Celu.py,sha256=9g7WNKo4G_jMtUXcoOfpNdLYqEsuyXLPkkyQZxDuL4U,3853
29
29
  onnx2tf/ops/Clip.py,sha256=K3Pgt9BXl5_rzg6s-kPFmwElL5COsvolRY1BUTo7UWw,8753
30
30
  onnx2tf/ops/Col2Im.py,sha256=MDqck00gURrbsroJAgUDkxmdsGyE9v2ez4NKdvdq5IY,7514
31
31
  onnx2tf/ops/Compress.py,sha256=NvDGr9gCNl-8YG41xDBfe3UvhRP03K-ktdtY_MoytBc,3667
32
- onnx2tf/ops/Concat.py,sha256=M0KSwymMIYR-YOIlylFe708TDdOvWNMxDE6V4UKE1MI,32570
32
+ onnx2tf/ops/Concat.py,sha256=kDk7LN01nHuQyYnEPUEikSQ-M17jguAc-qFtCb9tg9I,38537
33
33
  onnx2tf/ops/ConcatFromSequence.py,sha256=z8pNmGQRGq9cxWORW330NZS_0zsmhFudLswMyPn8AXU,3086
34
34
  onnx2tf/ops/Constant.py,sha256=BNZLzNI4rK9kXgVWwD-2RFsDsH7mMy7AY2JSgTNXIWk,10696
35
35
  onnx2tf/ops/ConstantOfShape.py,sha256=6eYm-niow-6fHVEyNyi81BdrVe3IbcdazCp2nySWExA,2331
@@ -199,7 +199,7 @@ onnx2tf/utils/enums.py,sha256=7c5TqetqB07VjyHoxJHfLgtqBqk9ZRyUF33fPOJR1IM,1649
199
199
  onnx2tf/utils/iterative_json_optimizer.py,sha256=qqeIxWGxrhcCYk8-ebWnblnOkzDCwi-nseipHzHR_bk,10436
200
200
  onnx2tf/utils/json_auto_generator.py,sha256=OC-SfKtUg7zUxaXTAg6kT0ShzIc3ByjDa3FNp173DtA,60302
201
201
  onnx2tf/utils/logging.py,sha256=yUCmPuJ_XiUItM3sZMcaMO24JErkQy7zZwVTYWAuiKg,1982
202
- onnx2tf-1.29.16.dist-info/WHEEL,sha256=e_m4S054HL0hyR3CpOk-b7Q7fDX6BuFkgL5OjAExXas,80
203
- onnx2tf-1.29.16.dist-info/entry_points.txt,sha256=GuhvLu7ZlYECumbmoiFlKX0mFPtFi_Ti9L-E5yuQqKs,42
204
- onnx2tf-1.29.16.dist-info/METADATA,sha256=2h83lAHOcFRpBz9nj2MaYmQZlNG74IdwlHkah1pZpeI,154244
205
- onnx2tf-1.29.16.dist-info/RECORD,,
202
+ onnx2tf-1.29.17.dist-info/WHEEL,sha256=e_m4S054HL0hyR3CpOk-b7Q7fDX6BuFkgL5OjAExXas,80
203
+ onnx2tf-1.29.17.dist-info/entry_points.txt,sha256=GuhvLu7ZlYECumbmoiFlKX0mFPtFi_Ti9L-E5yuQqKs,42
204
+ onnx2tf-1.29.17.dist-info/METADATA,sha256=1KG30m7PWIXRFCyU9xrvlttJLm4kZmZCj0BOrf-f_gw,154244
205
+ onnx2tf-1.29.17.dist-info/RECORD,,