1.整合自定义层
将自定义神经网络层集成到您的Core ML应用当中。
1.1 概述
神经网络领域是一个不断地发展的领域,新的体系结构和层次正在迅速产生,以解决新的问题。Core ML神经网络模型能够定义和使用他们自己定义的层。
注:
使用自定义层模型要求如下操作系统版本或更高版本: iOS 11.2, macOS 10.13.2, tvOS 11.2 or watchOS 4.2。
1.2 添加有自定义层的第三方模型
如果您获取一个使用自定义层的第三方模型,那么您的模型的Xcode UI会看起来和没有自定义层的模型有少许的不同。它会在网络输入输出的下方展示一个dependencies
列表。
Figure 1 The Xcode view of a custom model, listing the class dependencies of custom layers
在图一中,模型依赖于自定义层
AAPLAddOneLayer
和AAPLSimpleElementwiseLayer
。确保项目中包含了模型的所有依赖项的实现,以便使用模型进行预测。
1.3 创建您自己的自定义层
如果您的自定义层没有可用的实现,您可以自己创建它。创建自定义层要求你非常熟悉您的神将网络架构和您的自定义层的预期行为。从Create your Own Custom Layer查看详情。
2.创建自定义层
为Core ML模型创建您自己的自定义层。
2.1 概述
当您的神经网络层不被Core ML支持,您可以通过将模型中的层转换为Core ML并实现定义该层计算行为的支持类来创建自定义层。
2.2 将网络转换为Core ML
使用标准的Core ML Tools将带有自定义图层的网络转换为Core ML。在转换调用中启用add_custom_layers
标志,以避免在转换器遇到不能识别的图层(您的自定义图层)时失败。一个名为“custom”的站位图层会作为转换过程的一部分插入。清单1显示了脚本的示例调用。
coreml_model = keras_converter.convert(keras_model, add_custom_layers=True, ...
2.3 迁移网络参数和权重
网络的参数是存储在parameters自定义层的字段中的字典。初始化实现类时,这些参数将传递到自定义类实现以自定义初始化。
要迁移权重,请在自定义图层中创建新的权重数组,然后将权重从原始源图层复制到新创建的数组中。
Listing 2 Copying the weights from the source into a custom layer
custom_weights = layer.custom.weights
# For each weight parameter in the Keras model, copy them into the custom layer
for weights in k_weights:
migrated_weights = custom_weights.add()
migrated_weights.floatValue.extend(map(float, weights.flatten().tolist()))
权重以二进制格式存储,以便对大数量的数据进行优化。参数字典恰好相反——方便访问,但是不适用于大量数据。在决定是否将自定义层的数据表示为参数或权重时,请记住这一点。
2.4 Layer的命名
在保存模型之前,定义自定义层的名称。这也是实现自定义层行为的Swift或Objective-C类的名称。
Listing 3 在自定义层中设置className字段,以将该层映射到项目中的类
layer.custom.className = "MyCustomLayer"
2.5 保存转换后的模型
保存转换后的模型,以创建.mlmodel文件。模型的Xcode视图展示了模型的一组依赖,如“整合自定义层”所示。这个列表与添加到.mlmodel文件的自定义层类名匹配。
2.6 实现层
依赖项列表应该包含转换模型时定义的类名。在“创建自定义层”中,它指的是“ MyCustomLayer”。创建类,并通过实现下方描述方法使其符合MLCustomLayer
协议。
注
在Swift中,将@obj(<className>)属性添加到实现MLCustomLayer的类中。这个定义了类的OC名称,Core ML需要访问自定义层的实现。
- 实现
init(parameters:)
以初始化layer。此方法将在加载时使用.mlmodel文件中的参数调用一次。 - 实现
setWeightData(_:)
以配置layer的连接权重。初始化之后,加载的时候用将用您迁移到.mlmodel文件中的权重调用该方法一次。 - 实现
outputShapes(forInputShapes:)
以声明layer中给定输入形状的输出形状。该方法会在模型加载时调用,并在layer的输入形状发生更改时再次调用。 - 实现
evaluate(inputs:outputs:)
以定义自定义layer的计算行为。每次模型在CPU上进行预测时,都会调用此方法。 - 如果您想要layer能够在GPU上运行,可以选择实现
encode(eommandBuffer:inputs:putputs:)
。这个方法不保证在GPU上执行。
重要:
不要修改传递给这些函数的结构(权重,输入或输出)中的任何内存。
2.7 集成layer
对于没有任何自定义层的模型,预测工作流是相同的。实现了MLCustomLayer协议,您的模型同样可以使用prediction(form:)
方法来实现预测。为了准确起见,将定制的Core ML模型与原始实现进行比较。使用创建网络时使用的测试用例来验证Core ML模型的行为。
3. MLCustomModel
定义自定义模型行为的接口。
protocol MLCustomModel
使用MLCustomModel协议来定义自定义Core ML模型的行为。
3.1 创建模型
init(modelDescription: MLModelDescription, parameters: [String : Any]) throws
使用给定的描述和参数创建自定义模型。
3.2 预测
func prediction(from input: MLFeatureProvider, options: MLPredictionOptions) throws -> MLFeatureProvider
根据给定的输入features预测输出值。
optional func predictions(from inputBatch: MLBatchProvider, options: MLPredictionOptions) throws -> MLBatchProvider
根据给定的一批输入features预测输出值。
网友评论