From 69d9e76d6573816e8913d8c67d3fb5ef120f972b Mon Sep 17 00:00:00 2001 From: yuchaojie Date: Tue, 27 Oct 2020 17:01:04 +0800 Subject: [PATCH] rename create_quant_config && add notes --- mindspore/compression/quant/qat.py | 31 ++++----- mindspore/nn/layer/quant.py | 69 ++++++++++++------- .../models/resnet_quant_manual.py | 4 +- .../resnet50_quant/resnet_quant_manual.py | 4 +- 4 files changed, 65 insertions(+), 43 deletions(-) diff --git a/mindspore/compression/quant/qat.py b/mindspore/compression/quant/qat.py index 921529da9a5..5e20914b69a 100644 --- a/mindspore/compression/quant/qat.py +++ b/mindspore/compression/quant/qat.py @@ -33,7 +33,7 @@ from ..common import QuantDtype from .quantizer import Quantizer, OptimizeOption -__all__ = ["QuantizationAwareTraining"] +__all__ = ["QuantizationAwareTraining", "create_quant_config"] _ACTIVATION_MAP = {nn.ReLU: quant.ActQuant, @@ -44,13 +44,12 @@ _ACTIVATION_MAP = {nn.ReLU: quant.ActQuant, nn.HSwish: quant.HSwishQuant} -def get_quant_config(quant_observer=(quant.FakeQuantWithMinMaxObserver, quant.FakeQuantWithMinMaxObserver), - quant_delay=(0, 0), - quant_dtype=(QuantDtype.INT8, QuantDtype.INT8), - per_channel=(False, False), - symmetric=(False, False), - narrow_range=(False, False) - ): +def create_quant_config(quant_observer=(quant.FakeQuantWithMinMaxObserver, quant.FakeQuantWithMinMaxObserver), + quant_delay=(0, 0), + quant_dtype=(QuantDtype.INT8, QuantDtype.INT8), + per_channel=(False, False), + symmetric=(False, False), + narrow_range=(False, False)): r""" Configs the oberser type of weights and data flow with quant params. @@ -78,9 +77,9 @@ def get_quant_config(quant_observer=(quant.FakeQuantWithMinMaxObserver, quant.Fa weight_observer = quant_observer[0].partial_init(quant_delay=quant_delay[0], quant_dtype=quant_dtype[0], per_channel=per_channel[0], symmetric=symmetric[0], narrow_range=narrow_range[0]) - act_observer = quant_observer[0].partial_init(quant_delay=quant_delay[-1], quant_dtype=quant_dtype[-1], - per_channel=per_channel[-1], symmetric=symmetric[-1], - narrow_range=narrow_range[-1]) + act_observer = quant_observer[-1].partial_init(quant_delay=quant_delay[-1], quant_dtype=quant_dtype[-1], + per_channel=per_channel[-1], symmetric=symmetric[-1], + narrow_range=narrow_range[-1]) return quant.QuantConfig(weight=weight_observer, activation=act_observer) @@ -221,11 +220,11 @@ class QuantizationAwareTraining(Quantizer): self.act_range = Validator.check_bool(narrow_range[-1], "narrow range") self._convert_method_map = {quant.Conv2dBnAct: self._convert_conv, quant.DenseBnAct: self._convert_dense} - self.quant_config = get_quant_config(quant_delay=quant_delay, - quant_dtype=quant_dtype, - per_channel=per_channel, - symmetric=symmetric, - narrow_range=narrow_range) + self.quant_config = create_quant_config(quant_delay=quant_delay, + quant_dtype=quant_dtype, + per_channel=per_channel, + symmetric=symmetric, + narrow_range=narrow_range) def _convert_op_name(self, name): pattern = re.compile(r'([A-Z]{1})') diff --git a/mindspore/nn/layer/quant.py b/mindspore/nn/layer/quant.py index 14ef8466724..bdc0d1242a0 100644 --- a/mindspore/nn/layer/quant.py +++ b/mindspore/nn/layer/quant.py @@ -322,7 +322,7 @@ def _partial_init(cls_or_self, **kwargs): return r -class Observer(Cell): +class _Observer(Cell): """ Base class of Observer. Observer is used to calculate the statistics of specific layer. @@ -334,7 +334,7 @@ class Observer(Cell): """ def __init__(self, quant_dtype): - super(Observer, self).__init__() + super(_Observer, self).__init__() self.quant_dtype = quant_dtype def extend_repr(self): @@ -347,7 +347,7 @@ class Observer(Cell): partial_init = classmethod(_partial_init) -class UniformQuantObserver(Observer): +class UniformQuantObserver(_Observer): """ The base class of Uniform Quantization Observer. @@ -542,7 +542,8 @@ class Conv2dBnFoldQuant(Cell): var_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the variance vector. Default: 'ones'. fake (bool): Whether Conv2dBnFoldQuant Cell adds FakeQuantWithMinMaxObserver. Default: True. - quant_config (QuantConfig): Configs the oberser type of weight and activation. Default: quant_config_default. + quant_config (QuantConfig): Configs the oberser types and quant configs of weight and activation. Default: + both set to default FakeQuantWithMinMaxObserver. quant_dtype (QuantDtype): Specifies the FakeQuant datatype. Default: QuantDtype.INT8. freeze_bn (int): The quantization freeze BatchNormal op is according to the global step. Default: 100000. @@ -553,7 +554,9 @@ class Conv2dBnFoldQuant(Cell): Tensor of shape :math:`(N, C_{out}, H_{out}, W_{out})`. Examples: - >>> conv2d_bnfold = nn.Conv2dBnFoldQuant(1, 6, kernel_size=(2, 2), stride=(1, 1), pad_mode="valid") + >>> qconfig = compression.quant.create_quant_config() + >>> conv2d_bnfold = nn.Conv2dBnFoldQuant(1, 6, kernel_size=(2, 2), stride=(1, 1), pad_mode="valid", + >>> quant_config=qconfig) >>> input = Tensor(np.random.randint(-2, 2, (2, 1, 3, 3)), mindspore.float32) >>> result = conv2d_bnfold(input) >>> result.shape @@ -725,7 +728,8 @@ class Conv2dBnWithoutFoldQuant(Cell): weight_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the convolution kernel. Default: 'normal'. bias_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the bias vector. Default: 'zeros'. - quant_config (QuantConfig): Configs the oberser type of weight and activation. Default: quant_config_default. + quant_config (QuantConfig): Configs the oberser types and quant configs of weight and activation. Default: + both set to default FakeQuantWithMinMaxObserver. quant_dtype (QuantDtype): Specifies the FakeQuant datatype. Default: QuantDtype.INT8. Inputs: @@ -735,7 +739,9 @@ class Conv2dBnWithoutFoldQuant(Cell): Tensor of shape :math:`(N, C_{out}, H_{out}, W_{out})`. Examples: - >>> conv2d_no_bnfold = nn.Conv2dBnWithoutFoldQuant(1, 6, kernel_size=(2, 2), stride=(1, 1), pad_mode="valid") + >>> qconfig = compression.quant.create_quant_config() + >>> conv2d_no_bnfold = nn.Conv2dBnWithoutFoldQuant(1, 6, kernel_size=(2, 2), stride=(1, 1), pad_mode="valid", + >>> quant_config=qconfig) >>> input = Tensor(np.random.randint(-2, 2, (2, 1, 3, 3)), mstype.float32) >>> result = conv2d_no_bnfold(input) >>> result.shape @@ -846,7 +852,8 @@ class Conv2dQuant(Cell): weight_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the convolution kernel. Default: 'normal'. bias_init (Union[Tensor, str, Initializer, numbers.Number]): Initializer for the bias vector. Default: 'zeros'. - quant_config (QuantConfig): Configs the oberser type of weight and activation. Default: quant_config_default. + quant_config (QuantConfig): Configs the oberser types and quant configs of weight and activation. Default: + both set to default FakeQuantWithMinMaxObserver. quant_dtype (QuantDtype): Specifies the FakeQuant datatype. Default: QuantDtype.INT8. Inputs: @@ -856,7 +863,9 @@ class Conv2dQuant(Cell): Tensor of shape :math:`(N, C_{out}, H_{out}, W_{out})`. Examples: - >>> conv2d_quant = nn.Conv2dQuant(1, 6, kernel_size= (2, 2), stride=(1, 1), pad_mode="valid") + >>> qconfig = compression.quant.create_quant_config() + >>> conv2d_quant = nn.Conv2dQuant(1, 6, kernel_size= (2, 2), stride=(1, 1), pad_mode="valid", + >>> quant_config=qconfig) >>> input = Tensor(np.random.randint(-2, 2, (2, 1, 3, 3)), mindspore.float32) >>> result = conv2d_quant(input) >>> result.shape @@ -947,7 +956,8 @@ class DenseQuant(Cell): has_bias (bool): Specifies whether the layer uses a bias vector. Default: True. activation (Union[str, Cell, Primitive]): The regularization function applied to the output of the layer, eg. 'relu'. Default: None. - quant_config (QuantConfig): Configs the oberser type of weight and activation. Default: quant_config_default. + quant_config (QuantConfig): Configs the oberser types and quant configs of weight and activation. Default: + both set to default FakeQuantWithMinMaxObserver. quant_dtype (QuantDtype): Specifies the FakeQuant datatype. Default: QuantDtype.INT8. Inputs: @@ -957,7 +967,8 @@ class DenseQuant(Cell): Tensor of shape :math:`(N, C_{out}, H_{out}, W_{out})`. Examples: - >>> dense_quant = nn.DenseQuant(3, 6) + >>> qconfig = compression.quant.create_quant_config() + >>> dense_quant = nn.DenseQuant(3, 6, quant_config=qconfig) >>> input = Tensor(np.random.randint(-2, 2, (2, 3)), mindspore.float32) >>> result = dense_quant(input) >>> result.shape @@ -1048,7 +1059,8 @@ class ActQuant(_QuantActivation): Args: activation (Cell): Activation cell class. ema_decay (float): Exponential Moving Average algorithm parameter. Default: 0.999. - quant_config (QuantConfig): Configs the oberser type of weight and activation. Default: quant_config_default. + quant_config (QuantConfig): Configs the oberser types and quant configs of weight and activation. Default: + both set to default FakeQuantWithMinMaxObserver. quant_dtype (QuantDtype): Specifies the FakeQuant datatype. Default: QuantDtype.INT8. Inputs: @@ -1058,7 +1070,8 @@ class ActQuant(_QuantActivation): Tensor, with the same type and shape as the `input`. Examples: - >>> act_quant = nn.ActQuant(nn.ReLU()) + >>> qconfig = compression.quant.create_quant_config() + >>> act_quant = nn.ActQuant(nn.ReLU(), quant_config=qconfig) >>> input = Tensor(np.array([[1, 2, -1], [-2, 0, -1]]), mindspore.float32) >>> result = act_quant(input) >>> result @@ -1096,7 +1109,8 @@ class LeakyReLUQuant(_QuantActivation): Args: activation (Cell): Activation cell class. ema_decay (float): Exponential Moving Average algorithm parameter. Default: 0.999. - quant_config (QuantConfig): Configs the oberser type of weight and activation. Default: quant_config_default. + quant_config (QuantConfig): Configs the oberser types and quant configs of weight and activation. Default: + both set to default FakeQuantWithMinMaxObserver. quant_dtype (QuantDtype): Specifies the FakeQuant datatype. Default: QuantDtype.INT8. Inputs: @@ -1106,7 +1120,8 @@ class LeakyReLUQuant(_QuantActivation): Tensor, with the same type and shape as the `input`. Examples: - >>> activation = nn.LeakyReLUQuant(nn.LeakyReLU()) + >>> qconfig = compression.quant.create_quant_config() + >>> activation = nn.LeakyReLUQuant(nn.LeakyReLU(), quant_config=qconfig) >>> input = Tensor(np.array([[1, 2, 1], [-2, 0, -1]]), mindspore.float32) >>> result = activation(input) >>> result @@ -1153,7 +1168,8 @@ class HSwishQuant(_QuantActivation): Args: activation (Cell): Activation cell class. ema_decay (float): Exponential Moving Average algorithm parameter. Default: 0.999. - quant_config (QuantConfig): Configs the oberser type of weight and activation. Default: quant_config_default. + quant_config (QuantConfig): Configs the oberser types and quant configs of weight and activation. Default: + both set to default FakeQuantWithMinMaxObserver. quant_dtype (QuantDtype): Specifies the FakeQuant datatype. Default: QuantDtype.INT8. Inputs: @@ -1163,7 +1179,8 @@ class HSwishQuant(_QuantActivation): Tensor, with the same type and shape as the `input`. Examples: - >>> activation = nn.HSwishQuant(nn.HSwish()) + >>> qconfig = compression.quant.create_quant_config() + >>> activation = nn.HSwishQuant(nn.HSwish(), quant_config=qconfig) >>> input = Tensor(np.array([[1, 2, 1], [-2, 0, -1]]), mindspore.float32) >>> result = activation(input) >>> result @@ -1210,7 +1227,8 @@ class HSigmoidQuant(_QuantActivation): Args: activation (Cell): Activation cell class. ema_decay (float): Exponential Moving Average algorithm parameter. Default: 0.999. - quant_config (QuantConfig): Configs the oberser type of weight and activation. Default: quant_config_default. + quant_config (QuantConfig): Configs the oberser types and quant configs of weight and activation. Default: + both set to default FakeQuantWithMinMaxObserver. quant_dtype (QuantDtype): Specifies the FakeQuant datatype. Default: QuantDtype.INT8. Inputs: @@ -1220,7 +1238,8 @@ class HSigmoidQuant(_QuantActivation): Tensor, with the same type and shape as the `x`. Examples: - >>> activation = nn.HSigmoidQuant(nn.HSigmoid()) + >>> qconfig = compression.quant.create_quant_config() + >>> activation = nn.HSigmoidQuant(nn.HSigmoid(), quant_config=qconfig) >>> input = Tensor(np.array([[1, 2, 1], [-2, 0, -1]]), mindspore.float32) >>> result = activation(input) >>> result @@ -1266,7 +1285,8 @@ class TensorAddQuant(Cell): Args: ema_decay (float): Exponential Moving Average algorithm parameter. Default: 0.999. - quant_config (QuantConfig): Configs the oberser type of weight and activation. Default: quant_config_default. + quant_config (QuantConfig): Configs the oberser types and quant configs of weight and activation. Default: + both set to default FakeQuantWithMinMaxObserver. quant_dtype (QuantDtype): Specifies the FakeQuant datatype. Default: QuantDtype.INT8. Inputs: @@ -1277,7 +1297,8 @@ class TensorAddQuant(Cell): Tensor, with the same type and shape as the `input_x1`. Examples: - >>> add_quant = nn.TensorAddQuant() + >>> qconfig = compression.quant.create_quant_config() + >>> add_quant = nn.TensorAddQuant(quant_config=qconfig) >>> input_x1 = Tensor(np.array([[1, 2, 1], [-2, 0, -1]]), mindspore.float32) >>> input_x2 = Tensor(np.ones((2, 3)), mindspore.float32) >>> result = add_quant(input_x1, input_x2) @@ -1311,7 +1332,8 @@ class MulQuant(Cell): Args: ema_decay (float): Exponential Moving Average algorithm parameter. Default: 0.999. - quant_config (QuantConfig): Configs the oberser type of weight and activation. Default: quant_config_default. + quant_config (QuantConfig): Configs the oberser types and quant configs of weight and activation. Default: + both set to default FakeQuantWithMinMaxObserver. quant_dtype (QuantDtype): Specifies the FakeQuant datatype. Default: QuantDtype.INT8. Inputs: @@ -1322,7 +1344,8 @@ class MulQuant(Cell): Tensor, with the same type and shape as the `input_x1`. Examples: - >>> mul_quant = nn.MulQuant() + >>> qconfig = compression.quant.create_quant_config() + >>> mul_quant = nn.MulQuant(quant_config=qconfig) >>> input_x1 = Tensor(np.array([[1, 2, 1], [-2, 0, -1]]), mindspore.float32) >>> input_x2 = Tensor(np.ones((2, 3)) * 2, mindspore.float32) >>> result = mul_quant(input_x1, input_x2) diff --git a/model_zoo/official/cv/resnet50_quant/models/resnet_quant_manual.py b/model_zoo/official/cv/resnet50_quant/models/resnet_quant_manual.py index a74dba847b5..fa4da2e6c3f 100644 --- a/model_zoo/official/cv/resnet50_quant/models/resnet_quant_manual.py +++ b/model_zoo/official/cv/resnet50_quant/models/resnet_quant_manual.py @@ -18,13 +18,13 @@ import mindspore.nn as nn from mindspore.ops import operations as P from mindspore import Tensor from mindspore.nn import FakeQuantWithMinMaxObserver, Conv2dBnFoldQuant -from mindspore.compression.quant import qat +from mindspore.compression.quant import create_quant_config _ema_decay = 0.999 _symmetric = True _fake = True _per_channel = True -_quant_config = qat.get_quant_config(per_channel=(_per_channel, False), symmetric=(_symmetric, False)) +_quant_config = create_quant_config(per_channel=(_per_channel, False), symmetric=(_symmetric, False)) def _weight_variable(shape, factor=0.01): diff --git a/tests/st/quantization/resnet50_quant/resnet_quant_manual.py b/tests/st/quantization/resnet50_quant/resnet_quant_manual.py index 20f70f4b621..32693785c24 100644 --- a/tests/st/quantization/resnet50_quant/resnet_quant_manual.py +++ b/tests/st/quantization/resnet50_quant/resnet_quant_manual.py @@ -19,13 +19,13 @@ import mindspore.common.initializer as weight_init from mindspore.ops import operations as P from mindspore import Tensor from mindspore.nn import FakeQuantWithMinMaxObserver, Conv2dBnFoldQuant -from mindspore.compression.quant import qat +from mindspore.compression.quant import create_quant_config _ema_decay = 0.999 _symmetric = True _fake = True _per_channel = True -_quant_config = qat.get_quant_config(per_channel=(_per_channel, False), symmetric=(_symmetric, False)) +_quant_config = create_quant_config(per_channel=(_per_channel, False), symmetric=(_symmetric, False)) def _weight_variable(shape, factor=0.01):