tensorflow模型的量化与剪枝

1. float32 -> float16的量化

import tensorflow as tf
saved_model_dir="/path/to/mobilenet_v1_224"
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)

converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_types = [tf.lite.constants.FLOAT16]

tflite_model=converter.convert()
open("converted_model.tflite","wb").write(tflite_model)

2. float32 -> uint8的量化

import tensorflow as tf

converter = tf.lite.TFLiteConverter.from_keras_model_file(keras_model)

converter.inference_type = tf.uint8
converter.quantized_input_stats = {'input_1': (0, 255)}
converter.default_ranges_stats = (0, 1)

tflite_model = converter.convert()
open("converted_model_uint8.tflite", "wb").write(tflite_model)

由于uint8的数据只在0-255之间变化,而量化就是将整个float32的数据,在牺牲一定的数据精度的情况下,映射到0-255这256个整数上去,所以在输入数据的时候,就需要做一定的映射变换,我这里的input_1这个输入层本来是接受[-1,1]这个范围内的float数据的,现在需要接受了0-255的数据,为了模型能正确推理,所以需要有转化关系,以 x q x_q xq表示量化后的数据,以 x f l o a t x_{float} xfloat表示量化前的输入数据,有
x q − m e a n s t d = x f l o a t \frac{x_q-mean}{std}=x_{float} stdxqmean=xfloat
x q ∈ [ 0 , 255 ] x_q\in[0,255] xq[0,255],而 x f l o a t ∈ [ − 1 , 1 ] x_{float}\in[-1,1] xfloat[1,1],所以 s t d = 255 ÷ 2 = 127.5 std=255\div 2=127.5 std=255÷2=127.5,这样也可以得到 m e a n = 127.5 mean=127.5 mean=127.5。三种常见的输入范围的量化参数为:

    - range(0,255): mean=0,std=1
    - range(-1,1): mean=127.5,std=127.5
    - range(0,1): mean=0,std=255
  • (这个部分API太乱,没有找到确定的信息,可能不对)指定converter.default_ranges_stats = (0, 1)是所有层数值的范围,由于使用的Uint8量化,输出的数据也是0-255,而输出层需要转化为我们期待的结果,如0-1的float数据。在tf1.14.0中需要显式地指定这个参数,否则转换的时候会失败。这个有个说法是设置后,所有层的输出数值都会到这个范围内,实际使用中感觉不是这样的。如设置为0-1后,输出层的结果为0-255,并非0-1。在得到0-255的输出结果后,需要dequantize才能获得想要的结果。dequantize的方式可以通过Netron打开模型文件,或者在输出层tensor里面的参数获取。
  • 在这里,用Netron打开了一个模型,在输入的时候,由于是Uint8类型的数据,通过quantization表示的数据进行Uint8->float32的转化,在输出的时候,同样适用quantization将Uint8类型的数据,转化为后处理可以理解的那样的。

3. 混合量化

import tensorflow as tf
saved_model_dir="/path/to/mobilenet_v1_224"
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)

converter.optimizations = [tf.lite.Optimize.DEFAULT]

tflite_model=converter.convert()
open("converted_model.tflite","wb").write(tflite_model)

混合量化模型中参数是int8和float32一起的,具体使用什么数据类型,实际运算根据硬件支持情况而定

4. 存整数量化

import tensorflow as tf
saved_model_dir="/path/to/mobilenet_v1_224"
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)

converter.optimizations = [tf.lite.Optimize.DEFAULT]
def data_generator():
    for i in range(steps):
        # get sample input data
        yield [input_sample]
converter.representative_dataset = data_generator

tflite_model=converter.convert()
open("converted_model.tflite","wb").write(tflite_model)

将模型参数量化为int8,但是需要在data_generator中给出样本范例。

5. 训练中量化

import tensorflow_model_optimization as tfmot

model=build_model()

model_to_quantize = tfmot.quantization.keras.quantiza(model)
....


model_to_quantize.fit(....)

在训练过程中的量化。

6. 模型剪枝

import tensorflow_model_optimization as tfmot

model=build_model()

pruning_schedule =tfmot.sparsity.keras.PolynomialDecay(
    initial_sparsity = 0.0,
    final_sparsity = 0.5,
    begin_step = 2000,
    end_step = 4000
)
model_for_pruning = tfmot.sparsity.keras.prune_low_magnitude(model,pruning_schedule=pruning_schedule)

...
model_for_pruning.fit(......)

在剪枝50%的时候,基本上只有微小的精度损失。

ref

https://www.youtube.com/watch?v=Qef8-xgTE7s

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值