运行tflite模型时发生以下错误:MAX_POOL_2D节点中的input-> params.scale!= output-> params.scale

时间:2019-01-28 03:14:12

标签: tensorflow tensorflow-lite quantization

我用Tensorflow版本1.12.0的量化感知训练方法训练了人脸识别模型。网络使用inception-resnet_v1(代码来源为tensorflow / models / research / slim / nets /)。训练完成后,我得到ckpt,然后创建一个新的Frozen.py文件以生成eval.pb,然后使用toco成功生成tflite模型。但是当我最终用图像测试tflite模型时,出现以下错误:

File "src/test_tflite.py", line 21, in <module>
    Interpreter.allocate_tensors()
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/lite/python/interpreter.py", line 71, in allocate_tensors
    Return self._interpreter.AllocateTensors()
  File "/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/lite/python/interpreter_wrapper/tensorflow_wrap_interpreter_wrapper.py", line 106, in AllocateTensors
    Return _tensorflow_wrap_interpreter_wrapper.InterpreterWrapper_AllocateTensors(self)
RuntimeError: tensorflow/contrib/lite/kernels/pooling.cc:103 input->params.scale != output->params.scale (102483008 != 102482528)Node number 116 (MAX_POOL_2D) failed to prepare.

我尝试替换了网络inception-v3,inception-resnet-v2,但是都出现了类似的错误。

我的训练代码是基于facenet框架的,我在原始训练的基础上做了一些小的更改。定义total_loss_op之后,添加以下两行代码:

train_graph = tf.get_default_graph()
tf.contrib.quantize.create_training_graph(input_graph=train_graph, quant_delay=20000)

在freeze.py文件中,当定义了推理图时,我添加以下代码:

g = tf.get_default_graph()
tf.contrib.quantize.create_eval_graph(input_graph=g)

然后加载之前训练过的ckpt,最后将其另存为pb文件。代码如下:

saver = tf.train.Saver(tf.global_variables())
sess = tf.Session()
with sess.as_default():
   saver.restore(sess, ckpt_model_path)
   frozen_graph_def = graph_util.convert_variables_to_constants(
             sess, sess.graph_def, ['embeddings'])
   tf.train.write_graph(
             frozen_graph_def,
             os.path.dirname(save_pb_path),
             os.path.basename(save_pb_path),
             as_text=False)

然后我使用tensorflow1.12.0 toco工具转换了pb文件并成功生成了tflite。具体命令如下:

./bazel-bin/tensorflow/contrib/lite/toco/toco \
--input_file=inception_resnet_v1_fake_quantized_eval.pb \
--output_file=tflite_model.tflite \
--input_format=TENSORFLOW_GRAPHDEF \
--output_format=TFLITE \
--inference_type=QUANTIZED_UINT8 \
--input_shape="1,160,160,3" \
--input_array=input \
--output_array=embeddings \
--std_value=127.5 \
--mean_value=127.5 \
--default_ranges_min=-1.0 \
--default_ranges_max=1.0

最后,我使用生成的tflite模型测试图像,但出现以下错误。

RuntimeError: tensorflow/contrib/lite/kernels/pooling.cc:103 input->params.scale != output->params.scale (102483008 != 102482528)Node number 116 (MAX_POOL_2D) failed to prepare.

我的测试代码如下:

import numpy as np
import tensorflow as tf
import scipy

#Load TFLite model and allocate tensors.
interpreter = tf.contrib.lite.Interpreter(model_path="tensorflow-1.12.0/tflite_model.tflite")

interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
image = scipy.misc.imread("src/1511.jpg")
image_ = np.array([image.astype('uint8')])
print(image_.shape)
print(type(image_))
print(input_details)
print(output_details)
interpreter.set_tensor(input_details[0]['index'], image_)
interpreter.invoke()
output_data = interpreter.get_tensor(output_details[0]['index'])
print(output_data)

1 个答案:

答案 0 :(得分:0)

在转换模型时, hardcode_min_max.cc 中的函数 HardcodeMinMaxForConcatenation 将连接层的输入数组和输出数组的minmax调整为相同。

然后在同一文件中的函数 HardcodeMinMaxForAverageOrMaxPool ,将发现最大池化层的输出数组获得minmax信息,并跳过将其更改为与输入数组相同的信息。

结果显示池层的输入数组和输出数组的minmax不相同。

我相信这是一个错误。