Преобразованная модель Keras не может вызвать экспериментальный интерпретатор iOS TFLite - PullRequest
0 голосов
/ 28 апреля 2019

Я использую экспериментальный 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?

...