Add support of maximum and minumum, similar to concat operations.

PiperOrigin-RevId: 282726065
Change-Id: I3436727d5e4131695877c8adc54eb960bb1353b0
This commit is contained in:
Suharsh Sivakumar 2019-11-27 01:56:51 -08:00 committed by TensorFlower Gardener
parent 3a91a0251b
commit 481366eab2
4 changed files with 33 additions and 21 deletions

View File

@ -31,6 +31,7 @@ def make_maximum_tests(options):
"input_dtype": [tf.float32],
"input_shape_1": [[], [3], [1, 100], [4, 2, 3], [5, 224, 224, 3]],
"input_shape_2": [[], [3], [1, 100], [4, 2, 3], [5, 224, 224, 3]],
"fully_quantize": [False, True],
}]
def build_graph(parameters):
@ -48,11 +49,18 @@ def make_maximum_tests(options):
return [input_tensor_1, input_tensor_2], [out]
def build_inputs(parameters, sess, inputs, outputs):
"""Builds the inputs for the model above."""
values = [
create_tensor_data(parameters["input_dtype"],
parameters["input_shape_1"]),
create_tensor_data(parameters["input_dtype"],
parameters["input_shape_2"])
create_tensor_data(
parameters["input_dtype"],
parameters["input_shape_1"],
min_value=-1,
max_value=1),
create_tensor_data(
parameters["input_dtype"],
parameters["input_shape_2"],
min_value=-1,
max_value=1)
]
return values, sess.run(outputs, feed_dict=dict(zip(inputs, values)))
@ -61,4 +69,4 @@ def make_maximum_tests(options):
test_parameters,
build_graph,
build_inputs,
expected_tf_failures=8)
expected_tf_failures=16)

View File

@ -31,6 +31,7 @@ def make_minimum_tests(options):
"input_dtype": [tf.float32],
"input_shape_1": [[], [3], [1, 100], [4, 2, 3], [5, 224, 224, 3]],
"input_shape_2": [[], [3], [1, 100], [4, 2, 3], [5, 224, 224, 3]],
"fully_quantize": [False, True],
}]
def build_graph(parameters):
@ -48,11 +49,18 @@ def make_minimum_tests(options):
return [input_tensor_1, input_tensor_2], [out]
def build_inputs(parameters, sess, inputs, outputs):
"""Builds the inputs for the model above."""
values = [
create_tensor_data(parameters["input_dtype"],
parameters["input_shape_1"]),
create_tensor_data(parameters["input_dtype"],
parameters["input_shape_2"])
create_tensor_data(
parameters["input_dtype"],
parameters["input_shape_1"],
min_value=-1,
max_value=1),
create_tensor_data(
parameters["input_dtype"],
parameters["input_shape_2"],
min_value=-1,
max_value=1)
]
return values, sess.run(outputs, feed_dict=dict(zip(inputs, values)))
@ -61,4 +69,4 @@ def make_minimum_tests(options):
test_parameters,
build_graph,
build_inputs,
expected_tf_failures=8)
expected_tf_failures=16)

View File

@ -265,7 +265,7 @@ OperatorProperty GetOperatorProperty(const ModelT* model, int subgraph_index,
property.version = 2;
break;
case BuiltinOperator_MAXIMUM:
property.inputs = {{0, {}}};
property.arbitrary_inputs = true;
property.outputs = {{0, {}}};
property.restrict_same_input_output_scale = true;
property.version = 2;
@ -276,7 +276,7 @@ OperatorProperty GetOperatorProperty(const ModelT* model, int subgraph_index,
property.version = 2;
break;
case BuiltinOperator_MINIMUM:
property.inputs = {{0, {}}};
property.arbitrary_inputs = true;
property.outputs = {{0, {}}};
property.restrict_same_input_output_scale = true;
property.version = 2;

View File

@ -282,10 +282,9 @@ TfLiteStatus SetInputAndOutputTypes(ModelT* model, const TensorType& input_type,
}
// Apply constraints to ops if they have any.
// We have made the restriction that for int8 quantized concat, the inputs and
// outpus must have the same scale and zero point. The other ones with
// constraints(averagepool, maxpool, gather, softmax, tanh etc) are handled in
// QuantizeWeightsAndInput.
// We have made the restriction that for int8 quantized concat, minimum, and
// maximum, the inputs and outputs must have the same scale and zero point.
// The other ones with constraints are handled in QuantizeWeightsAndInput.
TfLiteStatus ApplyConstraints(ModelT* model,
const std::unordered_set<string>& operator_names,
ErrorReporter* error_reporter) {
@ -301,7 +300,6 @@ TfLiteStatus ApplyConstraints(ModelT* model,
if (!property.quantizable) {
continue;
}
// Basically only Concat passes this check.
if (!property.arbitrary_inputs ||
!property.restrict_same_input_output_scale) {
continue;
@ -311,8 +309,7 @@ TfLiteStatus ApplyConstraints(ModelT* model,
TensorT* output_tensor = subgraph->tensors[op->outputs[0]].get();
if (!utils::QuantizationParametersExist(output_tensor)) {
error_reporter->Report(
"Unable to get scale or zero point from the tensor at %d, which "
"is the output tensor for concat.",
"Unable to get scale or zero point from the tensor at %d.",
op->outputs[0]);
return kTfLiteError;
}
@ -322,8 +319,7 @@ TfLiteStatus ApplyConstraints(ModelT* model,
TensorT* input_tensor = subgraph->tensors[op->inputs[input_idx]].get();
if (!utils::QuantizationParametersExist(input_tensor)) {
error_reporter->Report(
"Unable to get scale or zero point from tensor at %d, which is "
"an input tensor of concat.",
"Unable to get scale or zero point from tensor at %d.",
op->inputs[input_idx]);
return kTfLiteError;
}