При запуске модели tflite произошла следующая ошибка: input-›params.scale != output-›params.scale в узле MAX_POOL_2D

Я обучил модель распознавания лиц с помощью метода обучения с учетом квантования tensorflow версии 1.12.0. В сети используется inception-resnet_v1 (источник кода — tensorflow/models/research/slim/nets/). После завершения обучения я получаю ckpt, затем создаю новый файл freeze.py для генерации eval.pb, а затем успешно генерирую модель tflite с помощью toco. Но когда я, наконец, протестировал модель 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.

Пробовал заменить network,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)

Затем я использовал toco-инструмент tensorflow1.12.0 для преобразования 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)

person lishanlu136    schedule 28.01.2019    source источник


Ответы (1)


При преобразовании модели функция HardcodeMinMaxForConcatenation в hardcode_min_max.cc настраивает минимальное максимальное значение входных массивов и выходного массива слоя конкатенации, чтобы они были одинаковыми.

Затем функция HardcodeMinMaxForAverageOrMaxPool в том же файле обнаружит, что выходной массив максимального слоя пула получает минимальную информацию, и пропустит ее изменение на то же, что и входные массивы.

Оказывается, minmax входного массива и выходного массива слоя объединения не совпадают.

Я считаю, что это ошибка.

person Won    schedule 10.10.2019