Я считаю, что в этом кроется множество проблем. Позвольте мне обратиться к ним по порядку.
1. Входные значения должны быть квантованы.
Ваш тестовый код (convolution_test_lite.py
) неправильно квантует входные значения.
В случае QUANTIZED_UINT8
квантования:
real_input_value = (quantized_input_value - mean_value) / std_dev_value
И это означает, что для преобразования вашего входного значения [0,1] в квантованное значение int вам необходимо:
quantized_input_value = real_input_value * std_dev_value + mean_value
и применить это к всем входным значениям .
Итак, в вашем convolution_test_lite.py
попробуйте изменить:
input_data = input_data.astype(np.uint8)
на
# Use the same values provided to the converter
mean_value = 0
std_dev_value = 255
input_data = input_data * std_dev_value + mean_value
input_data = input_data.astype(np.uint8)
То же самое касается вывода. Вы должны деквантовать вывод следующим образом:
real_output_value = (quantized_output_value - mean_value) / std_dev_value
При этом, поскольку вы просто получаете argmax, шаг деквантования не так важен. Если вы хотите увидеть фактические значения softmaxed в сумме до 1, вам следует деквантовать выходы.
2. Отсутствуют реальные значения диапазона min-max
Даже если вы правильно выполните квантование входных данных, точность модели значительно снизится. Это связано с тем, что модель не была обучена с использованием метода обучения с учетом квантования (который вы указали в своем комментарии). Обучение с учетом квантования позволяет вам фактически захватывать реальные минимальные и максимальные диапазоны промежуточных значений, необходимых для правильного полностью целочисленного квантования. укажите минимальные и максимальные диапазоны по умолчанию, которые являются значениями --default_ranges_min
, --default_ranges_max
. Это называется фиктивным квантованием , и ожидается, что точность модели значительно упадет.
Если вы использовали обучение с учетом квантования, вам не нужно было бы предоставлять значения по умолчанию, и полностью квантованная модель даст точные результаты.
3. Диапазон квантования
Это будет относительно незначительной проблемой, но поскольку диапазон входных значений MNIST составляет [0, 1], лучше использовать:
mean_value 0
std_dev_value 255
Таким образом, значение int 0
соответствует 0.0
, а 255
соответствует 1.0
.
Альтернатива: попробуйте post- обучающее квантование
Послетренировочное квантование просто квантует значения весовых коэффициентов и, таким образом, значительно уменьшает размер модели. Поскольку в этом случае входные / выходные данные не квантуются, вы могли бы использовать модель tflite, квантованную после обучения, вместо модели float32.
Вы можете попробовать:
tflite_convert --output_file model_lite/conv_net_post_quant.tflite \
--graph_def_file frozen_graphs/conv_net.pb \
--input_arrays "input" \
--input_shapes "1,784" \
--output_arrays output \
--output_format TFLITE \
--post_training_quantize 1
Предоставив опцию --post_training_quantize 1
, вы могли увидеть, что она производит гораздо меньшую модель по сравнению с обычной версией float32.
Вы можете запустить эту модель так же, как вы запускаете модель float32 в convolution_test_lite.py
.
Надеюсь, это поможет.