входные значения для Fa ceNet, квантованные с помощью TensorFlow Lite - PullRequest
1 голос
/ 06 апреля 2020

Я использую модель «FaceNet», преобразованную с «TensorFlow Lite» в квантованную модель. Это было сделано в соответствии с инструкциями на странице https://medium.com/analytics-vidhya/facenet-on-mobile-cb6aebe38505.

Это информация о входном и выходном буфере квантованной модели.

INPUTS:
    [{'index': 451, 'shape': array([  1, 160, 160,   3], dtype=int32), 'quantization': (0.0078125, 128L), 'name': 'input', 'dtype': <type 'numpy.uint8'>}]
OUTPUTS:
    [{'index': 450, 'shape': array([  1, 512], dtype=int32), 'quantization': (0.0235294122248888, 0L), 'name': 'embeddings', 'dtype': <type 'numpy.uint8'>}]

Мне не удается правильно заполнить входной буфер.

Я уже использовал ПОЛНУЮ модель «FaceNet», которая принимает значения с плавающей запятой, и она работала, как и ожидалось. Итак, я знаю, как должны выглядеть входные значения с плавающей точкой для полной модели, поэтому я предполагаю, что есть только один шаг, чтобы преобразовать каждое значение с плавающей точкой в ​​соответствующее значение байта и передать эти байтовые значения в модель TensorFlow Lite.

Это то, что я сделал с полной моделью FaceNet.

//extract all the pixels of the image (of the face area of 160 x 160)
bitmap.getPixels(intValues, 0, inputWidth, 0, 0, inputWidth, inputHeight);

//copy the value of each channel of each pixel into an array
for (int i = 0; i < intValues.length; ++i) {
    int p = intValues[i];

    shortValues[i * 3 + 2] = (short) (p & 0xFF);
    shortValues[i * 3 + 1] = (short) ((p >> 8) & 0xFF);
    shortValues[i * 3 + 0] = (short) ((p >> 16) & 0xFF);
}

//calculate the mean value of all the pixels of the image
double sum = 0f;
for (short shortValue : shortValues) {
    sum += shortValue;
}

double mean = sum / shortValues.length;

sum = 0f;
for (short shortValue : shortValues) {
    sum += Math.pow(shortValue - mean, 2);
}

//calculate the standard deviation of all the pixels of the image
double std = Math.sqrt(sum / shortValues.length);
double std_adj = Math.max(std, 1.0/ Math.sqrt(shortValues.length));

//FINALLY    fill the input buffer for the tensorflow 
//calculate a  float value for each pixel
for (short shortValue : shortValues) {
    inputFloatBuffer.put((float) ((shortValue - mean) * (1 / std_adj)));
}

}

Теперь, когда у меня есть значения с плавающей запятой, как преобразовать их в байтовые значения для TensorFlow Lite?

Я перепробовал все возможные комбинации со значениями «0,0078125» (1/128) и «128» (упоминается в верхней части поста), но ничего не дало значимых результатов.

Например:

int int_value = ((short)(float_value * 128)) + 128;

Я использовал масштабирование, чтобы сначала сжать значения с плавающей запятой в диапазоне [-1,1], но это тоже не помогло.

У кого-нибудь есть идеи?

1 Ответ

0 голосов
/ 13 апреля 2020

Я не знаю, как модель была квантована, но действительно стоит попробовать, чтобы непосредственно поместить пиксели значения int, полученные из растрового изображения (в диапазоне [0, 255]), в буфер. Обязательно используйте ByteBuffer вместо FloatBuffer.

...