如何格式化从keras转换的coreml中conv1d/lstm nn的输入数据

Posted

技术标签:

【中文标题】如何格式化从keras转换的coreml中conv1d/lstm nn的输入数据【英文标题】:How to format input data for an conv1d/lstm nn in coreml converted from keras 【发布时间】:2017-11-12 07:04:11 【问题描述】:

我的带有输入形状(无,40 个 [timesteps],12 个 [features])的 keras 模型如下所示:

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'),
])

将其转换为 .mlmodel 后,我将其添加到我的 XCodeProject:

然后我尝试进行推理并获得预测分数:

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)
    

但是predictionModel.prediction(input: input)方法总是失败并抛出如下错误:

“模型期望输入特征 lstm_1_h_in 是一个数组,但输入的类型是 0。”

因此需要初始化 lstm 层的隐藏状态。我不知道这种行为是否是预期的,因为我以前从未遇到过同样的问题。在 keras 本身或使用 google cloud ml 进行推理时。我也不知道通常选择用于推理的初始值。也许只是零数组?有没有人遇到过类似的问题?

.mlmodel 文件可以在here找到。

【问题讨论】:

实际的错误信息是什么? 愚蠢的我,我只是从苹果文档中复制了代码而没有真正发现错误。我相应地改变了我的问题。 【参考方案1】:

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

以下 sn-p 适用于 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)
        
    

你也可以看到我的full implementation。

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

【讨论】:

“零”初始化如何影响您的输出? 分类按预期工作(我的projects front page 上的 .gif 实际上显示了这个在使用中)并且类似于我在 google cloud ml 上的实现,我不需要初始化任何东西。我有一种感觉,只要你的序列足够长,初始化并不重要。但是到目前为止我还没有测试过随机初始化。

以上是关于如何格式化从keras转换的coreml中conv1d/lstm nn的输入数据的主要内容,如果未能解决你的问题,请参考以下文章

Keras 模型到 Coreml 并使用 OpenCV

如何在 TensorFlow、Keras 或 PyTorch 中部署 CoreML 模型?

.h5 keras 模型到 coreml 的分类转换在 IOS 中不起作用

如何将使用 Mask Rcnn 在自定义对象检测上创建蒙版图像的 Keras 模型转换为 CoreML 模型以在 iOS 应用程序中使用?

如何在 Keras 中生成 class_labels.txt 以在 CoreML 模型中使用?

Keras 'InputLayer 对象在转换为 CoreML 时没有属性'inbound_nodes'