Модель TensorFlow по-прежнему остается с плавающей запятой после посттренировочного квантования

После применения посттренировочного квантования моя пользовательская модель CNN была уменьшена до 1/4 от исходного размера (с 56,1 МБ до 14 МБ). Я помещаю изображение (100x100x3), которое должно быть предсказано, в ByteBuffer как 100x100x3 = 30 000 байт. Однако во время вывода я получил следующую ошибку:

java.lang.IllegalArgumentException: Cannot convert between a TensorFlowLite buffer with 120000 bytes and a ByteBuffer with 30000 bytes.**
        at org.tensorflow.lite.Tensor.throwExceptionIfTypeIsIncompatible(Tensor.java:221)
        at org.tensorflow.lite.Tensor.setTo(Tensor.java:93)
        at org.tensorflow.lite.NativeInterpreterWrapper.run(NativeInterpreterWrapper.java:136)
        at org.tensorflow.lite.Interpreter.runForMultipleInputsOutputs(Interpreter.java:216)
        at org.tensorflow.lite.Interpreter.run(Interpreter.java:195)
        at gov.nih.nlm.malaria_screener.imageProcessing.TFClassifier_Lite.recongnize(TFClassifier_Lite.java:102)
        at gov.nih.nlm.malaria_screener.imageProcessing.TFClassifier_Lite.process_by_batch(TFClassifier_Lite.java:145)
        at gov.nih.nlm.malaria_screener.Cells.runCells(Cells.java:269)
        at gov.nih.nlm.malaria_screener.CameraActivity.ProcessThinSmearImage(CameraActivity.java:1020)
        at gov.nih.nlm.malaria_screener.CameraActivity.access$600(CameraActivity.java:75)
        at gov.nih.nlm.malaria_screener.CameraActivity$8.run(CameraActivity.java:810)
        at java.lang.Thread.run(Thread.java:762) 

Размер импортированного изображения в модель: 100x100x3. В настоящее время я предсказываю одно изображение за раз. Итак, если я создаю Bytebuffer: 100x100x3 = 30 000 байт. Однако в приведенной выше информации журнала указано, что буфер TensorFlowLite имеет 120 000 байт. Это заставляет меня подозревать, что преобразованная модель tflite все еще находится в формате с плавающей запятой. Это ожидаемое поведение? Как получить квантованную модель, которая принимает входное изображение с точностью до 8 ям, как в пример из официального репозитория TensorFlow?

В примере кода ByteBuffer, используемый в качестве входных данных для tflite.run (), имеет 8-битную точность для квантованной модели.

Но я также прочитал из документа Google, где говорится: «При выводе веса преобразуются из 8-битной точности в числа с плавающей запятой и вычисляются с использованием ядер с плавающей запятой». Кажется, что эти два случая противоречат друг другу.

private static final int BATCH_SIZE = 1;

private static final int DIM_IMG_SIZE = 100;

private static final int DIM_PIXEL_SIZE = 3;

private static final int BYTE_NUM = 1;

imgData = ByteBuffer.allocateDirect(BYTE_NUM * BATCH_SIZE * DIM_IMG_SIZE * DIM_IMG_SIZE * DIM_PIXEL_SIZE);
imgData.order(ByteOrder.nativeOrder());

... ...

int pixel = 0;

        for (int i = 0; i < DIM_IMG_SIZE; ++i) {
            for (int j = 0; j < DIM_IMG_SIZE; ++j) {

                final int val = intValues[pixel++];

                imgData.put((byte)((val >> 16) & 0xFF));
                imgData.put((byte)((val >> 8) & 0xFF));
                imgData.put((byte)(val & 0xFF));

//                imgData.putFloat(((val >> 16) & 0xFF) / 255.0f);
//                imgData.putFloat(((val >> 8) & 0xFF) / 255.0f);
//                imgData.putFloat((val & 0xFF) / 255.0f);

            }
        } 

... ...

tfLite.run(imgData, labelProb);

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

import tensorflow as tf
import sys
import os

saved_model_dir = '/home/yuh5/Downloads/malaria_thinsmear.h5.pb'

input_arrays = ["input_2"]

output_arrays = ["output_node0"]

converter = tf.contrib.lite.TocoConverter.from_frozen_graph(saved_model_dir, input_arrays, output_arrays)

converter.post_training_quantize = True

tflite_model = converter.convert()
open("thinSmear_100.tflite", "wb").write(tflite_model)

person Hang    schedule 17.10.2018    source источник


Ответы (1)


Квантование после обучения не меняет формат входных или выходных слоев. Вы можете запустить свою модель с данными в том же формате, что и для обучения.

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

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

person rednuht    schedule 24.10.2018