From 8e439ccfff29e482a0201bceb505a52d8216aeae Mon Sep 17 00:00:00 2001 From: qingqing01 Date: Tue, 26 Feb 2019 16:33:37 +0800 Subject: [PATCH] Fix bug in fake_quantize_op and add more unit testing (#15912) --- paddle/fluid/operators/fake_quantize_op.cc | 6 +-- .../tests/unittests/test_fake_quantize_op.py | 37 ++++++++++++++++++- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/paddle/fluid/operators/fake_quantize_op.cc b/paddle/fluid/operators/fake_quantize_op.cc index d51eb054a9..3bb07d3835 100644 --- a/paddle/fluid/operators/fake_quantize_op.cc +++ b/paddle/fluid/operators/fake_quantize_op.cc @@ -31,7 +31,7 @@ template struct FindAbsMaxFunctor { void operator()(const platform::CPUDeviceContext& ctx, const T* in, const int num, T* out) { - *out = *(std::max_element(in + 0, in + num, Compare())); + *out = std::abs(*(std::max_element(in + 0, in + num, Compare()))); } }; @@ -46,10 +46,8 @@ struct ClipAndFakeQuantFunctor { platform::Transform trans; trans(ctx, in.data(), in.data() + in.numel(), out->mutable_data(ctx.GetPlace()), ClipFunctor(-s, s)); - auto in_e = framework::EigenVector::Flatten(in); auto out_e = framework::EigenVector::Flatten(*out); - - out_e.device(*ctx.eigen_device()) = (bin_cnt / s * in_e).round(); + out_e.device(*ctx.eigen_device()) = (bin_cnt / s * out_e).round(); } }; diff --git a/python/paddle/fluid/tests/unittests/test_fake_quantize_op.py b/python/paddle/fluid/tests/unittests/test_fake_quantize_op.py index 820ad4af88..4582b2a0ee 100644 --- a/python/paddle/fluid/tests/unittests/test_fake_quantize_op.py +++ b/python/paddle/fluid/tests/unittests/test_fake_quantize_op.py @@ -35,7 +35,7 @@ class TestFakeQuantizeOp(OpTest): self.check_output() -class TestFakeQuantizeOp(OpTest): +class TestFakeQuantizeRangeAbsMaxOp(OpTest): def setUp(self): self.op_type = "fake_quantize_range_abs_max" self.attrs = { @@ -43,8 +43,10 @@ class TestFakeQuantizeOp(OpTest): 'window_size': int(1), 'is_test': False } + x = (np.random.random((8, 16, 7, 7)) - 0.5) * 10 + x = x.astype("float32") self.inputs = { - 'X': np.random.random((8, 16, 7, 7)).astype("float32"), + 'X': x, 'Iter': np.zeros(1).astype("int64"), 'InScale': np.zeros(1).astype("float32") } @@ -62,5 +64,36 @@ class TestFakeQuantizeOp(OpTest): self.check_output() +class TestFakeQuantizeRangeAbsMaxOp2(OpTest): + def setUp(self): + self.op_type = "fake_quantize_range_abs_max" + self.attrs = { + 'bit_length': int(8), + 'window_size': int(1), + 'is_test': True + } + x = (np.random.random((8, 16, 7, 7)) - 0.5) * 10 + x = x.astype("float32") + scale = np.max(np.abs(x)).astype("float32") - 1.0 + out_scales = np.zeros(self.attrs['window_size']).astype("float32") + out_scales[0] = scale + + self.inputs = { + 'X': x, + 'Iter': np.zeros(1).astype("int64"), + 'InScale': scale.astype("float32") + } + xs = np.clip(x, -scale, scale) + qs = np.round(xs / scale * ((1 << (self.attrs['bit_length'] - 1)) - 1)) + self.outputs = { + 'Out': qs, + 'OutScale': scale.astype("float32"), + 'OutScales': out_scales, + } + + def test_check_output(self): + self.check_output(no_check_set=set(['OutScale', 'OutScales'])) + + if __name__ == "__main__": unittest.main() -- GitLab