Не удается преобразовать модель Keras с пользовательской метрикой в ​​tflite - PullRequest
0 голосов
/ 23 мая 2019

Вот моя модель:

model = keras.models.Sequential()
# layer 1
model.add(keras.layers.Conv2D(8, 5, padding='same', input_shape=(112,112,3)))
model.add(keras.layers.BatchNormalization())
model.add(keras.layers.Activation(activation='relu'))
model.add(keras.layers.MaxPooling2D(strides=2, padding='same'))
model.add(keras.layers.Dropout(0.2))
# layer 2
model.add(keras.layers.Conv2D(16, 5, padding='same'))
model.add(keras.layers.BatchNormalization())
model.add(keras.layers.Activation(activation='relu'))
model.add(keras.layers.MaxPooling2D(strides=2, padding='same'))
model.add(keras.layers.Dropout(0.2))
# layer 3
model.add(keras.layers.Conv2D(24, 5, padding='same'))
model.add(keras.layers.BatchNormalization())
model.add(keras.layers.Activation(activation='relu'))
model.add(keras.layers.MaxPooling2D(strides=2, padding='same'))
model.add(keras.layers.Dropout(0.2))
# layer 4
model.add(keras.layers.Conv2D(32, 5, padding='same'))
model.add(keras.layers.BatchNormalization())
model.add(keras.layers.Activation(activation='relu'))
model.add(keras.layers.MaxPooling2D(strides=2, padding='same'))
# Global avg pooling before fully connected. Can use Flatten instead to experiment
model.add(keras.layers.GlobalAveragePooling2D())
# Fully Connected
model.add(keras.layers.Dense(32, activation='relu'))
model.add(keras.layers.Dense(32, activation='relu'))
model.add(keras.layers.Dense(7, activation='softmax'))

model.compile(optimizer='adam', loss='categorical_crossentropy',
              metrics=[categorical_accuracy, top_3_accuracy, top_2_accuracy])
print(model.summary())

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

def top_3_accuracy(y_true, y_pred):
    return top_k_categorical_accuracy(y_true, y_pred, k=3)


def top_2_accuracy(y_true, y_pred):
    return top_k_categorical_accuracy(y_true, y_pred, k=2)


keras.metrics.top_3_accuracy = top_3_accuracy
keras.metrics.top_2_accuracy = top_2_accuracy

model = load_model(model_path + 'mymodel.hdf5')
print(model.summary())

Я следовал методу, указанному в tenorflow lite docs . Однако, когда я пытаюсь преобразовать его в tflite, я получаю сообщение об ошибке. преобразование в tflite:

import tensorflow as tf
import keras
from keras.engine.saving import load_model
from keras.metrics import top_k_categorical_accuracy
from config import model_path


def top_3_accuracy(y_true, y_pred):
    return top_k_categorical_accuracy(y_true, y_pred, k=3)


def top_2_accuracy(y_true, y_pred):
    return top_k_categorical_accuracy(y_true, y_pred, k=2)


if __name__ == '__main__':
    # to convert using custom metric
    keras.metrics.top_3_accuracy = top_3_accuracy
    keras.metrics.top_2_accuracy = top_2_accuracy
    model_name = 'mymodel'
    model_file = model_path + model_name + '.hdf5'  
    # model = load_model(model_file) ## this line works

    converter = tf.lite.TFLiteConverter.from_keras_model_file(model_file) # throws error
    tflite_model = converter.convert()
    open(model_path+model_name+'_lite.tflite', 'wb').write(tflite_model)

Я получаю следующую ошибку: ValueError: Unknown metric function:top_3_accuracy

Я использую tenorflow 1.13 и keras 2.2.4

...