Как обучить квантованную модель mobilenet-v1 для использования в TF Lite

Я повторно обучил модель классификации изображений mobilenet-v1 из Tensorflow Hub и преобразовал ее с помощью toco для вывода с помощью Tensorflow Lite.

Однако, когда я запускаю вывод с использованием модели tflite, требуется другой размер ввода, отличный от того, который я указал с помощью --input_shape.

Как я могу повторно обучить квантованную модель mobilenetv1 на моих собственных данных?

Вот шаги, которые я предпринял:

  • Загрузите набор обучающих данных из tensorflow для поэтов codelab
  • Переобучить квантованную модель мобильной сети v1 на концентраторе TF с использованием набор данных выше

    python retrain.py \ --bottleneck_dir="${IMAGE_DIR}"/tf_files/bottlenecks/ \ --how_many_training_steps=1000 \ --model_dir="${IMAGE_DIR}"/tf_files/models/mobilenet_v1_050_224 \ --summaries_dir="${IMAGE_DIR}"/tf_files/training_summaries/mobilenet_v1_050_224/ \ --output_graph="${IMAGE_DIR}"/tf_files/retrained_mobilenet_v1_050_224.pb \ --output_labels="${IMAGE_DIR}"/tf_files/retrained_labels.txt \ --tfhub_module=https://tfhub.dev/google/imagenet/mobilenet_v1_050_224/quantops/classification/1 \ --image_dir="${IMAGE_DIR}"/tf_files/flower_photos

  • Убедитесь, что модель правильно обучена и имя тензора ввода / вывода верное python label_image.py \ --graph="${IMAGE_DIR}"/tf_files/retrained_mobilenet_v1_050_224.pb \ --labels="${IMAGE_DIR}"/tf_files/retrained_labels.txt \ --input_layer=Placeholder \ --output_layer=final_result \ --input_height=224 --input_width=224 \ --image="${IMAGE_DIR}"/tf_files/flower_photos/daisy/21652746_cc379e0eea_m.jpg

  • Преобразуйте модель в tflite

    toco \ --input_file="${IMAGE_DIR}"/tf_files/retrained_mobilenet_v1_050_224.pb \ --output_file="${IMAGE_DIR}"/tf_files/mobilenet_v1_050_224_quant.tflite \ --input_format=TENSORFLOW_GRAPHDEF \ --output_format=TFLITE \ --input_shape=1,224,224,3 \ --input_array=Placeholder \ --output_array=final_result \ --inference_type=QUANTIZED_UINT8 \ --input_data_type=FLOAT

Хотя я указал --input_shape=1,224,224,3, при выполнении вывода я получил ошибку:

java.lang.IllegalArgumentException: DataType (1) of input data does not match with the DataType (3) of model inputs.


person khanhlvg    schedule 22.06.2018    source источник


Ответы (3)


--input_data_type = "" или --input_data_types = "" >> Тип входного массива, если он еще не указан на графике. Обычно необходимо указывать при передаче произвольных массивов в --input_arrays.

В моем случае это не понадобилось (я использовал предварительно обученную модель MobileNet_V2).

Вам нужно добавить еще несколько аргументов (--mean_value --std_value --default_ranges_min и --default_ranges_max) в вашу команду для кватизации.

Как указано в документации, у меня работает следующая команда

bazel-bin/tensorflow/contrib/lite/toco/toco --input_file=~/tf_files/retrained_graph_mobileNet_v2_100_224.pb --output_file=~/tf_files/retrained_graph_mobileNet_q_v2_100_224.tflite --input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE --inference_type=QUANTIZED_UINT8 --input_shape=1,224,224,3 --input_array=Placeholder --output_array=final_result --mean_value=128 --std_value=128 --default_ranges_min=0 --default_ranges_max=6
person Kaushik Roy    schedule 22.06.2018
comment
Не могли бы вы объяснить значения из --default_ranges_min=0 --default_ranges_max=6? Почему 0 и 6? - person user155; 13.05.2019
comment
Извините за мой поздний ответ и надеюсь, что вы уже знаете ответ. Тем не менее, я кратко изложу эту информацию, поскольку она может быть полезна другим. Модель MobileNet_V2 использует функцию активации Relu6, и выходной сигнал каждого нейрона должен находиться в диапазоне от 0 до 6. Следовательно, диапазоны активации должны содержаться в [0, 6]. Для получения подробной документации ссылка - person Kaushik Roy; 17.09.2019

Может я ошибаюсь,

но ошибка типа данных, похоже, не проблема с формой входных данных, а скорее с типом данных.

Если вы квантуете модель, это означает, что вы меняете тип данных с float32 на int8.

В зависимости от того, как вы запускаете свою модель, существуют разные типы квантования.

  • Использование нейронных процессоров в большинстве случаев требует полного квантования. - Это означает, что необходимо квантовать ввод и вывод, а также веса и смещение (смещение не на int8, а на int32)
  • Используя квантование только для того, чтобы сделать модель меньше и быстрее, но вы не запускаете ее на нейронном процессоре, половинное квантование вполне подойдет. - То есть, квантование только весов поможет.

Существуют также другие методы квантования, но я стремлюсь к следующему: если вы выполнили полное квантование, либо у вас есть слой квантования, который выполняет преобразование из float32 в int8 за вас, либо ваша модель ожидает входных данных int8.

edit: Я только что видел, что вы определяете вход как FLOAT. Возможно, термин float32 будет правильным. По крайней мере, что-то не так с вашим типом входных данных по сравнению с типом ввода первого слоя.

Вы можете использовать такой инструмент, как Netron, чтобы посмотреть на свой входной слой и увидеть, что ожидается. Этот инструмент также можно использовать для определения того, как была квантована ваша сеть.

Удачи и спасения.

person Florida Man    schedule 30.06.2020

Перенесемся в 2020 год, и сейчас самый простой способ обучить модель классификации изображений TF Lite - использовать TF Lite Model Maker. https://www.tensorflow.org/lite/tutorials/model_maker_image_classification

Выходную модель TF Lite можно перетащить в Android Studio с помощью подключаемого модуля привязки модели ML. Просмотрите сквозной поток в этом видео. https://www.youtube.com/watch?v=s_XOVkjXQbU

person khanhlvg    schedule 08.07.2020