为具有灵活形状的CoreML 2模型指定输入/输出尺寸

时间:2018-11-01 06:13:16

标签: ios swift coreml

我设法创建了具有灵活输入/输出形状大小的CoreML 2.0模型:

enter image description here

但是,我不知道如何在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

我是否必须创建一个新层,然后将其链接到输出到它的层以及输出到它的层?

0 个答案:

没有答案
相关问题