如何格式化从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.0、keras 2.0.4 和 coremltools 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的输入数据的主要内容,如果未能解决你的问题,请参考以下文章
如何在 TensorFlow、Keras 或 PyTorch 中部署 CoreML 模型?
.h5 keras 模型到 coreml 的分类转换在 IOS 中不起作用
如何将使用 Mask Rcnn 在自定义对象检测上创建蒙版图像的 Keras 模型转换为 CoreML 模型以在 iOS 应用程序中使用?