最近,我开始使用Tensorflow + Keras创建神经网络,我想尝试Tensorflow中提供的量化功能.到目前为止,尝试TF教程的示例工作得很好,我有这个基本的工作示例(来自https://www.tensorflow.org/tutorials/keras/basic_classification):
import tensorflow as tf
from tensorflow import keras
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
# fashion mnist data labels (indexes related to their respective labelling in the data set)
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
# preprocess the train and test images
train_images = train_images / 255.0
test_images = test_images / 255.0
# settings variables
input_shape = (train_images.shape[1], train_images.shape[2])
# create the model layers
model …Run Code Online (Sandbox Code Playgroud) 在运行Android 4.0或4.0.3的模拟器上,我看到了可怕的色带,我似乎无法摆脱它.在我测试的每个其他Android版本上,渐变看起来很流畅.
我有一个配置为RGBX_8888的SurfaceView,并且渲染画布中不存在条带.如果我通过在渲染结束时叠加噪声模式来手动抖动图像,我可以使渐变再次平滑,但显然代价是我宁愿避免的性能.
因此绑带将在稍后介绍.我只能假设,在4.0+上,我的SurfaceView在被绘制和显示之间的某个点处被量化为较低的位深度,我可以从屏幕截图中看到渐变是一次步进8个值每个通道,建议量化到555(而不是565).
我将以下内容添加到我的Activity onCreate函数中,但它没有任何区别.
getWindow().setFormat(PixelFormat.RGBA_8888);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DITHER);
Run Code Online (Sandbox Code Playgroud)
我也尝试将上面的内容放在onAttachedToWindow()上,但仍然没有变化.
(我相信RGBA_8888无论如何都是2.2及以上版本的默认窗口格式,因此明确设置该格式对4.0+没有影响也就不足为奇了.)
这就留下了一个问题,如果源是8888,目的地是8888,那么引入量化/条带的原因是什么,它为什么只出现在4.0+?
非常令人费解.我想知道是否有人可以放弃一些光线?
是否可以将tf.contrib.quantize.create_training_graph已训练的Keras模型用于模型量化?
据我了解,我可以tf.Graph从Keras模型导入,但是我可以在用修改后对其进行微调tf.contrib.quantize.create_training_graph吗?
我能够tf.contrib.quantize.create_training_graph(input_graph=K.get_session().graph, quant_delay=int(0))在模型定义和模型加载之后调用,但是得到:
2019-02-22 14:56:24.216742: W tensorflow/c/c_api.cc:686] Operation '{name:'global_average_pooling2d_1_1/Mean' id:3777 op device:{} def:{global_average_pooling2d_1_1/Mean = Mean[T=DT_FLOAT, Tidx=DT_INT32, keep_dims=false](conv2d_15_1/act_quant/FakeQuantWithMinMaxVars:0, global_average_pooling2d_1_1/Mean/reduction_indices)}}' was changed by updating input tensor after it was run by a session. This mutation will have no effect, and will trigger an error in the future. Either don't modify nodes after running them or create a new session.
Run Code Online (Sandbox Code Playgroud)
转换为keras-> tensorflow-> tflite时,至少我能够使用uint8权重保存模型,因为我了解到模型和推理的输入仍然是fp32。
converter = tf.contrib.lite.TFLiteConverter.from_frozen_graph(
graph_def_file='tf_model.pb',
input_arrays=input_node_names,
output_arrays=output_node_names)
converter.post_training_quantize = True
tflite_model = …Run Code Online (Sandbox Code Playgroud) 你有30秒的音频文件采样率为44.1 KHz,并用8位量化; 计算这个文件的比特率和单声道和立体声版本的大小?
我需要生成图像中前5种主色的调色板.我想复制Embedly的提取工具或Color Thief的结果.
以下命令给出了稍微不同的结果:
convert testimage.jpg -format %c -colorspace LAB -colors 5 histogram:info:- | sort -n -r
157154: ( 19, 28, 35) #131C23 srgb(19,28,35)
16164: ( 27, 51, 77) #1B334D srgb(27,51,77)
15725: ( 79, 88, 84) #4F5854 srgb(79,88,84)
8608: ( 44, 77,103) #2C4D67 srgb(44,77,103)
5149: ( 84,126,150) #547E96 srgb(84,126,150)
Run Code Online (Sandbox Code Playgroud)
我有点不确定我是否应该量化为5种颜色,因为我发现这样做不能很好地使用简单的图形(例如Google徽标).使用更大的调色板然后只选择前n种颜色会更好吗?
这引出了我关于所使用的量化算法的下一个问题.看看Embedly Extract的结果,输出颜色不一定是最常见的,但看起来是彼此最不同的聚类.
例如,假设我有一个非常暗的图像(黑色/棕色),细节为鲜红色.我如何确保ImageMagick包含红色?(道歉,如果这听起来很愚蠢,色彩理论对我来说都是新的!).
下面是我用于测试的图像:

我正在尝试使用 UINT8 量化,同时将 tensorflow 模型转换为 tflite 模型:
如果使用post_training_quantize = True,模型大小比原始 fp32 模型低 x4,所以我假设模型权重是 uint8,但是当我加载模型并通过interpreter_aligner.get_input_details()[0]['dtype']它的 float32获取输入类型时。量化模型的输出与原始模型大致相同。
converter = tf.contrib.lite.TFLiteConverter.from_frozen_graph(
graph_def_file='tflite-models/tf_model.pb',
input_arrays=input_node_names,
output_arrays=output_node_names)
converter.post_training_quantize = True
tflite_model = converter.convert()
Run Code Online (Sandbox Code Playgroud)
转换模型的输入/输出:
print(interpreter_aligner.get_input_details())
print(interpreter_aligner.get_output_details())
[{'name': 'input_1_1', 'index': 47, 'shape': array([ 1, 128, 128, 3], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0)}]
[{'name': 'global_average_pooling2d_1_1/Mean', 'index': 45, 'shape': array([ 1, 156], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0)}]
Run Code Online (Sandbox Code Playgroud)
另一种选择是明确指定更多参数:模型大小比原始 fp32 模型低 x4,模型输入类型为 uint8,但模型输出更像是垃圾。
converter = tf.contrib.lite.TFLiteConverter.from_frozen_graph(
graph_def_file='tflite-models/tf_model.pb',
input_arrays=input_node_names,
output_arrays=output_node_names)
converter.post_training_quantize = True …Run Code Online (Sandbox Code Playgroud) python quantization deep-learning tensorflow tensorflow-lite
假设我在[0,1]范围内有一个浮点数,我想量化并将其存储在无符号字节中.听起来很简单,但事实上它很复杂:
显而易见的解决方案如下:
unsigned char QuantizeFloat(float a)
{
return (unsigned char)(a * 255.0f);
}
Run Code Online (Sandbox Code Playgroud)
这种方法到目前为止我得到的所有数字都是0到255,但整数的分布并不均匀.该函数仅255在a完全正确时才返回1.0f.不是一个好的解决方案
如果我做适当的舍入,我只是转移问题:
unsigned char QuantizeFloat(float a)
{
return (unsigned char)(a * 255.0f + 0.5f);
}
Run Code Online (Sandbox Code Playgroud)
这里的结果0只覆盖浮动范围的一半,而不是任何其他数字.
如何使用相等的浮点范围分布进行量化?理想情况下,如果我量化均匀分布的随机浮点数,我希望获得相等的整数分布.
有任何想法吗?
顺便说一句:我的代码也在C中,问题与语言无关.对于非C的人:只是假设,float以int转换截断浮动.
编辑:因为我们在这里有一些困惑:我需要一个映射,将最小的输入float(0)映射到最小的unsigned char,并将我的范围(1.0f)的最高浮点数映射到最高的无符号字节(255).
我正在尝试使Mobilenetv2模型(将最后一层重新训练到我的数据中)在Google Edge TPU珊瑚上运行。
我已经按照这个教程https://www.tensorflow.org/lite/performance/post_training_quantization?hl=zh-CN进行了训练后量化。相关代码为:
...
train = tf.convert_to_tensor(np.array(train, dtype='float32'))
my_ds = tf.data.Dataset.from_tensor_slices(train).batch(1)
# POST TRAINING QUANTIZATION
def representative_dataset_gen():
for input_value in my_ds.take(30):
yield [input_value]
converter = tf.lite.TFLiteConverter.from_keras_model_file(saved_model_dir)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = representative_dataset_gen
converter.target_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
tflite_quant_model = converter.convert()
Run Code Online (Sandbox Code Playgroud)
我已经成功生成了tflite量化模型,但是当我运行edgetpu_compiler时(此页面为https://coral.withgoogle.com/docs/edgetpu/compiler/#usage),我得到以下输出:
edgetpu_compiler Notebooks/MobileNetv2_3class_visit_split_best-val-
acc.h5.quant.tflite
Edge TPU Compiler version 2.0.258810407
INFO: Initialized TensorFlow Lite runtime.
ERROR: quantized_dimension must be in range [0, 1). Was 3.
ERROR: quantized_dimension must be in range [0, 1). Was 3.
ERROR: quantized_dimension must …Run Code Online (Sandbox Code Playgroud) 我正在尝试将训练有素的模型从检查点文件转换为tflite. 我正在使用tf.lite.LiteConverter. 浮点转换顺利进行,推理速度合理。但是INT8转换的推理速度很慢。我试图通过输入一个非常小的网络来调试。我发现 INT8 模型的推理速度通常比浮点模型慢。
在 INT8 tflite 文件中,我发现了一些叫做 ReadVariableOp 的张量,在 TensorFlow 的官方 mobilenet tflite 模型中并不存在。
我想知道是什么导致了 INT8 推理的缓慢。
编辑:附加一些代码以帮助生成类似的结果(附加在末尾)
我有一个非常小的模型,其架构[2, 3, 6]中的隐藏层使用 ReLU,它是用于多类分类的 softmax 激活。离线训练并静态量化到 qint8。我现在想做的是提取权重,以便我可以通过矩阵乘法/加法在其他硬件上使用它们。我遇到的问题是它似乎没有按预期运行。以 state_dict() 的 GraphModule 输出为例:
OrderedDict([('input_layer_input_scale_0', tensor(0.0039)),
('input_layer_input_zero_point_0', tensor(0)),
('input_layer.scale', tensor(0.0297)),
('input_layer.zero_point', tensor(0)),
('input_layer._packed_params.dtype', torch.qint8),
('input_layer._packed_params._packed_params',
(tensor([[-0.1180, 0.1180],
[-0.2949, -0.5308],
[-3.3029, -7.5496]], size=(3, 2), dtype=torch.qint8,
quantization_scheme=torch.per_tensor_affine, scale=0.05898105353116989,
zero_point=0),
Parameter containing:
tensor([-0.4747, -0.3563, 7.7603], requires_grad=True))),
('out.scale', tensor(1.5963)),
('out.zero_point', tensor(243)),
('out._packed_params.dtype', torch.qint8),
('out._packed_params._packed_params',
(tensor([[ 0.4365, 0.4365, -55.4356],
[ 0.4365, 0.0000, 1.3095],
[ 0.4365, 0.0000, -13.9680],
[ 0.4365, -0.4365, 4.3650],
[ 0.4365, 0.4365, -3.0555],
[ 0.4365, 0.0000, -1.3095],
[ 0.4365, 0.0000, 3.0555]], size=(7, 3), …Run Code Online (Sandbox Code Playgroud) quantization ×10
tensorflow ×6
python ×3
keras ×2
android ×1
audio ×1
bitrate ×1
colors ×1
dithering ×1
google-coral ×1
gradient ×1
imagemagick ×1
integer ×1
pytorch ×1
rounding ×1
sample-rate ×1
surfaceview ×1
tpu ×1