首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >为具有柔性形状的CoreML 2模型指定输入/输出尺寸

为具有柔性形状的CoreML 2模型指定输入/输出尺寸
EN

Stack Overflow用户
提问于 2018-11-01 06:13:15
回答 1查看 1.9K关注 0票数 9

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

但是,我不知道如何在我的Xcode项目中设置大小。如果设置输入像素缓冲区大小2048x2048,则输出像素缓冲区仍为1536x1536。如果将其设置为768x768,则结果像素缓冲区仍为1536x1536,但在768x768区域外为空白。

我检查了自动生成的Swift模型类,没有看到任何线索。

我在任何地方都找不到一个例子,说明如何使用“灵活性”大小。

在WWDC 2018年会议708“核心ML中的新内容”中,第1部分指出:

这意味着,现在您必须交付一个单一的模式。你不必有任何多余的代码。如果您需要在标准定义和高清晰度之间切换,您可以更快地完成它,因为我们不需要从头开始重新加载模型;我们只需要调整它的大小。您有两个选项来指定模型的灵活性。可以为其维度定义范围,因此可以定义最小宽度和高度以及最大宽度和高度。然后在推理中选择介于两者之间的任何值。但还有另外一种方法。您可以枚举要使用的所有形状。例如,所有不同的高宽比,所有不同的分辨率,这是更好的性能。核心ML更早地了解您的用例,所以它可以--它有机会执行更多的优化。

他们说“我们只需要调整它的大小”。这太让人沮丧了,因为他们不告诉你怎么调整尺寸!他们还说,“然后在推断之间挑选任何价值”,但没有提供任何线索,如何在两者之间选择价值!

下面是我如何添加灵活的形状大小:

代码语言:javascript
代码运行次数:0
运行
复制
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')

下面是模型的描述:

代码语言:javascript
代码运行次数:0
运行
复制
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”的层:

代码语言:javascript
代码运行次数:0
运行
复制
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。

代码语言:javascript
代码运行次数:0
运行
复制
>>> layer = spec.neuralNetwork.layers[49]
>>> layer.convolution.outputShape
[1538L, 1538L]

我试着把它设置为[]:

代码语言:javascript
代码运行次数:0
运行
复制
layer.convolution.outputShape = []

以一种形状:

代码语言:javascript
代码运行次数:0
运行
复制
layer.convolution.outputShape = flexible_shape_utils.Shape(())

无论我尝试什么,我都会犯错误:

代码语言:javascript
代码运行次数:0
运行
复制
TypeError: Can't set composite field

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-01 23:40:52

本例中的问题是,模型中存在一些层,它们的outputShapes使用固定的形状。例如:

代码语言:javascript
代码运行次数:0
运行
复制
>>> layer = spec.neuralNetwork.layers[49]
>>> layer.convolution.outputShape
[1538L, 1538L]

所讨论的模型确实是完全卷积的,因此在转换到CoreML之前,它可以处理任何输入和输出形状。

我能够使用以下命令删除固定的outputShape:

代码语言:javascript
代码运行次数:0
运行
复制
layer = spec.neuralNetwork.layers[49]
del layer.convolution.outputShape[:]

在此之后,模型具有灵活的输入和输出形状。

这个答案的所有功劳都归功于马蒂杰斯·霍勒曼人。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53096060

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档