iOS:使用从Keras转换的模型,没有CoreML预测的结果

时间:2017-08-16 23:09:57

标签: ios tensorflow keras coreml machine-learning-model

我面临的问题是在Xcode 9( Beta 5 )中,我的模型的预测调用没有给出任何结果,只是在那里挂起,没有错误。

要求是识别用户电话的一个特定移动,并排除其他类似移动。所以我的输入是来自加速度计的x,y,z方向的数据,输出是[positiveProbability,negativeProbability]。

最初我的模型是用TensorFlow后端编写的,然后我将其转换为Keras模型并转换为CoreML模型。 ( TensorFlow-1.1.0 Keras-2.0.6 Protobuf-3.4.0

这是我模型的python代码:

import numpy as np
np.random.seed(123)  # for reproducibility
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Convolution2D, MaxPooling2D
from keras.utils import np_utils
from keras.datasets import mnist
from keras import backend as K
from keras.optimizers import sgd
import json
from data_fetcher import pre_process_data
import coremltools
print K.image_data_format()

def process_data(datafile):
  with open(datafile) as data_file:
    data = json.load(data_file)
  if K.image_data_format() == 'channels_last':
    # NHWC: tensorflow backend, always channel last
    _x = np.zeros(shape=(len(data), 200, 3, 1))
    _y = np.zeros(shape=(len(data), 2))

for i in range(len(data)):
    output = pre_process_data(data, i)
    output.data_process()
    output.fft()
    #output.plot_curve('Walk')
    temp = [output.acceHFX, output.acceHFY, output.acceHFZ]
    temp = np.transpose(temp)
    temp = np.reshape(temp, (200, 3, 1))
    label = output.string
    if label == 'Pattern1' or label == 'Pattern2':
      l = np.array([[1., 0.]])
    else:
      l = np.array([[0., 1.]])
    _x[i] = temp
    _y[i] = l
# shuffle the data set (_x,_y shuffle according to the same order)
c = list(zip(_x,_y))
np.random.shuffle(c)
_x1,_y1 = zip(*c)
Data = (np.asarray(_x1), np.asarray(_y1))
return Data

def deepnn():
  # 7. Define model architecture
  model = Sequential()

  # below is the model given by tensorflow example:
  model.add(Convolution2D(10, (5, 1), activation='relu', input_shape=(200, 3, 1))) # a stack of 10 H*W =200*3 images
  model.add(MaxPooling2D(pool_size=(5, 1))) # reduce size to (10,40,3)
  model.add(Convolution2D(20, (5, 1), activation='relu')) # a stack of 20 40*3 images
  model.add(MaxPooling2D(pool_size=(5, 1))) # reduce size to (20,8,3)
  model.add(Dropout(0.25))

  model.add(Flatten()) # flatten to be 20*8*3
  model.add(Dense(50, activation='relu')) # fully connected layer shrink down to 50 features
  model.add(Dropout(0.5))
  model.add(Dense(2, activation='softmax')) # map 50 features to 2 classes

  # 8. Compile model
  SGD = sgd(lr=0.05, decay=0.0, momentum=0.0, nesterov=False)
  model.compile(loss='categorical_crossentropy',
          optimizer='SGD',
          metrics=['accuracy'])
  return model

# 9. Fit model on training data

def main():
  model = deepnn()
  filename = 'datacollector-07182017Combined.json'
  xData = process_data(filename)
  testing_size = 0.25 # reserve 20 percent for testing
  num_inputs = len(xData[0])
  cutoff = int((1.0-testing_size)*num_inputs)
  x_train = xData[0][:cutoff]
  y_train = xData[1][:cutoff]
  x_test = xData[0][cutoff:]
  y_test = xData[1][cutoff:]
  model.fit(x_train, y_train,batch_size=5, epochs=8, verbose=1)

  # 10. Evaluate model on test data
  score = model.evaluate(x_test, y_test, verbose=0)
  print score

  coreml_model = coremltools.converters.keras.convert(model)
  coreml_model.save('model.mlmodel')

if __name__ == '__main__':
  main()

这是一个形状为200x3x1的顺序模型。导入Xcode后,它看起来像这样: enter image description here

以下是我的iOS项目中用于构造输入的代码:

private typealias Accelerate = (x: Double, y: Double, z: Double)

private func transformToModelInput(data: [Accelerate]) -> MLMultiArray {
    guard let input = try? MLMultiArray(shape:[1,200,3], dataType:MLMultiArrayDataType.double) else {
        fatalError("Unexpected runtime error. MLMultiArray")
    }

    var dataArray = data.map { $0.x }
    dataArray += data.map { $0.y }
    dataArray += data.map { $0.z }

    for (index, value) in dataArray.enumerated() {
        input[index] = NSNumber(floatLiteral: value)
    }

    return input
}

这是我的预测代码:

let input = transformToModelInput(data: sampledData)

do {
    let output = try model.prediction(input1: input)
    let multiArray = MultiArray<Double>.init(output.output1)

    if multiArray[0] > multiArray[1] {
        print("Prediction: POSITIVE  \(multiArray)")
    } else {
        print("Prediction: NEGATIVE  \(multiArray)")
    }
} catch let error {
    print("CoreML Prediction Failed: \(error)")
}

然而,model.prediction调用永远不会给出任何结果,项目永远挂在那里。我真的需要帮助找出问题所在,或至少如何调试问题。

0 个答案:

没有答案