Я использую экспериментальный Cocoapod TensorFlow Lite Swift, чтобы попытаться запустить конвертированную модель Keras в iOS, но я всегда получаю результат, который приблизительно равен нулю (например, [4.2580778e-32]
) для любой модели, которую я пробую.
Несколько моделей TensorFlow, которые я конвертировал в TensorFlow Lite, отлично работают в Swift, просто кажется, что модели Keras не работают в Swift, но они прекрасно работают, когда я тестирую их в Python.
Вотсупер простой пример кода, который выполняет следующее:
- создает модель Keras (которую я даже не обучаю, она просто инициализируется случайным образом)
- создает массив тестовых данных иполучить прогноз от модели
- записать модель Keras в файл
- импортировать эту модель в преобразователь 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.Существуют расширения для данных, использованные выше для преобразования в / из массивов, но они, по-видимому, не являются проблемой, так как они работают с моделями TFLite, которые были созданы просто из простых моделей TF.
Любые идеи, почему различныеМодели TensorFlow, преобразованные в TFLite, отлично работают в Swift с использованием Cocoapod TensorFlowLiteSwift, но различные модели Keras, преобразованные в TFLite, прекрасно работают в Python и дают число, равное нулю в Swift?