swift/coreml 实现的 LSTM 维度问题

Posted

技术标签:

【中文标题】swift/coreml 实现的 LSTM 维度问题【英文标题】:LSTM dimension issues with swift/coreml implementation 【发布时间】:2020-06-26 02:11:48 【问题描述】:

我使用 keras 和 tf 作为后端生成了一个用于音频分类的 LSTM 模型。使用 coremltools 转换为 .mlmodel 后,我遇到了问题,如您所见 here。尺寸与预期有很大不同。

我在 swift 中使用 this 作为我在 xcode 中的基础。

尤其是这个片段是我认为给我带来麻烦的:

do 
    let request = try SNClassifySoundRequest(mlModel: soundClassifier.model)
    try analyzer.add(request, withObserver: resultsObserver)
         catch 
                print("Unable to prepare request: \(error.localizedDescription)")
                return
                
   

运行这个模型给我以下错误:

Invalid model, inputDescriptions.count = 5

Unable to prepare request: Invalid model, inputDescriptions.count = 5

尽管当我 build 模型时,我看到了规范中的预期:

description 
  input 
    name: "audiosamples"
    shortDescription: "Audio from microphone"
    type 
      multiArrayType 
        shape: 13
        dataType: DOUBLE
      
    
  

我正在尝试将 this 帖子合并到我的代码中,但我不确定如何根据需要对其进行格式化。任何意见是极大的赞赏。我可以看到 MLMultiArray 是我的问题的关键,但我不确定:如何将正确的数据放入其中以及如何将其推送到 SNClassifySoundRequest 类型中。

keras == 2.3.1 coremltools == 3.3

【问题讨论】:

【参考方案1】:

当你使用SNClassifySoundRequest时,你的模型需要有一定的结构。我不知道我脑海中的确切细节,但我认为它需要是一个管道,其中第一个模型是将音频转换为频谱图的内置模型。

如果您使用 Keras 训练模型,它很可能不符合 SNClassifySoundRequest 的要求。

好消息是您不需要SNClassifySoundRequest 来运行您的模型。只需在模型上调用soundClassifier.prediction(...)

请注意,您需要传入输入以及 LSTM 层的隐藏状态。 Core ML 不会自动为您管理 LSTM 状态(与 Keras 不同)。

【讨论】:

谢谢你,你给我指明了正确的方向。我也在使用this 来提供帮助,这似乎很好,但我在设置模型输入时遇到了问题。我知道我向输入“audioSamples”提供了实际的音频数据,但是我要传递什么其他 LSTM 层呢? PS。我也得到了你的书,很棒的信息! guard let modelOutput = try? self.model.prediction(audioSamples: audioData, lstm_1_h_in: <#T##MLMultiArray?#>, lstm_1_c_in: <#T##MLMultiArray?#>, lstm_2_h_in: <#T##MLMultiArray?#>, lstm_2_c_in: <#T##MLMultiArray?#>) else fatalError("Error calling predict") 此外,我得到的确切错误是“[coreml] 验证输入失败。”这也发生在 modelInput 阶段,例如:let modelInput = classyInput(audioSamples: audioData, lstm_1_h_in: <#T##MLMultiArray?#>, lstm_1_c_in: <#T##MLMultiArray?#>, lstm_2_h_in: <#T##MLMultiArray?#>, lstm_2_c_in: <#T##MLMultiArray?#>),我的输出为:guard let modelOutput = try? self.model.prediction(input: modelInput) elsefatalError("Failure predicting model") 您需要创建正确形状的 MLMultiArray 对象(取决于 LSTM 中隐藏单元的数量)并用初始状态填充它。通常这将是零或随机数。但请注意,一个新的 MLMultiArray 里面会有废话,即它是未初始化的内存,所以你需要先用零或随机数自己覆盖它。你也可以传入 nil。

以上是关于swift/coreml 实现的 LSTM 维度问题的主要内容,如果未能解决你的问题,请参考以下文章

lstm维度

swift Camera_PIcker_CoreML

CNN+LSTM+Attention实现时间序列预测

Keras LSTM 输入维度设置

Tensorflow LSTM实现多维输入输出预测实践详解

Tensorflow LSTM实现多维输入输出预测实践详解