Resize#
Resize - 13#
Version
name: Resize (GitHub)
domain: main
since_version: 13
function: False
support_level: SupportType.COMMON
shape inference: True
This version of the operator has been available since version 13.
Summary
Resize the input tensor. In general, it calculates every value in the output tensor as a weighted average of neighborhood (a.k.a. sampling locations) in the input tensor. Each dimension value of the output tensor is:
output_dimension = floor(input_dimension * (roi_end - roi_start) * scale) if input "sizes" is not specified.
Attributes
- coordinate_transformation_mode:
This attribute describes how to transform the coordinate in the
resized tensor to the coordinate in the original tensor. <br/> The coordinate of each dimension is transformed individually. Let’s describe a case using axis x as an example. Denote x_resized as the coordinate of axis x in the resized tensor, x_original as the coordinate of axis x in the original tensor, length_original as the length of the original tensor in axis x, length_resized as the length of the resized tensor in axis x, roi_x = (start_x, end_x) of the axis x in input “roi”, scale = length_resized / length_original, <br/> if coordinate_transformation_mode is “half_pixel”, <br/> x_original = (x_resized + 0.5) / scale - 0.5, <br/> if coordinate_transformation_mode is “pytorch_half_pixel”, <br/> x_original = length_resized > 1 ? (x_resized + 0.5) / scale - 0.5 : 0, <br/> if coordinate_transformation_mode is “align_corners”, <br/> x_original = x_resized * (length_original - 1) / (length_resized - 1), <br/> if coordinate_transformation_mode is “asymmetric”, <br/> x_original = x_resized / scale, <br/> if coordinate_transformation_mode is “tf_crop_and_resize”, <br/> x_original = length_resized > 1 ? start_x * (length_original - 1) + x_resized * (end_x - start_x) * (length_original - 1) / (length_resized - 1) : 0.5 * (start_x + end_x) * (length_original - 1). Default value is
'half_pixel'
.cubic_coeff_a: The coefficient ‘a’ used in cubic interpolation. Two common choice are -0.5 (in some cases of TensorFlow) and -0.75 (in PyTorch). Check out Equation (4) in https://ieeexplore.ieee.org/document/1163711 for the details. This attribute is valid only if “mode” is “cubic”. Default value is
-0.75
.exclude_outside: If set to 1, the weight of sampling locations outside the tensor will be set to 0 and the weight will be renormalized so that their sum is 1.0. The default value is 0. Default value is
0
.extrapolation_value: When coordinate_transformation_mode is “tf_crop_and_resize” and x_original is outside the range [0, length_original - 1], this value is used as the corresponding output value. Default is 0.0f. Default value is
0.0
.mode: Three interpolation modes: nearest (default), linear and cubic. The “linear” mode includes linear interpolation for 1D tensor and N-linear interpolation for N-D tensor (for example, bilinear interpolation for 2D tensor). The “cubic” mode includes cubic interpolation for 1D tensor and N-cubic interpolation for N-D tensor (for example, bicubic interpolation for 2D tensor). Default value is
'nearest'
.nearest_mode: Four modes: round_prefer_floor (default, as known as round half down), round_prefer_ceil (as known as round half up), floor, ceil. Only used by nearest interpolation. It indicates how to get “nearest” pixel in input tensor from x_original, so this attribute is valid only if “mode” is “nearest”. Default value is
'round_prefer_floor'
.
Inputs
Between 1 and 4 inputs.
X (heterogeneous) - T1: N-D tensor
roi (optional, heterogeneous) - T2: 1-D tensor given as [start1, …, startN, end1, …, endN], where N is the rank of X. The RoIs’ coordinates are normalized in the coordinate system of the input image. It only takes effect when coordinate_transformation_mode is “tf_crop_and_resize”
scales (optional, heterogeneous) - tensor(float): The scale array along each dimension. It takes value greater than 0. If it’s less than 1, it’s sampling down, otherwise, it’s upsampling. The number of elements of ‘scales’ should be the same as the rank of input ‘X’. One of ‘scales’ and ‘sizes’ MUST be specified and it is an error if both are specified. If ‘sizes’ is needed, the user can use an empty string as the name of ‘scales’ in this operator’s input list.
sizes (optional, heterogeneous) - tensor(int64): The size of the output tensor. The number of elements of ‘sizes’ should be the same as the rank of input ‘X’. Only one of ‘scales’ and ‘sizes’ can be specified.
Outputs
Y (heterogeneous) - T1: N-D tensor after resizing
Type Constraints
T1 in ( tensor(bfloat16), tensor(bool), tensor(complex128), tensor(complex64), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8) ): Constrain input ‘X’ and output ‘Y’ to all tensor types.
T2 in ( tensor(double), tensor(float), tensor(float16) ): Constrain roi type to float or double.
Examples
resize_upsample_scales_nearest
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', 'scales'],
outputs=['Y'],
mode='nearest',
)
data = np.array([[[
[1, 2],
[3, 4],
]]], dtype=np.float32)
scales = np.array([1.0, 1.0, 2.0, 3.0], dtype=np.float32)
# [[[[1. 1. 1. 2. 2. 2.]
# [1. 1. 1. 2. 2. 2.]
# [3. 3. 3. 4. 4. 4.]
# [3. 3. 3. 4. 4. 4.]]]]
output = interpolate_nd(
data, nearest_coeffs, scale_factors=scales).astype(np.float32)
expect(node, inputs=[data, scales], outputs=[output],
name='test_resize_upsample_scales_nearest')
resize_downsample_scales_nearest
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', 'scales'],
outputs=['Y'],
mode='nearest',
)
data = np.array([[[
[1, 2, 3, 4],
[5, 6, 7, 8],
]]], dtype=np.float32)
scales = np.array([1.0, 1.0, 0.6, 0.6], dtype=np.float32)
# [[[[1. 3.]]]]
output = interpolate_nd(
data, nearest_coeffs, scale_factors=scales).astype(np.float32)
expect(node, inputs=[data, scales], outputs=[output],
name='test_resize_downsample_scales_nearest')
resize_upsample_sizes_nearest
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', '', 'sizes'],
outputs=['Y'],
mode='nearest',
)
data = np.array([[[
[1, 2],
[3, 4],
]]], dtype=np.float32)
sizes = np.array([1, 1, 7, 8], dtype=np.int64)
# [[[[1. 1. 1. 1. 2. 2. 2. 2.]
# [1. 1. 1. 1. 2. 2. 2. 2.]
# [1. 1. 1. 1. 2. 2. 2. 2.]
# [1. 1. 1. 1. 2. 2. 2. 2.]
# [3. 3. 3. 3. 4. 4. 4. 4.]
# [3. 3. 3. 3. 4. 4. 4. 4.]
# [3. 3. 3. 3. 4. 4. 4. 4.]]]]
output = interpolate_nd(
data, nearest_coeffs, output_size=sizes).astype(np.float32)
expect(node, inputs=[data, sizes], outputs=[output],
name='test_resize_upsample_sizes_nearest')
resize_downsample_sizes_nearest
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', '', 'sizes'],
outputs=['Y'],
mode='nearest',
)
data = np.array([[[
[1, 2, 3, 4],
[5, 6, 7, 8],
]]], dtype=np.float32)
sizes = np.array([1, 1, 1, 3], dtype=np.int64)
# [[[[1. 3.]]]]
output = interpolate_nd(
data, nearest_coeffs, output_size=sizes).astype(np.float32)
expect(node, inputs=[data, sizes], outputs=[output],
name='test_resize_downsample_sizes_nearest')
resize_upsample_scales_linear
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', 'scales'],
outputs=['Y'],
mode='linear',
)
data = np.array([[[
[1, 2],
[3, 4],
]]], dtype=np.float32)
scales = np.array([1.0, 1.0, 2.0, 2.0], dtype=np.float32)
# [[[[1. 1.25 1.75 2. ]
# [1.5 1.75 2.25 2.5 ]
# [2.5 2.75 3.25 3.5 ]
# [3. 3.25 3.75 4. ]]]]
output = interpolate_nd(
data, linear_coeffs, scale_factors=scales).astype(np.float32)
expect(node, inputs=[data, scales], outputs=[output],
name='test_resize_upsample_scales_linear')
resize_upsample_scales_linear_align_corners
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', 'scales'],
outputs=['Y'],
mode='linear',
coordinate_transformation_mode='align_corners'
)
data = np.array([[[
[1, 2],
[3, 4],
]]], dtype=np.float32)
scales = np.array([1.0, 1.0, 2.0, 2.0], dtype=np.float32)
# [[[[1. 1.33333333 1.66666667 2. ]
# [1.66666667 2. 2.33333333 2.66666667]
# [2.33333333 2.66666667 3. 3.33333333]
# [3. 3.33333333 3.66666667 4. ]]]]
output = interpolate_nd(
data, linear_coeffs, scale_factors=scales, coordinate_transformation_mode='align_corners').astype(np.float32)
expect(node, inputs=[data, scales], outputs=[output],
name='test_resize_upsample_scales_linear_align_corners')
resize_downsample_scales_linear
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', 'scales'],
outputs=['Y'],
mode='linear',
)
data = np.array([[[
[1, 2, 3, 4],
[5, 6, 7, 8],
]]], dtype=np.float32)
scales = np.array([1.0, 1.0, 0.6, 0.6], dtype=np.float32)
# [[[[2.6666665 4.3333331]]]]
output = interpolate_nd(
data, linear_coeffs, scale_factors=scales).astype(np.float32)
expect(node, inputs=[data, scales], outputs=[output],
name='test_resize_downsample_scales_linear')
resize_downsample_scales_linear_align_corners
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', 'scales'],
outputs=['Y'],
mode='linear',
coordinate_transformation_mode='align_corners'
)
data = np.array([[[
[1, 2, 3, 4],
[5, 6, 7, 8],
]]], dtype=np.float32)
scales = np.array([1.0, 1.0, 0.6, 0.6], dtype=np.float32)
# [[[[1. 3.142857]]]]
output = interpolate_nd(
data, linear_coeffs, scale_factors=scales, coordinate_transformation_mode='align_corners').astype(np.float32)
expect(node, inputs=[data, scales], outputs=[output],
name='test_resize_downsample_scales_linear_align_corners')
resize_upsample_scales_cubic
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', 'scales'],
outputs=['Y'],
mode='cubic',
)
data = np.array([[[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
]]], dtype=np.float32)
scales = np.array([1.0, 1.0, 2.0, 2.0], dtype=np.float32)
# [[[[ 0.47265625 0.76953125 1.24609375 1.875 2.28125
# 2.91015625 3.38671875 3.68359375]
# [ 1.66015625 1.95703125 2.43359375 3.0625 3.46875
# 4.09765625 4.57421875 4.87109375]
# [ 3.56640625 3.86328125 4.33984375 4.96875 5.375
# 6.00390625 6.48046875 6.77734375]
# [ 6.08203125 6.37890625 6.85546875 7.484375 7.890625
# 8.51953125 8.99609375 9.29296875]
# [ 7.70703125 8.00390625 8.48046875 9.109375 9.515625
# 10.14453125 10.62109375 10.91796875]
# [10.22265625 10.51953125 10.99609375 11.625 12.03125
# 12.66015625 13.13671875 13.43359375]
# [12.12890625 12.42578125 12.90234375 13.53125 13.9375
# 14.56640625 15.04296875 15.33984375]
# [13.31640625 13.61328125 14.08984375 14.71875 15.125
# 15.75390625 16.23046875 16.52734375]]]]
output = interpolate_nd(
data, cubic_coeffs, scale_factors=scales).astype(np.float32)
expect(node, inputs=[data, scales], outputs=[output],
name='test_resize_upsample_scales_cubic')
resize_upsample_scales_cubic_align_corners
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', 'scales'],
outputs=['Y'],
mode='cubic',
coordinate_transformation_mode='align_corners'
)
data = np.array([[[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
]]], dtype=np.float32)
scales = np.array([1.0, 1.0, 2.0, 2.0], dtype=np.float32)
# [[[[ 1. 1.34110787 1.80029155 2.32944606 2.67055394
# 3.19970845 3.65889213 4. ]
# [ 2.36443149 2.70553936 3.16472303 3.69387755 4.03498542
# 4.56413994 5.02332362 5.36443149]
# [ 4.20116618 4.54227405 5.00145773 5.53061224 5.87172012
# 6.40087464 6.86005831 7.20116618]
# [ 6.31778426 6.65889213 7.1180758 7.64723032 7.98833819
# 8.51749271 8.97667638 9.31778426]
# [ 7.68221574 8.02332362 8.48250729 9.01166181 9.35276968
# 9.8819242 10.34110787 10.68221574]
# [ 9.79883382 10.13994169 10.59912536 11.12827988 11.46938776
# 11.99854227 12.45772595 12.79883382]
# [11.63556851 11.97667638 12.43586006 12.96501458 13.30612245
# 13.83527697 14.29446064 14.63556851]
# [13. 13.34110787 13.80029155 14.32944606 14.67055394
# 15.19970845 15.65889213 16. ]]]]
output = interpolate_nd(
data, cubic_coeffs, scale_factors=scales, coordinate_transformation_mode='align_corners').astype(np.float32)
expect(node, inputs=[data, scales], outputs=[output],
name='test_resize_upsample_scales_cubic_align_corners')
resize_downsample_scales_cubic
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', 'scales'],
outputs=['Y'],
mode='cubic',
)
data = np.array([[[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
]]], dtype=np.float32)
scales = np.array([1.0, 1.0, 0.8, 0.8], dtype=np.float32)
# [[[[ 1.47119141 2.78125 4.08251953]
# [ 6.71142578 8.02148438 9.32275391]
# [11.91650391 13.2265625 14.52783203]]]]
output = interpolate_nd(
data, cubic_coeffs, scale_factors=scales).astype(np.float32)
expect(node, inputs=[data, scales], outputs=[output],
name='test_resize_downsample_scales_cubic')
resize_downsample_scales_cubic_align_corners
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', 'scales'],
outputs=['Y'],
mode='cubic',
coordinate_transformation_mode='align_corners'
)
data = np.array([[[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
]]], dtype=np.float32)
scales = np.array([1.0, 1.0, 0.8, 0.8], dtype=np.float32)
# [[[[ 1. 2.39519159 3.79038317]
# [ 6.58076634 7.97595793 9.37114951]
# [12.16153268 13.55672427 14.95191585]]]]
output = interpolate_nd(
data, cubic_coeffs, scale_factors=scales, coordinate_transformation_mode='align_corners').astype(np.float32)
expect(node, inputs=[data, scales], outputs=[output],
name='test_resize_downsample_scales_cubic_align_corners')
resize_upsample_sizes_cubic
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', '', 'sizes'],
outputs=['Y'],
mode='cubic',
)
data = np.array([[[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
]]], dtype=np.float32)
sizes = np.array([1, 1, 9, 10], dtype=np.int64)
# [[[[ 0.45507922 0.64057922 0.97157922 1.42257922 1.90732922
# 2.22332922 2.70807922 3.15907922 3.49007922 3.67557922]
# [ 1.39437963 1.57987963 1.91087963 2.36187963 2.84662963
# 3.16262963 3.64737963 4.09837963 4.42937963 4.61487963]
# [ 2.95130693 3.13680693 3.46780693 3.91880693 4.40355693
# 4.71955693 5.20430693 5.65530693 5.98630693 6.17180693]
# [ 5.20525069 5.39075069 5.72175069 6.17275069 6.65750069
# 6.97350069 7.45825069 7.90925069 8.24025069 8.42575069]
# [ 6.88975 7.07525 7.40625 7.85725 8.342
# 8.658 9.14275 9.59375 9.92475 10.11025 ]
# [ 8.57424931 8.75974931 9.09074931 9.54174931 10.02649931
# 10.34249931 10.82724931 11.27824931 11.60924931 11.79474931]
# [10.82819307 11.01369307 11.34469307 11.79569307 12.28044307
# 12.59644307 13.08119307 13.53219307 13.86319307 14.04869307]
# [12.38512037 12.57062037 12.90162037 13.35262037 13.83737037
# 14.15337037 14.63812037 15.08912037 15.42012037 15.60562037]
# [13.32442078 13.50992078 13.84092078 14.29192078 14.77667078
# 15.09267078 15.57742078 16.02842078 16.35942078 16.54492078]]]]
output = interpolate_nd(
data, cubic_coeffs, output_size=sizes).astype(np.float32)
expect(node, inputs=[data, sizes], outputs=[output],
name='test_resize_upsample_sizes_cubic')
resize_downsample_sizes_cubic
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', '', 'sizes'],
outputs=['Y'],
mode='cubic',
)
data = np.array([[[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
]]], dtype=np.float32)
sizes = np.array([1, 1, 3, 3], dtype=np.int64)
# [[[[ 1.63078704 3.00462963 4.37847222]
# [ 7.12615741 8.5 9.87384259]
# [12.62152778 13.99537037 15.36921296]]]]
output = interpolate_nd(
data, cubic_coeffs, output_size=sizes).astype(np.float32)
expect(node, inputs=[data, sizes], outputs=[output],
name='test_resize_downsample_sizes_cubic')
# TensorFlow v1 bicubic with half_pixel_centers=True
resize_upsample_scales_cubic_A_n0p5_exclude_outside
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', 'scales'],
outputs=['Y'],
mode='cubic',
cubic_coeff_a=-0.5,
exclude_outside=True
)
data = np.array([[[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
]]], dtype=np.float32)
scales = np.array([1.0, 1.0, 2.0, 2.0], dtype=np.float32)
# [[[[ 0.55882353 0.81494204 1.35698249 1.89705882 2.39705882
# 2.93713516 3.47917561 3.73529412]
# [ 1.58329755 1.83941606 2.38145651 2.92153285 3.42153285
# 3.96160918 4.50364964 4.75976814]
# [ 3.75145936 4.00757787 4.54961832 5.08969466 5.58969466
# 6.12977099 6.67181144 6.92792995]
# [ 5.91176471 6.16788321 6.70992366 7.25 7.75
# 8.29007634 8.83211679 9.08823529]
# [ 7.91176471 8.16788321 8.70992366 9.25 9.75
# 10.29007634 10.83211679 11.08823529]
# [10.07207005 10.32818856 10.87022901 11.41030534 11.91030534
# 12.45038168 12.99242213 13.24854064]
# [12.24023186 12.49635036 13.03839082 13.57846715 14.07846715
# 14.61854349 15.16058394 15.41670245]
# [13.26470588 13.52082439 14.06286484 14.60294118 15.10294118
# 15.64301751 16.18505796 16.44117647]]]]
output = interpolate_nd(data, lambda x: cubic_coeffs(x, A=-0.5), scale_factors=scales,
exclude_outside=True).astype(np.float32)
expect(node, inputs=[data, scales], outputs=[output],
name='test_resize_upsample_scales_cubic_A_n0p5_exclude_outside')
resize_downsample_scales_cubic_A_n0p5_exclude_outside
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', 'scales'],
outputs=['Y'],
mode='cubic',
cubic_coeff_a=-0.5,
exclude_outside=True
)
data = np.array([[[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
]]], dtype=np.float32)
scales = np.array([1.0, 1.0, 0.8, 0.8], dtype=np.float32)
# [[[[ 1.36812675 2.6695014 4.0133367 ]
# [ 6.57362535 7.875 9.2188353 ]
# [11.94896657 13.25034122 14.59417652]]]]
output = interpolate_nd(data, lambda x: cubic_coeffs(x, A=-0.5), scale_factors=scales,
exclude_outside=True).astype(np.float32)
expect(node, inputs=[data, scales], outputs=[output],
name='test_resize_downsample_scales_cubic_A_n0p5_exclude_outside')
# TensorFlow v1 bicubic with half_pixel_centers=False
resize_upsample_scales_cubic_asymmetric
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', 'scales'],
outputs=['Y'],
mode='cubic',
coordinate_transformation_mode='asymmetric'
)
data = np.array([[[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
]]], dtype=np.float32)
scales = np.array([1.0, 1.0, 2.0, 2.0], dtype=np.float32)
# [[[[ 1. 1.40625 2. 2.5 3. 3.59375 4.
# 4.09375]
# [ 2.625 3.03125 3.625 4.125 4.625 5.21875 5.625
# 5.71875]
# [ 5. 5.40625 6. 6.5 7. 7.59375 8.
# 8.09375]
# [ 7. 7.40625 8. 8.5 9. 9.59375 10.
# 10.09375]
# [ 9. 9.40625 10. 10.5 11. 11.59375 12.
# 12.09375]
# [11.375 11.78125 12.375 12.875 13.375 13.96875 14.375
# 14.46875]
# [13. 13.40625 14. 14.5 15. 15.59375 16.
# 16.09375]
# [13.375 13.78125 14.375 14.875 15.375 15.96875 16.375
# 16.46875]]]]
output = interpolate_nd(data, lambda x: cubic_coeffs(x, A=-0.75), scale_factors=scales,
coordinate_transformation_mode='asymmetric').astype(np.float32)
expect(node, inputs=[data, scales], outputs=[output],
name='test_resize_upsample_scales_cubic_asymmetric')
resize_tf_crop_and_resize
node = onnx.helper.make_node(
'Resize',
inputs=['X', 'roi', '', 'sizes'],
outputs=['Y'],
mode='linear',
coordinate_transformation_mode='tf_crop_and_resize'
)
data = np.array([[[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
]]], dtype=np.float32)
# Note: for some rois, the result may be different with that of TF for inaccurate floating point
roi = np.array([0, 0, 0.4, 0.6, 1, 1, 0.6, 0.8], dtype=np.float32)
sizes = np.array([1, 1, 3, 3], dtype=np.int64)
# [[[[ 7.6000004 7.9 8.2 ]
# [ 8.8 9.1 9.400001 ]
# [10. 10.3 10.6 ]]]]
output = interpolate_nd(data, linear_coeffs, output_size=sizes, roi=roi,
coordinate_transformation_mode='tf_crop_and_resize').astype(np.float32)
expect(node, inputs=[data, roi, sizes], outputs=[output],
name='test_resize_tf_crop_and_resize')
resize_tf_crop_and_resize_extrapolation_value
node = onnx.helper.make_node(
'Resize',
inputs=['X', 'roi', '', 'sizes'],
outputs=['Y'],
mode='linear',
coordinate_transformation_mode='tf_crop_and_resize',
extrapolation_value=10.0
)
data = np.array([[[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
]]], dtype=np.float32)
# Note: for some rois, the result may be different with that of TF for inaccurate floating point
roi = np.array([0, 0, 0.4, 0.6, 1, 1, 1.2, 1.7], dtype=np.float32)
sizes = np.array([1, 1, 3, 3], dtype=np.int64)
# [[[[ 7.6000004 10. 10. ]
# [12.400001 10. 10. ]
# [10. 10. 10. ]]]]
output = interpolate_nd(data, linear_coeffs, output_size=sizes, roi=roi,
coordinate_transformation_mode='tf_crop_and_resize', extrapolation_value=10.0).astype(np.float32)
expect(node, inputs=[data, roi, sizes], outputs=[output],
name='test_resize_tf_crop_and_resize')
resize_downsample_sizes_linear_pytorch_half_pixel
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', '', 'sizes'],
outputs=['Y'],
mode='linear',
coordinate_transformation_mode='pytorch_half_pixel'
)
data = np.array([[[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
]]], dtype=np.float32)
sizes = np.array([1, 1, 3, 1], dtype=np.int64)
# [[[[ 1.6666666]
# [ 7. ]
# [12.333333 ]]]]
output = interpolate_nd(
data, linear_coeffs, output_size=sizes, coordinate_transformation_mode='pytorch_half_pixel').astype(np.float32)
expect(node, inputs=[data, sizes], outputs=[output],
name='test_resize_downsample_sizes_linear_pytorch_half_pixel')
resize_upsample_sizes_nearest_floor_align_corners
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', '', 'sizes'],
outputs=['Y'],
mode='nearest',
coordinate_transformation_mode='align_corners',
nearest_mode='floor'
)
data = np.array([[[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
]]], dtype=np.float32)
sizes = np.array([1, 1, 8, 8], dtype=np.int64)
# [[[[ 1. 1. 1. 2. 2. 3. 3. 4.]
# [ 1. 1. 1. 2. 2. 3. 3. 4.]
# [ 1. 1. 1. 2. 2. 3. 3. 4.]
# [ 5. 5. 5. 6. 6. 7. 7. 8.]
# [ 5. 5. 5. 6. 6. 7. 7. 8.]
# [ 9. 9. 9. 10. 10. 11. 11. 12.]
# [ 9. 9. 9. 10. 10. 11. 11. 12.]
# [13. 13. 13. 14. 14. 15. 15. 16.]]]]
output = interpolate_nd(
data, lambda x: nearest_coeffs(x, mode='floor'), output_size=sizes, coordinate_transformation_mode='align_corners').astype(np.float32)
expect(node, inputs=[data, sizes], outputs=[output],
name='test_resize_upsample_sizes_nearest_floor_align_corners')
resize_upsample_sizes_nearest_round_prefer_ceil_asymmetric
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', '', 'sizes'],
outputs=['Y'],
mode='nearest',
coordinate_transformation_mode='asymmetric',
nearest_mode='round_prefer_ceil'
)
data = np.array([[[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
]]], dtype=np.float32)
sizes = np.array([1, 1, 8, 8], dtype=np.int64)
# [[[[ 1. 2. 2. 3. 3. 4. 4. 4.]
# [ 5. 6. 6. 7. 7. 8. 8. 8.]
# [ 5. 6. 6. 7. 7. 8. 8. 8.]
# [ 9. 10. 10. 11. 11. 12. 12. 12.]
# [ 9. 10. 10. 11. 11. 12. 12. 12.]
# [13. 14. 14. 15. 15. 16. 16. 16.]
# [13. 14. 14. 15. 15. 16. 16. 16.]
# [13. 14. 14. 15. 15. 16. 16. 16.]]]]
output = interpolate_nd(
data, lambda x: nearest_coeffs(x, mode='round_prefer_ceil'),
output_size=sizes, coordinate_transformation_mode='asymmetric').astype(np.float32)
expect(node, inputs=[data, sizes], outputs=[output],
name='test_resize_upsample_sizes_nearest_round_prefer_ceil_asymmetric')
resize_upsample_sizes_nearest_ceil_half_pixel
node = onnx.helper.make_node(
'Resize',
inputs=['X', '', '', 'sizes'],
outputs=['Y'],
mode='nearest',
coordinate_transformation_mode='half_pixel',
nearest_mode='ceil'
)
data = np.array([[[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
]]], dtype=np.float32)
sizes = np.array([1, 1, 8, 8], dtype=np.int64)
# [[[[ 1. 2. 2. 3. 3. 4. 4. 4.]
# [ 5. 6. 6. 7. 7. 8. 8. 8.]
# [ 5. 6. 6. 7. 7. 8. 8. 8.]
# [ 9. 10. 10. 11. 11. 12. 12. 12.]
# [ 9. 10. 10. 11. 11. 12. 12. 12.]
# [13. 14. 14. 15. 15. 16. 16. 16.]
# [13. 14. 14. 15. 15. 16. 16. 16.]
# [13. 14. 14. 15. 15. 16. 16. 16.]]]]
output = interpolate_nd(
data, lambda x: nearest_coeffs(x, mode='ceil'), output_size=sizes).astype(np.float32)
expect(node, inputs=[data, sizes], outputs=[output],
name='test_resize_upsample_sizes_nearest_ceil_half_pixel')
Differences
0 | 0 | Resize the input tensor. In general, it calculates every value in the output tensor as a weighted average of neighborhood (a.k.a. sampling locations) in the input tensor. | Resize the input tensor. In general, it calculates every value in the output tensor as a weighted average of neighborhood (a.k.a. sampling locations) in the input tensor. |
1 | 1 | Each dimension value of the output tensor is: | Each dimension value of the output tensor is: |
2 | 2 | output_dimension = floor(input_dimension * (roi_end - roi_start) * scale) if input \"sizes\" is not specified. | output_dimension = floor(input_dimension * (roi_end - roi_start) * scale) if input \"sizes\" is not specified. |
3 | 3 |
|
|
4 | 4 | **Attributes** | **Attributes** |
5 | 5 |
|
|
6 | 6 | * **coordinate_transformation_mode**: | * **coordinate_transformation_mode**: |
7 | 7 | This attribute describes how to transform the coordinate in the | This attribute describes how to transform the coordinate in the |
8 | 8 | resized tensor to the coordinate in the original tensor. | resized tensor to the coordinate in the original tensor. |
9 | 9 | coordinate of each dimension is transformed individually. Let's | coordinate of each dimension is transformed individually. Let's |
10 | 10 | describe a case using axis x as an example. Denote x_resized as the | describe a case using axis x as an example. Denote x_resized as the |
11 | 11 | coordinate of axis x in the resized tensor, x_original as the | coordinate of axis x in the resized tensor, x_original as the |
12 | 12 | coordinate of axis x in the original tensor, length_original as the | coordinate of axis x in the original tensor, length_original as the |
13 | 13 | length of the original tensor in axis x, length_resized as the | length of the original tensor in axis x, length_resized as the |
14 | 14 | length of the resized tensor in axis x, roi_x = (start_x, end_x) of | length of the resized tensor in axis x, roi_x = (start_x, end_x) of |
15 | 15 | the axis x in input "roi", scale = length_resized / length_original, | the axis x in input "roi", scale = length_resized / length_original, |
16 | 16 | | |
17 | 17 | x_original = (x_resized + 0.5) / scale - 0.5, | x_original = (x_resized + 0.5) / scale - 0.5, |
18 | 18 | coordinate_transformation_mode is "pytorch_half_pixel", | coordinate_transformation_mode is "pytorch_half_pixel", |
19 | 19 | x_original = length_resized > 1 ? (x_resized + 0.5) / scale - 0.5 : | x_original = length_resized > 1 ? (x_resized + 0.5) / scale - 0.5 : |
20 | 20 | 0, | 0, |
21 | 21 | | |
22 | 22 | (length_resized - 1), | (length_resized - 1), |
23 | 23 | "asymmetric", | "asymmetric", |
24 | coordinate_transformation_mode is "tf_half_pixel_for_nn", | ||
25 | x_original = (x_resized + 0.5) / scale, | ||
26 | 24 | coordinate_transformation_mode is "tf_crop_and_resize", | coordinate_transformation_mode is "tf_crop_and_resize", |
27 | 25 | x_original = length_resized > 1 ? start_x * (length_original - 1) + | x_original = length_resized > 1 ? start_x * (length_original - 1) + |
28 | 26 | x_resized * (end_x - start_x) * (length_original - 1) / | x_resized * (end_x - start_x) * (length_original - 1) / |
29 | 27 | (length_resized - 1) : 0.5 * (start_x + end_x) * (length_original - | (length_resized - 1) : 0.5 * (start_x + end_x) * (length_original - |
30 | 28 | 1). Default value is 'half_pixel'. | 1). Default value is 'half_pixel'. |
31 | 29 | * **cubic_coeff_a**: | * **cubic_coeff_a**: |
32 | 30 | The coefficient 'a' used in cubic interpolation. Two common choice | The coefficient 'a' used in cubic interpolation. Two common choice |
33 | 31 | are -0.5 (in some cases of TensorFlow) and -0.75 (in PyTorch). Check | are -0.5 (in some cases of TensorFlow) and -0.75 (in PyTorch). Check |
34 | 32 | out Equation (4) in https://ieeexplore.ieee.org/document/1163711 for | out Equation (4) in https://ieeexplore.ieee.org/document/1163711 for |
35 | 33 | the details. This attribute is valid only if "mode" is "cubic". Default value is -0.75. | the details. This attribute is valid only if "mode" is "cubic". Default value is -0.75. |
36 | 34 | * **exclude_outside**: | * **exclude_outside**: |
37 | 35 | If set to 1, the weight of sampling locations outside the tensor | If set to 1, the weight of sampling locations outside the tensor |
38 | 36 | will be set to 0 and the weight will be renormalized so that their | will be set to 0 and the weight will be renormalized so that their |
39 | 37 | sum is 1.0. The default value is 0. Default value is 0. | sum is 1.0. The default value is 0. Default value is 0. |
40 | 38 | * **extrapolation_value**: | * **extrapolation_value**: |
41 | 39 | When coordinate_transformation_mode is "tf_crop_and_resize" and | When coordinate_transformation_mode is "tf_crop_and_resize" and |
42 | 40 | x_original is outside the range [0, length_original - 1], this value | x_original is outside the range [0, length_original - 1], this value |
43 | 41 | is used as the corresponding output value. Default is 0.0f. Default value is 0.0. | is used as the corresponding output value. Default is 0.0f. Default value is 0.0. |
44 | 42 | * **mode**: | * **mode**: |
45 | 43 | Three interpolation modes: nearest (default), linear and cubic. The | Three interpolation modes: nearest (default), linear and cubic. The |
46 | 44 | "linear" mode includes linear interpolation for 1D tensor and | "linear" mode includes linear interpolation for 1D tensor and |
47 | 45 | N-linear interpolation for N-D tensor (for example, bilinear | N-linear interpolation for N-D tensor (for example, bilinear |
48 | 46 | interpolation for 2D tensor). The "cubic" mode includes cubic | interpolation for 2D tensor). The "cubic" mode includes cubic |
49 | 47 | interpolation for 1D tensor and N-cubic interpolation for N-D tensor | interpolation for 1D tensor and N-cubic interpolation for N-D tensor |
50 | 48 | (for example, bicubic interpolation for 2D tensor). Default value is 'nearest'. | (for example, bicubic interpolation for 2D tensor). Default value is 'nearest'. |
51 | 49 | * **nearest_mode**: | * **nearest_mode**: |
52 | 50 | Four modes: round_prefer_floor (default, as known as round half | Four modes: round_prefer_floor (default, as known as round half |
53 | 51 | down), round_prefer_ceil (as known as round half up), floor, ceil. | down), round_prefer_ceil (as known as round half up), floor, ceil. |
54 | 52 | Only used by nearest interpolation. It indicates how to get | Only used by nearest interpolation. It indicates how to get |
55 | 53 | "nearest" pixel in input tensor from x_original, so this attribute | "nearest" pixel in input tensor from x_original, so this attribute |
56 | 54 | is valid only if "mode" is "nearest". Default value is 'round_prefer_floor'. | is valid only if "mode" is "nearest". Default value is 'round_prefer_floor'. |
57 | 55 |
|
|
58 | 56 | **Inputs** | **Inputs** |
59 | 57 |
|
|
60 | 58 | Between 3 and 4 inputs. |
|
61 | 59 |
|
|
62 | 60 | * **X** (heterogeneous) - **T1**: | * **X** (heterogeneous) - **T1**: |
63 | 61 | N-D tensor | N-D tensor |
64 | 62 | * **roi** (heterogeneous) - **T2**: |
|
65 | 63 | 1-D tensor given as [start1, ..., startN, end1, ..., endN], where N | 1-D tensor given as [start1, ..., startN, end1, ..., endN], where N |
66 | 64 | is the rank of X. The RoIs' coordinates are normalized in the | is the rank of X. The RoIs' coordinates are normalized in the |
67 | 65 | coordinate system of the input image. It only takes effect when | coordinate system of the input image. It only takes effect when |
68 | 66 | coordinate_transformation_mode is "tf_crop_and_resize" | coordinate_transformation_mode is "tf_crop_and_resize" |
69 | 67 | * **scales** (heterogeneous) - **tensor(float)**: |
|
70 | 68 | The scale array along each dimension. It takes value greater than 0. | The scale array along each dimension. It takes value greater than 0. |
71 | 69 | If it's less than 1, it's sampling down, otherwise, it's upsampling. | If it's less than 1, it's sampling down, otherwise, it's upsampling. |
72 | 70 | The number of elements of 'scales' should be the same as the rank of | The number of elements of 'scales' should be the same as the rank of |
71 | input 'X'. One of 'scales' and 'sizes' MUST be specified and it is | ||
73 | 72 | input 'X'. If 'size' is needed, the user must set 'scales' to an |
|
74 | 73 | empty tensor. |
|
74 | list. | ||
75 | 75 | * **sizes** (optional, heterogeneous) - **tensor(int64)**: | * **sizes** (optional, heterogeneous) - **tensor(int64)**: |
76 | 76 | The size of the output tensor. The number of elements of 'sizes' | The size of the output tensor. The number of elements of 'sizes' |
77 | 77 | should be the same as the rank of input 'X'. May only be set if |
|
78 | 'scales' is set to an empty tensor. | ||
78 | and 'sizes' can be specified. | ||
79 | 79 |
|
|
80 | 80 | **Outputs** | **Outputs** |
81 | 81 |
|
|
82 | 82 | * **Y** (heterogeneous) - **T1**: | * **Y** (heterogeneous) - **T1**: |
83 | 83 | N-D tensor after resizing | N-D tensor after resizing |
84 | 84 |
|
|
85 | 85 | **Type Constraints** | **Type Constraints** |
86 | 86 |
|
|
87 | 87 | * **T1** in ( | * **T1** in ( |
88 | tensor(bfloat16), | ||
88 | 89 | tensor(bool), | tensor(bool), |
89 | 90 | tensor(complex128), | tensor(complex128), |
90 | 91 | tensor(complex64), | tensor(complex64), |
91 | 92 | tensor(double), | tensor(double), |
92 | 93 | tensor(float), | tensor(float), |
93 | 94 | tensor(float16), | tensor(float16), |
94 | 95 | tensor(int16), | tensor(int16), |
95 | 96 | tensor(int32), | tensor(int32), |
96 | 97 | tensor(int64), | tensor(int64), |
97 | 98 | tensor(int8), | tensor(int8), |
98 | 99 | tensor(string), | tensor(string), |
99 | 100 | tensor(uint16), | tensor(uint16), |
100 | 101 | tensor(uint32), | tensor(uint32), |
101 | 102 | tensor(uint64), | tensor(uint64), |
102 | 103 | tensor(uint8) | tensor(uint8) |
103 | 104 | ): | ): |
104 | 105 | Constrain input 'X' and output 'Y' to all tensor types. | Constrain input 'X' and output 'Y' to all tensor types. |
105 | 106 | * **T2** in ( | * **T2** in ( |
106 | 107 | tensor(double), | tensor(double), |
107 | 108 | tensor(float), | tensor(float), |
108 | 109 | tensor(float16) | tensor(float16) |
109 | 110 | ): | ): |
110 | 111 | Constrain roi type to float or double. | Constrain roi type to float or double. |
Resize - 11#
Version
name: Resize (GitHub)
domain: main
since_version: 11
function: False
support_level: SupportType.COMMON
shape inference: True
This version of the operator has been available since version 11.
Summary
Resize the input tensor. In general, it calculates every value in the output tensor as a weighted average of neighborhood (a.k.a. sampling locations) in the input tensor. Each dimension value of the output tensor is:
output_dimension = floor(input_dimension * (roi_end - roi_start) * scale) if input "sizes" is not specified.
Attributes
- coordinate_transformation_mode:
This attribute describes how to transform the coordinate in the
resized tensor to the coordinate in the original tensor. <br/> The coordinate of each dimension is transformed individually. Let’s describe a case using axis x as an example. Denote x_resized as the coordinate of axis x in the resized tensor, x_original as the coordinate of axis x in the original tensor, length_original as the length of the original tensor in axis x, length_resized as the length of the resized tensor in axis x, roi_x = (start_x, end_x) of the axis x in input “roi”, scale = length_resized / length_original, <br/> if coordinate_transformation_mode is “half_pixel”, <br/> x_original = (x_resized + 0.5) / scale - 0.5, <br/> if coordinate_transformation_mode is “pytorch_half_pixel”, <br/> x_original = length_resized > 1 ? (x_resized + 0.5) / scale - 0.5 : 0, <br/> if coordinate_transformation_mode is “align_corners”, <br/> x_original = x_resized * (length_original - 1) / (length_resized - 1), <br/> if coordinate_transformation_mode is “asymmetric”, <br/> x_original = x_resized / scale, <br/> if coordinate_transformation_mode is “tf_half_pixel_for_nn”, <br/> x_original = (x_resized + 0.5) / scale, <br/> if coordinate_transformation_mode is “tf_crop_and_resize”, <br/> x_original = length_resized > 1 ? start_x * (length_original - 1) + x_resized * (end_x - start_x) * (length_original - 1) / (length_resized - 1) : 0.5 * (start_x + end_x) * (length_original - 1). Default value is
'half_pixel'
.cubic_coeff_a: The coefficient ‘a’ used in cubic interpolation. Two common choice are -0.5 (in some cases of TensorFlow) and -0.75 (in PyTorch). Check out Equation (4) in https://ieeexplore.ieee.org/document/1163711 for the details. This attribute is valid only if “mode” is “cubic”. Default value is
-0.75
.exclude_outside: If set to 1, the weight of sampling locations outside the tensor will be set to 0 and the weight will be renormalized so that their sum is 1.0. The default value is 0. Default value is
0
.extrapolation_value: When coordinate_transformation_mode is “tf_crop_and_resize” and x_original is outside the range [0, length_original - 1], this value is used as the corresponding output value. Default is 0.0f. Default value is
0.0
.mode: Three interpolation modes: nearest (default), linear and cubic. The “linear” mode includes linear interpolation for 1D tensor and N-linear interpolation for N-D tensor (for example, bilinear interpolation for 2D tensor). The “cubic” mode includes cubic interpolation for 1D tensor and N-cubic interpolation for N-D tensor (for example, bicubic interpolation for 2D tensor). Default value is
'nearest'
.nearest_mode: Four modes: round_prefer_floor (default, as known as round half down), round_prefer_ceil (as known as round half up), floor, ceil. Only used by nearest interpolation. It indicates how to get “nearest” pixel in input tensor from x_original, so this attribute is valid only if “mode” is “nearest”. Default value is
'round_prefer_floor'
.
Inputs
Between 3 and 4 inputs.
X (heterogeneous) - T1: N-D tensor
roi (heterogeneous) - T2: 1-D tensor given as [start1, …, startN, end1, …, endN], where N is the rank of X. The RoIs’ coordinates are normalized in the coordinate system of the input image. It only takes effect when coordinate_transformation_mode is “tf_crop_and_resize”
scales (heterogeneous) - tensor(float): The scale array along each dimension. It takes value greater than 0. If it’s less than 1, it’s sampling down, otherwise, it’s upsampling. The number of elements of ‘scales’ should be the same as the rank of input ‘X’. If ‘size’ is needed, the user must set ‘scales’ to an empty tensor.
sizes (optional, heterogeneous) - tensor(int64): The size of the output tensor. The number of elements of ‘sizes’ should be the same as the rank of input ‘X’. May only be set if ‘scales’ is set to an empty tensor.
Outputs
Y (heterogeneous) - T1: N-D tensor after resizing
Type Constraints
T1 in ( tensor(bool), tensor(complex128), tensor(complex64), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8) ): Constrain input ‘X’ and output ‘Y’ to all tensor types.
T2 in ( tensor(double), tensor(float), tensor(float16) ): Constrain roi type to float or double.
Differences
0 | 0 | Resize the input tensor. |
|
1 | 1 | Each dimension value of the output tensor is: | Each dimension value of the output tensor is: |
2 | 2 | output_dimension = floor(input_dimension * scale). |
|
3 | 3 |
|
|
4 | 4 | **Attributes** | **Attributes** |
5 | 5 |
|
|
6 | * **coordinate_transformation_mode**: | ||
7 | This attribute describes how to transform the coordinate in the | ||
8 | resized tensor to the coordinate in the original tensor. | ||
9 | coordinate of each dimension is transformed individually. Let's | ||
10 | describe a case using axis x as an example. Denote x_resized as the | ||
11 | coordinate of axis x in the resized tensor, x_original as the | ||
12 | coordinate of axis x in the original tensor, length_original as the | ||
13 | length of the original tensor in axis x, length_resized as the | ||
14 | length of the resized tensor in axis x, roi_x = (start_x, end_x) of | ||
15 | the axis x in input "roi", scale = length_resized / length_original, | ||
16 | | ||
17 | x_original = (x_resized + 0.5) / scale - 0.5, | ||
18 | coordinate_transformation_mode is "pytorch_half_pixel", | ||
19 | x_original = length_resized > 1 ? (x_resized + 0.5) / scale - 0.5 : | ||
20 | 0, | ||
21 | | ||
22 | (length_resized - 1), | ||
23 | "asymmetric", | ||
24 | coordinate_transformation_mode is "tf_half_pixel_for_nn", | ||
25 | x_original = (x_resized + 0.5) / scale, | ||
26 | coordinate_transformation_mode is "tf_crop_and_resize", | ||
27 | x_original = length_resized > 1 ? start_x * (length_original - 1) + | ||
28 | x_resized * (end_x - start_x) * (length_original - 1) / | ||
29 | (length_resized - 1) : 0.5 * (start_x + end_x) * (length_original - | ||
30 | 1). Default value is 'half_pixel'. | ||
31 | * **cubic_coeff_a**: | ||
32 | The coefficient 'a' used in cubic interpolation. Two common choice | ||
33 | are -0.5 (in some cases of TensorFlow) and -0.75 (in PyTorch). Check | ||
34 | out Equation (4) in https://ieeexplore.ieee.org/document/1163711 for | ||
35 | the details. This attribute is valid only if "mode" is "cubic". Default value is -0.75. | ||
36 | * **exclude_outside**: | ||
37 | If set to 1, the weight of sampling locations outside the tensor | ||
38 | will be set to 0 and the weight will be renormalized so that their | ||
39 | sum is 1.0. The default value is 0. Default value is 0. | ||
40 | * **extrapolation_value**: | ||
41 | When coordinate_transformation_mode is "tf_crop_and_resize" and | ||
42 | x_original is outside the range [0, length_original - 1], this value | ||
43 | is used as the corresponding output value. Default is 0.0f. Default value is 0.0. | ||
6 | 44 | * **mode**: | * **mode**: |
7 | 45 | Two interpolation modes: nearest (default), and linear (including |
|
46 | "linear" mode includes linear interpolation for 1D tensor and | ||
47 | N-linear interpolation for N-D tensor (for example, bilinear | ||
48 | interpolation for 2D tensor). The "cubic" mode includes cubic | ||
49 | interpolation for 1D tensor and N-cubic interpolation for N-D tensor | ||
50 | (for example, bicubic interpolation for 2D tensor). Default value is 'nearest'. | ||
51 | * **nearest_mode**: | ||
52 | Four modes: round_prefer_floor (default, as known as round half | ||
53 | down), round_prefer_ceil (as known as round half up), floor, ceil. | ||
54 | Only used by nearest interpolation. It indicates how to get | ||
55 | "nearest" pixel in input tensor from x_original, so this attribute | ||
56 | is valid only if "mode" is "nearest". Default value is 'round_prefer_floor'. | ||
57 |
| ||
58 | **Inputs** | ||
59 |
| ||
8 | 60 | bilinear, trilinear, etc) Default value is 'nearest'. |
|
9 | 61 |
|
|
10 | 62 | **Inputs** |
|
11 |
| ||
63 | N-D tensor | ||
64 | * **roi** (heterogeneous) - **T2**: | ||
12 | 65 | * **X** (heterogeneous) - **T**: |
|
66 | is the rank of X. The RoIs' coordinates are normalized in the | ||
13 | 67 | N-D tensor |
|
68 | coordinate_transformation_mode is "tf_crop_and_resize" | ||
14 | 69 | * **scales** (heterogeneous) - **tensor(float)**: | * **scales** (heterogeneous) - **tensor(float)**: |
15 | 70 | The scale array along each dimension. It takes value greater than 0. | The scale array along each dimension. It takes value greater than 0. |
16 | 71 | If it's less than 1, it's sampling down, otherwise, it's upsampling. | If it's less than 1, it's sampling down, otherwise, it's upsampling. |
17 | 72 | The number of elements of 'scales' should be the same as the rank of | The number of elements of 'scales' should be the same as the rank of |
73 | input 'X'. If 'size' is needed, the user must set 'scales' to an | ||
74 | empty tensor. | ||
18 | 75 | input 'X'. |
|
76 | The size of the output tensor. The number of elements of 'sizes' | ||
77 | should be the same as the rank of input 'X'. May only be set if | ||
78 | 'scales' is set to an empty tensor. | ||
19 | 79 |
|
|
20 | 80 | **Outputs** | **Outputs** |
21 | 81 |
|
|
22 | 82 | * **Y** (heterogeneous) - **T**: |
|
23 | 83 | N-D tensor after resizing | N-D tensor after resizing |
24 | 84 |
|
|
25 | 85 | **Type Constraints** | **Type Constraints** |
26 | 86 |
|
|
27 | 87 | * **T** in ( |
|
28 | 88 | tensor(bool), | tensor(bool), |
29 | 89 | tensor(complex128), | tensor(complex128), |
30 | 90 | tensor(complex64), | tensor(complex64), |
31 | 91 | tensor(double), | tensor(double), |
32 | 92 | tensor(float), | tensor(float), |
33 | 93 | tensor(float16), | tensor(float16), |
34 | 94 | tensor(int16), | tensor(int16), |
35 | 95 | tensor(int32), | tensor(int32), |
36 | 96 | tensor(int64), | tensor(int64), |
37 | 97 | tensor(int8), | tensor(int8), |
38 | 98 | tensor(string), | tensor(string), |
39 | 99 | tensor(uint16), | tensor(uint16), |
40 | 100 | tensor(uint32), | tensor(uint32), |
41 | 101 | tensor(uint64), | tensor(uint64), |
42 | 102 | tensor(uint8) | tensor(uint8) |
43 | 103 | ): | ): |
44 | 104 | Constrain input 'X' and output 'Y' to all tensor types. | Constrain input 'X' and output 'Y' to all tensor types. |
105 | * **T2** in ( | ||
106 | tensor(double), | ||
107 | tensor(float), | ||
108 | tensor(float16) | ||
109 | ): | ||
110 | Constrain roi type to float or double. |
Resize - 10#
Version
name: Resize (GitHub)
domain: main
since_version: 10
function: False
support_level: SupportType.COMMON
shape inference: True
This version of the operator has been available since version 10.
Summary
Resize the input tensor. Each dimension value of the output tensor is:
output_dimension = floor(input_dimension * scale).
Attributes
mode: Two interpolation modes: nearest (default), and linear (including bilinear, trilinear, etc) Default value is
'nearest'
.
Inputs
X (heterogeneous) - T: N-D tensor
scales (heterogeneous) - tensor(float): The scale array along each dimension. It takes value greater than 0. If it’s less than 1, it’s sampling down, otherwise, it’s upsampling. The number of elements of ‘scales’ should be the same as the rank of input ‘X’.
Outputs
Y (heterogeneous) - T: N-D tensor after resizing
Type Constraints
T in ( tensor(bool), tensor(complex128), tensor(complex64), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8) ): Constrain input ‘X’ and output ‘Y’ to all tensor types.