首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TensorFlow版本2和BatchNorm折叠中的量化感知训练

TensorFlow版本2和BatchNorm折叠中的量化感知训练
EN

Stack Overflow用户
提问于 2020-03-27 18:13:59
回答 2查看 2.4K关注 0票数 5

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

Tensorflow 2有一个关于如何在他们最近采用的tf.keras应用编程接口中使用量化的tutorial,但他们没有提到任何关于批处理标准化的内容。我用BatchNorm层尝试了下面这个简单的例子:

代码语言:javascript
复制
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)

但是,它给出了以下例外:

代码语言:javascript
复制
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,他们在keras构建的模型上应用了tf.contrib.quantize.create_training_graph。然而,它们不使用BatchNorm层,所以我不确定这是否会起作用。

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

EN

回答 2

Stack Overflow用户

发布于 2020-04-25 06:51:47

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

代码语言:javascript
复制
# 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)
票数 1
EN

Stack Overflow用户

发布于 2020-08-24 19:15:56

您应该按照指令中的说明应用量化注释。我想你现在可以像这样调用BatchNorm:

代码语言:javascript
复制
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的返回列表的索引。然而,我不鼓励这种方式,因为它肯定会损害准确性,因为BN应该作为激活量化

您得到的结果将如下所示(RESNET50):

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60883928

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档