ml — 机器学习

ml 模块包含在 OpenMV Cam 上处理机器学习模型的功能。

ml 模块的核心是 Model() 对象,用于加载和执行 TensorFlow Lite 模型。Model() 对象接受一个最多为 4D 的输入张量列表,表示每个模型输入张量,并返回一个最多为 4D 的输出张量列表,表示每个模型输出张量。每个输入/输出张量都使用 numpy 的 ndarray 进行操作。

对于 TensorFlow Lite 模型,Model() 对象处理所有启用的操作,具体见 [此处](https://github.com/openmv/openmv/blob/master/src/lib/tflm/tflm_backend.cc)。Model() 对象会自动利用 CMSIS-NN、Helium 和 Ethos NPU(如果可用)来加速推理。这些加速器的可用性取决于 OpenMV Cam 的型号。

对于图像处理支持,ml 模块会通过将传递的图像对象包装在 Normalization() 对象中,自动将其转换为 numpy ndarray 对象,Normalization() 对象负责处理这一转换过程。Normalization() 对象也可以手动创建,以便控制转换过程、选择感兴趣区域(ROI)等。

有关 ndarray 对象的更多信息,请参阅 ulab 文档。所有 OpenMV Cam 都支持最多 4 维的 ndarray 对象(即 4D 张量)。

备注

为了节省闪存空间,目前所有 OpenMV Cam 上都禁用了复数支持和 scipy special 模块

子模块

类 model – 模型容器

模型对象用于加载和执行 TensorFlow Lite 模型。该模型对象接受一个最多为 4D 的输入张量列表,每个输入张量对应模型的输入张量数量,并返回一个最多为 4D 的输出张量列表,对应模型的输出张量数量。每个输入/输出张量都是一个 numpy ndarray

构造

class ml.Model(path: str, load_to_fb: bool = False) Model

path 加载模型到内存并准备执行。path 可以是磁盘上的文件路径,也可以是内置模型的名称,内置模型会从内部闪存加载。内置于内部闪存固件映像中的模型在使用时不会占用 RAM 来存储模型权重。

如果您尝试加载的模型非常大,无法适应 MicroPython 堆(heap),可以将 load_to_fb 设置为 True,将模型加载到帧缓冲区栈(frame buffer stack)中。这可以绕过堆大小的限制。然而,采用这种方式加载的模型需要与其他使用帧缓冲区栈的对象一起按顺序释放,而不是与 MicroPython 堆一起释放。通常,帧缓冲区栈比 MicroPython 堆要大得多,因此使用此选项可以加载更大的模型,但在释放时需要小心。

一旦模型加载完成,您可以使用 predict() 多次执行它,并传入不同的输入。模型将在多次调用 predict() 之间记住其内部状态。

当模型被删除时,它将自动释放其使用的内存,无论是来自堆(heap)还是帧缓冲区栈(frame buffer stack)。

方法

predict(inputs: list, callback=None) list

使用给定的输入执行模型。输入应该是一个 numpy ndarray 对象的列表,数量对应模型支持的输入张量数。该方法返回一个 numpy ndarray 对象的列表,数量对应模型的输出张量数。

模型的输入张量可以是最大为 4D 的 uint8、int8、uint16、int16 或 float32 类型的张量。传递的 numpy ndarray 对象会根据输入张量的缩放(scale)和零点(zero point)值,先转换为浮点数,并进行缩放/偏移,然后传递给模型。例如,一个 ndarray 类型的 uint8 值会被转换为 0.0 到 255.0 之间的 float32 值,再除以输入张量的缩放因子,然后加上输入张量的零点值。对于 int8、uint16 和 int16 值,也会执行相同的过程,而 float32 值则直接传递给模型,忽略缩放和零点值。

模型的输出张量可以是最大为 4D 的 uint8、int8、uint16、int16 或 float32 类型的张量。对于 uint8、int8、uint16 和 int16 张量,返回的 numpy ndarray 会通过先减去输出张量的零点值,再乘以输出张量的缩放值来创建。对于 float32 张量,值会直接传递到输出,不进行任何缩放或偏移。

请注意,predict() 方法要求输入的 ndarray 对象的形状必须与模型输入张量的形状完全匹配。如果需要,您可以使用 ndarray 的 reshape() 方法,结合模型的 input_shape 属性,将输入数据重塑为正确的形状。

如果传递了一个 callback,它将接收 Modelinputsoutputs 作为参数,这允许对模型输出进行自定义后处理。然后,回调函数可以返回任何它想要的内容,这将作为 predict() 的返回值。callback 方法使得可以构建一个后处理函数库,可以根据不同模型的需求随时调用。

对于自定义预处理,predict() 也接受可调用(”callable”)对象作为输入。任何实现了 __call__ 方法的对象都可以作为输入传递给 predict()predict() 会使用一个可写的字节数组(bytearray)表示输入张量,并传递该张量的形状元组和数据类型值(作为整数)来调用该对象。然后,该对象应该将字节数组中的输入张量数据设置为模型所期望的内容。这就是 Normalization() 如何将图像对象转换为输入张量的方式。

属性

len: int

加载的模型的大小(以字节为单位)。

ram: int

模型用于其张量区域(tensor arena)所使用的 RAM 大小。

input_shape: list[tuple[int, ...]]

包含每个输入张量形状的元组列表。

input_dtype: list[str]

包含每个输入张量数据类型的字符串列表。分别为 ‘B’(uint8)、’b’(int8)、’H’(uint16)、’h’(int16)和 ‘f’(float32)。

input_scale: list[float]

包含每个输入张量缩放因子的浮动列表。

input_zero_point: list[int]

包含每个输入张量零点的整数列表。

output_shape: list[tuple[int, ...]]

包含每个输出张量形状的元组列表。

output_dtype: list[str]

包含每个输出张量数据类型的字符串列表。分别为 ‘b’(int8)、’B’(uint8)和 ‘f’(float32)。

output_scale: list[float]

包含每个输出张量缩放因子的浮动列表。

output_zero_point: list[int]

包含每个输出张量零点的整数列表。

labels: list[str]

包含模型标签的字符串列表(如果模型内置在固件中并带有标签,否则为 None)。