Я хочу создать модель, которая предсказывает возраст и пол, и интегрировать ее в приложение для Android.
Я нахожусь на Ubuntu 16 и использую Python 3.6, Tensorflow 1.13.1 и Keras 2.2.4.
Сначала я тренирую разные модели с набором данных IMDB: Mobilenet V1 и V2 от керас, а также VGG, который я сам кодировал.
Для двух мобильных сетей я использовал веса imagenet для инициализации модели.
Точность довольно хорошая, более 90% для пола.
Когда обучение закончилось, я попробовал несколько способов конвертировать модели в tflite:
- три способа конвертации напрямую из файла .h5:
converter = tf.lite.TFLiteConverter.from_keras_model_file(model_to_convert)
tflite_model = converter.convert()
open(model_converted, "wb").write(tflite_model)
converter = tf.contrib.lite.TFLiteConverter.from_keras_model_file(model_to_convert)
tflite_model = converter.convert()
open(model_converted, "wb").write(tflite_model)
converter = tf.contrib.lite.TocoConverter.from_keras_model_file(model_to_convert)
tflite_model = converter.convert()
open(model_converted, "wb").write(tflite_model)
- тот, где я сначала конвертирую модель в график тф, как объяснено в этом примере
Я также пытался использовать эту строку кода перед преобразованием:
tf.keras.backend.set_learning_phase(0)
Наконец я загружаю файл .tflite в Android Studio:
private ByteBuffer convertBitmapToByteBuffer(Bitmap bitmap) {
int SIZE_IMAGE = 96;
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4*1*SIZE_IMAGE*SIZE_IMAGE*3);
byteBuffer.order(ByteOrder.nativeOrder());
int[] pixels = new int[SIZE_IMAGE * SIZE_IMAGE];
bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
int pixel = 0;
for(int i=0; i < SIZE_IMAGE; i++){
for(int j=0; j<SIZE_IMAGE;j++){
final int val = pixels[pixel++];
byteBuffer.putFloat((float) (((val >> 16) & 0xFF)/255));
byteBuffer.putFloat((float) (((val >> 8) & 0xFF)/255));
byteBuffer.putFloat((float) ((val & 0xFF)/255));
}
}
public String recognizeImage(Bitmap bitmap) {
ByteBuffer byteBuffer = convertBitmapToByteBuffer(bitmap);
Map<Integer, Object> cnnOutputs = new HashMap<>();
float[][] gender=new float[1][2];
cnnOutputs.put(0,gender);
float[][]age=new float[1][21];
cnnOutputs.put(1,age);
Object[] inputs = {byteBuffer};
interpreter.runForMultipleInputsOutputs(inputs, cnnOutputs);
String result = convertToResults(gender[0], age[0]);
return result;
}
Во время последнего вывода точность очень низкая независимо от используемой модели. Либо переводчик всегда прогнозирует один и тот же результат, либо прогнозируемый возраст немного меняется, но прогнозируемый пол всегда "женщина".
Что мне делать?
Заранее спасибо!