3

My keras model with input shape (none, 40 [timesteps], 12 [features]) looks like this:

model = Sequential([
    Conv1D(nodes_per_layer, filter_length, subsample_length=2, activation='relu', input_shape=(timesteps, data_dim), name='accelerations'),
    Conv1D(nodes_per_layer, filter_length, subsample_length=1, activation='relu'),
    LSTM(nodes_per_layer, return_sequences=True),
    LSTM(nodes_per_layer, return_sequences=False),
    Dropout(dropout),
    Dense(num_classes),
    Activation('softmax', name='scores'),
])

After converting it to .mlmodel, I add it to my XCodeProject: enter image description here

I then try to do inference and get prediction scores:

func makePredictionRequest(currentScaledMotionArrays: [[Double]]) {
    let data = _currentScaledMotionArrays.reduce([], +) //result is of type [Double] with 480 elements
    do {
        let mlMultiArray = try MLMultiArray(shape:[40,12], dataType:MLMultiArrayDataType.double)
        for (index, element) in data.enumerated() {
            mlMultiArray[index] = NSNumber(value: element)
        }
        let input = PredictionModelInput(accelerations: mlMultiArray)
        let predictionOutput = try _predictionModel.prediction(input: input)
    }
    catch {
        print(error.localizedDescription)
    }
}

But the predictionModel.prediction(input: input) method always fails and throws the following error:

"The model expects input feature lstm_1_h_in to be an array, but the input is of type 0."

So hidden states of the lstm layers need to be initialized. I don't know if this behavior is expected, since I never faced the same problem before. Neither while doing inference in keras itself or with google cloud ml. I also don't know the initial values, which are usually chosen for inference. Maybe just arrays of zeros? Did anyone face a similar problem?

The .mlmodel file could be found here.

4

1 回答 1

3

我实际上实现了我想做的事情。

以下片段适用于swift 4.0keras 2.0.4coremltools 0.4.0

keras 输入形状为(none, 40 [timesteps], 12 [features])。请注意下面更改的参数顺序(40 [timesteps]、none、12 [features])

两个 lstm 层的所有 32 个节点的隐藏统计信息都用零初始化。我必须测试这是否会导致预期的行为,或者我是否必须随机初始化它们。

func makePredictionRequest(evaluationStep: EvaluationStep) {
        let data = _currentScaledMotionArrays.reduce([], +) //result is of type [Double] with 480 elements
        do {
            let accelerationsMultiArray = try MLMultiArray(shape:[40,1,12], dataType:MLMultiArrayDataType.double)
            for (index, element) in data.enumerated() {
                accelerationsMultiArray[index] = NSNumber(value: element)
            }
            let hiddenStatesMultiArray = try MLMultiArray(shape: [32], dataType: MLMultiArrayDataType.double)
            for index in 0..<32 {
                hiddenStatesMultiArray[index] = NSNumber(integerLiteral: 0)
            }
            let input = PredictionModelInput(accelerations: accelerationsMultiArray, lstm_1_h_in: hiddenStatesMultiArray, lstm_1_c_in: hiddenStatesMultiArray, lstm_2_h_in: hiddenStatesMultiArray, lstm_2_c_in: hiddenStatesMultiArray)
            let predictionOutput = try _predictionModel.prediction(input: input)
            print(predictionOutput.scores)
        }
        catch {
            print(error.localizedDescription)
        }
    }

你也可以看到我的完整实现

如果我的回答解决了您的问题,请在此处给我留言 :)

于 2017-07-23T14:08:27.867 回答