Fix issue 22015, let Clip layer support 1-3 inputs#22100
Conversation
Let layer Clip support 1-3 inputs.
|
Thanks for the contribution @WanliZhong. As a short-term solution I think it's ok. In the long run, it cannot resolve the following |
added extra checks to min/max handling in Clip
|
Yes, this is a temporary solution. I have added such a model to verify the availability of the clip node when |
alalek
left a comment
There was a problem hiding this comment.
Thank you for contribution!
Please take a look on minor comments below.
| layerParams.set("max_value", layerParams.get<float>("max", FLT_MAX)); | ||
| float min_value = -FLT_MAX, max_value = FLT_MAX; | ||
| int input_size = node_proto.input_size(); | ||
| CV_Assert(1 <= input_size && input_size <= 3); |
There was a problem hiding this comment.
CV_Check(input_size, 1 <= input_size && input_size <= 3, "")
is preferable (more clear message in case of problem)
| TEST_P(Test_ONNX_layers, Clip) | ||
| { | ||
| testONNXModels("clip", npy); | ||
| testONNXModels("clip_init_min_max"); | ||
| } |
There was a problem hiding this comment.
Please create separate test for each model (grouping them is not a good practice).
TEST_P(Test_ONNX_layers, Clip_init_min_max)
{
testONNXModels("clip_init_min_max");
}
There was a problem hiding this comment.
Thanks, I will update the code in the next commit.
…put_size to provide a clearer message in case of problem.
|
@alalek Hi, why doesn't the workflow run automatically after the first approval? |
| if(input_size == 2) | ||
| { | ||
| if (constBlobs.find(node_proto.input(1)) != constBlobs.end()) | ||
| min_value = getBlob(node_proto, 1).at<float>(0); | ||
| else | ||
| CV_Error(Error::StsNotImplemented, "Non-constant min values in Clip are not supported"); | ||
| } | ||
|
|
||
| if(input_size == 3) | ||
| { | ||
| if (constBlobs.find(node_proto.input(1)) != constBlobs.end()) | ||
| min_value = getBlob(node_proto, 1).at<float>(0); | ||
| if (constBlobs.find(node_proto.input(2)) != constBlobs.end()) | ||
| max_value = getBlob(node_proto, 2).at<float>(0); | ||
| } |
There was a problem hiding this comment.
We could do something like:
if(input_size >= 2)
{
if (constBlobs.find(node_proto.input(1)) != constBlobs.end())
min_value = getBlob(node_proto, 1).at<float>(0);
else
CV_Error(Error::StsNotImplemented, "Non-constant min values in Clip are not supported");
}
if(input_size == 3)
{
if (constBlobs.find(node_proto.input(2)) != constBlobs.end())
max_value = getBlob(node_proto, 2).at<float>(0);
else
CV_Error(Error::StsNotImplemented, "Non-constant max values in Clip are not supported");
}
In order to print errors messages in both cases.
There was a problem hiding this comment.
Optional parameters can either be with empty name or omitted to indicate that they aren't supplied. So, we could just add a check that the name isn't empty.
There was a problem hiding this comment.
Thanks! This is indeed a better implementation and I will change it in the next commit.
|
@alalek, should this be backported to 4.x? |
|
It is a feature, so no - if there is no such requirement. |
Fix issue 22015, let Clip layer support 1-3 inputs * Fix issue 22015. Let layer Clip support 1-3 inputs. * Resolve other problems caused by modifications * Update onnx_importer.cpp added extra checks to min/max handling in Clip * Add assertions to check the size of the input * Add test for clip with min and max initializers * Separate test for "clip_init_min_max". Change the check method for input_size to provide a clearer message in case of problem. * Add tests for clip with min or max initializers * Change the implementation of getting input Co-authored-by: Vadim Pisarevsky <vadim.pisarevsky@gmail.com>



Merge with extra: opencv/opencv_extra#980
This PR will fix the issue #22015
The essence of the issue is that the
Clip layeris supposed to accept 1-3 inputs, but the implementation here is based onReLU6, which only supports attributes as parameters.opencv/modules/dnn/src/onnx/onnx_importer.cpp
Line 1935 in b19683e
Solution: When parsing the
Clip layer, theminandmaxobtained fromnode_proto.input(), instead of fromlayerParams, are passed as parameters to theReLU6. This allows theClip layerto support 1-3 inputs.