卷积CoreML模型中的灵活长度输出

时间:2020-02-24 15:27:48

标签: keras coreml coremltools

我已经使用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
    }
}

0 个答案:

没有答案