Quantized tflite что это
Распознавание объектов на android с помощью TensorFlow: от подготовки данных до запуска на устройстве
Обучение нейросети распознаванию образов — долгий и ресурсоемкий процесс. Особенно когда под рукой есть только недорогой ноут, а не компьютер с мощной видеокартой. В этом случае на помощь придёт Google Colaboratory, которая предлагает совершенно бесплатно воспользоваться GPU уровня Tesla K80 (подробнее).
В этой статье описан процесс подготовки данных, обучения модели tensorflow в Google Colaboratory и её запуск на android устройстве.
Подготовка данных
В качестве примера попробуем обучить нейросеть распознавать белые игральные кости на черном фоне. Соответственно, для начала, надо создать набор данных, достаточный для обучения (пока остановимся на
Для обучения воспользуемся Tensorflow Object Detection API. Все необходимые для обучения данные мы подготовим на ноутбуке. Нам понадобится менеджер управления окружением и зависимостями conda. Инструкция по установке тут.
Создадим окружение для работы:
Установим зависимости которые нам понадобятся:
Создадим папку object_detection, и положим все наши фотографии в папку object_detection/images.
В Google Colab есть ограничение на использование памяти, поэтому перед разметкой данных нужно снизить разрешение фотографий, чтобы в процессе обучения не столкнутся с ошибкой «tcmalloc: large alloc….».
Создадим папку object_detection/preprocessing и добавим в неё подготовленные скрипты.
Для изменения размера фото используем скрипт:
Этот скрипт пробежится по папке с указанными фото, изменит их размер до 800×600 и сложит их в object_detection/images/resized. Теперь можно заменить ими оригинальные фотографии в object_detection/images.
Для разметки данных воспользуемся тулзой labelImg.
Клонируем репозиторий labelImg в object_detection
Переходим в папку labelImg
и выполняем команду:
После этого можно приступить к разметке данных (это самый долгий и скучный этап):
В “Open dir” указываем папку object_detection/images и проходим по всем фото, выделяя объекты для распознавания и указывая их класс. В нашем случае это номиналы игральных костей (1, 2, 3, 4, 5, 6). Сохраним метаданные (файлы *.xml) в той же папке.
Создадим папку object_detection/training_demo, которую мы чуть позже зальем в Google Colab для обучения.
Разделим наши фото (с метаданными) на тренировочные и тестовые в соотношение 80/20 и переместим их в соответствующие папки object_detection/training_demo/images/train и object_detection/training_demo/images/test.
Создадим папку object_detection/training_demo/annotations, в которую будем складывать файлы с метаданными необходимыми для обучения. Первым из них будет label_map.pbtxt, в котором укажем отношение класса объекта и целочисленного значения. В нашем случае это:
Помните метаданные, которые мы получили в процессе разметки данных? Чтобы использовать их для обучения, необходимо конвертировать их в формат TFRecord. Для конвертации воспользуемся скриптами из источника [1].
Перейдём в папку preprocessing :
1.Из xml в csv
2. Из csv в record
На этом мы закончили подготовку данных, теперь надо выбрать модель, которую будем обучать.
Доступные модели для переобучения можно найти тут.
Сейчас мы выберем модель ssdlite_mobilenet_v2_coco, чтобы в дальнейшем запустить обученную модель на android устройстве.
Скачиваем архив с моделью и распаковываем его в object_detection/training_demo/pre-trained-model.
Должно получиться что-то вроде
object_detection/training_demo/pre-trained-model/ssdlite_mobilenet_v2_coco_2018_05_09
Из распакованного архива копируем файл pipeline.config в object_detection/training_demo/training и переименовываем его в ssdlite_mobilenet_v2_coco.config.
Далее нам надо настроить его под свою задачу, для этого:
1. Укажем количество классов
2. Укажем размер пакета (количество данных для обучения за одну итерацию), количество итераций и путь к сохраненной модели из архива, который мы скачали
3. Укажем количество фото в тренировочном наборе (object_detection/training_demo/images/train)
4. Укажем путь к набору данных для тренировки
5. Укажем путь к тестовому набору данных
В итоге, у вас должно получиться что то вроде этого.
Далее архивируем папку training_demo и получившийся training_demo.zip заливаем в Google Drive.
В этой статье рассказывается как примонтировать google drive к виртуальной машине Google Colab, но нужно не забыть поменять все пути в конфигах и скриптах
На этом подготовка данных закончена, перейдем к обучению.
Обучение модели
В Google Drive выбираем training_demo.zip, кликаем на Get shareable link и из полученной ссылки сохраним себе id этого файла:
drive.google.com/open?id=[YOUR_FILE_ID_HERE]
Самый просто способ воспользоваться Google Colab — создать новый блокнот в Google Drive.
По умолчанию обучение будет выполняться на CPU. Чтобы использовать GPU, нужно поменять тип runtime.
Готовый блокнот можно взять тут.
Обучение состоит из следующих этапов:
1. Клонируем репозиторий TensorFlow Models:
2. Устанавливаем protobuf и компилируем необходимые файлы в object_detection:
3. Добавляем необходимые пути в переменную окружения PYTHONPATH:
4. Для получения файла из Google Drive устанавливаем PyDrive и авторизируемся:
5. Скачиваем архив (нужно указать id вашего файла) и разархивируем его:
6. Запускаем процесс обучения:
—train_dir=./training_demo/training — путь к директории, где будут лежать
результаты обучение
—pipeline_config_path=./training_demo/training/ssdlite_mobilenet_v2_coco.config — путь к конфигу
7. Конвертируем результат обучения в frozen graph, который можно будет использовать:
—pipeline_config_path /content/training_demo/training/ssdlite_mobilenet_v2_coco.config — путь к конфигу
—trained_checkpoint_prefix /content/training_demo/training/model.ckpt-[CHECKPOINT_NUMBER] — путь к чекпоинту, который мы хотим конвертировать.
—output_directory /content/training_demo/training/output_inference_graph_v1.pb — имя сконвертированной модели
Номер чекпоинта [CHECKPOINT_NUMBER], можно посмотреть в папке content/training_demo/training/. ПОСЛЕ обучения там должны появиться файлы типа model.ckpt-1440.index, model.ckpt-1440.meta. 1440 — это и [CHECKPOINT_NUMBER] и номер итерации обучения.
Для визуализации результата обучения в блокноте есть специальный скрипт. На рисунке ниже показан результат распознавания изображения из тестового набора данных после
20000 итераций обучения.
8. Конвертация обученной модели в tflite.
Для использования tensorflow lite нужно конвертировать модель в формат tflite. Для этого конвертируем результат обучения в frozen graph который поддерживает конвертацию в tflite (параметры такие же как при использовании скрипта export_inference_graph.py):
Для конвертации в tflite нам нужна дополнительная информация о модели, для её получения скачиваем модель из output_inference_graph_tf_lite.pb:
И открываем её в тулзе Netron. Нас интересует названия и размерность входного и выходного узлов модели.
Зная их можно конвертировать pb модель в tflite формат:
—output_file=/content/training_demo/training/model_q.tflite — путь к результату конвертации
—graph_def_file=/content/training_demo/training/output_inference_graph_tf_lite_v1.pb/tflite_graph.pb — путь к frozen graph, который нужно конвертировать
—input_arrays=normalized_input_image_tensor — название входного узла, которое мы узнали выше
—output_arrays=’TFLite_Detection_PostProcess’,’TFLite_Detection_PostProcess:1′,’TFLite_Detection_PostProcess:2′,’TFLite_Detection_PostProcess:3′ — названия выходных узлов, которые мы узнали выше
—input_shapes=1,300,300,3 — размерность входных данных, которые мы узнали выше
—enable_select_tf_ops — для использования расширенного runtime TensorFlow Lite
—allow_custom_ops — для использования TensorFlow Lite Optimizing Converter
—inference_type=FLOAT — тип данных для всех массивов в модели кроме входных
—inference_input_type=QUANTIZED_UINT8 — тип данных для всех входных массивов в модели
—mean_values=128 —std_dev_values=128 — среднее значение и стандартное отклонение входных данных, для использования QUANTIZED_UINT8
Архивируем папку с результатами обучения и заливаем её в Google Drive:
Если будет ошибка Invalid client secrets file, то нужно сделать повторную авторизацию в google drive.
Запуск модели на android устройстве
В основе android приложения был использован официальный гайд по object detection, но он был полностью переписан с использованием kotlin и CameraX. Полностью код можно посмотреть тут.
CameraX уже имеет механизм для анализа входящих фреймов с камеры с помощью ImageAnalysis. Логика по распознаванию находится в ObjectDetectorAnalyzer.
Весь процесс распознавания изображения можно разбить на несколько этапов:
1. На вход мы получаем изображение которое имеет YUV формат. Для дальнейшей работы его нужно конвертировать в RGB формат:
2. Далее нужно трансформировать изображение (повернуть, если есть необходимость, и изменить размер до входных значений модели, в нашем случае это 300×300), для этого отрисуем массив с пикселями на Bitmap и применим на нём трансформацию:
3. Конвертируем bitmap в массив пикселей, и отдадим его на вход детектора:
4. Для визуализации передадим результат распознавания в RecognitionResultOverlayView и преобразуем координаты с соблюдением соотношения сторон:
Чтобы запустить нашу модель в приложении, нужно заменить в assets файл с моделью на training_demo/training/model_q.tflite (переименовав её в detect.tflite) и файл с метками labelmap.txt, в нашем случае это:
Так как в официальном гайде используется SSD Mobilenet V1, в котором индексация меток начинает с 1, а не с 0, нужно поменять labelOffset с 1 на 0 в методе collectDetectionResult класса ObjectDetector.
На этом всё.
На видео результат того, как обученная модель работает на стареньком Xiaomi Redmi 4X :
В процессе работы использовались следующие ресурсы:
Post-training integer quantization
Overview
Integer quantization is an optimization strategy that converts 32-bit floating-point numbers (such as weights and activation outputs) to the nearest 8-bit fixed-point numbers. This results in a smaller model and increased inferencing speed, which is valuable for low-power devices such as microcontrollers. This data format is also required by integer-only accelerators such as the Edge TPU.
In this tutorial, you’ll train an MNIST model from scratch, convert it into a Tensorflow Lite file, and quantize it using post-training quantization. Finally, you’ll check the accuracy of the converted model and compare it to the original float model.
You actually have several options as to how much you want to quantize a model. In this tutorial, you’ll perform «full integer quantization,» which converts all weights and activation outputs into 8-bit integer data—whereas other strategies may leave some amount of data in floating-point.
To learn more about the various quantization strategies, read about TensorFlow Lite model optimization.
Setup
In order to quantize both the input and output tensors, we need to use APIs added in TensorFlow r2.3:
Generate a TensorFlow Model
We’ll build a simple model to classify numbers from the MNIST dataset.
This training won’t take long because you’re training the model for just a 5 epochs, which trains to about
Convert to a TensorFlow Lite model
Now you can convert the trained model to TensorFlow Lite format using the TFLiteConverter API, and apply varying degrees of quantization.
Beware that some versions of quantization leave some of the data in float format. So the following sections show each option with increasing amounts of quantization, until we get a model that’s entirely int8 or uint8 data. (Notice we duplicate some code in each section so you can see all the quantization steps for each option.)
First, here’s a converted model with no quantization:
It’s now a TensorFlow Lite model, but it’s still using 32-bit float values for all parameter data.
Convert using dynamic range quantization
Now let’s enable the default optimizations flag to quantize all fixed parameters (such as weights):
The model is now a bit smaller with quantized weights, but other variable data is still in float format.
Convert using float fallback quantization
Now all weights and variable data are quantized, and the model is significantly smaller compared to the original TensorFlow Lite model.
However, to maintain compatibility with applications that traditionally use float model input and output tensors, the TensorFlow Lite Converter leaves the model input and output tensors in float:
That’s usually good for compatibility, but it won’t be compatible with devices that perform only integer-based operations, such as the Edge TPU.
Additionally, the above process may leave an operation in float format if TensorFlow Lite doesn’t include a quantized implementation for that operation. This strategy allows conversion to complete so you have a smaller and more efficient model, but again, it won’t be compatible with integer-only hardware. (All ops in this MNIST model have a quantized implementation.)
So to ensure an end-to-end integer-only model, you need a couple more parameters.
Convert using integer-only quantization
To quantize the input and output tensors, and make the converter throw an error if it encounters an operation it cannot quantize, convert the model again with some additional parameters:
The internal quantization remains the same as above, but you can see the input and output tensors are now integer format:
Now you have an integer quantized model that uses integer data for the model’s input and output tensors, so it’s compatible with integer-only hardware such as the Edge TPU.
Save the models as files
Run the TensorFlow Lite models
Now we’ll run inferences using the TensorFlow Lite Interpreter to compare the model accuracies.
First, we need a function that runs inference with a given model and images, and then returns the predictions:
Test the models on one image
Now we’ll compare the performance of the float model and quantized model:
Let’s create another function to print our predictions:
Now test the float model:
And test the quantized model:
Evaluate the models on all images
Now let’s run both models using all the test images we loaded at the beginning of this tutorial:
Evaluate the float model:
Evaluate the quantized model:
So you now have an integer quantized a model with almost no difference in the accuracy, compared to the float model.
To learn more about other quantization strategies, read about TensorFlow Lite model optimization.
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Распознавание объектов на android с помощью TensorFlow: от подготовки данных до запуска на устройстве
Обучение нейросети распознаванию образов — долгий и ресурсоемкий процесс. Особенно когда под рукой есть только недорогой ноут, а не компьютер с мощной видеокартой. В этом случае на помощь придёт Google Colaboratory, которая предлагает совершенно бесплатно воспользоваться GPU уровня Tesla K80 (подробнее).
В этой статье описан процесс подготовки данных, обучения модели tensorflow в Google Colaboratory и её запуск на android устройстве.
Подготовка данных
В качестве примера попробуем обучить нейросеть распознавать белые игральные кости на черном фоне. Соответственно, для начала, надо создать набор данных, достаточный для обучения (пока остановимся на
Для обучения воспользуемся Tensorflow Object Detection API. Все необходимые для обучения данные мы подготовим на ноутбуке. Нам понадобится менеджер управления окружением и зависимостями conda. Инструкция по установке тут.
Создадим окружение для работы:
Установим зависимости которые нам понадобятся:
Создадим папку object_detection, и положим все наши фотографии в папку object_detection/images.
В Google Colab есть ограничение на использование памяти, поэтому перед разметкой данных нужно снизить разрешение фотографий, чтобы в процессе обучения не столкнутся с ошибкой «tcmalloc: large alloc. «.
Создадим папку object_detection/preprocessing и добавим в неё подготовленные скрипты.
Для изменения размера фото используем скрипт:
Этот скрипт пробежится по папке с указанными фото, изменит их размер до 800×600 и сложит их в object_detection/images/resized. Теперь можно заменить ими оригинальные фотографии в object_detection/images.
Для разметки данных воспользуемся тулзой labelImg.
Клонируем репозиторий labelImg в object_detection
Переходим в папку labelImg
и выполняем команду:
После этого можно приступить к разметке данных (это самый долгий и скучный этап):
В “Open dir” указываем папку object_detection/images и проходим по всем фото, выделяя объекты для распознавания и указывая их класс. В нашем случае это номиналы игральных костей (1, 2, 3, 4, 5, 6). Сохраним метаданные (файлы *.xml) в той же папке.
Создадим папку object_detection/training_demo, которую мы чуть позже зальем в Google Colab для обучения.
Разделим наши фото (с метаданными) на тренировочные и тестовые в соотношение 80/20 и переместим их в соответствующие папки object_detection/training_demo/images/train и object_detection/training_demo/images/test.
Создадим папку object_detection/training_demo/annotations, в которую будем складывать файлы с метаданными необходимыми для обучения. Первым из них будет label_map.pbtxt, в котором укажем отношение класса объекта и целочисленного значения. В нашем случае это:
Помните метаданные, которые мы получили в процессе разметки данных? Чтобы использовать их для обучения, необходимо конвертировать их в формат TFRecord. Для конвертации воспользуемся скриптами из источника [1].
Как перенести нейросеть на мобильное устройство
В статье поговорим как обучить несложную CNN сеть с помощью tensorflow, конвертировать готовое с помощью tensoflow-lite и перенести на мобильное устройство под управлением android.
Описывается личный опыт автора, поэтому нет претензий на всеохватывающее руководство.
Нейросеть до конвертации.
Для старта возьмем не слишком сложную нейросеть, код которой приведен ниже:
Краткое пояснение по коду. После импорта пакетов tensorflow,numpy мы формируем модель нейросети. Модель представляет из себя только один слой и только один нейрон.
Сама структура модели представляет из себя два набора данных, в которых:
Данные наборы «укладываются» в формулу Y = 2X – 1. Таким образом, для каждого Y из набора прослеживается зависимость.
После формирования модели производится ее компиляция с оптимизатором sgd и функцией потерь mean_squared_error.
Далее в модель попадают наборы данных и производится обучение на протяжении 500 эпох
(model.fit(xs, ys, epochs=500).
*Нейросеть лучше обучать на железе помощнее либо в Google colab для ускорения процесса, так как 500 эпох могут занять до 2-3 часов времени.
И, наконец, модель проверяется путем подачи ей на вход числа 10.0. То есть мы пытаемся выяснить с помощью модели значение Y при X=10.0. В идеале, согласно формуле, Y должен быть 19.0. Но в итоге будет число, сильно приближенное по значению к 19.0.
Так работает созданная нейросеть. Именно ее мы и будем конвертировать и переносить на android устройство.
Конвертация нейросети.
Для целей переноса модели на мобильное устройство воспользуемся tensorflow-lite. Сам по себе tensorflow-lite представляется из себя набор утилит, преследующий две основные цели. Первая из которых — сделать из нейросети модель, приемлемую для мобильного устройства. Обычно под этим подразумевается уменьшение размера и сложности сети, что, в свою очередь, приводит к небольшому падению точности работы. Тем не менее это необходимый компромисс между аккуратностью работы нейросети и ее размерами на мобильном устройстве. Вторая цель — создание среды выполнения для различных мобильных платформ, включая android, ios, микроконтроллеры.
Важной чертой tensorflow-lite является то, что с ее помощью невозможно тренировать модель. Нейросеть должна быть сначала обучена с помощью tensorflow и далее конвертирована в формат tensorflow-lite.
Зачем вообще переносить нейросеть на мобильное устройство?
Вопрос риторический, но из аргументов «за» — приватность используемых данных и отсутствие необходимости использования сетей связи при работе, например, с облачными решениями.
Говоря о конвертации в приемлемый tensorflow-lite формат, вернемся к коду нейросети из предыдущего блока.
Необходимо сперва сохранить готовую модель:
В результате получится файл «model.pb».
Теперь очередь конвертации:
Готовую model.tflite модель можно использовать в различных окружениях, например, android или ios.
Как работает модель в tensorflow-lite
Загрузка модели, выделение тензоров
Загрузим модель в интерпретатор, выделим тензоры, которые будут использоваться для ввода данных в модель для прогнозирования, а затем прочитаем то, что выводит модель.
Здесь проявляется главное отличие tensorflow-lite от Tensorflow. Если во втором случае возможно просто использовать model.predict(что-то) и сразу получить результат, то в tensorflow-lite необходимо поработать с сходными и выходными тензорами, приводя свои данные для соответствия их формату.
Посмотрим как это выглядит:
В результате вывод будет следующим:
В выводе input_details необходимо обратить внимание на shape(размерность) — массив 1,1 и класс данных — numpy.float32. Эти параметры будут определять входные данные и их формат.
Используя данную информацию, определим Y для X=10.0:
В выводе output_details формат данных схож, поэтому ответ нейросети будет в виде [[y]], также как и [[x]]:
Прогнозирование, использование модели
Чтобы заставить интерпретатор выполнить прогнозирование, необходимо задать входной тензор со значением для прогнозирования:
Так как у нас очень простая модель, в которой есть только один параметр ввода, поэтому это input_details[0], к нему мы и обращаемся в индексе.
Затем мы вызываем интерпретатор с помощью метода invoke.
Теперь мы осуществим прогнозирование с помощью модели, используя выражение get_tensor:
Опять же, существует только один выходной тензор, поэтому он будет выглядеть как output_details[0].
В целом код выглядит следующим образом:
Где 10 — это входное значение или X, а 18.97 — предсказанная величина, близкая к 19 (формула нейросети та же Y=2X – 1).
Перенос модели на android устройство (мобильный телефон)
После создания модели нейросети и ее конвертации в формат tensorflow-lite,
создадим приложение для Android.
Скачивание и установка Android Studio может занять время, поэтому, если с этим возникнут сложности, лучше обратиться к сторонним мануалам. Язык, который будет использоваться при создании нашего приложения — Kotlin.
Приложение, которое будет перенесено на android — это простая нейросеть, которая была создана и конвертирована выше по тексту. При вводе значения Х пользователем, нейросеть будет предсказывать Y, выводя результат на экране смартфона.
Создаем новый проект в Android Studio
Цепочка действий после запуска Android Studio следующая:
File → New → New Project→ Empty Activity
Далее заполним поля проекта, не забыв указать язык — Kotlin:
После нажатия Finish, Android Studio создаст проект.
*На картинке уже готовый проект, при создании дизайн выглядит иначе.
Заменим код, который там приведен на
Это сформирует внешний вид приложения.
Добавим зависимости Tensorflow lite
Нам нужны build.gradle файлы. Их в проекте два, и нужен тот, который содержит app в названии и расположен в директории app:
В этом же файле также необходимо добавить:
Полностью файл build.gradle будет выглядеть так:
Теперь добавим в проект саму модель нейросети tf-lite
В папке main создадим папку assets и перенесем туда ранее сконвертированную модель —
Привяжем модель нейросети к android приложению
Откроем файл MainActivity.kt:
После этого, можно протестировать готовое приложение, нажав на кнопку Run ‘app’
Тестирование проведем в эмуляторе android устройства:
После ввода X, приложение выдаст значение Y, приближенное к расчетному значению по формуле Y=2X-1, то есть нейросеть работает.
\app\build\outputs\apk\debug и, подключив смартфон к ПК, перенести на смартфон.
В принципе, все, теперь простая нейросеть живет на смартфоне, занимая всего 10Мб.