【问题标题】:Quantization aware training in TensorFlow version 2 and BatchNorm foldingTensorFlow 版本 2 和 BatchNorm 折叠中的量化感知训练
【发布时间】:2020-07-08 01:40:41
【问题描述】:

我想知道在 Tensorflow 2 的量化感知训练期间模拟 BatchNorm 折叠的当前可用选项是什么。Tensorflow 1 具有 tf.contrib.quantize.create_training_graph 函数,该函数将 FakeQuantization 层插入图中并负责模拟批量归一化折叠(根据到这个white paper)。

Tensorflow 2 在他们最近采用的tf.keras API 中有一个关于如何使用量化的tutorial,但他们没有提到任何关于批量标准化的内容。我尝试了以下带有 BatchNorm 层的简单示例:

import tensorflow_model_optimization as tfmo

model = tf.keras.Sequential([
      l.Conv2D(32, 5, padding='same', activation='relu', input_shape=input_shape),
      l.MaxPooling2D((2, 2), (2, 2), padding='same'),
      l.Conv2D(64, 5, padding='same', activation='relu'),
      l.BatchNormalization(),    # BN!
      l.MaxPooling2D((2, 2), (2, 2), padding='same'),
      l.Flatten(),
      l.Dense(1024, activation='relu'),
      l.Dropout(0.4),
      l.Dense(num_classes),
      l.Softmax(),
])
model = tfmo.quantization.keras.quantize_model(model)

但是它给出了以下例外:

RuntimeError: Layer batch_normalization:<class 'tensorflow.python.keras.layers.normalization.BatchNormalization'> is not supported. You can quantize this layer by passing a `tfmot.quantization.keras.QuantizeConfig` instance to the `quantize_annotate_layer` API.

表示 TF 不知道如何处理它。

我还看到this related topic 他们将tf.contrib.quantize.create_training_graph 应用于 keras 构建的模型。但是他们不使用 BatchNorm 层,所以我不确定这是否可行。

那么在 TF2 中使用 BatchNorm 折叠功能有哪些选项?这可以从 keras API 完成,还是我应该切换回 TensorFlow 1 API 并以旧方式定义图形?

【问题讨论】:

    标签: python tensorflow tensorflow2.0 batch-normalization quantization-aware-training


    【解决方案1】:

    如果您在激活之前添加 BatchNormalization,您不会遇到量化问题。注意:只有当该层正好在 Conv2D 层之后时,BatchNormalization 才支持量化。 https://www.tensorflow.org/model_optimization/guide/quantization/training

    # Change
    l.Conv2D(64, 5, padding='same', activation='relu'),
    l.BatchNormalization(),    # BN!
    # with this
    l.Conv2D(64, 5, padding='same'),
    l.BatchNormalization(),
    l.Activation('relu'),
    
    #Other way of declaring the same
    o = (Conv2D(512, (3, 3), padding='valid' , data_format=IMAGE_ORDERING))(o)
    o = (BatchNormalization())(o)
    o = Activation('relu')(o)
    

    【讨论】:

      【解决方案2】:

      您应该按照说明应用量化注释。我认为您现在可以像这样调用 BatchNorm:

      class DefaultBNQuantizeConfig(tfmot.quantization.keras.QuantizeConfig):
      
      def get_weights_and_quantizers(self, layer):
          return []
      
      def get_activations_and_quantizers(self, layer):
          return []
      
      def set_quantize_weights(self, layer, quantize_weights):
          pass
      def set_quantize_activations(self, layer, quantize_activations):
          pass
      def get_output_quantizers(self, layer):
          return [tfmot.quantization.keras.quantizers.MovingAverageQuantizer(
          num_bits=8, per_axis=False, symmetric=False, narrow_range=False)]
      
      def get_config(self):
          return {}
      

      如果您仍想对层进行量化,请将 get_weights_and_quantizers 的返回更改为 return [(layer.weights[i], LastValueQuantizer(num_bits=8, symmetric=True, narrow_range=False, per_axis=False)) for i in range(2)]。然后根据上面 set_quantize_weights 的返回列表的索引将量化器设置回 gamma,beta,...。但是,我不鼓励这种方式,因为它肯定会损害准确性,因为 BN 应该充当激活量化

      你得到的结果是这样的(RESNET50):

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-22
        相关资源
        最近更新 更多