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 维度问题的主要内容,如果未能解决你的问题,请参考以下文章