Uh oh!
There was an error while loading. Please reload this page.
[Frontend][TFlite] Add parser support for relu6, leaky_relu, relu_n1_to_1, log_softmax - #4805
Conversation
There was a problem hiding this comment.
Relu and Clip implementation does not look right.
We can keep the computation in integer domain. The way to do that is to subtract the input zero point, and then call Relu, then requantize to the output scale (only if output scale/zero point are different from input scale/zero point).
| return out | ||
| def convert_leaky_relu(self, op): | ||
| """Convert TFLite LEAKY_RELU""" |
There was a problem hiding this comment.
Not important, I think it should be """Convert TFLite Leaky_ReLU""" to align with """One iteration of Leaky_ReLU""".
| return out | ||
| def convert_relu_n1_to_1(self, op): | ||
| """Convert TFLite RELU_N1_TO_1""" |
There was a problem hiding this comment.
Not important, I think it should be """Convert TFLite ReLU_n1_to_1""" to align with """One iteration of ReLU_n1_to_1""".
tqchen
commented
Feb 26, 2020
@inadob please followup to address the review comments :) |
That's fine for the standard ReLU op but I am not entirely sure whether we can follow this logic when we apply ReLU6 and ReLU1. Is there a way to recreate them in Relay without clip?. What I did, in this case, was to shift the data by subtracting the zero point, do clip, shift back and finally requantize if needed. The problem here was that |
anijain2305
commented
Feb 28, 2020
Can you show me code example here? I have typically used float numbers like 1.0 or 6.0 to work with |
inadob
commented
Mar 5, 2020
Expr ClipQnnCanonicalize(const Attrs& attrs, const Array<Expr>& new_args,
const Array<tvm::relay::Type>& arg_types) {
CHECK_EQ(new_args.size(), 7);
auto& input_tensor = new_args[0];
auto& input_scale = new_args[1]; // in fpauto& input_zero_point = new_args[2]; // in int32auto& clip_min = new_args[3]; // value is in fpauto& clip_max = new_args[4]; // value is in fpauto& output_scale = new_args[5];
auto& output_zero_point = new_args[6];
// Get the input dtype and shape.CHECK_EQ(arg_types.size(), 8);
auto tensor_type = arg_types[0].as<TensorTypeNode>();
CHECK(tensor_type != nullptr);
auto input_dtype = tensor_type->dtype;
auto input_shape = tensor_type->shape;
// shift the input by subtracting the input zero_pointauto shifted_input = Subtract(Cast(input_tensor, DataType::Int(32)), input_zero_point);
// do the clipping in int32// auto clipped_tensor = Clip(shifted_input, clip_min, clip_max)auto clipped_tensor = Clip(shifted_input, Cast(clip_min, DataType::Float(64)), Cast(clip_max, DataType::Float(64)))
// shift the input back by adding the zero_point
clipped_tensor = Add(clipped_tensor, input_zero_point);
// requantize the output if neededauto requantized_output = clipped_tensor;
if (!IsEqualScalar(input_scale, output_scale) ||
!IsEqualScalar(input_zero_point, output_zero_point)) {
requantized_output = Requantize(clipped_tensor, input_shape, input_scale, input_zero_point, output_scale,
output_zero_point, DataType::Int(32));
}
// Go back to lower precision.auto q_min = GetQmin(input_dtype);
auto q_max = GetQmax(input_dtype);
requantized_output = Clip(requantized_output, q_min, q_max); returnCast(requantized_output, input_dtype);
}And I am getting a complaint about double dtype... The commented out line where I directly do clip() without casting to float64 didn't work too. |
tqchen
commented
Mar 30, 2020
@anijain2305@inadob please followup :) |
tqchen
commented
Apr 24, 2020
ping |
inadob
commented
Apr 28, 2020
@anijain can you please help me with the quantized operators |
Uh oh!
There was an error while loading. Please reload this page.
anijain2305
commented
May 30, 2020
Ping @inadob Let us know if you are working on this. Or else I can take a chance at this. |
@anijain2305 Yes, I am working on it - I will be ready in the next few days. Sorry for the delay |
anijain2305
commented
Jun 4, 2020
@inadob Your changes look better now. Can you please rebase? ( |
anijain2305
commented
Jun 4, 2020
It seems you still have old `3rdparty/dmlc-core'. You can check that by clicking on "Files changed" tab. |
inadob
commented
Jun 5, 2020
It's fixed now. |
anijain2305
commented
Jun 5, 2020
@inadob Can you please fix the CI error? |
anijain2305
commented
Jun 10, 2020
Ping @inadob :) |
tqchen
commented
Jun 12, 2020
Glad that it is moving, @anijain2305 please manage this PR |
…g_softmax * add implementation in parser * add qnn tests for each operator
* add 'clip' as in the quantized fused operations * remove redundant assertions and imports
4781b9e to
126361cCompareinadob
commented
Jun 16, 2020
@anijain2305 |
anijain2305
commented
Jun 16, 2020
Thanks @inadob This is merged! |
…to_1, log_softmax (apache#4805) * [Frontend][TFLite]Add support for relu6, leaky_relu, relu_n1_to_1, log_softmax * add implementation in parser * add qnn tests for each operator * Implement clip operation for quantized relu6, relu1 * add 'clip' as in the quantized fused operations * remove redundant assertions and imports * Fix floating value quantization for RELU6 and RELU1
…to_1, log_softmax (apache#4805) * [Frontend][TFLite]Add support for relu6, leaky_relu, relu_n1_to_1, log_softmax * add implementation in parser * add qnn tests for each operator * Implement clip operation for quantized relu6, relu1 * add 'clip' as in the quantized fused operations * remove redundant assertions and imports * Fix floating value quantization for RELU6 and RELU1
This patch is made on top of #4789.