提交 5b69b26b 编写于 作者: B Bin Li

Convert quantized concat to the same range

上级 416a7885
...@@ -44,8 +44,8 @@ struct ConcatFunctor : ConcatFunctorBase { ...@@ -44,8 +44,8 @@ struct ConcatFunctor : ConcatFunctorBase {
: ConcatFunctorBase(context, axis) {} : ConcatFunctorBase(context, axis) {}
MaceStatus operator()(const std::vector<const Tensor *> &input_list, MaceStatus operator()(const std::vector<const Tensor *> &input_list,
Tensor *output, Tensor *output,
StatsFuture *future) { StatsFuture *future) {
MACE_UNUSED(future); MACE_UNUSED(future);
const Tensor *input0 = input_list.front(); const Tensor *input0 = input_list.front();
const size_t inputs_count = input_list.size(); const size_t inputs_count = input_list.size();
...@@ -59,6 +59,9 @@ struct ConcatFunctor : ConcatFunctorBase { ...@@ -59,6 +59,9 @@ struct ConcatFunctor : ConcatFunctorBase {
outer_sizes[0] = input0->size() / inner_size; outer_sizes[0] = input0->size() / inner_size;
for (size_t i = 1; i < inputs_count; ++i) { for (size_t i = 1; i < inputs_count; ++i) {
const Tensor *input = input_list[i]; const Tensor *input = input_list[i];
MACE_CHECK(input->scale() == output->scale()
&& input->zero_point() == output->zero_point(),
"Inputs and output must have the same scale and zero_point.");
MACE_CHECK(input->dim_size() == input0->dim_size(), MACE_CHECK(input->dim_size() == input0->dim_size(),
"Ranks of all input tensors must be same."); "Ranks of all input tensors must be same.");
for (int j = 0; j < input->dim_size(); ++j) { for (int j = 0; j < input->dim_size(); ++j) {
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "mace/core/future.h" #include "mace/core/future.h"
#include "mace/core/tensor.h" #include "mace/core/tensor.h"
#include "mace/kernels/kernel.h" #include "mace/kernels/kernel.h"
#include "mace/utils/quantize.h"
#ifdef MACE_ENABLE_OPENCL #ifdef MACE_ENABLE_OPENCL
#include "mace/core/runtime/opencl/cl2_header.h" #include "mace/core/runtime/opencl/cl2_header.h"
...@@ -90,7 +91,7 @@ inline uint8_t ComputeLerp<uint8_t>(const uint8_t top_left, ...@@ -90,7 +91,7 @@ inline uint8_t ComputeLerp<uint8_t>(const uint8_t top_left,
const float y_lerp) { const float y_lerp) {
const float top = top_left + (top_right - top_left) * x_lerp; const float top = top_left + (top_right - top_left) * x_lerp;
const float bottom = bottom_left + (bottom_right - bottom_left) * x_lerp; const float bottom = bottom_left + (bottom_right - bottom_left) * x_lerp;
return static_cast<uint8_t>(roundf(top + (bottom - top) * y_lerp)); return Saturate<uint8_t>(roundf(top + (bottom - top) * y_lerp));
} }
template <typename T> template <typename T>
......
...@@ -1674,10 +1674,12 @@ class Transformer(base_converter.ConverterInterface): ...@@ -1674,10 +1674,12 @@ class Transformer(base_converter.ConverterInterface):
"""Assume biasadd has been already folded with convolution and fc""" """Assume biasadd has been already folded with convolution and fc"""
if tensor.data_type == mace_pb2.DT_FLOAT: if tensor.data_type == mace_pb2.DT_FLOAT:
ops = self._consumers.get(tensor.name, None) ops = self._consumers.get(tensor.name, None)
if len(ops) == 1 and ops[0].type in [MaceOp.Conv2D.name, if ops is not None \
MaceOp.Deconv2D.name, and len(ops) == 1 \
MaceOp.DepthwiseConv2d.name, and ops[0].type in [MaceOp.Conv2D.name,
MaceOp.FullyConnected.name] \ MaceOp.Deconv2D.name,
MaceOp.DepthwiseConv2d.name,
MaceOp.FullyConnected.name] \
and len(ops[0].input) >= 3 \ and len(ops[0].input) >= 3 \
and ops[0].input[2] == tensor.name: and ops[0].input[2] == tensor.name:
conv_op = ops[0] conv_op = ops[0]
...@@ -1723,6 +1725,13 @@ class Transformer(base_converter.ConverterInterface): ...@@ -1723,6 +1725,13 @@ class Transformer(base_converter.ConverterInterface):
return quantize_info return quantize_info
def copy_quantize_info(self, op, info):
quantize_info = op.quantize_info.add()
quantize_info.minval = info.minval
quantize_info.maxval = info.maxval
quantize_info.scale = info.scale
quantize_info.zero_point = info.zero_point
def transform_fake_quantize(self): def transform_fake_quantize(self):
if not self._option.quantize: if not self._option.quantize:
return False return False
...@@ -1833,19 +1842,34 @@ class Transformer(base_converter.ConverterInterface): ...@@ -1833,19 +1842,34 @@ class Transformer(base_converter.ConverterInterface):
for op in self._model.op: for op in self._model.op:
if op.type in [MaceOp.Pooling.name, if op.type in [MaceOp.Pooling.name,
MaceOp.Squeeze.name, MaceOp.Squeeze.name,
MaceOp.Concat.name,
MaceOp.ResizeBilinear.name, MaceOp.ResizeBilinear.name,
MaceOp.BatchToSpaceND.name, MaceOp.BatchToSpaceND.name,
MaceOp.SpaceToBatchND.name]: MaceOp.SpaceToBatchND.name]:
del op.quantize_info[:] del op.quantize_info[:]
producer_op = self._producer[op.input[0]] producer_op = self._producer[op.input[0]]
quantize_info = op.quantize_info.add() self.copy_quantize_info(op, producer_op.quantize_info[0])
quantize_info.minval = producer_op.quantize_info[0].minval self._quantize_activation_info[op.output[0]] = \
quantize_info.maxval = producer_op.quantize_info[0].maxval op.quantize_info[0]
quantize_info.scale = producer_op.quantize_info[0].scale elif op.type == MaceOp.Concat.name:
quantize_info.zero_point = \ if op.quantize_info:
producer_op.quantize_info[0].zero_point maxval = op.quantize_info[0].maxval
minval = op.quantize_info[0].minval
del op.quantize_info[:]
else:
maxval = float("-inf")
minval = float("inf")
for i in range(len(op.input)):
minval = min(minval, self._producer[op.input[i]].quantize_info[0].minval) # noqa
maxval = max(maxval, self._producer[op.input[i]].quantize_info[0].maxval) # noqa
quantize_info = \
self.add_quantize_info(op, minval, maxval)
self._quantize_activation_info[op.output[0]] = quantize_info self._quantize_activation_info[op.output[0]] = quantize_info
for i in range(len(op.input)):
producer_op = self._producer[op.input[i]]
del producer_op.quantize_info[:]
self.copy_quantize_info(producer_op, quantize_info)
self._quantize_activation_info[producer_op.output[0]] = \
producer_op.quantize_info[0]
elif op.type == MaceOp.Softmax.name: elif op.type == MaceOp.Softmax.name:
del op.quantize_info[:] del op.quantize_info[:]
quantize_info = \ quantize_info = \
...@@ -1860,16 +1884,12 @@ class Transformer(base_converter.ConverterInterface): ...@@ -1860,16 +1884,12 @@ class Transformer(base_converter.ConverterInterface):
del op.quantize_info[:] del op.quantize_info[:]
producer_op0 = self._producer[op.input[0]] producer_op0 = self._producer[op.input[0]]
producer_op1 = self._producer[op.input[1]] producer_op1 = self._producer[op.input[1]]
quantize_info = op.quantize_info.add() minval = producer_op0.quantize_info[0].minval \
quantize_info.minval = producer_op0.quantize_info[0].minval \
+ producer_op1.quantize_info[0].minval + producer_op1.quantize_info[0].minval
quantize_info.maxval = producer_op0.quantize_info[0].maxval \ maxval = producer_op0.quantize_info[0].maxval \
+ producer_op1.quantize_info[0].maxval + producer_op1.quantize_info[0].maxval
scale, zero = quantize_util.adjust_range(quantize_info.minval, quantize_info = \
quantize_info.maxval, self.add_quantize_info(op, minval, maxval)
non_zero=False)
quantize_info.scale = scale
quantize_info.zero_point = zero
self._quantize_activation_info[op.output[0]] = quantize_info self._quantize_activation_info[op.output[0]] = quantize_info
print ("Add default quantize info for input") print ("Add default quantize info for input")
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册