转换后的Keras模型无法从实验性iOS TFLite解释器调用

时间:2019-04-28 05:43:07

标签: swift tensorflow keras

我正在使用实验性TensorFlow Lite Swift cocoapod尝试在iOS中运行转换后的Keras模型,但是无论我尝试哪种模型,我总是得到大约为零的结果(例如[4.2580778e-32])。

我已经转换为TensorFlow Lite的多个TensorFlow模型在Swift中可以正常工作,似乎只是Keras模型在Swift中不起作用,但是当我在Python中对其进行测试时它们可以正常工作。

这是示例代码的一个非常简单的代码,它可以执行以下操作:

  • 创建Keras模型(我什至不训练,它只是随机初始化的)
  • 建立测试数据数组并从模型中获得预测
  • 将Keras模型写入文件
  • 将该模型导入TFLite转换器并写出TFLite转换文件
  • 通过将TFLite文件加载到解释器并从上方对同一测试数据阵列进行测试来测试TFLite文件
import numpy as np
import tensorflow as tf
import keras
from keras.models import Sequential
from keras.layers import Dense, Flatten

# create the model
model = Sequential()
model.add(Dense(32, input_shape=(10,128)))
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))

# create a test data array matching input shape with batch size of 1, filled with ones
test_data = np.empty((1,10,128), dtype=np.float32)
test_data.fill(1)
print(model.predict(test_data))
# above print produces [[0.20321347]] from random initialization

# write Keras model to a file, also prepare a path for the TFLite file
target_path = 'SimpleTest'
h5_path = 'Models/' + target_path + '.h5'
tflite_path = 'Models/converted_' + target_path + '.tflite'
model.save(h5_path)

# use TFLite converter to write to file
converter = tf.lite.TFLiteConverter.from_keras_model_file(h5_path)
tflite_model = converter.convert()
open(tflite_path, "wb").write(tflite_model)

# Load TFLite model and allocate tensors.
interpreter = tf.lite.Interpreter(model_path=tflite_path)
interpreter.allocate_tensors()

# Get input and output tensors.
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
print(input_details, output_details)
# Test model on input data
interpreter.set_tensor(input_details[0]['index'], test_data)
interpreter.invoke()
output_data = interpreter.get_tensor(output_details[0]['index'])
print(output_data)

# The above print statements print [{'name': 'dense_1_input', 'index': 5, 'shape': array([  1,  10, 128], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0)}] [{'name': 'dense_2/Sigmoid', 'index': 8, 'shape': array([1, 1], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0)}]
# [[0.2032134]]

您可以看到TFLite模型的输出与原始Keras模型的输出非常匹配。到目前为止,一切都很顺利-TFLite模型可以在Python中完美运行。

在Swift中,我在类的init中包含以下代码:

do{
    var options = InterpreterOptions()
    options.isErrorLoggingEnabled = true
    try self.interpreter = Interpreter(modelPath: Bundle.main.path(forResource: modelFileName, ofType: "tflite")!, options: options)
    // allocate input tensors at the given shapes
    try self.interpreter.allocateTensors()
}catch {
    print("initialize TF interpreter failed: \(error)")
    return nil
}

let data = Data(copyingBufferOf: Array<Float>(repeating: 1, count: 128*10))
try interpreter.copy(data, toInputAt: 0)
try interpreter.invoke()
let outputTensor = try interpreter.output(at: 0)
let outputResult = [Float](unsafeData: outputTensor.data)!
print("interpreter result on test data", outputResult)
precondition(outputResult == [0.2032134])

问题在于,我得到的值接近于零,而不是近似等于期望值。相同的Swift代码可完美地与普通TensorFlow模型配合使用。上面使用了Data扩展来转换为数组,或从数组转换为Data,但这似乎不是问题,因为它们可以与从普通TF模型创建的TFLite模型一起使用。

有什么想法为什么使用TensorFlowLiteSwift cocoapod在Swift中可以将各种TensorFlow模型转换为TFLite,但是在Python中可以将各种Keras模型转换为TFLite并在Swift中产生大约为零的数字吗?

0 个答案:

没有答案