Google I / O возвращается 18-20 мая! Зарезервируйте место и составьте свое расписание Зарегистрируйтесь сейчас

Квантование после обучения

Квантование после обучения - это метод преобразования, который может уменьшить размер модели, а также улучшить задержку ЦП и аппаратного ускорителя с небольшим ухудшением точности модели. Вы можете квантовать уже обученную модель TensorFlow с плавающей запятой при преобразовании ее в формат TensorFlow Lite с помощью TensorFlow Lite Converter .

Методы оптимизации

Есть несколько вариантов квантования после обучения на выбор. Вот сводная таблица вариантов выбора и преимуществ, которые они предоставляют:

Техника Преимущества Аппаратное обеспечение
Квантование динамического диапазона В 4 раза меньше, ускорение в 2–3 раза Процессор
Полное целочисленное квантование В 4 раза меньше, в 3 раза + ускорение ЦП, Edge TPU, микроконтроллеры
Квантование Float16 В 2 раза меньше, ускорение графического процессора CPU, GPU

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

варианты посттренировочной оптимизации

Квантование динамического диапазона

Простейшая форма посттренировочного квантования статически квантует только веса от числа с плавающей запятой до целого числа, которое имеет 8-битную точность:

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_quant_model = converter.convert()

При выводе веса преобразуются из 8-битной точности в числа с плавающей запятой и вычисляются с использованием ядер с плавающей запятой. Это преобразование выполняется один раз и кэшируется для уменьшения задержки.

Чтобы еще больше уменьшить время ожидания, операторы «динамического диапазона» динамически квантуют активации в соответствии с их диапазоном до 8-битных значений и выполняют вычисления с 8-битными весовыми коэффициентами и активациями. Эта оптимизация обеспечивает задержки, близкие к выводу с полностью фиксированной точкой. Однако выходные данные по-прежнему сохраняются с использованием плавающей запятой, так что ускорение с помощью операций динамического диапазона меньше, чем полное вычисление с фиксированной запятой.

Полное целочисленное квантование

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

Для полного целочисленного квантования вам необходимо откалибровать или оценить диапазон, т. Е. (Мин., Макс.) Всех тензоров с плавающей запятой в модели. В отличие от постоянных тензоров, таких как веса и смещения, переменные тензоры, такие как входные данные модели, активации (выходы промежуточных слоев) и выходные данные модели, нельзя откалибровать, если мы не запустим несколько циклов вывода. В результате конвертеру требуется репрезентативный набор данных для их калибровки. Этот набор данных может представлять собой небольшое подмножество (около ~ 100-500 выборок) данных обучения или проверки. Обратитесь к функции representative_dataset() ниже.

def representative_dataset():
  for data in tf.data.Dataset.from_tensor_slices((images)).batch(1).take(100):
    yield [tf.dtypes.cast(data, tf.float32)]

В целях тестирования вы можете использовать фиктивный набор данных следующим образом:

def representative_dataset():
    for _ in range(100):
      data = np.random.rand(1, 244, 244, 3)
      yield [data.astype(np.float32)]
 

Целое число с резервным значением с плавающей запятой (с использованием ввода / вывода с плавающей запятой по умолчанию)

Чтобы полностью квантовать модель целыми числами, но использовать операторы с плавающей запятой, когда они не имеют целочисленной реализации (чтобы преобразование происходило плавно), используйте следующие шаги:

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = representative_dataset
tflite_quant_model = converter.convert()

Только целое число

Создание только целочисленных моделей - распространенный вариант использования TensorFlow Lite для микроконтроллеров и TPU Coral Edge .

Кроме того, чтобы обеспечить совместимость с целочисленными устройствами (такими как 8-битные микроконтроллеры) и ускорителями (такими как Coral Edge TPU), вы можете принудительно применить полное целочисленное квантование для всех операций, включая ввод и вывод, выполнив следующие действия:

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = representative_dataset
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter.inference_input_type = tf.int8  # or tf.uint8
converter.inference_output_type = tf.int8  # or tf.uint8
tflite_quant_model = converter.convert()

Квантование Float16

Вы можете уменьшить размер модели с плавающей запятой, квантовав веса до float16, стандарта IEEE для 16-битных чисел с плавающей запятой. Чтобы включить квантование весов float16, выполните следующие действия:

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_types = [tf.float16]
tflite_quant_model = converter.convert()

Преимущества квантования float16 следующие:

  • Он уменьшает размер модели почти вдвое (так как все веса становятся вдвое меньше исходного размера).
  • Это вызывает минимальную потерю точности.
  • Он поддерживает некоторые делегаты (например, делегат графического процессора), которые могут работать непосредственно с данными типа float16, что приводит к более быстрому выполнению, чем вычисления с плавающей точкой 32.

Недостатки квантования float16 следующие:

  • Это не уменьшает задержку так сильно, как квантование по математике с фиксированной запятой.
  • По умолчанию квантованная модель float16 будет «деквантовать» значения весов до float32 при запуске на ЦП. (Обратите внимание, что делегат GPU не будет выполнять это деквантование, поскольку он может работать с данными типа float16.)

Только целое число: 16-битные активации с 8-битными весами (экспериментально)

Это экспериментальная схема квантования. Это похоже на схему «только целое число», но активации квантуются на основе их диапазона до 16 бит, веса квантуются в 8-битовое целое число, а смещение квантуется в 64-битное целое число. Далее это называется квантованием 16x8.

Основное преимущество этого квантования состоит в том, что оно может значительно повысить точность, но лишь немного увеличить размер модели.

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.representative_dataset = representative_dataset
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_ops = [tf.lite.OpsSet.EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8]
tflite_quant_model = converter.convert()

Если квантование 16x8 не поддерживается для некоторых операторов в модели, то модель все равно можно квантовать, но неподдерживаемые операторы остаются в плавающем положении. Для этого в target_spec необходимо добавить следующую опцию.

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)
converter.representative_dataset = representative_dataset
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_ops = [tf.lite.OpsSet.EXPERIMENTAL_TFLITE_BUILTINS_ACTIVATIONS_INT16_WEIGHTS_INT8,
tf.lite.OpsSet.TFLITE_BUILTINS]
tflite_quant_model = converter.convert()

Примеры вариантов использования, в которых повышение точности, обеспечиваемое этой схемой квантования, включают: * сверхвысокое разрешение, * обработку аудиосигнала, такую ​​как шумоподавление и формирование луча, * уменьшение шума изображения, * восстановление HDR из одного изображения.

Недостатком такого квантования является:

  • В настоящее время вывод заметно медленнее, чем 8-битное полное целое число из-за отсутствия оптимизированной реализации ядра.
  • В настоящее время он несовместим с существующими делегатами TFLite с аппаратным ускорением.

Учебное пособие по этому режиму квантования можно найти здесь .

Точность модели

Поскольку веса квантуются после обучения, возможна потеря точности, особенно для небольших сетей. Предварительно обученные полностью квантованные модели предоставляются для конкретных сетей в репозитории моделей TensorFlow Lite . Важно проверить точность квантованной модели, чтобы убедиться, что любое ухудшение точности находится в допустимых пределах. Существуют инструменты для оценки точности модели TensorFlow Lite .

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

Представление для квантованных тензоров

8-битное квантование приближает значения с плавающей запятой по следующей формуле.

$$real\_value = (int8\_value - zero\_point) \times scale$$

Представление состоит из двух основных частей:

  • По оси (также по каналу) или по тензору веса, представленные int8 двумя дополнительными значениями в диапазоне [-127, 127] с нулевой точкой, равной 0.

  • Активации / входы на тензор, представленные int8 двумя дополнительными значениями в диапазоне [-128, 127] с нулевой точкой в ​​диапазоне [-128, 127].

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