-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mark scales as optional and remove tf_half_pixel_for_nn in resize op #3026
Conversation
…favor of half_pixel + round_prefer_ceil Signed-off-by: daquexian <daquexian566@gmail.com>
Signed-off-by: daquexian <daquexian566@gmail.com>
f9db08e
to
f120eff
Compare
<dt><tt>scales</tt> : tensor(float)</dt> | ||
<dd>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'. Only one of 'scales' and 'sizes' can be specified. If 'size' is specified, then set scales to empty data (zero shape) in this operator's input list.</dd> | ||
<dt><tt>scales</tt> (optional) : tensor(float)</dt> | ||
<dd>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'. Only one of 'scales' and 'sizes' can be specified. If 'size' is needed, the user can use an empty string as the name of 'scales' in this operator's input list.</dd> | ||
<dt><tt>sizes</tt> (optional) : tensor(int64)</dt> | ||
<dd>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.</dd> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since both scales and sizes are now "optional" per schema - should we go ahead and include a line that says - one of the two optional inputs MUST be specified. We already have a line that says "only one can be specified...", maybe we can say - "one of the two MUST be specified and it is an error if both are specified."
Also does the onnx checker catch cases where the Resize node has only two inputs - which means it is missing one of the two ? Also, Inputs (2-4)
- is that correct ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also does the onnx checker catch cases where the Resize node has only two inputs - which means it is missing one of the two ? Also, Inputs (2-4) - is that correct ?
Agree. But it seems like the infra (checker and doc generator) cannot support "one of these optional inputs must be specified".
docs/Operators.md
Outdated
@@ -15669,15 +15666,15 @@ x_original = length_resized > 1 ? start_x * (length_original - 1) + x_resized * | |||
<dd>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".</dd> | |||
</dl> | |||
|
|||
#### Inputs (3 - 4) | |||
#### Inputs (2 - 4) | |||
|
|||
<dl> | |||
<dt><tt>X</tt> : T1</dt> | |||
<dd>N-D tensor</dd> | |||
<dt><tt>roi</tt> : T2</dt> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not make roi optional as well? since it only takes effect when coordinate_transformation_mode is "tf_crop_and_resize"
docs/Operators.md
Outdated
@@ -15669,15 +15666,15 @@ x_original = length_resized > 1 ? start_x * (length_original - 1) + x_resized * | |||
<dd>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".</dd> | |||
</dl> | |||
|
|||
#### Inputs (3 - 4) | |||
#### Inputs (2 - 4) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be 2 to 3? Because Sizes and Scales should not be specified together right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@askhade @hariharans29 I agree that here should be 2-3, but this line is generated automatically. Is there any way to overwrite it?
@daquexian : Marking this PR for 1.8 release. Let's try and get this change checked in before 1.8 to avoid another version bump for resize. |
Signed-off-by: daquexian <daquexian566@gmail.com>
@askhade @hariharans29 I have updated the spec to "one of the two MUST be specified and it is an error if both are specified" and made the input "roi" also optional. When it comes to "input (2-4)" and the checker problem, maybe we need to update the infra to support the case "one of these optional inputs must be specified" first? |
Thanks for adding the line to the spec. It leaves no place for ambiguity atleast with the spec description. It does a look a little weird to see (2-4) when actually the correct line there must read (2-3), but looks like ONNX doesn't have the infrastructure to deal with "inter-dependence" of optional inputs/outputs (i.e.) we are not able to say - 'scales' and 'sizes' are individually optional both they are NOT both optional and both can't co-exist. So, I guess we can leave it for now and enhance the infrastructure for later. For the second aspect of the PR - deprecating |
@@ -9760,7 +9760,6 @@ data = np.array([[[ | |||
]]], dtype=np.float32) | |||
|
|||
roi = np.array([], dtype=np.float32) | |||
scales = np.array([], dtype=np.float32) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we add a test where scales exists and sizes does not ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. There are already such tests before this PR submitted (e.g., https://github.com/onnx/onnx/blob/master/onnx/backend/test/case/node/resize.py#L341) .
onnx/defs/tensor/defs.cc
Outdated
.Input( | ||
2, | ||
"scales", | ||
"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'. Only one of 'scales' and 'sizes' can be specified. If 'size' is specified, then set scales to empty data (zero shape) in this operator's input list.", | ||
" 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 'size' is needed, the user can use an empty string as the name of 'scales' in this operator's input list.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: If 'sizes' is needed (not if 'size' is needed) for consistency
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Fixed
Overall, I am good with this PR - left a couple of minor comments |
@hariharans29 Yes, it is correct. All the converter only have to replace replace 'tf_half_pixel_for_nn' with 'half_pixel' + 'round_prefer_ceil'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Signed-off-by: daquexian <daquexian566@gmail.com>
bf1a53f
to
5538783
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@daquexian : It seems the tests were not updated after roi was made optional. Can you update the test script and regenerate the tests again. Thanks!
Signed-off-by: daquexian <daquexian566@gmail.com>
Thanks. Updated. |
@daquexian : The tests are checked in with the test script. So you need to update the generated tests as well. I think you only updated the test script. |
It is true that the documentation-generator does not have infrastructure to fix the number of inputs expected. However, the type-and-shape-inference checker can be augmented to verify that exactly one of two inputs is specified. (Well, sort of ... we can do the check using both getNumInputs and getInputType; we will need to use getInputType as a proxy for whether a particular input is specified; it is not perfect, but it is reasonable. The only minor issue would be a misleading error-message in the case where an input is specified, but type-inference could not infer its type. |
Specifically: a utility function like below should help: inline bool hasInput(InferenceContext& ctx, size_t n) {
return ctx.getNumInputs() > static_cast<size_t>(n) && ctx.getInputType(n);
} We can then add a check one of the two inputs is specified. |
Shape inference code for resize needs fixes. onnx/onnx/defs/tensor/utils.cc Line 73 in 5305778
Current shape inference code will pick sizes input only if number of inputs is 4 but with roi and scales being optional inputs shape inference will fail. |
Signed-off-by: daquexian <daquexian566@gmail.com>
Signed-off-by: daquexian <daquexian566@gmail.com>
@askhade Thanks! Updated.
I don't think so. onnx/onnx/shape_inference/implementation.h Lines 59 to 65 in 88e5d3e
onnx/onnx/shape_inference/implementation.h Lines 87 to 89 in 88e5d3e
The |
Good advice! Let's merge this PR for 1.8 release and I can submit another pr for this in the future. |
mark 'scales' of the resize op as an optional input (Doc update for Resize to correct some wrong information #2948 (comment)).
remove coordinate_transformation_mode 'tf_half_pixel_for_nn'. This mode was introduced by me for resize_nearest half_pixel of tensorflow, but it is indeed unnecessary.
The equation of nearest + half_pixel is
x' = round((x + 0.5) / scale - 0.5)
, while in tf it is optimized asx' = floor((x + 0.5) / scale)
. As a result, I introduced a transformation mode 'tf_half_pixel_for_nn' for the transformation(x + 0.5) / scale
in PR Update resize op #2057.However, as shown above, it should be replaced with a plain 'half_pixel' + 'round_prefer_ceil'