From f78eef649f4e3958f93de6d78b2f463cf008396e Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EB=82=A8=EA=B6=81=EC=84=9D/=EB=8F=99=EC=9E=91=EC=A0=9C?= =?utf8?q?=EC=96=B4Lab=28SR=29/Engineer/=EC=82=BC=EC=84=B1=EC=A0=84?= =?utf8?q?=EC=9E=90?= Date: Tue, 27 Nov 2018 13:07:22 +0900 Subject: [PATCH] [tflchef] Support quantization parameters (#2379) * [tflchef] Support quantization parameters This commit will introduce quantization parameters and add related tests Signed-off-by: Seok NamKoong * modify convention and data --- contrib/tflchef/core/src/ModelChef.cpp | 41 +++++++++++++++++++++++ contrib/tflchef/proto/tflchef.proto | 9 ++++- contrib/tflchef/tests/quantization/test.recipe | 46 ++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 contrib/tflchef/tests/quantization/test.recipe diff --git a/contrib/tflchef/core/src/ModelChef.cpp b/contrib/tflchef/core/src/ModelChef.cpp index ba09cfb..1e24727 100644 --- a/contrib/tflchef/core/src/ModelChef.cpp +++ b/contrib/tflchef/core/src/ModelChef.cpp @@ -282,6 +282,45 @@ GeneratedModel cook(const ::tflchef::ModelRecipe &model_recipe) buffer_vec.emplace_back(buffer); } + flatbuffers::Offset quant_index; + + // Create QuantizationParameters if quant is specified + if (operand.has_quant()) + { + const auto &quant = operand.quant(); + + // Create each parameters + // NOTE if some parameters are not given, those will be set to default value + std::vector quant_max_vec(quant.max_size()); + std::vector quant_min_vec(quant.min_size()); + std::vector quant_scale_vec(quant.scale_size()); + std::vector quant_zero_point_vec(quant.zero_point_size()); + + for (uint32_t i = 0; i < quant.max_size(); ++i) + quant_max_vec.push_back(quant.max(i)); + for (uint32_t i = 0; i < quant.min_size(); ++i) + quant_max_vec.push_back(quant.min(i)); + for (uint32_t i = 0; i < quant.scale_size(); ++i) + quant_max_vec.push_back(quant.scale(i)); + for (uint32_t i = 0; i < quant.zero_point_size(); ++i) + quant_max_vec.push_back(quant.zero_point(i)); + + auto quant_max = flatbuffer_builder->CreateVector(quant_max_vec); + auto quant_min = flatbuffer_builder->CreateVector(quant_min_vec); + auto quant_scale = flatbuffer_builder->CreateVector(quant_scale_vec); + auto quant_zero_point = flatbuffer_builder->CreateVector(quant_zero_point_vec); + + // Create QuantizationParameters + tflite::QuantizationParametersBuilder quant_builder{*flatbuffer_builder}; + quant_builder.add_max(quant_max); + quant_builder.add_min(quant_min); + quant_builder.add_scale(quant_scale); + quant_builder.add_zero_point(quant_zero_point); + + // Update QuantizationParameters Index + quant_index = quant_builder.Finish(); + } + // Create Tensor tflite::TensorBuilder tensor_builder{*flatbuffer_builder}; @@ -289,6 +328,8 @@ GeneratedModel cook(const ::tflchef::ModelRecipe &model_recipe) tensor_builder.add_type(as_tflite_tensortype(operand.type())); tensor_builder.add_buffer(buffer_index); tensor_builder.add_name(name); + if (operand.has_quant()) + tensor_builder.add_quantization(quant_index); // Append! tensor_vec.emplace_back(tensor_builder.Finish()); diff --git a/contrib/tflchef/proto/tflchef.proto b/contrib/tflchef/proto/tflchef.proto index 8995184..781f36d 100644 --- a/contrib/tflchef/proto/tflchef.proto +++ b/contrib/tflchef/proto/tflchef.proto @@ -17,12 +17,19 @@ message TensorFiller { repeated string arg = 2; } +message TensorQuantization { + repeated float min = 1; + repeated float max = 2; + repeated float scale = 3; + repeated int64 zero_point = 4; +} + message Operand { optional string name = 1; optional TensorType type = 2; optional TensorShape shape = 3; optional TensorFiller filler = 4; - // TODO Support Quantization Parameter + optional TensorQuantization quant = 5; } // This enum value corresponds to Padding in TensorFlow Lite schema diff --git a/contrib/tflchef/tests/quantization/test.recipe b/contrib/tflchef/tests/quantization/test.recipe new file mode 100644 index 0000000..be5d222 --- /dev/null +++ b/contrib/tflchef/tests/quantization/test.recipe @@ -0,0 +1,46 @@ +operand { + name: "ifm" + type: FLOAT32 + shape { dim: 1 dim: 3 dim: 3 dim: 2 } + quant { min: 0 max: 128 scale: 2 zero_point: 2 } +} +operand { + name: "ker" + type: FLOAT32 + shape { dim: 1 dim: 1 dim: 1 dim: 2 } + filler { + tag: "gaussian" + arg: "0.0" + arg: "1.0" + } +} +operand { + name: "bias" + type: FLOAT32 + shape { dim: 1 } + filler { + tag: "gaussian" + arg: "0.0" + arg: "1.0" + } +} +operand { + name: "ofm" + type: FLOAT32 + shape { dim: 1 dim: 3 dim: 3 dim: 1 } + quant { min: 0 max: 80 scale: 1.5 zero_point: 3 } +} +operation { + type: "Conv2D" + conv2d_options { + padding: VALID + stride_w: 1 + stride_h: 1 + } + input: "ifm" + input: "ker" + input: "bias" + output: "ofm" +} +input: "ifm" +output: "ofm" -- 2.7.4