Невозможно протестировать и развернуть модель сегментации deeplabv3-mobilenetv2 tensorflow-lite для вывода

Мы пытаемся запустить модель семантической сегментации на android с помощью deeplabv3 и mobilenetv2. Мы следовали официальной процедуре преобразования tensorflow lite с использованием TOCO и tflite_convert с помощью bazel. Исходный замороженный график был получен из официального зоопарка TensorFlow DeepLab Model Zoo.

Нам удалось успешно преобразовать модель с помощью следующей команды: -

CUDA_VISIBLE_DEVICES = "0" toco --output_file=toco256.tflite --graph_def_file=path/to/deeplab/deeplabv3_mnv2_pascal_trainval/frozen_inference_graph.pb --input_arrays=ImageTensor --output_arrays=SemanticPredictions --input_shapes=1,256,256,3 --inference_input_type=QUANTIZED_UINT8 --inference_type=FLOAT --mean_values=128 --std_dev_values=127 --allow_custom_ops --post_training_quantize

Размер файла tflite составлял около 2,25 Мб, но когда мы попытались протестировать модель с помощью официального инструмента для тестирования производительности, у нас возник следующий отчет об ошибке:

bazel run -c opt tensorflow/contrib/lite/tools/benchmark:benchmark_model -- --graph=`realpath toco256.tflite`
INFO: Analysed target //tensorflow/contrib/lite/tools/benchmark:benchmark_model (0 packages loaded).
INFO: Found 1 target...
Target //tensorflow/contrib/lite/tools/benchmark:benchmark_model up-to-date:
  bazel-bin/tensorflow/contrib/lite/tools/benchmark/benchmark_model
INFO: Elapsed time: 0.154s, Critical Path: 0.00s
INFO: 0 processes.
INFO: Build completed successfully, 1 total action
INFO: Running command line: bazel-bin/tensorflow/contrib/lite/tools/benchmark/benchmark_model '--graph=path/to/deeplab/venINFO: Build completed successfully, 1 total action
STARTING!
Num runs: [50]
Inter-run delay (seconds): [-1]
Num threads: [1]
Benchmark name: []
Output prefix: []
Warmup runs: [1]
Graph: path/to/venv/tensorflow/toco256.tflite]
Input layers: []
Input shapes: []
Use nnapi : [0]
Loaded model path/to/venv/tensorflow/toco256.tflite
resolved reporter
Initialized session in 45.556ms
Running benchmark for 1 iterations 
tensorflow/contrib/lite/kernels/pad.cc:96 op_context.dims != 4 (3 != 4)
Node number 24 (PAD) failed to prepare.

Failed to invoke!
Aborted (core dumped)

Мы также попробовали ту же команду без включения параметров allow_custom_ops и post_training_quantize и даже использовали тот же размер ввода, что и 1,513,513,3; но результат был таким же.

Эта проблема похожа на следующую проблему на github: (https://github.com/tensorflow/tensorflow/issues/21266). Однако в последней версии TensorFlow проблема должна быть исправлена.

Модель: http://download.tensorflow.org/models/deeplabv3_mnv2_pascal_trainval_2018_01_29.tar.gz Версия Tensorflow: 1.11 Версия Bazel: 0.17.2 ОС: Ubuntu 18.04

Также приложение Android не смогло правильно загрузить модель (интерпретатор tflite)

Итак, как мы можем правильно преобразовать модель сегментации в формат tflite, который можно использовать для вывода на устройстве Android?

ОБНОВИТЬ:-

Используя тензорный поток 1.12, мы получили новую ошибку:

$ bazel run -c opt tensorflow/lite/tools/benchmark:benchmark_model -- --graph=`realpath /path/to/research/deeplab/venv/tensorflow/toco256.tflite`

    tensorflow/lite/kernels/depthwise_conv.cc:99 params->depth_multiplier * SizeOfDimension(input, 3) != SizeOfDimension(filter, 3) (0 != 32)
    Node number 30 (DEPTHWISE_CONV_2D) failed to prepare.

Кроме того, при использовании более новой версии той же модели (файл .pb размером 3 МБ) с depth_multiplier = 0,5 из tensorflow deeplab модельный зоопарк мы получили другую ошибку: -

F tensorflow/lite/toco/graph_transformations/propagate_fixed_sizes.cc:116] Check failed: dim_x == dim_y (3 vs. 32)Dimensions must match

В этом случае мы использовали ту же вышеупомянутую команду для преобразования tflite; но мы даже не смогли создать файл tflite в качестве вывода. Похоже, это проблема со значениями множителя глубины (даже мы пытались указать параметр depth_multiplier в качестве аргумента. на момент конвертации).

9
0
4 092
2

Ответы 2

У меня такая же проблема. от https://github.com/tantara/JejuNet я вижу, что он успешно конвертировал модель в tflite. Я пишу ему в личку с просьбой о помощи, но, к сожалению, сейчас ответа нет.

Собственно, мы тоже пробовали то же самое и даже обсуждали с одним и тем же человеком. К сожалению, мы не смогли решить проблему. Но похоже, что проблема кроется в начальных слоях замороженного графа, где выполняются некоторые операции p-обработки. связанных с размером или регулировкой размера (ввод [1,?,?, 3], для принятия произвольного размера). Некоторые из них могут не поддерживаться tenorflow lite (который ожидает входов фиксированного размера). Может быть, если мы удаляем или пропускаем их, это может сработать. В противном случае нам, возможно, придется переобучить сеть после ее изменения.

anilsathyan7 24.11.2018 04:51

Скинул JejuNet tflite, он сильно отличается от того, что мы преобразовали из официальной модели. входной узел - MobilenetV2 / MobilenetV2 / input и тип uint8 [1,256,256,3]. всего ОП только 71. а у нас 156

Alpha 26.11.2018 03:11

Теперь проблема решена? Если да, не могли бы вы рассказать, как решить. В моем случае я мог сгенерировать файл .tflite. но, когда я помещаю его в Jejunet, я получаю ошибку типа «java.lang.IllegalArgumentException: ByteBuffer не является допустимой моделью плоского буфера». По возможности поделитесь параметрами для преобразования .pb в .tflite. Если вы не используете JejuNet, подскажите, пожалуйста, что еще я могу использовать?

Rajesh_Saladi 19.04.2019 08:08

Я тоже столкнулся с этой проблемой. Похоже, что при преобразовании есть 2 проблемы:

  • Входной тензор имеет динамическую форму, то есть [?,?,?, 3]
  • Часть узла pad_to_bounding_box не преобразуется автоматически в статическую форму

Для решения ниже это проверено на:

  • Tensorflow 1.15
  • Ubuntu 16.0.4

Решение

Я предполагаю, что вы уже создали файл .pb с помощью файла export_model.py в папке deeplab и назвали этот файл deeplab_mobilenet_v2.pb. С этого момента:

ШАГ 1: ОПТИМИЗАЦИЯ ВЫВОДА

python3 optimize_for_inference.py \
        --input "path/to/your/deeplab_mobilenet_v2.pb" \
        --output "path/to/deeplab_mobilenet_v2_opt.pb" \
        --frozen_graph True \
        --input_names ImageTensor \
        --output_names SemanticPredictions \
        --placeholder_type_enum=4

placeholder_type_enum = 4 - тип данных uint8 (dtypes.uint8.as_datatype_enum)

ШАГ 2: ПРИМЕНЕНИЕ ИНСТРУМЕНТА ПРЕОБРАЗОВАНИЯ ГРАФИКА

Убедитесь, что вы установили bazel и загрузили ветку tensorflow r1.15 с github. Затем создайте инструмент transform_graph из репозитория тензорного потока:

bazel build tensorflow/tools/graph_transforms:transform_graph

Затем запустите инструмент transform_graph (убедитесь, что вы установили форму для той формы, которую вы используете в качестве входных):

bazel-bin/tensorflow/tools/graph_transforms/transform_graph \
--in_graph = "/path/to/deeplab_mobilenet_v2_opt.pb" \
--out_graph = "/path/to/deeplab_mobilenet_v2_opt_flatten.pb" \
--inputs='ImageTensor' \
--outputs='SemanticPredictions' \
--transforms='
    strip_unused_nodes(type=quint8, shape = "1,400,225,3")
    flatten_atrous_conv
    fold_constants(ignore_errors=true, clear_output_shapes=false)
    fold_batch_norms
    fold_old_batch_norms
    remove_device
    sort_by_execution_order'

ШАГ 3: ОБЙТИ УЗЛА pad_to_bounding_box И СДЕЛАЙТЕ ВХОД СТАТИЧЕСКИМ

Запустите файл python ниже, не забудьте изменить model_filepath, save_folder и save_name на все, что вам подходит.

import tensorflow as tf
import numpy as np
from tensorflow.contrib import graph_editor as ge

def freeze_session(session, keep_var_names=None, output_names=None, clear_devices=True):
    """
    Freezes the state of a session into a pruned computation graph.

    Creates a new computation graph where variable nodes are replaced by
    constants taking their current value in the session. The new graph will be
    pruned so subgraphs that are not necessary to compute the requested
    outputs are removed.
    @param session The TensorFlow session to be frozen.
    @param keep_var_names A list of variable names that should not be frozen,
                          or None to freeze all the variables in the graph.
    @param output_names Names of the relevant graph outputs.
    @param clear_devices Remove the device directives from the graph for better portability.
    @return The frozen graph definition.
    """
    graph = session.graph
    with graph.as_default():
        freeze_var_names = list(set(v.op.name for v in tf.global_variables()).difference(keep_var_names or []))
        output_names = output_names or []
        output_names += [v.op.name for v in tf.global_variables()]
        input_graph_def = graph.as_graph_def()
        if clear_devices:
            for node in input_graph_def.node:
                node.device = ""
        frozen_graph = tf.graph_util.convert_variables_to_constants(
            session, input_graph_def, output_names, freeze_var_names)
        return frozen_graph

def load_convert_save_graph(model_filepath, save_folder, save_name):
    '''
    Lode trained model.
    '''
    print('Loading model...')
    graph = tf.Graph()
    sess = tf.InteractiveSession(graph = graph)

    with tf.gfile.GFile(model_filepath, 'rb') as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())

    print('Check out the input placeholders:')
    nodes = [n.name + ' => ' +  n.op for n in graph_def.node if n.op in ('Placeholder')]
    for node in nodes:
        print(node)

    # Define input tensor
    input = tf.placeholder(np.uint8, shape = [1,400,225,3], name='ImageTensor')

    tf.import_graph_def(graph_def, {'ImageTensor': input}, name='')

    print('Model loading complete!')

    # remove the pad to bounding box node
    name = "pad_to_bounding_box"
    print(name)
    sgv = ge.make_view_from_scope(name, tf.get_default_graph())
    print("\t" + sgv.inputs[0].name)
    for node in sgv.inputs:
        print("name in = " + node.name)
    for node in sgv.outputs:
        print("name out = " + node.name)
    print("\t" + sgv.outputs[len(sgv.outputs)-1].name)
    sgv = sgv.remap_inputs([0])
    sgv = sgv.remap_outputs([len(sgv.outputs)-1])
    (sgv2, det_inputs) = ge.bypass(sgv)


    frozen_graph = freeze_session(sess,
                              output_names=['SemanticPredictions'])
    tf.train.write_graph(frozen_graph, save_folder, save_name, as_text=False)


load_convert_save_graph("path/to/deeplab_mobilenet_v2_opt_flatten.pb", "/path/to", "deeplab_mobilenet_v2_opt_flatten_static.pb")

ШАГ 4: ПРЕОБРАЗОВАТЬ В TFLITE

tflite_convert \
  --graph_def_file = "/path/to/deeplab_mobilenet_v2_opt_flatten_static.pb" \
  --output_file = "/path/to/deeplab_mobilenet_v2_opt_flatten_static.tflite" \
  --output_format=TFLITE \
  --input_shape=1,400,225,3 \
  --input_arrays = "ImageTensor" \
  --inference_type=FLOAT \
  --inference_input_type=QUANTIZED_UINT8 \
  --std_dev_values=128 \
  --mean_values=128 \
  --change_concat_input_ranges=true \
  --output_arrays = "SemanticPredictions" \
  --allow_custom_ops

СДЕЛАНО

Теперь вы можете запустить свою модель tflite

Если бы была возможность проголосовать много раз, я бы это сделал. Эти ответы сэкономили мне много времени!

guneykayim 16.11.2020 18:05

Другие вопросы по теме