我正在使用实验性TensorFlow Lite Swift cocoapod尝试在iOS中运行转换后的Keras模型,但是无论我尝试哪种模型,我总是得到大约为零的结果(例如[4.2580778e-32]
)。
我已经转换为TensorFlow Lite的多个TensorFlow模型在Swift中可以正常工作,似乎只是Keras模型在Swift中不起作用,但是当我在Python中对其进行测试时它们可以正常工作。
这是示例代码的一个非常简单的代码,它可以执行以下操作:
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中产生大约为零的数字吗?