我设法创建了具有灵活输入/输出形状大小的CoreML 2.0模型:
但是,我不知道如何在Xcode项目中设置大小。如果将输入像素缓冲区的大小设置为2048x2048,则输出像素缓冲区仍为1536x1536。如果将其设置为768x768,则生成的像素缓冲区仍为1536x1536-但在768x768区域之外为空白。
我检查了自动生成的Swift模型类,但那里没有任何线索。
在任何地方都找不到一个示例来说明如何使用“灵活性”尺寸。
在WWDC 2018大会708“ Core ML的新功能”的第1部分中,它指出:
这意味着现在您必须运送单个模型。您不必具有任何冗余代码。而且,如果您需要在标准清晰度和高清晰度之间切换,则可以更快地完成,因为我们不需要从头开始重新加载模型。我们只需要调整它的大小即可。您有两个选项可以指定模型的灵活性。您可以为其尺寸定义范围,因此可以定义最小宽度和高度以及最大宽度和高度。然后推论选择两者之间的任何值。但是还有另一种方式。您可以枚举要使用的所有形状。例如,所有不同的宽高比,所有不同的分辨率,这对于性能而言更好。 Core ML较早就了解您的用例,因此可以-它有机会执行更多优化。
他们说“我们只需要调整大小”。如此令人沮丧,因为他们没有告诉您如何调整尺寸!他们还说“然后推论选择两者之间的任何值”,但不提供如何选择两者之间的价值的线索!
这是我添加柔性形状尺寸的方法:
import coremltools
from coremltools.models.neural_network import flexible_shape_utils
spec = coremltools.utils.load_spec('mymodel_fxedShape.mlmodel')
img_size_ranges = flexible_shape_utils.NeuralNetworkImageSizeRange()
img_size_ranges.add_height_range(640, 2048)
img_size_ranges.add_width_range(640, 2048)
flexible_shape_utils.update_image_size_range(spec, feature_name='inputImage', size_range=img_size_ranges)
flexible_shape_utils.update_image_size_range(spec, feature_name='outputImage', size_range=img_size_ranges)
coremltools.utils.save_spec(spec, 'myModel.mlmodel')
这是模型的描述:
description {
input {
name: "inputImage"
shortDescription: "Image to stylize"
type {
imageType {
width: 1536
height: 1536
colorSpace: BGR
imageSizeRange {
widthRange {
lowerBound: 640
upperBound: 2048
}
heightRange {
lowerBound: 640
upperBound: 2048
}
}
}
}
}
output {
name: "outputImage"
shortDescription: "Stylized image"
type {
imageType {
width: 1536
height: 1536
colorSpace: BGR
imageSizeRange {
widthRange {
lowerBound: 640
upperBound: 2048
}
heightRange {
lowerBound: 640
upperBound: 2048
}
}
}
}
}
}
使用“ outputShape”有两层:
layers {
name: "SpatialFullConvolution_63"
input: "Sequential_53"
output: "SpatialFullConvolution_63_output"
convolution {
outputChannels: 16
kernelChannels: 32
nGroups: 1
kernelSize: 3
kernelSize: 3
stride: 2
stride: 2
dilationFactor: 1
dilationFactor: 1
valid {
paddingAmounts {
borderAmounts {
}
borderAmounts {
}
}
}
isDeconvolution: true
hasBias: true
weights {
}
bias {
}
outputShape: 770
outputShape: 770
}
}
...relu layer...
layers {
name: "SpatialFullConvolution_67"
input: "ReLU_66"
output: "SpatialFullConvolution_67_output"
convolution {
outputChannels: 8
kernelChannels: 16
nGroups: 1
kernelSize: 3
kernelSize: 3
stride: 2
stride: 2
dilationFactor: 1
dilationFactor: 1
valid {
paddingAmounts {
borderAmounts {
}
borderAmounts {
}
}
}
isDeconvolution: true
hasBias: true
weights {
}
bias {
}
outputShape: 1538
outputShape: 1538
}
}
我现在试图弄清楚如何从这两层中删除outputShape。
>>> layer = spec.neuralNetwork.layers[49]
>>> layer.convolution.outputShape
[1538L, 1538L]
我尝试将其设置为[]:
layer.convolution.outputShape = []
到形状:
layer.convolution.outputShape = flexible_shape_utils.Shape(())
无论我尝试什么,都会收到错误消息:
TypeError: Can't set composite field
我是否必须创建一个新层,然后将其链接到输出到它的层以及输出到它的层?