最近我在尝试追踪关于使用TPU支持部署TF模型的错误。我可以成功运行没有TPU支持的模型,但一旦启用量化,就会迷失方向。
我处于以下情况:
- 创建并训练了一个模型
- 创建了模型的评估图
- 将模型冻结并将结果保存为协议缓冲区
- 成功转换并部署了没有TPU支持的模型
对于最后一点,我使用了TFLiteConverter的Python API。生成功能性tflite模型的脚本为:
import tensorflow as tf
graph_def_file = 'frozen_model.pb'
inputs = ['dense_input']
outputs = ['dense/BiasAdd']
converter = tf.lite.TFLiteConverter.from_frozen_graph(graph_def_file, inputs, outputs)
converter.inference_type = tf.lite.constants.FLOAT
input_arrays = converter.get_input_arrays()
converter.optimizations = [tf.lite.Optimize.OPTIMIZE_FOR_SIZE]
tflite_model = converter.convert()
open('model.tflite', 'wb').write(tflite_model)
这告诉我到目前为止我的方法似乎还可以。现在,如果我想要使用Coral TPU棒,我必须量化我的模型(我在训练过程中已经考虑到了这一点)。我所要做的就是修改我的转换脚本。我发现我需要将它改为:
import tensorflow as tf
graph_def_file = 'frozen_model.pb'
inputs = ['dense_input']
outputs = ['dense/BiasAdd']
converter = tf.lite.TFLiteConverter.from_frozen_graph(graph_def_file, inputs, outputs)
converter.inference_type = tf.lite.constants.QUANTIZED_UINT8 ## Indicates TPU compatibility
input_arrays = converter.get_input_arrays()
converter.quantized_input_stats = {input_arrays[0]: (0., 1.)} ## mean, std_dev
converter.default_ranges_stats = (-128, 127) ## min, max values for quantization (?)
converter.allow_custom_ops = True ## not sure if this is needed
## REMOVED THE OPTIMIZATIONS ALTOGETHER TO MAKE IT WORK
tflite_model = converter.convert()
open('model.tflite', 'wb').write(tflite_model)
这个tflite模型能够在Python API解释器中加载后产生结果,但我无法理解它们的含义。此外,关于如何选择平均值,标准差和最小/最大范围,没有(或者如果有,它被隐藏得很好)文档。另外,在使用edgetpu_compiler进行编译并部署(使用C++ API加载)后,我收到了一个错误:
INFO: Initialized TensorFlow Lite runtime.
ERROR: Failed to prepare for TPU. generic::failed_precondition: Custom op already assigned to a different TPU.
ERROR: Node number 0 (edgetpu-custom-op) failed to prepare.
Segmentation fault
我想我在转换过程中可能错过了某个标志。但由于文档也缺乏这方面的资料,我不能确定。
简而言之:
- 参数std_dev、min/max是什么意思,它们如何相互作用?
- 转换过程中我做错了什么?
非常感谢任何帮助或指导!
编辑:我已经在Github问题页面上发布了完整的测试代码。请随意尝试。