绑定模型
机器学习模型具有输入和输出特征,用于将信息传入和传出模型。
将模型加载为 LearningModel 后,可以使用 LearningModel.InputFeatures 和 LearningModel.OutputFeatures 来获取 ILearningModelFeatureDescriptor 对象。 它们列出了模型的预期输入和输出特征类型。
可以使用 LearningModelBinding 将值绑定到某个特征,通过 Name 属性引用 ILearningModelFeatureDescriptor。
以下视频提供了有关绑定机器学习模型特征的简要概述。
特征类型
Windows ML 支持所有 ONNX 特征类型,LearningModelFeatureKind 中枚举了这些类型。 它们映射到不同的特征描述符类:
- 张量:TensorFeatureDescriptor
- 序列:SequenceFeatureDescriptor
- 映射:MapFeatureDescriptor
- 图像:ImageFeatureDescriptor
张量
张量是多维数组,最常见的张量是 32 位浮点数的张量。 张量的维是行优先的,包含表示每个维的紧密打包的连续数据。 张量的总大小是每个维的大小的乘积。
序列
序列是值的向量。 序列类型的一个常见用法是浮点数概率向量,一些分类模型返回该向量来指示每次预测的准确度等级。
地图
映射是信息的键/值对。 分类模型通常返回一个字符串/浮点数映射,该映射描述所标记的每个分类名称的浮点数概率。 例如,尝试预测图片中狗的品种的模型输出可能是 ["Boston terrier", 90.0], ["Golden retriever", 7.4], ["Poodle", 2.6]
。
标量
大多数映射和序列都具有标量值。 当 TensorFeatureDescriptor.Shape.Size 为零 (0) 时会显示这些值。 在这种情况下,映射或序列将是标量类型的。 最常见的是 float
。 例如,字符串到浮点数映射将是:
MapFeatureDescriptor.KeyKind == TensorKind.String
MapFeatureDescriptor.ValueDescriptor.Kind == LearningModelFeatureKind.Tensor
MapFeatureDescriptor.ValueDescriptor.as<TensorFeatureDescriptor>().Shape.Size == 0
实际的映射特征值将是 IMap<string, float>
。
映射序列
映射序列恰好是键/值对的一个向量。 例如,字符串到浮点数映射的序列是 IVector<IMap<string, float>>
类型的。 上面的狗品种预测输出 ["Boston terrier", 90.0], ["Golden retriever", 7.4], ["Poodle", 2.6]
就是一个映射序列示例。
映像
当处理图像时,你需要知道图像格式和张量化。
图像格式
模型是使用图像训练数据训练的,并且会为该训练集保存和定制权重。 将图像输入传递到模型时,其格式必须与训练图像的格式相匹配。
在许多情况下,模型会描述预期的图像格式;ONNX 模型可以使用元数据描述预期的图像格式。
大多数模型使用以下格式,但这并非通用于所有模型:
- Image.BitmapPixelFormat:Bgr8
- Image.ColorSpaceGamma:SRGB
- Image.NominalPixelRange:NominalRange_0_255
张量化
图像在 Windows ML 中以张量格式表示。 张量化是指将图像转换为张量的过程,并且发生在绑定期间。
Windows ML 采用“NCHW 张量格式”将图像转换为 32 位浮点数的 4 维张量:
- N:批大小(或图像数)。 Windows ML 当前支持的批大小 N 为 1。
- C:通道计数(1 表示 Gray8,3 表示 Bgr8)。
- H:高度。
- W:宽度。
图像的每个像素都是一个 8 位的颜色编号,存储在 0-255 范围内,并打包为 32 位浮点数。
如何将图像传递到模型
可以通过两种方法将图像传递到模型:
-
我们建议使用 ImageFeatureValue 将图像绑定为输入和输出,因为它同时处理转换和张量化,因此图像与模型所需的图像格式匹配。 当前支持的模型格式类型为 Gray8、Rgb8 和 Bgr8,当前支持的像素范围为 0-255。
可以使用静态方法 ImageFeatureValue.CreateFromVideoFrame 创建 ImageFeatureValue。
为了找出模型需要的格式,WinML 使用以下逻辑和优先顺序:
- Bind(String, Object, IPropertySet) 将替代所有图像设置。
- 然后,将检查并使用模型元数据(如果可用)。
- 如果未提供模型元数据,并且没有调用方提供的属性,则运行时将尝试进行最佳匹配。
- 如果张量看起来像 NCHW (4 维 float32, N==1),则运行时将采用 Gray8 (C==1) 或 Bgr8 (C==3),具体取决于通道计数。
- 采用 NominalRange_0_255
- 采用 SRGB
有多个可以传递到 Bind(String, Object, IPropertySet) 的可选属性:
- BitmapBounds:如果指定,则它们是在将图像发送到模型之前要应用的剪裁边界。
- BitmapPixelFormat:如果指定,则这是在图像转换期间将用作模型像素格式的像素格式。
对于图像形状,模型可以指定它采用的特定形状(例如,SqueezeNet 采用 224,224),模型还可以为任何形状图像指定自由尺寸(许多 StyleTransfer 类型的模型可以采用可变大小的图像)。 调用方可以使用 BitmapBounds 来选择要使用图像的哪一部分。 如果未指定,则运行时会将图像缩放到模型大小(保持纵横比),然后居中裁剪。
-
如果 Windows ML 不支持模型的颜色格式或像素范围,则你可以实现转换和张量化。 你将为输入值的 32 位浮点数创建 NCHW 四维张量。 有关如何执行此操作的示例,请参阅自定义张量化示例。
使用此方法时,将忽略模型上的任何图像元数据。
示例
以下示例展示了如何绑定到模型的输入。 在本例中,我们从会话创建一个绑定,基于 inputFrame 创建一个 ImageFeatureValue,并将图像绑定到模型的输入 inputName。
private void BindModel(
LearningModelSession session,
VideoFrame inputFrame,
string inputName)
{
// Create a binding object from the session
LearningModelBinding binding = new LearningModelBinding(session);
// Create an image tensor from a video frame
ImageFeatureValue image =
ImageFeatureValue.CreateFromVideoFrame(inputFrame);
// Bind the image to the input
binding.Bind(inputName, image);
}
另请参阅
注意
使用以下资源可获取有关 Windows ML 的帮助:
- 若要提出或回答有关 Windows ML 的技术问题,请在 Stack Overflow 上使用 windows-machine-learning 标记。
- 若要报告 bug,请在 GitHub 上提交问题。