无法将具有自定义指标的Keras模型转换为tflite

时间:2019-05-23 01:00:26

标签: tensorflow keras tensorflow-lite

这是我的模特:

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())

我遵循了tensorflow 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

我正在使用tensorflow 1.13和keras 2.2.4

1 个答案:

答案 0 :(得分:0)

这对我有用,我也对你有用:

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_keras_model_file('model.h5',custom_objects= 
{'top_2_accuracy':top_2_accuracy,'top_3_accuracy':top_3_accuracy}) 
tfmodel = converter.convert() 
open ("model.tflite" , "wb") .write(tfmodel)