在 Core ML 上具有两个参数函数的自定义层
Custom layer with two parameters function on Core ML
感谢这篇很棒的文章 (http://machinethink.net/blog/coreml-custom-layers/),我了解了如何使用 coremltools 和 Lambda 以及 Keras 自定义层编写转换。
但是,我无法理解带有两个参数的函数的情况。
#python
def scaling(x, scale):
return x * scale
Keras 层在这里。
#python
up = conv2d_bn(mixed,
K.int_shape(x)[channel_axis],
1,
activation=None,
use_bias=True,
name=name_fmt('Conv2d_1x1'))
x = Lambda(scaling, # HERE !!
output_shape=K.int_shape(up)[1:],
arguments={'scale': scale})(up)
x = add([x, up])
在这种情况下,如何在Swift上的custom MLCustomLayer class
中写func evaluate(inputs: [MLMultiArray], outputs: [MLMultiArray])
?我理解的只是在一个参数函数的情况下,像这样,
#swift
func evaluate(inputs: [MLMultiArray], outputs: [MLMultiArray]) throws {
for i in 0..<inputs.count {
let input = inputs[i]
let output = outputs[i]
for j in 0..<input.count {
let x = input[j].floatValue
let y = x / (1 + exp(-x))
output[j] = NSNumber(value: y)
}
}
}
两个参数函数怎么样,比如x * scale
?
完整代码在这里。
- 正在转换为具有自定义层的 Core ML 模型
https://github.com/osmszk/dla_team14/blob/master/facenet/coreml/CoremlTest.ipynb
- Keras 的网络模型
https://github.com/osmszk/dla_team14/blob/master/facenet/code/facenet_keras_v2.py
谢谢。
看起来 scale
是一个超参数,而不是可学习的参数,对吗?
在这种情况下,您需要将 scale
添加到自定义层的参数字典中。然后在您的 Swift class 中,scale
也将在传递给您的 init(parameters)
函数的参数字典中。将其存储在 属性 中,然后在 evaluate(inputs, outputs)
中再次读取 属性。
我的博客 post 实际上展示了如何做到这一点。 ;-)
感谢hollance的博客,我通过这种方式解决了这个问题。在转换 func 时,在这种情况下,在 convert_lambda
中,我应该为自定义层添加一个 scale
参数。
python 代码(转换 Core ML)
def convert_lambda(layer):
if layer.function == scaling:
params = NeuralNetwork_pb2.CustomLayerParams()
params.className = "scaling"
params.description = "scaling input"
# HERE!! This is important.
params.parameters["scale"].doubleValue = layer.arguments['scale']
return params
else:
return None
coreml_model = coremltools.converters.keras.convert(
model,
input_names="image",
image_input_names="image",
output_names="output",
add_custom_layers=True,
custom_conversion_functions={ "Lambda": convert_lambda })
swift代码(自定义图层)
//custom MLCustomLayer `scaling` class
let scale: Float
required init(parameters: [String : Any]) throws {
if let scale = parameters["scale"] as? Float {
self.scale = scale
} else {
self.scale = 1.0
}
print(#function, parameters, self.scale)
super.init()
}
func evaluate(inputs: [MLMultiArray], outputs: [MLMultiArray]) throws {
for i in 0..<inputs.count {
let input = inputs[i]
let output = outputs[i]
for j in 0..<input.count {
let x = input[j].floatValue
let y = x * self.scale
output[j] = NSNumber(value: y)
}
//faster
/*
let count = input.count
let inputPointer = UnsafeMutablePointer<Float>(OpaquePointer(input.dataPointer))
let outputPointer = UnsafeMutablePointer<Float>(OpaquePointer(output.dataPointer))
var scale = self.scale
vDSP_vsmul(inputPointer, 1, &scale, outputPointer, 1, vDSP_Length(count))
*/
}
}
谢谢。
感谢这篇很棒的文章 (http://machinethink.net/blog/coreml-custom-layers/),我了解了如何使用 coremltools 和 Lambda 以及 Keras 自定义层编写转换。 但是,我无法理解带有两个参数的函数的情况。
#python
def scaling(x, scale):
return x * scale
Keras 层在这里。
#python
up = conv2d_bn(mixed,
K.int_shape(x)[channel_axis],
1,
activation=None,
use_bias=True,
name=name_fmt('Conv2d_1x1'))
x = Lambda(scaling, # HERE !!
output_shape=K.int_shape(up)[1:],
arguments={'scale': scale})(up)
x = add([x, up])
在这种情况下,如何在Swift上的custom MLCustomLayer class
中写func evaluate(inputs: [MLMultiArray], outputs: [MLMultiArray])
?我理解的只是在一个参数函数的情况下,像这样,
#swift
func evaluate(inputs: [MLMultiArray], outputs: [MLMultiArray]) throws {
for i in 0..<inputs.count {
let input = inputs[i]
let output = outputs[i]
for j in 0..<input.count {
let x = input[j].floatValue
let y = x / (1 + exp(-x))
output[j] = NSNumber(value: y)
}
}
}
两个参数函数怎么样,比如x * scale
?
完整代码在这里。
- 正在转换为具有自定义层的 Core ML 模型 https://github.com/osmszk/dla_team14/blob/master/facenet/coreml/CoremlTest.ipynb
- Keras 的网络模型 https://github.com/osmszk/dla_team14/blob/master/facenet/code/facenet_keras_v2.py
谢谢。
看起来 scale
是一个超参数,而不是可学习的参数,对吗?
在这种情况下,您需要将 scale
添加到自定义层的参数字典中。然后在您的 Swift class 中,scale
也将在传递给您的 init(parameters)
函数的参数字典中。将其存储在 属性 中,然后在 evaluate(inputs, outputs)
中再次读取 属性。
我的博客 post 实际上展示了如何做到这一点。 ;-)
感谢hollance的博客,我通过这种方式解决了这个问题。在转换 func 时,在这种情况下,在 convert_lambda
中,我应该为自定义层添加一个 scale
参数。
python 代码(转换 Core ML)
def convert_lambda(layer):
if layer.function == scaling:
params = NeuralNetwork_pb2.CustomLayerParams()
params.className = "scaling"
params.description = "scaling input"
# HERE!! This is important.
params.parameters["scale"].doubleValue = layer.arguments['scale']
return params
else:
return None
coreml_model = coremltools.converters.keras.convert(
model,
input_names="image",
image_input_names="image",
output_names="output",
add_custom_layers=True,
custom_conversion_functions={ "Lambda": convert_lambda })
swift代码(自定义图层)
//custom MLCustomLayer `scaling` class
let scale: Float
required init(parameters: [String : Any]) throws {
if let scale = parameters["scale"] as? Float {
self.scale = scale
} else {
self.scale = 1.0
}
print(#function, parameters, self.scale)
super.init()
}
func evaluate(inputs: [MLMultiArray], outputs: [MLMultiArray]) throws {
for i in 0..<inputs.count {
let input = inputs[i]
let output = outputs[i]
for j in 0..<input.count {
let x = input[j].floatValue
let y = x * self.scale
output[j] = NSNumber(value: y)
}
//faster
/*
let count = input.count
let inputPointer = UnsafeMutablePointer<Float>(OpaquePointer(input.dataPointer))
let outputPointer = UnsafeMutablePointer<Float>(OpaquePointer(output.dataPointer))
var scale = self.scale
vDSP_vsmul(inputPointer, 1, &scale, outputPointer, 1, vDSP_Length(count))
*/
}
}
谢谢。