TensorFlow技术内幕(十一):模型优化之量化(Quantize)

背景

  • Neural Network模型一般都会占用很大的磁盘空间,比如AlexNet的模型文件就超过了200 MB.模型包含了数百万的参数,绝大部分的空间都用来存储这些模型的参数了。这些参数是浮点数类型的,普通的压缩算法很难压缩它们的空间。
  • 一般模型的内部的计算都采用了浮点数计算,浮点数的计算会消耗比较大的计算资源(空间和cpu/gpu时间),如果在不影响模型准确率的情况下,模型内部可以采用其他简单数值类型进行计算的话,计算速度会提高很多,消耗的计算资源会大大减小,尤其是对于移动设备来说,这点尤其重要。

由此引入量化技术。

Quantize

单词的意思是(来自Dictionary.com):

Mathematics, Physics. to restrict (a variable quantity) to 
discrete values rather than to a continuous set of values.

对于模型文件的量化压缩,过程比较简单。我们发现模型属于同一层的参数值会分布在一个较小的区间内,比如-3, 5之间,我们可以记下这个最小值和最大值,在采用8位数量化(可以有其他选择)的情况下,可以把同一层的所有参数都线性映射(也可以采用非线性映射进一步压缩空间)到区间[-3, 5]之间的255个8位整数中的最接近的一个数,例如如下映射:

float  | Quantized 
-------+----------
 -3.0  | 0     
 5.0   | 255   
 0.92  | 125    

这样模型文件的大小就基本压缩到了原来的25%,而且在加载的时候可以恢复到原来的数值,当然恢复的数值跟压缩之前会有差异,但事实证明,模型对这种压缩照成的噪音表现的很健壮。

满足第一个需求就这么简单,模型不需要改变,需要改变的是模型的存储和加载部分;但是要解决第二个问题就不这么简单了,事实证明,模型内部的计算如果都采用8位整形数来计算的话,模型的表现会相差很大,原因是模型的训练过程中,需要计算梯度,然后运用一定的学习算法,不断的更新参数,每次的更新量可能是很小的。所以模型的训练过程需要高精度的浮点型数值的。那么模型的预测过程是否可以使用整形数值代替呢?事实证明是可行的。

TensorFlow中模型的量化过程是这样实现的:

  • 将模型中实现了对应的量化操作的操作符替换成量化操作符,例如图1是原始的计算图,图2是量化后的计算图。

TensorFlow技术内幕(十一):模型优化之量化(Quantize)_第1张图片

图1

TensorFlow技术内幕(十一):模型优化之量化(Quantize)_第2张图片

图2

  • 优化量化处理后的计算图,去掉冗余操作,如下图3

TensorFlow技术内幕(十一):模型优化之量化(Quantize)_第3张图片

图3

实践

以inception模型为例,可以通过下列命令操作量化模型:

$ curl http://download.tensorflow.org/models/image/imagenet/inception-2015-12-05.tgz -o /tmp/inceptionv3.tgz
$ tar xzf /tmp/inceptionv3.tgz -C /tmp/
$ bazel build tensorflow/contrib/quantization/tools:quantize_graph
$ bazel-bin/tensorflow/contrib/quantization/tools/quantize_graph \
--input=/tmp/classify_image_graph_def.pb \
--output_node_names="softmax" --output=/tmp/quantized_graph.pb \
--mode=eightbit

你可能感兴趣的:(TensorFlow技术内幕(十一):模型优化之量化(Quantize))