onnx2tf 1.29.18__py3-none-any.whl → 1.29.19__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 +1 -1
- onnx2tf/ops/Col2Im.py +108 -64
- onnx2tf/ops/DFT.py +245 -0
- onnx2tf/ops/DeformConv.py +399 -0
- {onnx2tf-1.29.18.dist-info → onnx2tf-1.29.19.dist-info}/METADATA +5 -5
- {onnx2tf-1.29.18.dist-info → onnx2tf-1.29.19.dist-info}/RECORD +8 -6
- {onnx2tf-1.29.18.dist-info → onnx2tf-1.29.19.dist-info}/WHEEL +0 -0
- {onnx2tf-1.29.18.dist-info → onnx2tf-1.29.19.dist-info}/entry_points.txt +0 -0
onnx2tf/__init__.py
CHANGED
onnx2tf/ops/Col2Im.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import sys
|
|
1
2
|
import random
|
|
2
3
|
random.seed(0)
|
|
3
4
|
import numpy as np
|
|
4
5
|
np.random.seed(0)
|
|
5
6
|
import tensorflow as tf
|
|
6
|
-
import tf_keras
|
|
7
7
|
import onnx_graphsurgeon as gs
|
|
8
8
|
from onnx2tf.utils.common_functions import (
|
|
9
9
|
get_constant_or_variable,
|
|
@@ -14,57 +14,32 @@ from onnx2tf.utils.common_functions import (
|
|
|
14
14
|
pre_process_transpose,
|
|
15
15
|
post_process_transpose,
|
|
16
16
|
)
|
|
17
|
+
from onnx2tf.utils.logging import *
|
|
17
18
|
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
def _build_col2im_kernel(
|
|
21
|
+
*,
|
|
22
|
+
k_h,
|
|
23
|
+
k_w,
|
|
24
|
+
dilation_h,
|
|
25
|
+
dilation_w,
|
|
26
|
+
dtype,
|
|
27
|
+
):
|
|
28
|
+
k_h = tf.cast(k_h, tf.int32)
|
|
29
|
+
k_w = tf.cast(k_w, tf.int32)
|
|
30
|
+
eff_k_h = (k_h - 1) * dilation_h + 1
|
|
31
|
+
eff_k_w = (k_w - 1) * dilation_w + 1
|
|
22
32
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
N, _, L = input_tensor.shape
|
|
34
|
-
if output_shape is not None:
|
|
35
|
-
C = tf.convert_to_tensor(output_shape[1])
|
|
36
|
-
output_shape = tf.convert_to_tensor([output_shape[0]] + [s for s in output_shape[2:]] + [output_shape[1]])
|
|
37
|
-
else:
|
|
38
|
-
C = tf.convert_to_tensor(input_tensor.shape[1] // (input_block_shape[0] * input_block_shape[1]))
|
|
39
|
-
output_shape = tf.convert_to_tensor([N] + input_image_shape + [C])
|
|
40
|
-
im = tf.TensorArray(input_tensor.dtype, size=N, dynamic_size=True)
|
|
41
|
-
|
|
42
|
-
def loop_over_l(n, im_n, l):
|
|
43
|
-
row_idx = tf.convert_to_tensor((l // ((input_image_shape[1] - (input_block_shape[1] - 1) * dilations[1] - 1 + strides[1]) // strides[1])) * strides[0])
|
|
44
|
-
col_idx = tf.convert_to_tensor((l % ((input_image_shape[1] - (input_block_shape[1] - 1) * dilations[1] - 1 + strides[1]) // strides[1])) * strides[1])
|
|
45
|
-
|
|
46
|
-
def loop_over_c(c, im_n):
|
|
47
|
-
patch_idx = tf.convert_to_tensor(c * input_block_shape[0] * input_block_shape[1])
|
|
48
|
-
patch = tf.reshape(input_tensor[n, patch_idx:patch_idx + input_block_shape[0] * input_block_shape[1], l], input_block_shape)
|
|
49
|
-
if dilations[0] > 1 or dilations[1] > 1:
|
|
50
|
-
dilated_patch = tf.zeros([(input_block_shape[0] - 1) * dilations[0] + 1, (input_block_shape[1] - 1) * dilations[1] + 1], dtype=patch.dtype)
|
|
51
|
-
for i in tf.range(input_block_shape[0]):
|
|
52
|
-
for j in tf.range(input_block_shape[1]):
|
|
53
|
-
dilated_patch = tf.tensor_scatter_nd_update(dilated_patch, [[i * dilations[0], j * dilations[1]]], [patch[i, j]])
|
|
54
|
-
patch = dilated_patch
|
|
55
|
-
patch_shape = tf.shape(patch)
|
|
56
|
-
indices = tf.reshape(tf.stack(tf.meshgrid(row_idx + tf.range(patch_shape[0]), col_idx + tf.range(patch_shape[1]), c, indexing='ij'), axis=-1), [-1, 3])
|
|
57
|
-
updates = tf.reshape(patch, [-1])
|
|
58
|
-
return tf.tensor_scatter_nd_add(im_n, indices, updates)
|
|
59
|
-
return tf.reduce_sum(tf.map_fn(lambda c: loop_over_c(c, im_n), tf.range(C), dtype=im_n.dtype), axis=0)
|
|
60
|
-
|
|
61
|
-
def loop_over_n(n):
|
|
62
|
-
im_n = tf.zeros(output_shape[1:], dtype=input_tensor.dtype)
|
|
63
|
-
return tf.reduce_sum(tf.map_fn(lambda l: loop_over_l(n, im_n, l), tf.range(L), dtype=im_n.dtype), axis=0)
|
|
64
|
-
|
|
65
|
-
im = tf.map_fn(loop_over_n, tf.range(N), dtype=input_tensor.dtype)
|
|
66
|
-
|
|
67
|
-
return im[:, pads[0]:input_image_shape[0]-pads[2], pads[1]:input_image_shape[1]-pads[3], :]
|
|
33
|
+
ky = tf.reshape(tf.repeat(tf.range(k_h), k_w), tf.stack([k_h, k_w]))
|
|
34
|
+
kx = tf.reshape(tf.tile(tf.range(k_w), [k_h]), tf.stack([k_h, k_w]))
|
|
35
|
+
|
|
36
|
+
positions = ky * dilation_h * eff_k_w + kx * dilation_w
|
|
37
|
+
positions = tf.reshape(positions, [-1])
|
|
38
|
+
one_hot = tf.one_hot(positions, depth=eff_k_h * eff_k_w, dtype=dtype)
|
|
39
|
+
kernel = tf.reshape(one_hot, tf.stack([k_h * k_w, eff_k_h, eff_k_w]))
|
|
40
|
+
kernel = tf.transpose(kernel, [1, 2, 0])
|
|
41
|
+
kernel = tf.expand_dims(kernel, axis=2)
|
|
42
|
+
return kernel, eff_k_h, eff_k_w
|
|
68
43
|
|
|
69
44
|
|
|
70
45
|
@print_node_info
|
|
@@ -114,10 +89,9 @@ def make_node(
|
|
|
114
89
|
input_block_shape = tf_layers_dict[graph_node_input_3.name]['tf_node'] \
|
|
115
90
|
if isinstance(graph_node_input_3, gs.Variable) else graph_node_input_3
|
|
116
91
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
strides = graph_node.attrs.get('strides', [1] * spatial_size)
|
|
92
|
+
dilations = graph_node.attrs.get('dilations', [1, 1])
|
|
93
|
+
pads = graph_node.attrs.get('pads', [0, 0, 0, 0])
|
|
94
|
+
strides = graph_node.attrs.get('strides', [1, 1])
|
|
121
95
|
|
|
122
96
|
# Preserving Graph Structure (Dict)
|
|
123
97
|
tf_layers_dict[graph_node_output.name] = {
|
|
@@ -142,17 +116,87 @@ def make_node(
|
|
|
142
116
|
tf_layers_dict[graph_node_output.name].pop('nhwc')
|
|
143
117
|
|
|
144
118
|
# Generation of TF OP
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
119
|
+
original_dtype = input_tensor.dtype
|
|
120
|
+
compute_dtype = original_dtype
|
|
121
|
+
if original_dtype not in (tf.float16, tf.float32, tf.float64, tf.bfloat16):
|
|
122
|
+
if original_dtype in (tf.complex64, tf.complex128):
|
|
123
|
+
error('Col2Im does not support complex types in non-Flex implementation.')
|
|
124
|
+
sys.exit(1)
|
|
125
|
+
compute_dtype = tf.float32
|
|
126
|
+
input_tensor = tf.cast(input_tensor, compute_dtype)
|
|
127
|
+
|
|
128
|
+
input_image_shape = tf.cast(input_image_shape, tf.int32)
|
|
129
|
+
input_block_shape = tf.cast(input_block_shape, tf.int32)
|
|
130
|
+
|
|
131
|
+
if input_image_shape.shape is not None \
|
|
132
|
+
and input_image_shape.shape.rank is not None \
|
|
133
|
+
and input_image_shape.shape.rank != 1:
|
|
134
|
+
error('Col2Im supports only 2D image_shape input.')
|
|
135
|
+
sys.exit(1)
|
|
136
|
+
|
|
137
|
+
if input_block_shape.shape is not None \
|
|
138
|
+
and input_block_shape.shape.rank is not None \
|
|
139
|
+
and input_block_shape.shape.rank != 1:
|
|
140
|
+
error('Col2Im supports only 2D block_shape input.')
|
|
141
|
+
sys.exit(1)
|
|
142
|
+
|
|
143
|
+
k_h = input_block_shape[0]
|
|
144
|
+
k_w = input_block_shape[1]
|
|
145
|
+
h_img = input_image_shape[0]
|
|
146
|
+
w_img = input_image_shape[1]
|
|
147
|
+
|
|
148
|
+
stride_h, stride_w = strides
|
|
149
|
+
dilation_h, dilation_w = dilations
|
|
150
|
+
pad_top, pad_left, pad_bottom, pad_right = pads
|
|
151
|
+
|
|
152
|
+
kernel, eff_k_h, eff_k_w = _build_col2im_kernel(
|
|
153
|
+
k_h=k_h,
|
|
154
|
+
k_w=k_w,
|
|
155
|
+
dilation_h=dilation_h,
|
|
156
|
+
dilation_w=dilation_w,
|
|
157
|
+
dtype=compute_dtype,
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
h_pad = h_img + pad_top + pad_bottom
|
|
161
|
+
w_pad = w_img + pad_left + pad_right
|
|
162
|
+
|
|
163
|
+
out_h = tf.math.floordiv(h_pad - eff_k_h, stride_h) + 1
|
|
164
|
+
out_w = tf.math.floordiv(w_pad - eff_k_w, stride_w) + 1
|
|
165
|
+
|
|
166
|
+
input_shape = tf.shape(input_tensor)
|
|
167
|
+
n = input_shape[0]
|
|
168
|
+
ck = input_shape[1]
|
|
169
|
+
c = tf.math.floordiv(ck, k_h * k_w)
|
|
170
|
+
|
|
171
|
+
cols = tf.reshape(
|
|
172
|
+
input_tensor,
|
|
173
|
+
tf.stack([n, c, k_h * k_w, out_h, out_w]),
|
|
174
|
+
)
|
|
175
|
+
cols = tf.transpose(cols, [0, 1, 3, 4, 2])
|
|
176
|
+
cols = tf.reshape(cols, tf.stack([n * c, out_h, out_w, k_h * k_w]))
|
|
177
|
+
|
|
178
|
+
output_shape = tf.stack([n * c, h_pad, w_pad, 1])
|
|
179
|
+
output = tf.nn.conv2d_transpose(
|
|
180
|
+
cols,
|
|
181
|
+
kernel,
|
|
182
|
+
output_shape=output_shape,
|
|
183
|
+
strides=[1, stride_h, stride_w, 1],
|
|
184
|
+
padding='VALID',
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
output = tf.reshape(output, tf.stack([n, c, h_pad, w_pad]))
|
|
188
|
+
output = tf.transpose(output, [0, 2, 3, 1])
|
|
189
|
+
|
|
190
|
+
output = tf.slice(
|
|
191
|
+
output,
|
|
192
|
+
tf.stack([0, pad_top, pad_left, 0]),
|
|
193
|
+
tf.stack([-1, h_img, w_img, -1]),
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
if output.dtype != original_dtype:
|
|
197
|
+
output = tf.cast(output, original_dtype)
|
|
198
|
+
|
|
199
|
+
tf_layers_dict[graph_node_output.name]['tf_node'] = output
|
|
156
200
|
|
|
157
201
|
# Post-process transpose
|
|
158
202
|
before_trans_shape = tf_layers_dict[graph_node_output.name]['tf_node'].shape
|
onnx2tf/ops/DFT.py
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import random
|
|
3
|
+
random.seed(0)
|
|
4
|
+
import numpy as np
|
|
5
|
+
np.random.seed(0)
|
|
6
|
+
import tensorflow as tf
|
|
7
|
+
import onnx_graphsurgeon as gs
|
|
8
|
+
from onnx2tf.utils.common_functions import (
|
|
9
|
+
get_constant_or_variable,
|
|
10
|
+
print_node_info,
|
|
11
|
+
inverted_operation_enable_disable,
|
|
12
|
+
make_tf_node_info,
|
|
13
|
+
get_replacement_parameter,
|
|
14
|
+
pre_process_transpose,
|
|
15
|
+
post_process_transpose,
|
|
16
|
+
)
|
|
17
|
+
from onnx2tf.utils.logging import *
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _normalize_axis(axis, rank):
|
|
21
|
+
axis = tf.cast(axis, tf.int32)
|
|
22
|
+
rank = tf.cast(rank, tf.int32)
|
|
23
|
+
return tf.where(axis < 0, axis + rank, axis)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _move_axis_to_last(x, axis):
|
|
27
|
+
rank = tf.rank(x)
|
|
28
|
+
axis = _normalize_axis(axis, rank)
|
|
29
|
+
range0 = tf.range(axis)
|
|
30
|
+
range1 = tf.range(axis + 1, rank)
|
|
31
|
+
perm = tf.concat([range0, range1, [axis]], axis=0)
|
|
32
|
+
x_t = tf.transpose(x, perm)
|
|
33
|
+
inv_perm = tf.argsort(perm)
|
|
34
|
+
return x_t, inv_perm
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _pad_or_slice_last(x, length):
|
|
38
|
+
length = tf.cast(length, tf.int32)
|
|
39
|
+
current = tf.shape(x)[-1]
|
|
40
|
+
|
|
41
|
+
def _pad():
|
|
42
|
+
pad_amount = length - current
|
|
43
|
+
pad = tf.concat(
|
|
44
|
+
[
|
|
45
|
+
tf.zeros([tf.rank(x) - 1, 2], dtype=tf.int32),
|
|
46
|
+
tf.stack([[0, pad_amount]]),
|
|
47
|
+
],
|
|
48
|
+
axis=0,
|
|
49
|
+
)
|
|
50
|
+
return tf.pad(x, pad)
|
|
51
|
+
|
|
52
|
+
def _slice():
|
|
53
|
+
return x[..., :length]
|
|
54
|
+
|
|
55
|
+
x = tf.cond(current < length, _pad, lambda: x)
|
|
56
|
+
x = tf.cond(current > length, _slice, lambda: x)
|
|
57
|
+
return x
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@print_node_info
|
|
61
|
+
@inverted_operation_enable_disable
|
|
62
|
+
@get_replacement_parameter
|
|
63
|
+
def make_node(
|
|
64
|
+
*,
|
|
65
|
+
graph_node: gs.Node,
|
|
66
|
+
tf_layers_dict: dict,
|
|
67
|
+
**kwargs: dict,
|
|
68
|
+
):
|
|
69
|
+
"""DFT
|
|
70
|
+
|
|
71
|
+
Parameters
|
|
72
|
+
----------
|
|
73
|
+
graph_node: gs.Node
|
|
74
|
+
graph_surgeon Node
|
|
75
|
+
|
|
76
|
+
tf_layers_dict: dict
|
|
77
|
+
optype, shape, dtype, tensorflow graph
|
|
78
|
+
"""
|
|
79
|
+
before_op_output_shape_trans_1 = \
|
|
80
|
+
tf_layers_dict.get(graph_node.inputs[0].name, {}).get('before_op_output_shape_trans', True)
|
|
81
|
+
|
|
82
|
+
graph_node_input_1 = get_constant_or_variable(
|
|
83
|
+
graph_node.inputs[0],
|
|
84
|
+
before_op_output_shape_trans_1,
|
|
85
|
+
)
|
|
86
|
+
graph_node_input_2 = get_constant_or_variable(
|
|
87
|
+
graph_node.inputs[1],
|
|
88
|
+
before_op_output_shape_trans=False,
|
|
89
|
+
) if len(graph_node.inputs) >= 2 else None
|
|
90
|
+
graph_node_input_3 = get_constant_or_variable(
|
|
91
|
+
graph_node.inputs[2],
|
|
92
|
+
before_op_output_shape_trans=False,
|
|
93
|
+
) if len(graph_node.inputs) >= 3 else None
|
|
94
|
+
|
|
95
|
+
graph_node_output: gs.Variable = graph_node.outputs[0]
|
|
96
|
+
shape = graph_node_output.shape
|
|
97
|
+
dtype = graph_node_output.dtype
|
|
98
|
+
|
|
99
|
+
input_tensor = tf_layers_dict[graph_node_input_1.name]['tf_node'] \
|
|
100
|
+
if isinstance(graph_node_input_1, gs.Variable) else graph_node_input_1
|
|
101
|
+
dft_length = tf_layers_dict[graph_node_input_2.name]['tf_node'] \
|
|
102
|
+
if isinstance(graph_node_input_2, gs.Variable) else graph_node_input_2
|
|
103
|
+
axis = tf_layers_dict[graph_node_input_3.name]['tf_node'] \
|
|
104
|
+
if isinstance(graph_node_input_3, gs.Variable) else graph_node_input_3
|
|
105
|
+
|
|
106
|
+
onesided = bool(graph_node.attrs.get('onesided', 0))
|
|
107
|
+
inverse = bool(graph_node.attrs.get('inverse', 0))
|
|
108
|
+
|
|
109
|
+
# Preserving Graph Structure (Dict)
|
|
110
|
+
tf_layers_dict[graph_node_output.name] = {
|
|
111
|
+
'optype': graph_node.op,
|
|
112
|
+
'shape': shape,
|
|
113
|
+
'dtype': dtype,
|
|
114
|
+
'nhwc': tf_layers_dict[graph_node_input_1.name]['nhwc'] \
|
|
115
|
+
if isinstance(graph_node_input_1, gs.Variable) \
|
|
116
|
+
and 'nhwc' in tf_layers_dict[graph_node_input_1.name].keys() else False,
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
# Pre-process transpose
|
|
120
|
+
input_tensor = pre_process_transpose(
|
|
121
|
+
value_before_transpose=input_tensor,
|
|
122
|
+
param_target='inputs',
|
|
123
|
+
param_name=graph_node.inputs[0].name,
|
|
124
|
+
**kwargs,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
input_rank = tf.rank(input_tensor)
|
|
128
|
+
axis_attr = graph_node.attrs.get('axis', None)
|
|
129
|
+
if axis is None:
|
|
130
|
+
if axis_attr is not None:
|
|
131
|
+
axis = tf.constant(axis_attr, dtype=tf.int32)
|
|
132
|
+
else:
|
|
133
|
+
axis = tf.cast(input_rank - 2, tf.int32)
|
|
134
|
+
else:
|
|
135
|
+
axis = tf.cast(tf.reshape(axis, []), tf.int32)
|
|
136
|
+
axis = _normalize_axis(axis, input_rank)
|
|
137
|
+
|
|
138
|
+
dft_length_value = None
|
|
139
|
+
if dft_length is not None:
|
|
140
|
+
dft_length_value = tf.cast(tf.reshape(dft_length, []), tf.int32)
|
|
141
|
+
|
|
142
|
+
input_dtype = input_tensor.dtype
|
|
143
|
+
if input_dtype in (tf.float64,):
|
|
144
|
+
float_dtype = tf.float64
|
|
145
|
+
complex_dtype = tf.complex128
|
|
146
|
+
elif input_dtype in (tf.float32,):
|
|
147
|
+
float_dtype = tf.float32
|
|
148
|
+
complex_dtype = tf.complex64
|
|
149
|
+
elif input_dtype in (tf.float16, tf.bfloat16):
|
|
150
|
+
float_dtype = tf.float32
|
|
151
|
+
complex_dtype = tf.complex64
|
|
152
|
+
else:
|
|
153
|
+
error('DFT supports float/bfloat16 types only.')
|
|
154
|
+
sys.exit(1)
|
|
155
|
+
|
|
156
|
+
# Convert to complex tensor (drop last dim)
|
|
157
|
+
last_dim_static = input_tensor.shape[-1]
|
|
158
|
+
if last_dim_static is not None:
|
|
159
|
+
if last_dim_static == 1:
|
|
160
|
+
real = tf.squeeze(input_tensor, axis=-1)
|
|
161
|
+
imag = tf.zeros_like(real)
|
|
162
|
+
elif last_dim_static == 2:
|
|
163
|
+
real, imag = tf.unstack(input_tensor, axis=-1)
|
|
164
|
+
else:
|
|
165
|
+
error('DFT input last dimension must be 1 or 2.')
|
|
166
|
+
sys.exit(1)
|
|
167
|
+
else:
|
|
168
|
+
last_dim = tf.shape(input_tensor)[-1]
|
|
169
|
+
def _real_case():
|
|
170
|
+
real = tf.squeeze(input_tensor, axis=-1)
|
|
171
|
+
imag = tf.zeros_like(real)
|
|
172
|
+
return real, imag
|
|
173
|
+
def _complex_case():
|
|
174
|
+
real, imag = tf.unstack(input_tensor, axis=-1)
|
|
175
|
+
return real, imag
|
|
176
|
+
real, imag = tf.cond(
|
|
177
|
+
tf.equal(last_dim, 1),
|
|
178
|
+
_real_case,
|
|
179
|
+
_complex_case,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
real = tf.cast(real, float_dtype)
|
|
183
|
+
imag = tf.cast(imag, float_dtype)
|
|
184
|
+
signal = tf.complex(real, imag)
|
|
185
|
+
|
|
186
|
+
signal_t, inv_perm = _move_axis_to_last(signal, axis)
|
|
187
|
+
signal_len = tf.shape(signal_t)[-1]
|
|
188
|
+
|
|
189
|
+
if onesided and inverse:
|
|
190
|
+
if last_dim_static == 1:
|
|
191
|
+
error('DFT onesided inverse supports only complex input.')
|
|
192
|
+
sys.exit(1)
|
|
193
|
+
if dft_length_value is None:
|
|
194
|
+
dft_length_value = tf.cast(signal_len * 2 - 2, tf.int32)
|
|
195
|
+
out_real = tf.signal.irfft(signal_t, fft_length=[dft_length_value])
|
|
196
|
+
out_real = tf.transpose(out_real, inv_perm)
|
|
197
|
+
output = tf.expand_dims(out_real, axis=-1)
|
|
198
|
+
elif onesided and not inverse:
|
|
199
|
+
if last_dim_static == 2:
|
|
200
|
+
error('DFT onesided forward supports only real input.')
|
|
201
|
+
sys.exit(1)
|
|
202
|
+
if dft_length_value is None:
|
|
203
|
+
dft_length_value = tf.cast(signal_len, tf.int32)
|
|
204
|
+
real_signal = tf.math.real(signal_t)
|
|
205
|
+
out_complex = tf.signal.rfft(real_signal, fft_length=[dft_length_value])
|
|
206
|
+
out_complex = tf.transpose(out_complex, inv_perm)
|
|
207
|
+
output = tf.stack([tf.math.real(out_complex), tf.math.imag(out_complex)], axis=-1)
|
|
208
|
+
else:
|
|
209
|
+
if dft_length_value is not None:
|
|
210
|
+
signal_t = _pad_or_slice_last(signal_t, dft_length_value)
|
|
211
|
+
if inverse:
|
|
212
|
+
out_complex = tf.signal.ifft(signal_t)
|
|
213
|
+
else:
|
|
214
|
+
out_complex = tf.signal.fft(signal_t)
|
|
215
|
+
out_complex = tf.transpose(out_complex, inv_perm)
|
|
216
|
+
output = tf.stack([tf.math.real(out_complex), tf.math.imag(out_complex)], axis=-1)
|
|
217
|
+
|
|
218
|
+
if output.dtype != input_dtype:
|
|
219
|
+
output = tf.cast(output, input_dtype)
|
|
220
|
+
|
|
221
|
+
# Post-process transpose
|
|
222
|
+
tf_layers_dict[graph_node_output.name]['tf_node'] = post_process_transpose(
|
|
223
|
+
value_before_transpose=output,
|
|
224
|
+
param_target='outputs',
|
|
225
|
+
param_name=graph_node.outputs[0].name,
|
|
226
|
+
**kwargs,
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
# Generation of Debug Info
|
|
230
|
+
tf_layers_dict[graph_node_output.name]['tf_node_info'] = \
|
|
231
|
+
make_tf_node_info(
|
|
232
|
+
node_info={
|
|
233
|
+
'tf_op_type': 'DFT',
|
|
234
|
+
'tf_inputs': {
|
|
235
|
+
'input': input_tensor,
|
|
236
|
+
'axis': axis,
|
|
237
|
+
'dft_length': dft_length_value,
|
|
238
|
+
'onesided': onesided,
|
|
239
|
+
'inverse': inverse,
|
|
240
|
+
},
|
|
241
|
+
'tf_outputs': {
|
|
242
|
+
'output': tf_layers_dict[graph_node_output.name]['tf_node'],
|
|
243
|
+
},
|
|
244
|
+
}
|
|
245
|
+
)
|
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import random
|
|
3
|
+
random.seed(0)
|
|
4
|
+
import numpy as np
|
|
5
|
+
np.random.seed(0)
|
|
6
|
+
import tensorflow as tf
|
|
7
|
+
import onnx_graphsurgeon as gs
|
|
8
|
+
from onnx2tf.utils.common_functions import (
|
|
9
|
+
get_constant_or_variable,
|
|
10
|
+
get_weights_constant_or_variable,
|
|
11
|
+
print_node_info,
|
|
12
|
+
inverted_operation_enable_disable,
|
|
13
|
+
make_tf_node_info,
|
|
14
|
+
get_replacement_parameter,
|
|
15
|
+
pre_process_transpose,
|
|
16
|
+
post_process_transpose,
|
|
17
|
+
transpose_with_flexing_deterrence,
|
|
18
|
+
)
|
|
19
|
+
from onnx2tf.utils.logging import *
|
|
20
|
+
|
|
21
|
+
INF_INDEX_VALUE: int = 4294967296
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _to_int_tensor(value, name=None):
|
|
25
|
+
if isinstance(value, tf.Tensor):
|
|
26
|
+
return tf.cast(value, tf.int32)
|
|
27
|
+
return tf.constant(value, dtype=tf.int32, name=name)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _bilinear_sample_2d(
|
|
31
|
+
image,
|
|
32
|
+
coords,
|
|
33
|
+
):
|
|
34
|
+
"""
|
|
35
|
+
image: [N, H, W, C]
|
|
36
|
+
coords: [N, oH, oW, kH, kW, 2] in absolute coords (y, x)
|
|
37
|
+
"""
|
|
38
|
+
coord_dtype = coords.dtype
|
|
39
|
+
h = tf.shape(image)[1]
|
|
40
|
+
w = tf.shape(image)[2]
|
|
41
|
+
h_f = tf.cast(h, coord_dtype)
|
|
42
|
+
w_f = tf.cast(w, coord_dtype)
|
|
43
|
+
max_y = h_f - 1.0
|
|
44
|
+
max_x = w_f - 1.0
|
|
45
|
+
|
|
46
|
+
y, x = tf.split(coords, num_or_size_splits=2, axis=-1)
|
|
47
|
+
|
|
48
|
+
y0 = tf.floor(y)
|
|
49
|
+
x0 = tf.floor(x)
|
|
50
|
+
y1 = y0 + 1.0
|
|
51
|
+
x1 = x0 + 1.0
|
|
52
|
+
|
|
53
|
+
dy = y - y0
|
|
54
|
+
dx = x - x0
|
|
55
|
+
|
|
56
|
+
w00 = (1.0 - dy) * (1.0 - dx)
|
|
57
|
+
w10 = dy * (1.0 - dx)
|
|
58
|
+
w11 = dy * dx
|
|
59
|
+
w01 = (1.0 - dy) * dx
|
|
60
|
+
|
|
61
|
+
def _in_bounds(y_idx, x_idx):
|
|
62
|
+
return tf.logical_and(
|
|
63
|
+
tf.logical_and(y_idx >= 0.0, y_idx <= max_y),
|
|
64
|
+
tf.logical_and(x_idx >= 0.0, x_idx <= max_x),
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
m00 = _in_bounds(y0, x0)
|
|
68
|
+
m10 = _in_bounds(y1, x0)
|
|
69
|
+
m11 = _in_bounds(y1, x1)
|
|
70
|
+
m01 = _in_bounds(y0, x1)
|
|
71
|
+
|
|
72
|
+
y0c = tf.clip_by_value(y0, 0.0, max_y)
|
|
73
|
+
x0c = tf.clip_by_value(x0, 0.0, max_x)
|
|
74
|
+
y1c = tf.clip_by_value(y1, 0.0, max_y)
|
|
75
|
+
x1c = tf.clip_by_value(x1, 0.0, max_x)
|
|
76
|
+
|
|
77
|
+
y0i = tf.cast(y0c, tf.int32)
|
|
78
|
+
x0i = tf.cast(x0c, tf.int32)
|
|
79
|
+
y1i = tf.cast(y1c, tf.int32)
|
|
80
|
+
x1i = tf.cast(x1c, tf.int32)
|
|
81
|
+
|
|
82
|
+
input_flat = tf.reshape(image, tf.stack([tf.shape(image)[0], h * w, tf.shape(image)[3]]))
|
|
83
|
+
|
|
84
|
+
def _gather(y_idx, x_idx):
|
|
85
|
+
linear = y_idx * w + x_idx
|
|
86
|
+
linear = tf.squeeze(linear, axis=-1)
|
|
87
|
+
return tf.gather(input_flat, linear, batch_dims=1)
|
|
88
|
+
|
|
89
|
+
v00 = _gather(y0i, x0i)
|
|
90
|
+
v10 = _gather(y1i, x0i)
|
|
91
|
+
v11 = _gather(y1i, x1i)
|
|
92
|
+
v01 = _gather(y0i, x1i)
|
|
93
|
+
|
|
94
|
+
m00 = tf.cast(m00, image.dtype)
|
|
95
|
+
m10 = tf.cast(m10, image.dtype)
|
|
96
|
+
m11 = tf.cast(m11, image.dtype)
|
|
97
|
+
m01 = tf.cast(m01, image.dtype)
|
|
98
|
+
|
|
99
|
+
output = w00 * m00 * v00 + w10 * m10 * v10 + w11 * m11 * v11 + w01 * m01 * v01
|
|
100
|
+
return output
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
@print_node_info
|
|
104
|
+
@inverted_operation_enable_disable
|
|
105
|
+
@get_replacement_parameter
|
|
106
|
+
def make_node(
|
|
107
|
+
*,
|
|
108
|
+
graph_node: gs.Node,
|
|
109
|
+
tf_layers_dict: dict,
|
|
110
|
+
**kwargs: dict,
|
|
111
|
+
):
|
|
112
|
+
"""DeformConv
|
|
113
|
+
|
|
114
|
+
Parameters
|
|
115
|
+
----------
|
|
116
|
+
graph_node: gs.Node
|
|
117
|
+
graph_surgeon Node
|
|
118
|
+
|
|
119
|
+
tf_layers_dict: dict
|
|
120
|
+
optype, shape, dtype, tensorflow graph
|
|
121
|
+
"""
|
|
122
|
+
before_op_output_shape_trans_1 = \
|
|
123
|
+
tf_layers_dict.get(graph_node.inputs[0].name, {}).get('before_op_output_shape_trans', True)
|
|
124
|
+
before_op_output_shape_trans_3 = \
|
|
125
|
+
tf_layers_dict.get(graph_node.inputs[2].name, {}).get('before_op_output_shape_trans', True)
|
|
126
|
+
before_op_output_shape_trans_4 = \
|
|
127
|
+
tf_layers_dict.get(graph_node.inputs[3].name, {}).get('before_op_output_shape_trans', True) \
|
|
128
|
+
if len(graph_node.inputs) >= 4 else True
|
|
129
|
+
before_op_output_shape_trans_5 = \
|
|
130
|
+
tf_layers_dict.get(graph_node.inputs[4].name, {}).get('before_op_output_shape_trans', True) \
|
|
131
|
+
if len(graph_node.inputs) >= 5 else True
|
|
132
|
+
|
|
133
|
+
graph_node_input_1 = get_constant_or_variable(
|
|
134
|
+
graph_node.inputs[0],
|
|
135
|
+
before_op_output_shape_trans_1,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
kernel_shape = graph_node.attrs.get('kernel_shape', [])
|
|
139
|
+
if kernel_shape == [] and graph_node.inputs[1].shape is not None:
|
|
140
|
+
kernel_shape = graph_node.inputs[1].shape[2:]
|
|
141
|
+
kernel_size = len(kernel_shape) if kernel_shape != [] else 2
|
|
142
|
+
|
|
143
|
+
graph_node_input_2 = get_weights_constant_or_variable(
|
|
144
|
+
const_or_var=graph_node.inputs[1],
|
|
145
|
+
kernel_size=kernel_size,
|
|
146
|
+
)
|
|
147
|
+
graph_node_input_3 = get_constant_or_variable(
|
|
148
|
+
graph_node.inputs[2],
|
|
149
|
+
before_op_output_shape_trans_3,
|
|
150
|
+
)
|
|
151
|
+
graph_node_input_4 = get_constant_or_variable(
|
|
152
|
+
graph_node.inputs[3],
|
|
153
|
+
before_op_output_shape_trans_4,
|
|
154
|
+
) if len(graph_node.inputs) >= 4 else None
|
|
155
|
+
graph_node_input_5 = get_constant_or_variable(
|
|
156
|
+
graph_node.inputs[4],
|
|
157
|
+
before_op_output_shape_trans_5,
|
|
158
|
+
) if len(graph_node.inputs) >= 5 else None
|
|
159
|
+
|
|
160
|
+
graph_node_output: gs.Variable = graph_node.outputs[0]
|
|
161
|
+
output_tensor_shape = graph_node_output.shape
|
|
162
|
+
dtype = graph_node_output.dtype
|
|
163
|
+
|
|
164
|
+
input_tensor = tf_layers_dict[graph_node_input_1.name]['tf_node'] \
|
|
165
|
+
if isinstance(graph_node_input_1, gs.Variable) else graph_node_input_1
|
|
166
|
+
weights = tf_layers_dict[graph_node_input_2.name]['tf_node'] \
|
|
167
|
+
if isinstance(graph_node_input_2, gs.Variable) else graph_node_input_2
|
|
168
|
+
offset = tf_layers_dict[graph_node_input_3.name]['tf_node'] \
|
|
169
|
+
if isinstance(graph_node_input_3, gs.Variable) else graph_node_input_3
|
|
170
|
+
bias = tf_layers_dict[graph_node_input_4.name]['tf_node'] \
|
|
171
|
+
if isinstance(graph_node_input_4, gs.Variable) else graph_node_input_4
|
|
172
|
+
mask = tf_layers_dict[graph_node_input_5.name]['tf_node'] \
|
|
173
|
+
if isinstance(graph_node_input_5, gs.Variable) else graph_node_input_5
|
|
174
|
+
|
|
175
|
+
input_tensor_shape = input_tensor.shape
|
|
176
|
+
|
|
177
|
+
if input_tensor_shape is not None and len(input_tensor_shape) != 4:
|
|
178
|
+
error('DeformConv currently supports only 2D inputs (N, C, H, W).')
|
|
179
|
+
sys.exit(1)
|
|
180
|
+
|
|
181
|
+
# Preserving Graph Structure (Dict)
|
|
182
|
+
tf_layers_dict[graph_node_output.name] = {
|
|
183
|
+
'optype': graph_node.op,
|
|
184
|
+
'shape': output_tensor_shape,
|
|
185
|
+
'dtype': dtype,
|
|
186
|
+
'nhwc': True,
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
# Pre-process transpose
|
|
190
|
+
input_tensor = pre_process_transpose(
|
|
191
|
+
value_before_transpose=input_tensor,
|
|
192
|
+
param_target='inputs',
|
|
193
|
+
param_name=graph_node.inputs[0].name,
|
|
194
|
+
**kwargs,
|
|
195
|
+
)
|
|
196
|
+
offset = pre_process_transpose(
|
|
197
|
+
value_before_transpose=offset,
|
|
198
|
+
param_target='inputs',
|
|
199
|
+
param_name=graph_node.inputs[2].name,
|
|
200
|
+
**kwargs,
|
|
201
|
+
)
|
|
202
|
+
if mask is not None:
|
|
203
|
+
mask = pre_process_transpose(
|
|
204
|
+
value_before_transpose=mask,
|
|
205
|
+
param_target='inputs',
|
|
206
|
+
param_name=graph_node.inputs[4].name,
|
|
207
|
+
**kwargs,
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
input_dtype = input_tensor.dtype
|
|
211
|
+
if weights is not None and weights.dtype != input_dtype:
|
|
212
|
+
weights = tf.cast(weights, input_dtype)
|
|
213
|
+
if offset is not None and offset.dtype != input_dtype:
|
|
214
|
+
offset = tf.cast(offset, input_dtype)
|
|
215
|
+
if bias is not None and bias.dtype != input_dtype:
|
|
216
|
+
bias = tf.cast(bias, input_dtype)
|
|
217
|
+
if mask is not None and mask.dtype != input_dtype:
|
|
218
|
+
mask = tf.cast(mask, input_dtype)
|
|
219
|
+
|
|
220
|
+
# Workaround to avoid as many conversion failures as possible
|
|
221
|
+
onnx_input_shape = [
|
|
222
|
+
dim if isinstance(dim, int) else None for dim in graph_node.inputs[0].shape
|
|
223
|
+
] if graph_node.inputs[0].shape is not None else None
|
|
224
|
+
tf_input_shape = [
|
|
225
|
+
dim if isinstance(dim, int) else None for dim in input_tensor.shape
|
|
226
|
+
]
|
|
227
|
+
if onnx_input_shape is not None \
|
|
228
|
+
and len(onnx_input_shape) > 1 and len(tf_input_shape) > 1 \
|
|
229
|
+
and onnx_input_shape == tf_input_shape:
|
|
230
|
+
|
|
231
|
+
shape_for_judging_skip = [
|
|
232
|
+
dim if dim is not None else INF_INDEX_VALUE for dim in onnx_input_shape[1:]
|
|
233
|
+
]
|
|
234
|
+
if shape_for_judging_skip.count(shape_for_judging_skip[0]) != len(shape_for_judging_skip):
|
|
235
|
+
input_tensor = transpose_with_flexing_deterrence(
|
|
236
|
+
input_tensor=input_tensor,
|
|
237
|
+
perm=[0,2,3,1],
|
|
238
|
+
**kwargs,
|
|
239
|
+
)
|
|
240
|
+
offset = transpose_with_flexing_deterrence(
|
|
241
|
+
input_tensor=offset,
|
|
242
|
+
perm=[0,2,3,1],
|
|
243
|
+
**kwargs,
|
|
244
|
+
)
|
|
245
|
+
if mask is not None:
|
|
246
|
+
mask = transpose_with_flexing_deterrence(
|
|
247
|
+
input_tensor=mask,
|
|
248
|
+
perm=[0,2,3,1],
|
|
249
|
+
**kwargs,
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
# Attributes
|
|
253
|
+
dilations = graph_node.attrs.get('dilations', [1, 1])
|
|
254
|
+
group = graph_node.attrs.get('group', 1)
|
|
255
|
+
offset_group = graph_node.attrs.get('offset_group', 1)
|
|
256
|
+
pads = graph_node.attrs.get('pads', [0, 0, 0, 0])
|
|
257
|
+
strides = graph_node.attrs.get('strides', [1, 1])
|
|
258
|
+
|
|
259
|
+
dilation_h, dilation_w = dilations
|
|
260
|
+
stride_h, stride_w = strides
|
|
261
|
+
pad_top, pad_left, pad_bottom, pad_right = pads
|
|
262
|
+
|
|
263
|
+
# Input prep
|
|
264
|
+
if pad_top != 0 or pad_bottom != 0 or pad_left != 0 or pad_right != 0:
|
|
265
|
+
input_tensor = tf.pad(
|
|
266
|
+
input_tensor,
|
|
267
|
+
paddings=[[0, 0], [pad_top, pad_bottom], [pad_left, pad_right], [0, 0]],
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
batch = tf.shape(input_tensor)[0]
|
|
271
|
+
in_h = tf.shape(input_tensor)[1]
|
|
272
|
+
in_w = tf.shape(input_tensor)[2]
|
|
273
|
+
in_c = tf.shape(input_tensor)[3]
|
|
274
|
+
|
|
275
|
+
offset_shape = tf.shape(offset)
|
|
276
|
+
out_h = offset_shape[1]
|
|
277
|
+
out_w = offset_shape[2]
|
|
278
|
+
|
|
279
|
+
# Kernel shape
|
|
280
|
+
if kernel_shape != []:
|
|
281
|
+
kh = _to_int_tensor(kernel_shape[0])
|
|
282
|
+
kw = _to_int_tensor(kernel_shape[1])
|
|
283
|
+
else:
|
|
284
|
+
kh = _to_int_tensor(tf.shape(weights)[0])
|
|
285
|
+
kw = _to_int_tensor(tf.shape(weights)[1])
|
|
286
|
+
|
|
287
|
+
# Base grid: [oH, oW, kH, kW, 2]
|
|
288
|
+
oy = tf.range(out_h, dtype=input_dtype) * tf.cast(stride_h, input_dtype)
|
|
289
|
+
ox = tf.range(out_w, dtype=input_dtype) * tf.cast(stride_w, input_dtype)
|
|
290
|
+
ky = tf.range(kh, dtype=input_dtype) * tf.cast(dilation_h, input_dtype)
|
|
291
|
+
kx = tf.range(kw, dtype=input_dtype) * tf.cast(dilation_w, input_dtype)
|
|
292
|
+
|
|
293
|
+
oy = tf.reshape(oy, tf.stack([out_h, 1, 1, 1]))
|
|
294
|
+
ox = tf.reshape(ox, tf.stack([1, out_w, 1, 1]))
|
|
295
|
+
ky = tf.reshape(ky, tf.stack([1, 1, kh, 1]))
|
|
296
|
+
kx = tf.reshape(kx, tf.stack([1, 1, 1, kw]))
|
|
297
|
+
|
|
298
|
+
y = oy + ky
|
|
299
|
+
x = ox + kx
|
|
300
|
+
target_shape = tf.stack([out_h, out_w, kh, kw])
|
|
301
|
+
y = tf.broadcast_to(y, target_shape)
|
|
302
|
+
x = tf.broadcast_to(x, target_shape)
|
|
303
|
+
base_grid = tf.stack([y, x], axis=-1)
|
|
304
|
+
|
|
305
|
+
# Offset reshape: [N, oH, oW, Goff, kH, kW, 2]
|
|
306
|
+
offset = tf.reshape(
|
|
307
|
+
offset,
|
|
308
|
+
tf.stack([batch, out_h, out_w, offset_group, kh, kw, 2]),
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
coords = base_grid[None, :, :, None, :, :, :] + offset
|
|
312
|
+
coords = tf.transpose(coords, [0, 3, 1, 2, 4, 5, 6])
|
|
313
|
+
coords = tf.reshape(coords, tf.stack([batch * offset_group, out_h, out_w, kh, kw, 2]))
|
|
314
|
+
|
|
315
|
+
# Input grouping for offset_group
|
|
316
|
+
c_per_offset = tf.math.floordiv(in_c, offset_group)
|
|
317
|
+
input_tensor = tf.reshape(
|
|
318
|
+
input_tensor,
|
|
319
|
+
tf.stack([batch, in_h, in_w, offset_group, c_per_offset]),
|
|
320
|
+
)
|
|
321
|
+
input_tensor = tf.transpose(input_tensor, [0, 3, 1, 2, 4])
|
|
322
|
+
input_tensor = tf.reshape(
|
|
323
|
+
input_tensor,
|
|
324
|
+
tf.stack([batch * offset_group, in_h, in_w, c_per_offset]),
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
sampled = _bilinear_sample_2d(input_tensor, coords)
|
|
328
|
+
sampled = tf.reshape(
|
|
329
|
+
sampled,
|
|
330
|
+
tf.stack([batch, offset_group, out_h, out_w, kh, kw, c_per_offset]),
|
|
331
|
+
)
|
|
332
|
+
sampled = tf.transpose(sampled, [0, 2, 3, 1, 4, 5, 6])
|
|
333
|
+
|
|
334
|
+
if mask is not None:
|
|
335
|
+
mask = tf.reshape(
|
|
336
|
+
mask,
|
|
337
|
+
tf.stack([batch, out_h, out_w, offset_group, kh, kw, 1]),
|
|
338
|
+
)
|
|
339
|
+
sampled = sampled * tf.cast(mask, sampled.dtype)
|
|
340
|
+
|
|
341
|
+
# Merge offset_group back to channel dim: [N, oH, oW, kH, kW, C]
|
|
342
|
+
sampled = tf.reshape(
|
|
343
|
+
sampled,
|
|
344
|
+
tf.stack([batch, out_h, out_w, kh, kw, in_c]),
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
# Grouped convolution via batched matmul
|
|
348
|
+
out_c = tf.shape(weights)[3]
|
|
349
|
+
c_per_group = tf.math.floordiv(in_c, group)
|
|
350
|
+
out_c_per_group = tf.math.floordiv(out_c, group)
|
|
351
|
+
|
|
352
|
+
cols = tf.reshape(sampled, tf.stack([batch * out_h * out_w, kh * kw * in_c]))
|
|
353
|
+
cols = tf.reshape(cols, tf.stack([batch * out_h * out_w, group, kh * kw * c_per_group]))
|
|
354
|
+
cols = tf.transpose(cols, [1, 0, 2])
|
|
355
|
+
|
|
356
|
+
weights = tf.reshape(weights, tf.stack([kh, kw, c_per_group, group, out_c_per_group]))
|
|
357
|
+
weights = tf.transpose(weights, [3, 0, 1, 2, 4])
|
|
358
|
+
weights = tf.reshape(weights, tf.stack([group, kh * kw * c_per_group, out_c_per_group]))
|
|
359
|
+
|
|
360
|
+
output = tf.matmul(cols, weights)
|
|
361
|
+
output = tf.transpose(output, [1, 0, 2])
|
|
362
|
+
output = tf.reshape(output, tf.stack([batch, out_h, out_w, out_c]))
|
|
363
|
+
|
|
364
|
+
if bias is not None:
|
|
365
|
+
output += tf.reshape(bias, tf.stack([1, 1, 1, out_c]))
|
|
366
|
+
|
|
367
|
+
if output.dtype != input_dtype:
|
|
368
|
+
output = tf.cast(output, input_dtype)
|
|
369
|
+
|
|
370
|
+
# Post-process transpose
|
|
371
|
+
tf_layers_dict[graph_node_output.name]['tf_node'] = post_process_transpose(
|
|
372
|
+
value_before_transpose=output,
|
|
373
|
+
param_target='outputs',
|
|
374
|
+
param_name=graph_node.outputs[0].name,
|
|
375
|
+
**kwargs,
|
|
376
|
+
)
|
|
377
|
+
|
|
378
|
+
# Generation of Debug Info
|
|
379
|
+
tf_layers_dict[graph_node_output.name]['tf_node_info'] = \
|
|
380
|
+
make_tf_node_info(
|
|
381
|
+
node_info={
|
|
382
|
+
'tf_op_type': 'DeformConv',
|
|
383
|
+
'tf_inputs': {
|
|
384
|
+
'input_tensor': input_tensor,
|
|
385
|
+
'weights': weights,
|
|
386
|
+
'offset': offset,
|
|
387
|
+
'bias': bias,
|
|
388
|
+
'mask': mask,
|
|
389
|
+
'strides': strides,
|
|
390
|
+
'dilations': dilations,
|
|
391
|
+
'pads': pads,
|
|
392
|
+
'group': group,
|
|
393
|
+
'offset_group': offset_group,
|
|
394
|
+
},
|
|
395
|
+
'tf_outputs': {
|
|
396
|
+
'output': tf_layers_dict[graph_node_output.name]['tf_node'],
|
|
397
|
+
},
|
|
398
|
+
}
|
|
399
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: onnx2tf
|
|
3
|
-
Version: 1.29.
|
|
3
|
+
Version: 1.29.19
|
|
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
|
|
@@ -137,11 +137,11 @@ https://github.com/PINTO0309/onnx2tf/wiki/model_status
|
|
|
137
137
|
|Cos|:heavy_check_mark:|
|
|
138
138
|
|CumProd|:heavy_check_mark:|
|
|
139
139
|
|CumSum|:heavy_check_mark:|
|
|
140
|
-
|DeformConv
|
|
140
|
+
|DeformConv|:white_check_mark:|
|
|
141
141
|
|DepthToSpace|:heavy_check_mark:|
|
|
142
142
|
|Det|:heavy_check_mark:|
|
|
143
143
|
|DequantizeLinear|:heavy_check_mark:|
|
|
144
|
-
|DFT
|
|
144
|
+
|DFT|:white_check_mark:|
|
|
145
145
|
|Div|:heavy_check_mark:|
|
|
146
146
|
|Dropout|:heavy_check_mark:|
|
|
147
147
|
|DynamicQuantizeLinear|:heavy_check_mark:|
|
|
@@ -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.19
|
|
369
369
|
|
|
370
370
|
or
|
|
371
371
|
|
|
@@ -373,7 +373,7 @@ 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.19
|
|
377
377
|
|
|
378
378
|
or
|
|
379
379
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
onnx2tf/__init__.py,sha256=
|
|
1
|
+
onnx2tf/__init__.py,sha256=j0g0sP9V7WMAY5PXs_oOHLBgUSJ1dcjLILPUq39xOnU,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
|
|
@@ -27,7 +27,7 @@ onnx2tf/ops/Cast.py,sha256=M0LRClHPgZ_8NubwME6ipKrAqcY9aKC5ihQXCkTkNkM,4601
|
|
|
27
27
|
onnx2tf/ops/Ceil.py,sha256=0-jaueltpQSwpOIDUmy9DdTy98qN-XimYu5cHVPnUIs,3586
|
|
28
28
|
onnx2tf/ops/Celu.py,sha256=9g7WNKo4G_jMtUXcoOfpNdLYqEsuyXLPkkyQZxDuL4U,3853
|
|
29
29
|
onnx2tf/ops/Clip.py,sha256=K3Pgt9BXl5_rzg6s-kPFmwElL5COsvolRY1BUTo7UWw,8753
|
|
30
|
-
onnx2tf/ops/Col2Im.py,sha256=
|
|
30
|
+
onnx2tf/ops/Col2Im.py,sha256=8n66z3O59VJvJRlcrj93a5TLJ_qh-aSdR_-8SAQIlRo,7658
|
|
31
31
|
onnx2tf/ops/Compress.py,sha256=NvDGr9gCNl-8YG41xDBfe3UvhRP03K-ktdtY_MoytBc,3667
|
|
32
32
|
onnx2tf/ops/Concat.py,sha256=kDk7LN01nHuQyYnEPUEikSQ-M17jguAc-qFtCb9tg9I,38537
|
|
33
33
|
onnx2tf/ops/ConcatFromSequence.py,sha256=z8pNmGQRGq9cxWORW330NZS_0zsmhFudLswMyPn8AXU,3086
|
|
@@ -40,6 +40,8 @@ onnx2tf/ops/Cos.py,sha256=0v5ZJZRzrswVEObyxf4f0RvnWMWZA4uCEdoeq_VE31s,3608
|
|
|
40
40
|
onnx2tf/ops/Cosh.py,sha256=-L3QkQtiVBJIv1sSxbXtetVIwgI_2T4WC1O4t2aJ8Gc,3585
|
|
41
41
|
onnx2tf/ops/CumProd.py,sha256=k4hTEQrkwS7vk7pEy2Btvy2y0o70NlWj1MgsNomfOPg,3957
|
|
42
42
|
onnx2tf/ops/CumSum.py,sha256=SYKmD5r9Cm9gsCkJPNFoHigvvBO1PmRYRrVmn1HE78o,3954
|
|
43
|
+
onnx2tf/ops/DFT.py,sha256=rL_w1z16N9Kkf0TyMbywOawld0qZ_g1QOD9npGYD_zY,8086
|
|
44
|
+
onnx2tf/ops/DeformConv.py,sha256=tlhZDzNYAT093PkBDP4s6-EO-vnSdW_0KZTxtddjajM,13541
|
|
43
45
|
onnx2tf/ops/DepthToSpace.py,sha256=BiyBZ88dmXQAkZ5Jc-Ddo-5Kn8dRYCnoik_XnOFzqXc,14449
|
|
44
46
|
onnx2tf/ops/DequantizeLinear.py,sha256=1v43E1hUqO3g7N-PL1fy_cGj4oUgbphh7vXIGhUAyGc,6463
|
|
45
47
|
onnx2tf/ops/Det.py,sha256=kxuHkpv_KNHkof0uBv2RLtr3G1uA76MFHyCiCYCBXkw,3590
|
|
@@ -209,7 +211,7 @@ onnx2tf/utils/enums.py,sha256=7c5TqetqB07VjyHoxJHfLgtqBqk9ZRyUF33fPOJR1IM,1649
|
|
|
209
211
|
onnx2tf/utils/iterative_json_optimizer.py,sha256=qqeIxWGxrhcCYk8-ebWnblnOkzDCwi-nseipHzHR_bk,10436
|
|
210
212
|
onnx2tf/utils/json_auto_generator.py,sha256=OC-SfKtUg7zUxaXTAg6kT0ShzIc3ByjDa3FNp173DtA,60302
|
|
211
213
|
onnx2tf/utils/logging.py,sha256=yUCmPuJ_XiUItM3sZMcaMO24JErkQy7zZwVTYWAuiKg,1982
|
|
212
|
-
onnx2tf-1.29.
|
|
213
|
-
onnx2tf-1.29.
|
|
214
|
-
onnx2tf-1.29.
|
|
215
|
-
onnx2tf-1.29.
|
|
214
|
+
onnx2tf-1.29.19.dist-info/WHEEL,sha256=fAguSjoiATBe7TNBkJwOjyL1Tt4wwiaQGtNtjRPNMQA,80
|
|
215
|
+
onnx2tf-1.29.19.dist-info/entry_points.txt,sha256=GuhvLu7ZlYECumbmoiFlKX0mFPtFi_Ti9L-E5yuQqKs,42
|
|
216
|
+
onnx2tf-1.29.19.dist-info/METADATA,sha256=rSyPbOdWaW3QovkZCVvFg5zn_INzTCm8KN_rjZBah0Q,154312
|
|
217
|
+
onnx2tf-1.29.19.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|