我已经使用Keras训练了卷积模型,该模型接受大小为(None,2)的输入并产生大小为(None,2)的输出。然后,我将模型导出为CoreML模型,并将其导入到Swift中。但是,当我使用模型预测使用大小为(N,2)的输入时,我仍然会得到大小为2的输出,而我希望输出的大小为(N,2)。为什么会这样,如何获得灵活的长度输出?
这是我训练和导出模型的代码:
# Create model
model = Sequential()
model.add(Conv1D((2), 3, padding='same', activation='relu', input_shape=(None,2)))
# Compile model
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
...[Set up training and validation generators]...
# Fit model
model.fit_generator(t_gen, steps_per_epoch=t_spe, epochs=epochs, verbose=1, validation_data=v_gen, validation_steps=v_spe)
# Save model
coreml_model = coremltools.converters.keras.convert(model)
coreml_model.save('model.mlmodel')
spec = coremltools.utils.load_spec('model.mlmodel')
range = coremltools.models.neural_network.flexible_shape_utils.NeuralNetworkMultiArrayShapeRange()
range.add_channel_range((2, -1))
coremltools.models.neural_network.flexible_shape_utils.update_multiarray_shape_range(spec, feature_name='input1', shape_range=range)
coremltools.models.neural_network.flexible_shape_utils.update_multiarray_shape_range(spec, feature_name='output1', shape_range=range)
coremltools.models.utils.save_spec(spec, 'model.mlmodel')
这是我用于导入和进行预测的代码:
let mlModel = model.mlModel
let input:[Double] = [0.0,0.5,0,0,0.3,0]
var output:[Double] = []
do {
let provider = PointProvider()
provider.update(point: input)
let outputProvider = try mlModel.prediction(from: provider)
let result = outputProvider.featureValue(for: "output1")!.multiArrayValue!
for i in 0..<result.count { output.append(result[i].doubleValue) }
print(output)
} catch {
print(error)
}
class PointProvider : MLFeatureProvider {
var featureValues:[String:MLFeatureValue?] = [:]
func update(point: [Double]) {
featureValues["input1"] = makePointFeature(point: point)
}
func makePointFeature(point: [Double]) -> MLFeatureValue? {
do {
let m = try MLMultiArray(shape: [NSNumber(integerLiteral: point.count)], dataType: .double)
for i in point.indices {
m[i] = NSNumber(floatLiteral: point[i])
}
return MLFeatureValue(multiArray: m)
} catch {
print(error)
}
return nil
}
var featureNames: Set<String> {
return Set(featureValues.keys)
}
func featureValue(for featureName: String) -> MLFeatureValue? {
return featureValues[featureName] ?? nil
}
}