.. _l-onnx-doc-Resize: ====== Resize ====== .. contents:: :local: .. _l-onnx-op-resize-18: Resize - 18 =========== **Version** * **name**: `Resize (GitHub) `_ * **domain**: **main** * **since_version**: **18** * **function**: False * **support_level**: SupportType.COMMON * **shape inference**: True This version of the operator has been available **since version 18**. **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** * **antialias**: If set to 1, "linear" and "cubic" interpolation modes will use an antialiasing filter when downscaling. Antialiasing is achieved by stretching the resampling filter by a factor max(1, 1 / scale), which means that when downsampling, more input pixels contribute to an output pixel. Default value is ``0``. * **axes**: If provided, it specifies a subset of axes that 'roi', 'scales' and 'sizes' refer to. If not provided, all axes are assumed [0, 1, ..., r-1], where r = rank(data). Non-specified dimensions are interpreted as non-resizable. Negative value means counting dimensions from the back. Accepted range is [-r, r-1], where r = rank(data). Behavior is undefined if an axis is repeated. * **coordinate_transformation_mode**: This attribute describes how to transform the coordinate in the resized tensor to the coordinate in the original tensor.
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`,
if coordinate_transformation_mode is `"half_pixel"`,
`x_original = (x_resized + 0.5) / scale - 0.5`
if coordinate_transformation_mode is `"pytorch_half_pixel"`,
`x_original = length_resized > 1 ? (x_resized + 0.5) / scale - 0.5 : 0`
if coordinate_transformation_mode is `"align_corners"`,
`x_original = x_resized * (length_original - 1) / (length_resized - 1)`
if coordinate_transformation_mode is `"asymmetric"`,
`x_original = x_resized / scale`
if coordinate_transformation_mode is `"tf_crop_and_resize"`,
`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``. * **keep_aspect_ratio_policy**: This attribute describes how to interpret the `sizes` input with regard to keeping the original aspect ratio of the input, and it is not applicable when the `scales` input is used.
Given a set of `sizes`, associated with a subset of `axes` (explicitly provided or default), and assuming `d = axes[i]`, with `i` being the index of the provided `sizes`.
If `keep_aspect_ratio_policy` is `"stretch"`, the original aspect ratio is disregarded, and the input is resized to the specified size:
`out_size[d] = sizes[i]`
If `keep_aspect_ratio_policy` is `"not_larger"`, the sizes are adjusted so that no extent of the output is larger than the specified size, while keeping the original aspect ratio:
`scale = Min(sizes[i] / in_size[d])`
`out_size[d] = round_int(scale * in_size[i])`
If `keep_aspect_ratio_policy` is `"not_smaller"`, the sizes are adjusted so that no extent of the output is smaller than the specified size, while keeping the original aspect ratio:
`scale = Max(sizes[i] / in_size[d])`
`out_size[d] = round_int(scale * in_size[i])`
For non- resizable axes (those not specified in `axes`), the output size will be equal to the input size. Note: `round_int` stands for computing the nearest integer value, rounding halfway cases up. Default value is ``'stretch'``. * **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 or the length of axes, if provided. 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' or the length of 'axes', if provided. 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)**: Target size of the output tensor. Its interpretation depends on the 'keep_aspect_ratio_policy' value.The number of elements of 'sizes' should be the same as the rank of input 'X', or the length of 'axes', if provided. 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, lambda x, _: nearest_coeffs(x), 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, lambda x, _: nearest_coeffs(x), 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, lambda x, _: nearest_coeffs(x), 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. 2. 4.]]]] output = interpolate_nd( data, lambda x, _: nearest_coeffs(x), 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, lambda x, _: linear_coeffs(x), 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, lambda x, _: linear_coeffs(x), 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, lambda x, _: linear_coeffs(x), 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, lambda x, _: linear_coeffs(x), 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, lambda x, _: cubic_coeffs(x), 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, lambda x, _: cubic_coeffs(x), 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, lambda x, _: cubic_coeffs(x), 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, lambda x, _: cubic_coeffs(x), 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, lambda x, _: cubic_coeffs(x), 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, lambda x, _: cubic_coeffs(x), 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, lambda x, _: linear_coeffs(x), 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, lambda x, _: linear_coeffs(x), 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, lambda x, _: linear_coeffs(x), 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", ) **_resize_downsample_scales_linear_antialias** :: node = onnx.helper.make_node( "Resize", inputs=["X", "", "scales"], outputs=["Y"], mode="linear", antialias=1, ) 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.6, 0.6], dtype=np.float32) # [[[[ 2.875 4.5 ] # [ 9.375 11. ]]]] output = interpolate_nd( data, linear_coeffs_antialias, scale_factors=scales ).astype(np.float32) expect( node, inputs=[data, scales], outputs=[output], name="test_resize_downsample_scales_linear_antialias", ) **_resize_downsample_sizes_linear_antialias** :: node = onnx.helper.make_node( "Resize", inputs=["X", "", "", "sizes"], outputs=["Y"], mode="linear", antialias=1, ) 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) # [[[[ 2.3636363 3.590909 4.818182 ] # [ 7.2727275 8.5 9.727273 ] # [12.181818 13.409091 14.636364 ]]]] output = interpolate_nd( data, linear_coeffs_antialias, output_size=sizes ).astype(np.float32) expect( node, inputs=[data, sizes], outputs=[output], name="test_resize_downsample_sizes_linear_antialias", ) **_resize_downsample_scales_cubic_antialias** :: node = onnx.helper.make_node( "Resize", inputs=["X", "", "scales"], outputs=["Y"], mode="cubic", antialias=1, ) 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.6, 0.6], dtype=np.float32) # [[[[ 2.5180721 4.2858863] # [ 9.589329 11.357142 ]]]] output = interpolate_nd( data, cubic_coeffs_antialias, scale_factors=scales ).astype(np.float32) expect( node, inputs=[data, scales], outputs=[output], name="test_resize_downsample_scales_cubic_antialias", ) **_resize_downsample_sizes_cubic_antialias** :: node = onnx.helper.make_node( "Resize", inputs=["X", "", "", "sizes"], outputs=["Y"], mode="cubic", antialias=1, ) 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.7750092 3.1200073 4.4650054] # [ 7.1550016 8.5 9.844998 ] # [12.534994 13.8799925 15.224991 ]]]] output = interpolate_nd(data, cubic_coeffs_antialias, output_size=sizes).astype( np.float32 ) expect( node, inputs=[data, sizes], outputs=[output], name="test_resize_downsample_sizes_cubic_antialias", ) **_resize_upsample_scales_nearest_axes_2_3** :: axes = [2, 3] node = onnx.helper.make_node( "Resize", inputs=["X", "", "scales"], outputs=["Y"], mode="nearest", axes=axes, ) data = np.array( [ [ [ [1, 2], [3, 4], ] ] ], dtype=np.float32, ) scales = np.array([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, lambda x, _: nearest_coeffs(x), scale_factors=scales, axes=axes ).astype(np.float32) expect( node, inputs=[data, scales], outputs=[output], name="test_resize_upsample_scales_nearest_axes_2_3", ) **_resize_upsample_scales_nearest_axes_3_2** :: axes = [3, 2] node = onnx.helper.make_node( "Resize", inputs=["X", "", "scales"], outputs=["Y"], mode="nearest", axes=axes, ) data = np.array( [ [ [ [1, 2], [3, 4], ] ] ], dtype=np.float32, ) scales = np.array([3.0, 2.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, lambda x, _: nearest_coeffs(x), scale_factors=scales, axes=axes ).astype(np.float32) expect( node, inputs=[data, scales], outputs=[output], name="test_resize_upsample_scales_nearest_axes_3_2", ) **_resize_upsample_sizes_nearest_axes_2_3** :: axes = [2, 3] node = onnx.helper.make_node( "Resize", inputs=["X", "", "", "sizes"], outputs=["Y"], mode="nearest", axes=axes, ) data = np.array( [ [ [ [1, 2], [3, 4], ] ] ], dtype=np.float32, ) sizes = np.array([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, lambda x, _: nearest_coeffs(x), output_size=sizes, axes=axes ).astype(np.float32) expect( node, inputs=[data, sizes], outputs=[output], name="test_resize_upsample_sizes_nearest_axes_2_3", ) **_resize_upsample_sizes_nearest_axes_3_2** :: axes = [3, 2] node = onnx.helper.make_node( "Resize", inputs=["X", "", "", "sizes"], outputs=["Y"], mode="nearest", axes=axes, ) data = np.array( [ [ [ [1, 2], [3, 4], ] ] ], dtype=np.float32, ) sizes = np.array([8, 7], 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, lambda x, _: nearest_coeffs(x), output_size=sizes, axes=axes ).astype(np.float32) expect( node, inputs=[data, sizes], outputs=[output], name="test_resize_upsample_sizes_nearest_axes_3_2", ) **_resize_tf_crop_and_resize_axes_2_3** :: axes = [2, 3] node = onnx.helper.make_node( "Resize", inputs=["X", "roi", "", "sizes"], outputs=["Y"], mode="linear", coordinate_transformation_mode="tf_crop_and_resize", axes=axes, ) 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.4, 0.6, 0.6, 0.8], dtype=np.float32) sizes = np.array([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, lambda x, _: linear_coeffs(x), output_size=sizes, roi=roi, axes=axes, 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_axes_2_3", ) **_resize_tf_crop_and_resize_axes_3_2** :: axes = [3, 2] node = onnx.helper.make_node( "Resize", inputs=["X", "roi", "", "sizes"], outputs=["Y"], mode="linear", coordinate_transformation_mode="tf_crop_and_resize", axes=axes, ) 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.6, 0.4, 0.8, 0.6], dtype=np.float32) sizes = np.array([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, lambda x, _: linear_coeffs(x), output_size=sizes, roi=roi, axes=axes, 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_axes_3_2", ) **_resize_upsample_sizes_nearest_not_larger** :: keep_aspect_ratio_policy = "not_larger" axes = [2, 3] node = onnx.helper.make_node( "Resize", inputs=["X", "", "", "sizes"], outputs=["Y"], mode="nearest", axes=axes, keep_aspect_ratio_policy=keep_aspect_ratio_policy, ) data = np.array( [ [ [ [1, 2], [3, 4], ] ] ], dtype=np.float32, ) sizes = np.array([7, 8], dtype=np.int64) # Results in 7x7 # [[[[1. 1. 1. 1. 2. 2. 2.] # [1. 1. 1. 1. 2. 2. 2.] # [1. 1. 1. 1. 2. 2. 2.] # [1. 1. 1. 1. 2. 2. 2.] # [3. 3. 3. 3. 4. 4. 4.] # [3. 3. 3. 3. 4. 4. 4.] # [3. 3. 3. 3. 4. 4. 4.]]]] output = interpolate_nd( data, lambda x, _: nearest_coeffs(x), output_size=sizes, axes=axes, keep_aspect_ratio_policy=keep_aspect_ratio_policy, ).astype(np.float32) expect( node, inputs=[data, sizes], outputs=[output], name="test_resize_upsample_sizes_nearest_not_larger", ) **_resize_upsample_sizes_nearest_not_smaller** :: keep_aspect_ratio_policy = "not_smaller" axes = [2, 3] node = onnx.helper.make_node( "Resize", inputs=["X", "", "", "sizes"], outputs=["Y"], mode="nearest", axes=axes, keep_aspect_ratio_policy=keep_aspect_ratio_policy, ) data = np.array( [ [ [ [1, 2], [3, 4], ] ] ], dtype=np.float32, ) sizes = np.array([7, 8], dtype=np.int64) # Results in 8x8 # [[[[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, lambda x, _: nearest_coeffs(x), output_size=sizes, axes=axes, keep_aspect_ratio_policy=keep_aspect_ratio_policy, ).astype(np.float32) expect( node, inputs=[data, sizes], outputs=[output], name="test_resize_upsample_sizes_nearest_not_larger", ) **_resize_downsample_sizes_nearest_not_larger** :: keep_aspect_ratio_policy = "not_larger" axes = [2, 3] node = onnx.helper.make_node( "Resize", inputs=["X", "", "", "sizes"], outputs=["Y"], mode="nearest", axes=axes, keep_aspect_ratio_policy=keep_aspect_ratio_policy, ) data = np.array( [ [ [ [1, 2, 3, 4], [5, 6, 7, 8], ] ] ], dtype=np.float32, ) sizes = np.array([1, 3], dtype=np.int64) # Results in 1x2 # [[[[1. 3.]]]] output = interpolate_nd( data, lambda x, _: nearest_coeffs(x), output_size=sizes, axes=axes, keep_aspect_ratio_policy=keep_aspect_ratio_policy, ).astype(np.float32) expect( node, inputs=[data, sizes], outputs=[output], name="test_resize_downsample_sizes_nearest_not_larger", ) **_resize_downsample_sizes_nearest_not_smaller** :: keep_aspect_ratio_policy = "not_smaller" axes = [2, 3] node = onnx.helper.make_node( "Resize", inputs=["X", "", "", "sizes"], outputs=["Y"], mode="nearest", axes=axes, keep_aspect_ratio_policy=keep_aspect_ratio_policy, ) data = np.array( [ [ [ [1, 2, 3, 4], [5, 6, 7, 8], ] ] ], dtype=np.float32, ) sizes = np.array([1, 3], dtype=np.int64) # Results in 2x3 # [[[[1. 2. 4.] # [5. 6. 8.]]]] output = interpolate_nd( data, lambda x, _: nearest_coeffs(x), output_size=sizes, axes=axes, keep_aspect_ratio_policy=keep_aspect_ratio_policy, ).astype(np.float32) expect( node, inputs=[data, sizes], outputs=[output], name="test_resize_downsample_sizes_nearest_not_smaller", ) **Differences** .. raw:: html
00Resize 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.
11Each dimension value of the output tensor is:Each dimension value of the output tensor is: <br/>
22 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) <br/>
3if input \"sizes\" is not specified.
34
45**Attributes****Attributes**
56
7* **antialias**:
8 If set to 1, "linear" and "cubic" interpolation modes will use an
9 antialiasing filter when downscaling. Antialiasing is achieved by
10 stretching the resampling filter by a factor max(1, 1 / scale),
11 which means that when downsampling, more input pixels contribute to
12 an output pixel. Default value is 0.
13* **axes**:
14 If provided, it specifies a subset of axes that 'roi', 'scales' and
15 'sizes' refer to. If not provided, all axes are assumed [0, 1, ...,
16 r-1], where r = rank(data). Non-specified dimensions are interpreted
17 as non-resizable. Negative value means counting dimensions from the
18 back. Accepted range is [-r, r-1], where r = rank(data). Behavior is
19 undefined if an axis is repeated.
620* **coordinate_transformation_mode**:* **coordinate_transformation_mode**:
721 This attribute describes how to transform the coordinate in the This attribute describes how to transform the coordinate in the
822 resized tensor to the coordinate in the original tensor.
The
resized tensor to the coordinate in the original tensor.
The
923 coordinate of each dimension is transformed individually. Let's coordinate of each dimension is transformed individually. Let's
1024 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
1125 coordinate of axis x in the resized tensor, x_original as the coordinate of axis x in the resized tensor, x_original as the
1226 coordinate of axis x in the original tensor, length_original as the coordinate of axis x in the original tensor, length_original as
1327 length of the original tensor in axis x, length_resized as the the length of the original tensor in axis x, length_resized as the
1428 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
1529 the axis x in input "roi", scale = length_resized / length_original, the axis x in input "roi", scale = length_resized /
1630
if coordinate_transformation_mode is "half_pixel", <br/>
length_original,
if coordinate_transformation_mode is
1731 x_original = (x_resized + 0.5) / scale - 0.5, <br/> if "half_pixel", <br/> x_original = (x_resized + 0.5) / scale - 0.5
1832 coordinate_transformation_mode is "pytorch_half_pixel", <br/> <br/> if coordinate_transformation_mode is "pytorch_half_pixel",
1933 x_original = length_resized > 1 ? (x_resized + 0.5) / scale - 0.5 : <br/> x_original = length_resized > 1 ? (x_resized + 0.5) / scale -
2034 0,
if coordinate_transformation_mode is "align_corners",
0.5 : 0
if coordinate_transformation_mode is
2135
x_original = x_resized * (length_original - 1) /
"align_corners",
x_original = x_resized * (length_original
36 - 1) / (length_resized - 1)
if
37 coordinate_transformation_mode is "asymmetric",
x_original
2238 (length_resized - 1),
if coordinate_transformation_mode is
= x_resized / scale
if coordinate_transformation_mode is
2339 "asymmetric",
x_original = x_resized / scale, <br/> if
"tf_crop_and_resize",
x_original = length_resized > 1 ?
24 coordinate_transformation_mode is "tf_crop_and_resize",
25 x_original = length_resized > 1 ? start_x * (length_original - 1) +
2640 x_resized * (end_x - start_x) * (length_original - 1) / start_x * (length_original - 1) + x_resized * (end_x - start_x) *
2741 (length_resized - 1) : 0.5 * (start_x + end_x) * (length_original - (length_original - 1) / (length_resized - 1) : 0.5 * (start_x +
2842 1). Default value is 'half_pixel'. end_x) * (length_original - 1) . Default value is 'half_pixel'.
2943* **cubic_coeff_a**:* **cubic_coeff_a**:
3044 The coefficient 'a' used in cubic interpolation. Two common choice The coefficient 'a' used in cubic interpolation. Two common choice
3145 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
3246 out Equation (4) in https://ieeexplore.ieee.org/document/1163711 for out Equation (4) in https://ieeexplore.ieee.org/document/1163711 for
3347 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.
3448* **exclude_outside**:* **exclude_outside**:
3549 If set to 1, the weight of sampling locations outside the tensor If set to 1, the weight of sampling locations outside the tensor
3650 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
3751 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.
3852* **extrapolation_value**:* **extrapolation_value**:
3953 When coordinate_transformation_mode is "tf_crop_and_resize" and When coordinate_transformation_mode is "tf_crop_and_resize" and
4054 x_original is outside the range [0, length_original - 1], this value x_original is outside the range [0, length_original - 1], this value
4155 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.
56* **keep_aspect_ratio_policy**:
57 This attribute describes how to interpret the sizes input with
58 regard to keeping the original aspect ratio of the input, and it is
59 not applicable when the scales input is used.
Given a set
60 of sizes, associated with a subset of axes (explicitly provided
61 or default), and assuming d = axes[i], with i being the index of
62 the provided sizes.
If keep_aspect_ratio_policy is
63 "stretch", the original aspect ratio is disregarded, and the input
64 is resized to the specified size:
out_size[d] = sizes[i]
65
If keep_aspect_ratio_policy is "not_larger", the sizes
66 are adjusted so that no extent of the output is larger than the
67 specified size, while keeping the original aspect ratio:
68 scale = Min(sizes[i] / in_size[d])
out_size[d] =
69 round_int(scale * in_size[i])
If keep_aspect_ratio_policy
70 is "not_smaller", the sizes are adjusted so that no extent of the
71 output is smaller than the specified size, while keeping the
72 original aspect ratio:
scale = Max(sizes[i] / in_size[d])
73
out_size[d] = round_int(scale * in_size[i])
For non-
74 resizable axes (those not specified in axes), the output size will
75 be equal to the input size. Note: round_int stands for computing
76 the nearest integer value, rounding halfway cases up. Default value is 'stretch'.
4277* **mode**:* **mode**:
4378 Three interpolation modes: nearest (default), linear and cubic. The Three interpolation modes: "nearest" (default), "linear" and
4479 "linear" mode includes linear interpolation for 1D tensor and "cubic". The "linear" mode includes linear interpolation for 1D
4580 N-linear interpolation for N-D tensor (for example, bilinear tensor and N-linear interpolation for N-D tensor (for example,
4681 interpolation for 2D tensor). The "cubic" mode includes cubic bilinear interpolation for 2D tensor). The "cubic" mode includes
4782 interpolation for 1D tensor and N-cubic interpolation for N-D tensor cubic interpolation for 1D tensor and N-cubic interpolation for N-D
4883 (for example, bicubic interpolation for 2D tensor). Default value is 'nearest'. tensor (for example, bicubic interpolation for 2D tensor). Default value is 'nearest'.
4984* **nearest_mode**:* **nearest_mode**:
5085 Four modes: round_prefer_floor (default, as known as round half Four modes: "round_prefer_floor" (default, as known as round half
5186 down), round_prefer_ceil (as known as round half up), floor, ceil. down), "round_prefer_ceil" (as known as round half up), "floor",
5287 Only used by nearest interpolation. It indicates how to get "ceil". Only used by nearest interpolation. It indicates how to get
5388 "nearest" pixel in input tensor from x_original, so this attribute "nearest" pixel in input tensor from x_original, so this attribute
5489 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'.
5590
5691**Inputs****Inputs**
5792
5893Between 1 and 4 inputs.Between 1 and 4 inputs.
5994
6095* **X** (heterogeneous) - **T1**:* **X** (heterogeneous) - **T1**:
6196 N-D tensor N-D tensor
6297* **roi** (optional, heterogeneous) - **T2**:* **roi** (optional, heterogeneous) - **T2**:
6398 1-D tensor given as [start1, ..., startN, end1, ..., endN], where N 1-D tensor given as [start1, ..., startN, end1, ..., endN], where N
6499 is the rank of X. The RoIs' coordinates are normalized in the is the rank of X or the length of axes, if provided. The RoIs'
65100 coordinate system of the input image. It only takes effect when coordinates are normalized in the coordinate system of the input
101 image. It only takes effect when coordinate_transformation_mode is
66102 coordinate_transformation_mode is "tf_crop_and_resize" "tf_crop_and_resize"
67103* **scales** (optional, heterogeneous) - **tensor(float)**:* **scales** (optional, heterogeneous) - **tensor(float)**:
68104 The scale array along each dimension. It takes value greater than 0. The scale array along each dimension. It takes value greater than 0.
69105 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.
70106 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
107 input 'X' or the length of 'axes', if provided. One of 'scales' and
71108 input 'X'. One of 'scales' and 'sizes' MUST be specified and it is 'sizes' MUST be specified and it is an error if both are specified.
72109 an error if both are specified. If 'sizes' is needed, the user can If 'sizes' is needed, the user can use an empty string as the name
73110 use an empty string as the name of 'scales' in this operator's input of 'scales' in this operator's input list.
74 list.
75111* **sizes** (optional, heterogeneous) - **tensor(int64)**:* **sizes** (optional, heterogeneous) - **tensor(int64)**:
76112 The size of the output tensor. The number of elements of 'sizes' Target size of the output tensor. Its interpretation depends on the
113 'keep_aspect_ratio_policy' value.The number of elements of 'sizes'
77114 should be the same as the rank of input 'X'. Only one of 'scales' should be the same as the rank of input 'X', or the length of
78115 and 'sizes' can be specified. 'axes', if provided. Only one of 'scales' and 'sizes' can be
116 specified.
79117
80118**Outputs****Outputs**
81119
82120* **Y** (heterogeneous) - **T1**:* **Y** (heterogeneous) - **T1**:
83121 N-D tensor after resizing N-D tensor after resizing
84122
85123**Type Constraints****Type Constraints**
86124
87125* **T1** in (* **T1** in (
88126 tensor(bfloat16), tensor(bfloat16),
89127 tensor(bool), tensor(bool),
90128 tensor(complex128), tensor(complex128),
91129 tensor(complex64), tensor(complex64),
92130 tensor(double), tensor(double),
93131 tensor(float), tensor(float),
94132 tensor(float16), tensor(float16),
95133 tensor(int16), tensor(int16),
96134 tensor(int32), tensor(int32),
97135 tensor(int64), tensor(int64),
98136 tensor(int8), tensor(int8),
99137 tensor(string), tensor(string),
100138 tensor(uint16), tensor(uint16),
101139 tensor(uint32), tensor(uint32),
102140 tensor(uint64), tensor(uint64),
103141 tensor(uint8) tensor(uint8)
104142 ): ):
105143 Constrain input 'X' and output 'Y' to all tensor types. Constrain input 'X' and output 'Y' to all tensor types.
106144* **T2** in (* **T2** in (
107145 tensor(double), tensor(double),
108146 tensor(float), tensor(float),
109147 tensor(float16) tensor(float16)
110148 ): ):
111149 Constrain roi type to float or double. Constrain roi type to float or double.
.. _l-onnx-op-resize-13: 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.
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,
if coordinate_transformation_mode is "half_pixel",
x_original = (x_resized + 0.5) / scale - 0.5,
if coordinate_transformation_mode is "pytorch_half_pixel",
x_original = length_resized > 1 ? (x_resized + 0.5) / scale - 0.5 : 0,
if coordinate_transformation_mode is "align_corners",
x_original = x_resized * (length_original - 1) / (length_resized - 1),
if coordinate_transformation_mode is "asymmetric",
x_original = x_resized / scale,
if coordinate_transformation_mode is "tf_crop_and_resize",
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. **Differences** .. raw:: html
00Resize 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.
11Each dimension value of the output tensor is:Each dimension value of the output tensor is:
22 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.
33
44**Attributes****Attributes**
55
66* **coordinate_transformation_mode**:* **coordinate_transformation_mode**:
77 This attribute describes how to transform the coordinate in the This attribute describes how to transform the coordinate in the
88 resized tensor to the coordinate in the original tensor.
The
resized tensor to the coordinate in the original tensor.
The
99 coordinate of each dimension is transformed individually. Let's coordinate of each dimension is transformed individually. Let's
1010 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
1111 coordinate of axis x in the resized tensor, x_original as the coordinate of axis x in the resized tensor, x_original as the
1212 coordinate of axis x in the original tensor, length_original as the coordinate of axis x in the original tensor, length_original as the
1313 length of the original tensor in axis x, length_resized as the length of the original tensor in axis x, length_resized as the
1414 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
1515 the axis x in input "roi", scale = length_resized / length_original, the axis x in input "roi", scale = length_resized / length_original,
1616
if coordinate_transformation_mode is "half_pixel",

if coordinate_transformation_mode is "half_pixel",
1717 x_original = (x_resized + 0.5) / scale - 0.5,
if
x_original = (x_resized + 0.5) / scale - 0.5,
if
1818 coordinate_transformation_mode is "pytorch_half_pixel",
coordinate_transformation_mode is "pytorch_half_pixel",
1919 x_original = length_resized > 1 ? (x_resized + 0.5) / scale - 0.5 : x_original = length_resized > 1 ? (x_resized + 0.5) / scale - 0.5 :
2020 0,
if coordinate_transformation_mode is "align_corners",
0,
if coordinate_transformation_mode is "align_corners",
2121
x_original = x_resized * (length_original - 1) /

x_original = x_resized * (length_original - 1) /
2222 (length_resized - 1),
if coordinate_transformation_mode is
(length_resized - 1),
if coordinate_transformation_mode is
2323 "asymmetric",
x_original = x_resized / scale,
if
"asymmetric",
x_original = x_resized / scale,
if
24 coordinate_transformation_mode is "tf_half_pixel_for_nn",
25 x_original = (x_resized + 0.5) / scale,
if
2624 coordinate_transformation_mode is "tf_crop_and_resize",
coordinate_transformation_mode is "tf_crop_and_resize",
2725 x_original = length_resized > 1 ? start_x * (length_original - 1) + x_original = length_resized > 1 ? start_x * (length_original - 1) +
2826 x_resized * (end_x - start_x) * (length_original - 1) / x_resized * (end_x - start_x) * (length_original - 1) /
2927 (length_resized - 1) : 0.5 * (start_x + end_x) * (length_original - (length_resized - 1) : 0.5 * (start_x + end_x) * (length_original -
3028 1). Default value is 'half_pixel'. 1). Default value is 'half_pixel'.
3129* **cubic_coeff_a**:* **cubic_coeff_a**:
3230 The coefficient 'a' used in cubic interpolation. Two common choice The coefficient 'a' used in cubic interpolation. Two common choice
3331 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
3432 out Equation (4) in https://ieeexplore.ieee.org/document/1163711 for out Equation (4) in https://ieeexplore.ieee.org/document/1163711 for
3533 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.
3634* **exclude_outside**:* **exclude_outside**:
3735 If set to 1, the weight of sampling locations outside the tensor If set to 1, the weight of sampling locations outside the tensor
3836 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
3937 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.
4038* **extrapolation_value**:* **extrapolation_value**:
4139 When coordinate_transformation_mode is "tf_crop_and_resize" and When coordinate_transformation_mode is "tf_crop_and_resize" and
4240 x_original is outside the range [0, length_original - 1], this value x_original is outside the range [0, length_original - 1], this value
4341 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.
4442* **mode**:* **mode**:
4543 Three interpolation modes: nearest (default), linear and cubic. The Three interpolation modes: nearest (default), linear and cubic. The
4644 "linear" mode includes linear interpolation for 1D tensor and "linear" mode includes linear interpolation for 1D tensor and
4745 N-linear interpolation for N-D tensor (for example, bilinear N-linear interpolation for N-D tensor (for example, bilinear
4846 interpolation for 2D tensor). The "cubic" mode includes cubic interpolation for 2D tensor). The "cubic" mode includes cubic
4947 interpolation for 1D tensor and N-cubic interpolation for N-D tensor interpolation for 1D tensor and N-cubic interpolation for N-D tensor
5048 (for example, bicubic interpolation for 2D tensor). Default value is 'nearest'. (for example, bicubic interpolation for 2D tensor). Default value is 'nearest'.
5149* **nearest_mode**:* **nearest_mode**:
5250 Four modes: round_prefer_floor (default, as known as round half Four modes: round_prefer_floor (default, as known as round half
5351 down), round_prefer_ceil (as known as round half up), floor, ceil. down), round_prefer_ceil (as known as round half up), floor, ceil.
5452 Only used by nearest interpolation. It indicates how to get Only used by nearest interpolation. It indicates how to get
5553 "nearest" pixel in input tensor from x_original, so this attribute "nearest" pixel in input tensor from x_original, so this attribute
5654 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'.
5755
5856**Inputs****Inputs**
5957
6058Between 3 and 4 inputs.Between 1 and 4 inputs.
6159
6260* **X** (heterogeneous) - **T1**:* **X** (heterogeneous) - **T1**:
6361 N-D tensor N-D tensor
6462* **roi** (heterogeneous) - **T2**:* **roi** (optional, heterogeneous) - **T2**:
6563 1-D tensor given as [start1, ..., startN, end1, ..., endN], where N 1-D tensor given as [start1, ..., startN, end1, ..., endN], where N
6664 is the rank of X. The RoIs' coordinates are normalized in the is the rank of X. The RoIs' coordinates are normalized in the
6765 coordinate system of the input image. It only takes effect when coordinate system of the input image. It only takes effect when
6866 coordinate_transformation_mode is "tf_crop_and_resize" coordinate_transformation_mode is "tf_crop_and_resize"
6967* **scales** (heterogeneous) - **tensor(float)**:* **scales** (optional, heterogeneous) - **tensor(float)**:
7068 The scale array along each dimension. It takes value greater than 0. The scale array along each dimension. It takes value greater than 0.
7169 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.
7270 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
7372 input 'X'. If 'size' is needed, the user must set 'scales' to an an error if both are specified. If 'sizes' is needed, the user can
7473 empty tensor. use an empty string as the name of 'scales' in this operator's input
74 list.
7575* **sizes** (optional, heterogeneous) - **tensor(int64)**:* **sizes** (optional, heterogeneous) - **tensor(int64)**:
7676 The size of the output tensor. The number of elements of 'sizes' The size of the output tensor. The number of elements of 'sizes'
7777 should be the same as the rank of input 'X'. May only be set if should be the same as the rank of input 'X'. Only one of 'scales'
78 'scales' is set to an empty tensor.
78 and 'sizes' can be specified.
7979
8080**Outputs****Outputs**
8181
8282* **Y** (heterogeneous) - **T1**:* **Y** (heterogeneous) - **T1**:
8383 N-D tensor after resizing N-D tensor after resizing
8484
8585**Type Constraints****Type Constraints**
8686
8787* **T1** in (* **T1** in (
88 tensor(bfloat16),
8889 tensor(bool), tensor(bool),
8990 tensor(complex128), tensor(complex128),
9091 tensor(complex64), tensor(complex64),
9192 tensor(double), tensor(double),
9293 tensor(float), tensor(float),
9394 tensor(float16), tensor(float16),
9495 tensor(int16), tensor(int16),
9596 tensor(int32), tensor(int32),
9697 tensor(int64), tensor(int64),
9798 tensor(int8), tensor(int8),
9899 tensor(string), tensor(string),
99100 tensor(uint16), tensor(uint16),
100101 tensor(uint32), tensor(uint32),
101102 tensor(uint64), tensor(uint64),
102103 tensor(uint8) tensor(uint8)
103104 ): ):
104105 Constrain input 'X' and output 'Y' to all tensor types. Constrain input 'X' and output 'Y' to all tensor types.
105106* **T2** in (* **T2** in (
106107 tensor(double), tensor(double),
107108 tensor(float), tensor(float),
108109 tensor(float16) tensor(float16)
109110 ): ):
110111 Constrain roi type to float or double. Constrain roi type to float or double.
.. _l-onnx-op-resize-11: 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.
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,
if coordinate_transformation_mode is "half_pixel",
x_original = (x_resized + 0.5) / scale - 0.5,
if coordinate_transformation_mode is "pytorch_half_pixel",
x_original = length_resized > 1 ? (x_resized + 0.5) / scale - 0.5 : 0,
if coordinate_transformation_mode is "align_corners",
x_original = x_resized * (length_original - 1) / (length_resized - 1),
if coordinate_transformation_mode is "asymmetric",
x_original = x_resized / scale,
if coordinate_transformation_mode is "tf_half_pixel_for_nn",
x_original = (x_resized + 0.5) / scale,
if coordinate_transformation_mode is "tf_crop_and_resize",
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** .. raw:: html
00Resize 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.
11Each dimension value of the output tensor is:Each dimension value of the output tensor is:
22 output_dimension = floor(input_dimension * scale). output_dimension = floor(input_dimension * (roi_end - roi_start) * scale) if input \"sizes\" is not specified.
33
44**Attributes****Attributes**
55
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.
The
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
if coordinate_transformation_mode is "half_pixel",
17 x_original = (x_resized + 0.5) / scale - 0.5,
if
18 coordinate_transformation_mode is "pytorch_half_pixel",
19 x_original = length_resized > 1 ? (x_resized + 0.5) / scale - 0.5 :
20 0,
if coordinate_transformation_mode is "align_corners",
21
x_original = x_resized * (length_original - 1) /
22 (length_resized - 1),
if coordinate_transformation_mode is
23 "asymmetric",
x_original = x_resized / scale,
if
24 coordinate_transformation_mode is "tf_half_pixel_for_nn",
25 x_original = (x_resized + 0.5) / scale,
if
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.
644* **mode**:* **mode**:
745 Two interpolation modes: nearest (default), and linear (including Three interpolation modes: nearest (default), linear and cubic. The
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
860 bilinear, trilinear, etc) Default value is 'nearest'.Between 3 and 4 inputs.
961
1062**Inputs*** **X** (heterogeneous) - **T1**:
11
63 N-D tensor
64* **roi** (heterogeneous) - **T2**:
1265* **X** (heterogeneous) - **T**: 1-D tensor given as [start1, ..., startN, end1, ..., endN], where N
66 is the rank of X. The RoIs' coordinates are normalized in the
1367 N-D tensor coordinate system of the input image. It only takes effect when
68 coordinate_transformation_mode is "tf_crop_and_resize"
1469* **scales** (heterogeneous) - **tensor(float)**:* **scales** (heterogeneous) - **tensor(float)**:
1570 The scale array along each dimension. It takes value greater than 0. The scale array along each dimension. It takes value greater than 0.
1671 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.
1772 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.
1875 input 'X'.* **sizes** (optional, heterogeneous) - **tensor(int64)**:
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.
1979
2080**Outputs****Outputs**
2181
2282* **Y** (heterogeneous) - **T**:* **Y** (heterogeneous) - **T1**:
2383 N-D tensor after resizing N-D tensor after resizing
2484
2585**Type Constraints****Type Constraints**
2686
2787* **T** in (* **T1** in (
2888 tensor(bool), tensor(bool),
2989 tensor(complex128), tensor(complex128),
3090 tensor(complex64), tensor(complex64),
3191 tensor(double), tensor(double),
3292 tensor(float), tensor(float),
3393 tensor(float16), tensor(float16),
3494 tensor(int16), tensor(int16),
3595 tensor(int32), tensor(int32),
3696 tensor(int64), tensor(int64),
3797 tensor(int8), tensor(int8),
3898 tensor(string), tensor(string),
3999 tensor(uint16), tensor(uint16),
40100 tensor(uint32), tensor(uint32),
41101 tensor(uint64), tensor(uint64),
42102 tensor(uint8) tensor(uint8)
43103 ): ):
44104 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.
.. _l-onnx-op-resize-10: 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.