onnx2tf 1.29.17__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.
@@ -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
+ )
@@ -0,0 +1,147 @@
1
+ import random
2
+ random.seed(0)
3
+ import numpy as np
4
+ np.random.seed(0)
5
+ import tensorflow as tf
6
+ import onnx_graphsurgeon as gs
7
+ import cv2
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 _as_tensor(value):
21
+ if isinstance(value, np.ndarray):
22
+ return tf.convert_to_tensor(value)
23
+ if isinstance(value, (np.generic, int, float, bool, str, bytes)):
24
+ return tf.convert_to_tensor(value)
25
+ return value
26
+
27
+
28
+ def _decode_image_np(encoded_stream, pixel_format):
29
+ if encoded_stream is None:
30
+ return np.zeros((0, 0, 0), dtype=np.uint8)
31
+ if encoded_stream.dtype != np.uint8:
32
+ encoded_stream = encoded_stream.astype(np.uint8)
33
+ if encoded_stream.size == 0:
34
+ return np.zeros((0, 0, 0), dtype=np.uint8)
35
+ if encoded_stream.ndim != 1:
36
+ encoded_stream = encoded_stream.reshape(-1)
37
+ try:
38
+ if pixel_format == 'Grayscale':
39
+ flag = cv2.IMREAD_GRAYSCALE
40
+ else:
41
+ flag = cv2.IMREAD_COLOR
42
+ decoded = cv2.imdecode(encoded_stream, flag)
43
+ if decoded is None:
44
+ raise ValueError('cv2.imdecode failed')
45
+ if pixel_format == 'RGB':
46
+ decoded = cv2.cvtColor(decoded, cv2.COLOR_BGR2RGB)
47
+ if pixel_format == 'Grayscale' and decoded.ndim == 2:
48
+ decoded = decoded[..., np.newaxis]
49
+ return decoded.astype(np.uint8)
50
+ except Exception:
51
+ if pixel_format == 'Grayscale':
52
+ return np.zeros((0, 0, 1), dtype=np.uint8)
53
+ return np.zeros((0, 0, 3), dtype=np.uint8)
54
+
55
+
56
+ @print_node_info
57
+ @inverted_operation_enable_disable
58
+ @get_replacement_parameter
59
+ def make_node(
60
+ *,
61
+ graph_node: gs.Node,
62
+ tf_layers_dict: dict,
63
+ **kwargs: dict,
64
+ ):
65
+ """ImageDecoder
66
+
67
+ Parameters
68
+ ----------
69
+ graph_node: gs.Node
70
+ graph_surgeon Node
71
+
72
+ tf_layers_dict: dict
73
+ optype, shape, dtype, tensorflow graph
74
+ """
75
+ before_op_output_shape_trans_1 = \
76
+ tf_layers_dict.get(graph_node.inputs[0].name, {}).get('before_op_output_shape_trans', True)
77
+ before_op_output_shape_trans = \
78
+ before_op_output_shape_trans_1
79
+
80
+ graph_node_input = get_constant_or_variable(
81
+ graph_node.inputs[0],
82
+ before_op_output_shape_trans,
83
+ )
84
+ graph_node_output: gs.Variable = graph_node.outputs[0]
85
+ shape = graph_node_output.shape
86
+ dtype = graph_node_output.dtype
87
+
88
+ input_tensor = tf_layers_dict[graph_node_input.name]['tf_node'] \
89
+ if isinstance(graph_node_input, gs.Variable) else graph_node_input
90
+
91
+ # Preserving Graph Structure (Dict)
92
+ tf_layers_dict[graph_node_output.name] = {
93
+ 'optype': graph_node.op,
94
+ 'shape': shape,
95
+ 'dtype': dtype,
96
+ }
97
+
98
+ # Pre-process transpose
99
+ input_tensor = pre_process_transpose(
100
+ value_before_transpose=input_tensor,
101
+ param_target='inputs',
102
+ param_name=graph_node.inputs[0].name,
103
+ **kwargs,
104
+ )
105
+
106
+ # Generation of TF OP
107
+ input_tensor = _as_tensor(input_tensor)
108
+ pixel_format = graph_node.attrs.get('pixel_format', 'RGB')
109
+ if pixel_format not in ['RGB', 'BGR', 'Grayscale']:
110
+ error(
111
+ f'ImageDecoder pixel_format={pixel_format} is not supported.\n' +
112
+ f'graph_node.name: {graph_node.name}'
113
+ )
114
+ pixel_format = 'RGB'
115
+
116
+ decoded = tf.numpy_function(
117
+ func=lambda x: _decode_image_np(x, pixel_format),
118
+ inp=[input_tensor],
119
+ Tout=tf.uint8,
120
+ name=graph_node.name,
121
+ )
122
+ channels = 1 if pixel_format == 'Grayscale' else 3
123
+ decoded = tf.ensure_shape(decoded, [None, None, channels])
124
+ tf_layers_dict[graph_node_output.name]['tf_node'] = decoded
125
+
126
+ # Post-process transpose
127
+ tf_layers_dict[graph_node_output.name]['tf_node'] = post_process_transpose(
128
+ value_before_transpose=tf_layers_dict[graph_node_output.name]['tf_node'],
129
+ param_target='outputs',
130
+ param_name=graph_node.outputs[0].name,
131
+ **kwargs,
132
+ )
133
+
134
+ # Generation of Debug Info
135
+ tf_layers_dict[graph_node_output.name]['tf_node_info'] = \
136
+ make_tf_node_info(
137
+ node_info={
138
+ 'tf_op_type': 'ImageDecoder',
139
+ 'tf_inputs': {
140
+ 'encoded_stream': input_tensor,
141
+ 'pixel_format': pixel_format,
142
+ },
143
+ 'tf_outputs': {
144
+ 'output': tf_layers_dict[graph_node_output.name]['tf_node'],
145
+ },
146
+ }
147
+ )