onnx2tf 1.29.20__tar.gz → 1.29.22__tar.gz
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-1.29.20 → onnx2tf-1.29.22}/PKG-INFO +29 -8
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/README.md +27 -6
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/__init__.py +1 -1
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/onnx2tf.py +31 -2
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/MaxPool.py +54 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ScatterElements.py +50 -1
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Unique.py +71 -11
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/utils/common_functions.py +99 -2
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/pyproject.toml +2 -2
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/__main__.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Abs.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Acos.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Acosh.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Add.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/AffineGrid.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/And.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ArgMax.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ArgMin.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Asin.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Asinh.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Atan.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Atanh.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Attention.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/AveragePool.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/BatchNormalization.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Bernoulli.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/BitShift.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/BitwiseAnd.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/BitwiseNot.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/BitwiseOr.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/BitwiseXor.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/BlackmanWindow.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Cast.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Ceil.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Celu.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Clip.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Col2Im.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Compress.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Concat.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ConcatFromSequence.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Constant.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ConstantOfShape.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Conv.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ConvInteger.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ConvTranspose.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Cos.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Cosh.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/CumProd.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/CumSum.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/DFT.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/DeformConv.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/DepthToSpace.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/DequantizeLinear.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Det.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Div.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Dropout.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/DynamicQuantizeLinear.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Einsum.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Elu.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Equal.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Erf.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Exp.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Expand.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/EyeLike.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Flatten.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Floor.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/FusedConv.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/GRU.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Gather.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/GatherElements.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/GatherND.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Gelu.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Gemm.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/GlobalAveragePool.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/GlobalLpPool.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/GlobalMaxPool.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Greater.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/GreaterOrEqual.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/GridSample.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/GroupNorm.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/HammingWindow.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/HannWindow.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/HardSigmoid.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/HardSwish.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Hardmax.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Identity.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/If.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ImageDecoder.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Input.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/InstanceNormalization.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Inverse.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/IsInf.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/IsNaN.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/LRN.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/LSTM.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/LayerNormalization.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/LeakyRelu.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Less.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/LessOrEqual.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Log.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/LogSoftmax.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Loop.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/LpNormalization.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/LpPool.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/MatMul.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/MatMulInteger.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Max.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/MaxRoiPool.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/MaxUnpool.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Mean.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/MeanVarianceNormalization.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/MelWeightMatrix.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Min.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Mish.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Mod.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Mul.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Multinomial.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Neg.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/NegativeLogLikelihoodLoss.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/NonMaxSuppression.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/NonZero.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Not.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/OneHot.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/OptionalGetElement.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/OptionalHasElement.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Or.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/PRelu.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Pad.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Pow.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/QLinearAdd.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/QLinearConcat.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/QLinearConv.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/QLinearLeakyRelu.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/QLinearMatMul.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/QLinearMul.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/QLinearSigmoid.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/QLinearSoftmax.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/QuantizeLinear.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/RMSNormalization.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/RNN.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/RandomNormal.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/RandomNormalLike.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/RandomUniform.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/RandomUniformLike.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Range.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Reciprocal.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ReduceL1.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ReduceL2.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ReduceLogSum.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ReduceLogSumExp.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ReduceMax.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ReduceMean.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ReduceMin.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ReduceProd.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ReduceSum.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ReduceSumSquare.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/RegexFullMatch.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Relu.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Reshape.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Resize.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ReverseSequence.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/RoiAlign.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/RotaryEmbedding.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Round.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/STFT.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ScaleAndTranslate.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Scan.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Scatter.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ScatterND.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Selu.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/SequenceAt.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/SequenceConstruct.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/SequenceEmpty.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/SequenceErase.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/SequenceInsert.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/SequenceLength.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Shape.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Shrink.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Sigmoid.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Sign.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Sin.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Sinh.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Size.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Slice.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Softmax.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/SoftmaxCrossEntropyLoss.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Softplus.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Softsign.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/SpaceToDepth.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Split.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/SplitToSequence.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Sqrt.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Squeeze.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/StringConcat.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/StringNormalizer.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/StringSplit.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Sub.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Sum.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Tan.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Tanh.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/TensorScatter.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/ThresholdedRelu.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Tile.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/TopK.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Transpose.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Trilu.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Unsqueeze.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Upsample.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Where.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/Xor.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/ops/__init__.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/utils/__init__.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/utils/enums.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/utils/iterative_json_optimizer.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/utils/json_auto_generator.py +0 -0
- {onnx2tf-1.29.20 → onnx2tf-1.29.22}/onnx2tf/utils/logging.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: onnx2tf
|
|
3
|
-
Version: 1.29.
|
|
3
|
+
Version: 1.29.22
|
|
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
|
|
@@ -18,7 +18,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
18
18
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
19
|
Requires-Dist: requests==2.32.5
|
|
20
20
|
Requires-Dist: numpy==1.26.4
|
|
21
|
-
Requires-Dist: onnx==1.19.
|
|
21
|
+
Requires-Dist: onnx==1.19.1
|
|
22
22
|
Requires-Dist: onnxruntime==1.23.0
|
|
23
23
|
Requires-Dist: opencv-python==4.11.0.86
|
|
24
24
|
Requires-Dist: onnxsim==0.4.36
|
|
@@ -365,7 +365,7 @@ Video speed is adjusted approximately 50 times slower than actual speed.
|
|
|
365
365
|
docker run --rm -it \
|
|
366
366
|
-v `pwd`:/workdir \
|
|
367
367
|
-w /workdir \
|
|
368
|
-
ghcr.io/pinto0309/onnx2tf:1.29.
|
|
368
|
+
ghcr.io/pinto0309/onnx2tf:1.29.22
|
|
369
369
|
|
|
370
370
|
or
|
|
371
371
|
|
|
@@ -373,18 +373,18 @@ Video speed is adjusted approximately 50 times slower than actual speed.
|
|
|
373
373
|
docker run --rm -it \
|
|
374
374
|
-v `pwd`:/workdir \
|
|
375
375
|
-w /workdir \
|
|
376
|
-
docker.io/pinto0309/onnx2tf:1.29.
|
|
376
|
+
docker.io/pinto0309/onnx2tf:1.29.22
|
|
377
377
|
|
|
378
378
|
or
|
|
379
379
|
|
|
380
|
-
pip install -U onnx==1.19.
|
|
380
|
+
pip install -U onnx==1.19.1 \
|
|
381
381
|
&& pip install -U onnx-graphsurgeon==0.5.8 \
|
|
382
382
|
&& pip install -U onnxruntime==1.23.0 \
|
|
383
383
|
&& pip install -U onnxsim==0.4.36 \
|
|
384
384
|
&& pip install -U onnxoptimizer==0.4.2 \
|
|
385
385
|
&& pip install -U simple_onnx_processing_tools==1.1.32 \
|
|
386
|
-
&& pip install -U sne4onnx
|
|
387
|
-
&& pip install -U sng4onnx
|
|
386
|
+
&& pip install -U sne4onnx==1.0.15 \
|
|
387
|
+
&& pip install -U sng4onnx==1.0.5 \
|
|
388
388
|
&& pip install -U ai_edge_litert==1.2.0 \
|
|
389
389
|
&& pip install -U tensorflow==2.19.0 \
|
|
390
390
|
&& pip install -U protobuf==3.20.3 \
|
|
@@ -630,7 +630,7 @@ After many upgrades, the need for JSON parameter correction has become much less
|
|
|
630
630
|
|
|
631
631
|
`-ois` an option to overwrite the input OP to a static size if it has undefined dimensions. `-cotof` option checks the accuracy of all OPs one by one. `-cotoa` is the error value of the threshold for determining an accuracy error. If there are undefined dimensions in the input OP, it is better to fix them to the static geometry to improve the accuracy of the accuracy measurement.
|
|
632
632
|
|
|
633
|
-
Also, you can use the `-cind` option to specify custom input for `-cotof`, instead of using the default dummy input. Otherwise, all input values will be set to 1. For more information about the `-cind` option, please refer to [here](#cli-parameter).
|
|
633
|
+
Also, you can use the `-cind` option to specify custom input for `-cotof`, instead of using the default dummy input. Otherwise, all input values will be set to 1. You can override the dummy input values with `--value_hints` (scalar only, `*:default` supported). For more information about the `-cind` option, please refer to [here](#cli-parameter).
|
|
634
634
|
|
|
635
635
|
The `-cotof` option only compares the original ONNX and converted TensorFlow (Keras) models at Float32 precision, not at Float16 or INT8 precision.
|
|
636
636
|
|
|
@@ -644,6 +644,10 @@ onnx2tf -i mobilenetv2-12.onnx -b 1 -cotof -cotoa 1e-1
|
|
|
644
644
|
or
|
|
645
645
|
|
|
646
646
|
onnx2tf -i mobilenetv2-12.onnx -cotof -cotoa 1e-1 -cind "input" "/your/path/x.npy"
|
|
647
|
+
|
|
648
|
+
or
|
|
649
|
+
|
|
650
|
+
onnx2tf -i mobilenetv2-12.onnx -cotof -cotoa 1e-1 --value_hints "input:0.5" "*:1.0"
|
|
647
651
|
```
|
|
648
652
|

|
|
649
653
|
|
|
@@ -1826,6 +1830,14 @@ optional arguments:
|
|
|
1826
1830
|
A value of 1 or more must be specified.
|
|
1827
1831
|
Numerical values other than dynamic dimensions are ignored.
|
|
1828
1832
|
|
|
1833
|
+
-vh VALUE_HINTS [VALUE_HINTS ...], \
|
|
1834
|
+
--value_hints VALUE_HINTS [VALUE_HINTS ...]
|
|
1835
|
+
Value hints for dummy inference input tensors.
|
|
1836
|
+
The format is
|
|
1837
|
+
"input_name_1:value" "input_name_2:value" "*:default_value"
|
|
1838
|
+
"*" applies to all inputs not explicitly specified.
|
|
1839
|
+
Values are scalar only.
|
|
1840
|
+
|
|
1829
1841
|
-nlt, --no_large_tensor
|
|
1830
1842
|
Suppresses constant bloat caused by Tile OP when optimizing models in onnxsim.
|
|
1831
1843
|
See: https://github.com/daquexian/onnx-simplifier/issues/178
|
|
@@ -2157,6 +2169,7 @@ convert(
|
|
|
2157
2169
|
batch_size: Union[int, NoneType] = None,
|
|
2158
2170
|
overwrite_input_shape: Union[List[str], NoneType] = None,
|
|
2159
2171
|
shape_hints: Union[List[str], NoneType] = None,
|
|
2172
|
+
value_hints: Union[List[str], NoneType] = None,
|
|
2160
2173
|
no_large_tensor: Optional[bool] = False,
|
|
2161
2174
|
output_nms_with_dynamic_tensor: Optional[bool] = False,
|
|
2162
2175
|
switch_nms_version: Optional[str] = 'v4',
|
|
@@ -2377,6 +2390,13 @@ convert(
|
|
|
2377
2390
|
A value of 1 or more must be specified.
|
|
2378
2391
|
Numerical values other than dynamic dimensions are ignored.
|
|
2379
2392
|
|
|
2393
|
+
value_hints: Optional[List[str]]
|
|
2394
|
+
Value hints for dummy inference input tensors.
|
|
2395
|
+
The format is
|
|
2396
|
+
['input_name_1:value', 'input_name_2:value', '*:default_value']
|
|
2397
|
+
"*" applies to all inputs not explicitly specified.
|
|
2398
|
+
Values are scalar only.
|
|
2399
|
+
|
|
2380
2400
|
no_large_tensor: Optional[bool]
|
|
2381
2401
|
Suppresses constant bloat caused by Tile OP when optimizing models in onnxsim.
|
|
2382
2402
|
See: https://github.com/daquexian/onnx-simplifier/issues/178
|
|
@@ -3032,6 +3052,7 @@ The above differences often cannot be dealt with by simply converting the model
|
|
|
3032
3052
|
14. [nobuco](https://github.com/AlexanderLutsenko/nobuco)
|
|
3033
3053
|
15. [onnx2torch](https://github.com/ENOT-AutoDL/onnx2torch)
|
|
3034
3054
|
16. [ai-edge-torch](https://github.com/google-ai-edge/ai-edge-torch)
|
|
3055
|
+
17. [LiteRT.js](https://ai.google.dev/edge/litert/web)
|
|
3035
3056
|
|
|
3036
3057
|
## Acknowledgement
|
|
3037
3058
|
1. https://github.com/onnx/models
|
|
@@ -323,7 +323,7 @@ Video speed is adjusted approximately 50 times slower than actual speed.
|
|
|
323
323
|
docker run --rm -it \
|
|
324
324
|
-v `pwd`:/workdir \
|
|
325
325
|
-w /workdir \
|
|
326
|
-
ghcr.io/pinto0309/onnx2tf:1.29.
|
|
326
|
+
ghcr.io/pinto0309/onnx2tf:1.29.22
|
|
327
327
|
|
|
328
328
|
or
|
|
329
329
|
|
|
@@ -331,18 +331,18 @@ Video speed is adjusted approximately 50 times slower than actual speed.
|
|
|
331
331
|
docker run --rm -it \
|
|
332
332
|
-v `pwd`:/workdir \
|
|
333
333
|
-w /workdir \
|
|
334
|
-
docker.io/pinto0309/onnx2tf:1.29.
|
|
334
|
+
docker.io/pinto0309/onnx2tf:1.29.22
|
|
335
335
|
|
|
336
336
|
or
|
|
337
337
|
|
|
338
|
-
pip install -U onnx==1.19.
|
|
338
|
+
pip install -U onnx==1.19.1 \
|
|
339
339
|
&& pip install -U onnx-graphsurgeon==0.5.8 \
|
|
340
340
|
&& pip install -U onnxruntime==1.23.0 \
|
|
341
341
|
&& pip install -U onnxsim==0.4.36 \
|
|
342
342
|
&& pip install -U onnxoptimizer==0.4.2 \
|
|
343
343
|
&& pip install -U simple_onnx_processing_tools==1.1.32 \
|
|
344
|
-
&& pip install -U sne4onnx
|
|
345
|
-
&& pip install -U sng4onnx
|
|
344
|
+
&& pip install -U sne4onnx==1.0.15 \
|
|
345
|
+
&& pip install -U sng4onnx==1.0.5 \
|
|
346
346
|
&& pip install -U ai_edge_litert==1.2.0 \
|
|
347
347
|
&& pip install -U tensorflow==2.19.0 \
|
|
348
348
|
&& pip install -U protobuf==3.20.3 \
|
|
@@ -588,7 +588,7 @@ After many upgrades, the need for JSON parameter correction has become much less
|
|
|
588
588
|
|
|
589
589
|
`-ois` an option to overwrite the input OP to a static size if it has undefined dimensions. `-cotof` option checks the accuracy of all OPs one by one. `-cotoa` is the error value of the threshold for determining an accuracy error. If there are undefined dimensions in the input OP, it is better to fix them to the static geometry to improve the accuracy of the accuracy measurement.
|
|
590
590
|
|
|
591
|
-
Also, you can use the `-cind` option to specify custom input for `-cotof`, instead of using the default dummy input. Otherwise, all input values will be set to 1. For more information about the `-cind` option, please refer to [here](#cli-parameter).
|
|
591
|
+
Also, you can use the `-cind` option to specify custom input for `-cotof`, instead of using the default dummy input. Otherwise, all input values will be set to 1. You can override the dummy input values with `--value_hints` (scalar only, `*:default` supported). For more information about the `-cind` option, please refer to [here](#cli-parameter).
|
|
592
592
|
|
|
593
593
|
The `-cotof` option only compares the original ONNX and converted TensorFlow (Keras) models at Float32 precision, not at Float16 or INT8 precision.
|
|
594
594
|
|
|
@@ -602,6 +602,10 @@ onnx2tf -i mobilenetv2-12.onnx -b 1 -cotof -cotoa 1e-1
|
|
|
602
602
|
or
|
|
603
603
|
|
|
604
604
|
onnx2tf -i mobilenetv2-12.onnx -cotof -cotoa 1e-1 -cind "input" "/your/path/x.npy"
|
|
605
|
+
|
|
606
|
+
or
|
|
607
|
+
|
|
608
|
+
onnx2tf -i mobilenetv2-12.onnx -cotof -cotoa 1e-1 --value_hints "input:0.5" "*:1.0"
|
|
605
609
|
```
|
|
606
610
|

|
|
607
611
|
|
|
@@ -1784,6 +1788,14 @@ optional arguments:
|
|
|
1784
1788
|
A value of 1 or more must be specified.
|
|
1785
1789
|
Numerical values other than dynamic dimensions are ignored.
|
|
1786
1790
|
|
|
1791
|
+
-vh VALUE_HINTS [VALUE_HINTS ...], \
|
|
1792
|
+
--value_hints VALUE_HINTS [VALUE_HINTS ...]
|
|
1793
|
+
Value hints for dummy inference input tensors.
|
|
1794
|
+
The format is
|
|
1795
|
+
"input_name_1:value" "input_name_2:value" "*:default_value"
|
|
1796
|
+
"*" applies to all inputs not explicitly specified.
|
|
1797
|
+
Values are scalar only.
|
|
1798
|
+
|
|
1787
1799
|
-nlt, --no_large_tensor
|
|
1788
1800
|
Suppresses constant bloat caused by Tile OP when optimizing models in onnxsim.
|
|
1789
1801
|
See: https://github.com/daquexian/onnx-simplifier/issues/178
|
|
@@ -2115,6 +2127,7 @@ convert(
|
|
|
2115
2127
|
batch_size: Union[int, NoneType] = None,
|
|
2116
2128
|
overwrite_input_shape: Union[List[str], NoneType] = None,
|
|
2117
2129
|
shape_hints: Union[List[str], NoneType] = None,
|
|
2130
|
+
value_hints: Union[List[str], NoneType] = None,
|
|
2118
2131
|
no_large_tensor: Optional[bool] = False,
|
|
2119
2132
|
output_nms_with_dynamic_tensor: Optional[bool] = False,
|
|
2120
2133
|
switch_nms_version: Optional[str] = 'v4',
|
|
@@ -2335,6 +2348,13 @@ convert(
|
|
|
2335
2348
|
A value of 1 or more must be specified.
|
|
2336
2349
|
Numerical values other than dynamic dimensions are ignored.
|
|
2337
2350
|
|
|
2351
|
+
value_hints: Optional[List[str]]
|
|
2352
|
+
Value hints for dummy inference input tensors.
|
|
2353
|
+
The format is
|
|
2354
|
+
['input_name_1:value', 'input_name_2:value', '*:default_value']
|
|
2355
|
+
"*" applies to all inputs not explicitly specified.
|
|
2356
|
+
Values are scalar only.
|
|
2357
|
+
|
|
2338
2358
|
no_large_tensor: Optional[bool]
|
|
2339
2359
|
Suppresses constant bloat caused by Tile OP when optimizing models in onnxsim.
|
|
2340
2360
|
See: https://github.com/daquexian/onnx-simplifier/issues/178
|
|
@@ -2990,6 +3010,7 @@ The above differences often cannot be dealt with by simply converting the model
|
|
|
2990
3010
|
14. [nobuco](https://github.com/AlexanderLutsenko/nobuco)
|
|
2991
3011
|
15. [onnx2torch](https://github.com/ENOT-AutoDL/onnx2torch)
|
|
2992
3012
|
16. [ai-edge-torch](https://github.com/google-ai-edge/ai-edge-torch)
|
|
3013
|
+
17. [LiteRT.js](https://ai.google.dev/edge/litert/web)
|
|
2993
3014
|
|
|
2994
3015
|
## Acknowledgement
|
|
2995
3016
|
1. https://github.com/onnx/models
|
|
@@ -43,6 +43,7 @@ from typing import Optional, List, Any, Dict
|
|
|
43
43
|
from argparse import ArgumentParser
|
|
44
44
|
|
|
45
45
|
import importlib
|
|
46
|
+
import onnx2tf.utils.common_functions as common_functions
|
|
46
47
|
from onnx2tf.utils.common_functions import (
|
|
47
48
|
dummy_onnx_inference,
|
|
48
49
|
dummy_tf_inference,
|
|
@@ -639,6 +640,7 @@ def convert(
|
|
|
639
640
|
batch_size: Optional[int] = None,
|
|
640
641
|
overwrite_input_shape: Optional[List[str]] = None,
|
|
641
642
|
shape_hints: Optional[List[str]] = None,
|
|
643
|
+
value_hints: Optional[List[str]] = None,
|
|
642
644
|
no_large_tensor: Optional[bool] = False,
|
|
643
645
|
output_nms_with_dynamic_tensor: Optional[bool] = False,
|
|
644
646
|
switch_nms_version: Optional[str] = 'v4',
|
|
@@ -850,6 +852,15 @@ def convert(
|
|
|
850
852
|
A value of 1 or more must be specified.\n
|
|
851
853
|
Numerical values other than dynamic dimensions are ignored.
|
|
852
854
|
|
|
855
|
+
value_hints: Optional[List[str]]
|
|
856
|
+
Value hints for dummy inference input tensors.\n
|
|
857
|
+
The format is\n
|
|
858
|
+
["input_name_1:value","input_name_2:value","*:default_value"].\n
|
|
859
|
+
"*" applies to all inputs not explicitly specified.\n
|
|
860
|
+
Values are scalar only.\n
|
|
861
|
+
e.g.\n
|
|
862
|
+
['input0:0.5','mask:0','*:1.0']\n
|
|
863
|
+
|
|
853
864
|
no_large_tensor: Optional[bool]
|
|
854
865
|
Suppresses constant bloat caused by Tile OP when optimizing models in onnxsim.\n
|
|
855
866
|
See: https://github.com/daquexian/onnx-simplifier/issues/178
|
|
@@ -1110,6 +1121,8 @@ def convert(
|
|
|
1110
1121
|
if verbosity is None:
|
|
1111
1122
|
verbosity = 'debug'
|
|
1112
1123
|
set_log_level('error' if non_verbose else verbosity)
|
|
1124
|
+
common_functions.set_dummy_shape_hints(shape_hints)
|
|
1125
|
+
common_functions.set_dummy_value_hints(value_hints)
|
|
1113
1126
|
|
|
1114
1127
|
# Either designation required
|
|
1115
1128
|
if not input_onnx_file_path and not onnx_graph:
|
|
@@ -1326,6 +1339,10 @@ def convert(
|
|
|
1326
1339
|
'Failed to optimize the onnx file.'
|
|
1327
1340
|
)
|
|
1328
1341
|
|
|
1342
|
+
has_external_data = False
|
|
1343
|
+
if input_onnx_file_path and os.path.exists(input_onnx_file_path):
|
|
1344
|
+
has_external_data = check_has_external_data(input_onnx_file_path)
|
|
1345
|
+
|
|
1329
1346
|
# Automatic generation of each OP name - sng4onnx
|
|
1330
1347
|
if not not_use_opname_auto_generate:
|
|
1331
1348
|
info('')
|
|
@@ -1357,9 +1374,7 @@ def convert(
|
|
|
1357
1374
|
|
|
1358
1375
|
# Loading Graphs
|
|
1359
1376
|
# onnx_graph If specified, onnx_graph is processed first
|
|
1360
|
-
has_external_data = False
|
|
1361
1377
|
if not onnx_graph:
|
|
1362
|
-
has_external_data = check_has_external_data(input_onnx_file_path)
|
|
1363
1378
|
onnx_graph = onnx.load(input_onnx_file_path)
|
|
1364
1379
|
|
|
1365
1380
|
if not auto_split_model and onnx_graph is not None:
|
|
@@ -1686,6 +1701,7 @@ def convert(
|
|
|
1686
1701
|
'batch_size': batch_size,
|
|
1687
1702
|
'overwrite_input_shape': overwrite_input_shape,
|
|
1688
1703
|
'shape_hints': shape_hints,
|
|
1704
|
+
'value_hints': value_hints,
|
|
1689
1705
|
'no_large_tensor': no_large_tensor,
|
|
1690
1706
|
'output_nms_with_dynamic_tensor': output_nms_with_dynamic_tensor,
|
|
1691
1707
|
'switch_nms_version': switch_nms_version,
|
|
@@ -3874,6 +3890,18 @@ def main():
|
|
|
3874
3890
|
'Only applied to dynamic dimensions in inputs. \n' +
|
|
3875
3891
|
'Only used when -cotof or -coto are specified.'
|
|
3876
3892
|
)
|
|
3893
|
+
parser.add_argument(
|
|
3894
|
+
'-vh',
|
|
3895
|
+
'--value_hints',
|
|
3896
|
+
type=str,
|
|
3897
|
+
nargs='+',
|
|
3898
|
+
help=\
|
|
3899
|
+
'Value hints for dummy inference input tensors. \n' +
|
|
3900
|
+
'The format is\n' +
|
|
3901
|
+
'"input_name_1:value" "input_name_2:value" "*:default_value". \n' +
|
|
3902
|
+
'"*" applies to all inputs not explicitly specified. \n' +
|
|
3903
|
+
'Values are scalar only.'
|
|
3904
|
+
)
|
|
3877
3905
|
parser.add_argument(
|
|
3878
3906
|
'-nlt',
|
|
3879
3907
|
'--no_large_tensor',
|
|
@@ -4359,6 +4387,7 @@ def main():
|
|
|
4359
4387
|
batch_size=args.batch_size,
|
|
4360
4388
|
overwrite_input_shape=args.overwrite_input_shape,
|
|
4361
4389
|
shape_hints=args.shape_hints,
|
|
4390
|
+
value_hints=args.value_hints,
|
|
4362
4391
|
no_large_tensor=args.no_large_tensor,
|
|
4363
4392
|
output_nms_with_dynamic_tensor=args.output_nms_with_dynamic_tensor,
|
|
4364
4393
|
switch_nms_version=args.switch_nms_version,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import random
|
|
2
2
|
random.seed(0)
|
|
3
3
|
import numpy as np
|
|
4
|
+
import itertools
|
|
4
5
|
np.random.seed(0)
|
|
5
6
|
import tensorflow as tf
|
|
6
7
|
import tf_keras
|
|
@@ -119,6 +120,59 @@ def make_node(
|
|
|
119
120
|
**kwargs,
|
|
120
121
|
)
|
|
121
122
|
|
|
123
|
+
# Guard: brute-force axis alignment between NCHW and NHWC when batch dim mismatches.
|
|
124
|
+
# Only trigger when shapes are fully known to avoid destabilizing existing behavior.
|
|
125
|
+
def _shape_matches(shape_a, shape_b):
|
|
126
|
+
if shape_a is None or shape_b is None or len(shape_a) != len(shape_b):
|
|
127
|
+
return False
|
|
128
|
+
for dim_a, dim_b in zip(shape_a, shape_b):
|
|
129
|
+
if dim_a is None or dim_b is None:
|
|
130
|
+
continue
|
|
131
|
+
if dim_a != dim_b:
|
|
132
|
+
return False
|
|
133
|
+
return True
|
|
134
|
+
|
|
135
|
+
def _best_perm_to_match(cur_shape, target_shape):
|
|
136
|
+
rank = len(cur_shape)
|
|
137
|
+
best_perm = None
|
|
138
|
+
best_cost = None
|
|
139
|
+
for perm in itertools.permutations(range(rank)):
|
|
140
|
+
permuted = [cur_shape[i] for i in perm]
|
|
141
|
+
if not _shape_matches(permuted, target_shape):
|
|
142
|
+
continue
|
|
143
|
+
cost = sum(abs(i - perm[i]) for i in range(rank))
|
|
144
|
+
if best_cost is None or cost < best_cost:
|
|
145
|
+
best_cost = cost
|
|
146
|
+
best_perm = perm
|
|
147
|
+
return best_perm
|
|
148
|
+
|
|
149
|
+
try:
|
|
150
|
+
current_shape = input_tensor.shape.as_list()
|
|
151
|
+
except Exception:
|
|
152
|
+
current_shape = None
|
|
153
|
+
|
|
154
|
+
if onnx_input_shape is not None and current_shape is not None:
|
|
155
|
+
onnx_shape = [
|
|
156
|
+
dim if isinstance(dim, int) else None for dim in onnx_input_shape
|
|
157
|
+
]
|
|
158
|
+
cur_shape = [
|
|
159
|
+
dim if isinstance(dim, int) else None for dim in current_shape
|
|
160
|
+
]
|
|
161
|
+
if len(onnx_shape) in (3, 4, 5) \
|
|
162
|
+
and len(cur_shape) == len(onnx_shape) \
|
|
163
|
+
and None not in onnx_shape \
|
|
164
|
+
and None not in cur_shape:
|
|
165
|
+
expected_shape = [onnx_shape[0]] + onnx_shape[2:] + [onnx_shape[1]]
|
|
166
|
+
if cur_shape[0] != onnx_shape[0] \
|
|
167
|
+
and not _shape_matches(cur_shape, expected_shape):
|
|
168
|
+
perm = _best_perm_to_match(cur_shape, expected_shape)
|
|
169
|
+
if perm is not None:
|
|
170
|
+
input_tensor = transpose_with_flexing_deterrence(
|
|
171
|
+
input_tensor=input_tensor,
|
|
172
|
+
perm=list(perm),
|
|
173
|
+
**kwargs,
|
|
174
|
+
)
|
|
175
|
+
|
|
122
176
|
filter = None
|
|
123
177
|
|
|
124
178
|
auto_pad = graph_node.attrs.get('auto_pad', 'NOTSET')
|
|
@@ -146,6 +146,48 @@ def make_node(
|
|
|
146
146
|
axis=axis,
|
|
147
147
|
indices=indices_tensor,
|
|
148
148
|
)
|
|
149
|
+
indices_rank = None
|
|
150
|
+
if hasattr(indices_tensor, "shape") and indices_tensor.shape is not None:
|
|
151
|
+
try:
|
|
152
|
+
indices_rank = len(indices_tensor.shape)
|
|
153
|
+
except TypeError:
|
|
154
|
+
indices_rank = indices_tensor.shape.rank
|
|
155
|
+
updates_rank = updates_tensor_rank
|
|
156
|
+
broadcast_shape = None
|
|
157
|
+
pad_rank = 0
|
|
158
|
+
|
|
159
|
+
def _pad_and_broadcast(target_tensor, pad_rank, target_shape):
|
|
160
|
+
tensor = target_tensor
|
|
161
|
+
if isinstance(tensor, np.ndarray):
|
|
162
|
+
tensor = tf.convert_to_tensor(tensor)
|
|
163
|
+
if pad_rank <= 0:
|
|
164
|
+
return tf.broadcast_to(tensor, target_shape)
|
|
165
|
+
tensor_shape = tf.shape(tensor)
|
|
166
|
+
new_shape = tf.concat(
|
|
167
|
+
[tf.ones([pad_rank], dtype=tf.int32), tensor_shape],
|
|
168
|
+
axis=0,
|
|
169
|
+
)
|
|
170
|
+
tensor = tf.reshape(tensor, new_shape)
|
|
171
|
+
return tf.broadcast_to(tensor, target_shape)
|
|
172
|
+
|
|
173
|
+
updates_tensor_for_scatter = updates_tensor
|
|
174
|
+
if indices_rank is not None and updates_rank is not None and indices_rank != updates_rank:
|
|
175
|
+
if indices_rank > updates_rank:
|
|
176
|
+
broadcast_shape = tf.shape(indices_tensor)
|
|
177
|
+
pad_rank = indices_rank - updates_rank
|
|
178
|
+
updates_tensor_for_scatter = _pad_and_broadcast(
|
|
179
|
+
updates_tensor,
|
|
180
|
+
pad_rank,
|
|
181
|
+
broadcast_shape,
|
|
182
|
+
)
|
|
183
|
+
else:
|
|
184
|
+
broadcast_shape = tf.shape(updates_tensor)
|
|
185
|
+
pad_rank = updates_rank - indices_rank
|
|
186
|
+
indices_tensor = _pad_and_broadcast(
|
|
187
|
+
indices_tensor,
|
|
188
|
+
pad_rank,
|
|
189
|
+
broadcast_shape,
|
|
190
|
+
)
|
|
149
191
|
sparsified_dense_idx_shape = updates_tensor_shape
|
|
150
192
|
|
|
151
193
|
if None not in sparsified_dense_idx_shape:
|
|
@@ -160,6 +202,13 @@ def make_node(
|
|
|
160
202
|
]
|
|
161
203
|
|
|
162
204
|
idx_tensors_per_axis = tf.meshgrid(*idx_tensors_per_axis, indexing='ij')
|
|
205
|
+
if indices_rank is not None \
|
|
206
|
+
and updates_rank is not None \
|
|
207
|
+
and indices_rank > updates_rank:
|
|
208
|
+
idx_tensors_per_axis = [
|
|
209
|
+
_pad_and_broadcast(idx_tensor, pad_rank, broadcast_shape)
|
|
210
|
+
for idx_tensor in idx_tensors_per_axis
|
|
211
|
+
]
|
|
163
212
|
idx_tensors_per_axis[axis] = indices_tensor
|
|
164
213
|
dim_expanded_idx_tensors_per_axis = [
|
|
165
214
|
tf.expand_dims(idx_tensor, axis=-1)
|
|
@@ -194,7 +243,7 @@ def make_node(
|
|
|
194
243
|
)
|
|
195
244
|
|
|
196
245
|
indices = tf.reshape(coordinate, [-1, input_tensor_rank])
|
|
197
|
-
updates = tf.reshape(
|
|
246
|
+
updates = tf.reshape(updates_tensor_for_scatter, [-1])
|
|
198
247
|
output = tf.tensor_scatter_nd_update(
|
|
199
248
|
tensor=input_tensor,
|
|
200
249
|
indices=indices,
|
|
@@ -14,6 +14,7 @@ from onnx2tf.utils.common_functions import (
|
|
|
14
14
|
make_tf_node_info,
|
|
15
15
|
get_replacement_parameter,
|
|
16
16
|
pre_process_transpose,
|
|
17
|
+
convert_axis,
|
|
17
18
|
)
|
|
18
19
|
from onnx2tf.utils.logging import Color
|
|
19
20
|
|
|
@@ -69,8 +70,20 @@ def make_node(
|
|
|
69
70
|
**kwargs,
|
|
70
71
|
)
|
|
71
72
|
|
|
73
|
+
input_tensor_shape = input_tensor.shape
|
|
74
|
+
tensor_rank = len(input_tensor_shape) \
|
|
75
|
+
if input_tensor_shape != tf.TensorShape(None) else 1
|
|
76
|
+
|
|
72
77
|
axis = graph_node.attrs.get('axis', None)
|
|
73
78
|
sorted = graph_node.attrs.get('sorted', 1)
|
|
79
|
+
if axis is not None:
|
|
80
|
+
if isinstance(axis, np.ndarray) and axis.shape == ():
|
|
81
|
+
axis = int(axis)
|
|
82
|
+
axis = convert_axis(
|
|
83
|
+
axis=int(axis),
|
|
84
|
+
tensor_rank=tensor_rank,
|
|
85
|
+
before_op_output_shape_trans=before_op_output_shape_trans,
|
|
86
|
+
)
|
|
74
87
|
|
|
75
88
|
# Preserving Graph Structure (Dict)
|
|
76
89
|
for graph_node_output in graph_node_outputs:
|
|
@@ -101,17 +114,64 @@ def make_node(
|
|
|
101
114
|
|
|
102
115
|
# tf unique returns unsorted tensor, need to sort if option is enabled
|
|
103
116
|
if sorted:
|
|
104
|
-
#
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
117
|
+
# Sort unique outputs to match ONNX sorted behavior.
|
|
118
|
+
def _argsort_supported(dtype):
|
|
119
|
+
return dtype.is_floating or dtype.is_integer or dtype == tf.bool
|
|
120
|
+
|
|
121
|
+
y_rank = y.shape.rank
|
|
122
|
+
axis_ = axis
|
|
123
|
+
if axis_ is None:
|
|
124
|
+
axis_ = 0
|
|
125
|
+
if axis_ < 0 and y_rank is not None:
|
|
126
|
+
axis_ = axis_ + y_rank
|
|
127
|
+
|
|
128
|
+
def _lexsort_perm(flat_2d):
|
|
129
|
+
if not _argsort_supported(flat_2d.dtype):
|
|
130
|
+
return None
|
|
131
|
+
cols = flat_2d.shape[1]
|
|
132
|
+
if cols is None:
|
|
133
|
+
return None
|
|
134
|
+
order = tf.range(tf.shape(flat_2d)[0])
|
|
135
|
+
for col in reversed(range(cols)):
|
|
136
|
+
col_vals = tf.gather(flat_2d, order)[:, col]
|
|
137
|
+
if col_vals.dtype == tf.bool:
|
|
138
|
+
col_vals = tf.cast(col_vals, tf.int32)
|
|
139
|
+
order = tf.gather(order, tf.argsort(col_vals, stable=True))
|
|
140
|
+
return order
|
|
141
|
+
|
|
142
|
+
order = None
|
|
143
|
+
if y_rank is not None and y_rank == 1:
|
|
144
|
+
if _argsort_supported(y.dtype):
|
|
145
|
+
sort_vals = y
|
|
146
|
+
if sort_vals.dtype == tf.bool:
|
|
147
|
+
sort_vals = tf.cast(sort_vals, tf.int32)
|
|
148
|
+
order = tf.argsort(sort_vals, stable=True)
|
|
149
|
+
elif y_rank is not None and axis_ is not None and 0 <= axis_ < y_rank:
|
|
150
|
+
perm = [axis_] + [i for i in range(y_rank) if i != axis_]
|
|
151
|
+
y_t = tf.transpose(y, perm)
|
|
152
|
+
flat = tf.reshape(y_t, [tf.shape(y_t)[0], -1])
|
|
153
|
+
order = _lexsort_perm(flat)
|
|
154
|
+
|
|
155
|
+
if order is None:
|
|
156
|
+
warn_msg = f'' + \
|
|
157
|
+
Color.YELLOW(f'WARNING:') + ' ' + \
|
|
158
|
+
f'Unique sort fallback to unsorted due to dynamic shape or unsupported dtype.'
|
|
159
|
+
print(warn_msg)
|
|
160
|
+
else:
|
|
161
|
+
y = tf.gather(y, order, axis=axis_)
|
|
162
|
+
count = tf.gather(count, order)
|
|
163
|
+
indices = tf.gather(indices, order)
|
|
164
|
+
inv_order = tf.argsort(order)
|
|
165
|
+
inverse_indices = tf.gather(inv_order, inverse_indices)
|
|
166
|
+
|
|
167
|
+
if len(graph_node_outputs) >= 1:
|
|
168
|
+
tf_layers_dict[graph_node_outputs[0].name]['tf_node'] = y
|
|
169
|
+
if len(graph_node_outputs) >= 2:
|
|
170
|
+
tf_layers_dict[graph_node_outputs[1].name]['tf_node'] = indices
|
|
171
|
+
if len(graph_node_outputs) >= 3:
|
|
172
|
+
tf_layers_dict[graph_node_outputs[2].name]['tf_node'] = inverse_indices
|
|
173
|
+
if len(graph_node_outputs) >= 4:
|
|
174
|
+
tf_layers_dict[graph_node_outputs[3].name]['tf_node'] = count
|
|
115
175
|
|
|
116
176
|
# Generation of Debug Info
|
|
117
177
|
tf_outputs = {f"output{idx}": value for idx, value in enumerate([y, indices, inverse_indices, count])}
|