跳到主要内容

ML 多维数组模块

MLMultiArray 是 CoreML 里最常见的张量类型。
这页统一说明 coreml 模块中与 MLMultiArray 相关的模块级函数和对象方法,包括:

  • 创建张量
  • 把 Lua / 图像 / OpenCV 数据转成张量
  • MLMultiArray 与 ORT tensor 互转
  • 常用数学运算、归约、排序和拼接
  • 检测 / OBB / mask / keypoint / tracker 等后处理辅助

如果你要在 Lua 层封装分类、Embedding、文本模型、检测模型或其它通用 CoreML 模型,这一页里的能力就是主要基础。

该模块在 20260319 以后版本方可使用

创建与转换

coreml.new_multi_array(opts) / coreml.tensor(opts)

多维数组对象, 错误信息 = coreml.new_multi_array({
shape = 形状数组,
data_type = 数据类型,
})

用于创建一个空的 CoreML 多维数组对象,适合后续作为模型输入或中间张量使用。

  • shape 为目标形状,例如 {1, 3, 224, 224}
  • data_type 可选 "int32""float32""float16""double""float64" 可作为 "double" 的别名
  • coreml.tensor(opts) 是同义别名

coreml.multi_array_from_table(data, opts) / coreml.tensor_from_table(data, opts)

多维数组对象, 错误信息 = coreml.multi_array_from_table(数据表, {
shape = 形状数组,
data_type = 数据类型,
})

用于把 Lua 表中的数据显式转换成 MLMultiArray

  • shape 必须与数据总量匹配
  • data_type 规则与 new_multi_array() 一致
  • coreml.tensor_from_table(...) 是同义别名

coreml.tensor_from_image(image[, opts])

多维数组对象, 元信息 = coreml.tensor_from_image(图片, 配置)

用于把图片对象按显式配置转换为 CoreML 可用的张量。

常用配置字段:

  • width / height
  • layout:仅支持 "nchw""nhwc"
  • channel_order"rgb""bgr""gray""grey""grayscale"
  • data_type
  • scale
  • mean
  • std
  • resize_mode"stretch""letterbox""center_crop"
  • letterbox_mode:支持 "center""top_left",其中 "topleft" 也会按 "top_left" 处理
  • pad_color
  • interpolation"bilinear""nearest"
  • alpha_mode"ignore""white""black""premultiply"
  • crop = {x, y, width, height}

说明:

  • 该函数只负责显式配置驱动的图像张量化,不会隐式绑定某个具体模型的预处理规则
  • 成功时第二个返回值是预处理元信息表;失败时返回 nil, 错误信息
  • 元信息常见字段包括: src_widthsrc_heightcrop_xcrop_ycrop_widthcrop_heightdst_widthdst_heightresized_widthresized_heightscale_xscale_yratiopad_leftpad_toppad_rightpad_bottomresize_modeoffset_xoffset_yletterbox_mode

coreml.tensor_from_images(images[, opts])

批量张量, 批量元信息 = coreml.tensor_from_images({img1, img2}, {
width = 640,
height = 640,
layout = "nchw",
})

把一组图像批量转换成 MLMultiArray

  • 原图尺寸可以不同
  • 只要每张图解析后的输出 shape 与 data_type 一致,就能拼成 batch
  • 第二个返回值是与输入顺序对应的元信息数组

coreml.image_from_tensor(tensor[, opts])

图像对象, 错误信息 = coreml.image_from_tensor(张量, opts)

把 2D / 3D / 4D MLMultiArray 还原成图像对象,适合调试模型输入输出。

常用配置字段:

  • layout
  • channel_order
  • batch_index:1-based,默认第 1 个 batch
  • scale
  • mean
  • std
  • clamp
  • value_range"0_255""0_1"

说明:

  • 仅支持 2D / 3D / 4D 张量
  • 通道数仅支持 13

coreml.image_to_multi_array(image[, opts])

这是旧接口名,当前只是 coreml.tensor_from_image(...) 的兼容别名。新代码建议统一使用 tensor_from_image()

coreml.tensor_from_cv_mat(mat[, opts]) / coreml.multi_array_from_cv_mat(mat[, opts])

用于把 cv.mat 转成 MLMultiArray

  • 需要先 require("image.cv")
  • 两个名字是同义别名

coreml.tensor_from_quad(mat, quad[, opts]) / coreml.multi_array_from_quad(mat, quad[, opts])

多维数组对象, 错误信息 = coreml.tensor_from_quad(mat, {
{x = 0, y = 0},
{x = 100, y = 0},
{x = 100, y = 32},
{x = 0, y = 32},
}, {
width = 100,
height = 32,
layout = "hwc",
channel_order = "rgb",
data_type = "float32",
})

用于从 cv.mat 中按四边形区域做透视裁剪,再直接得到 MLMultiArray

  • 需要先 require("image.cv")
  • quad 可以直接传四个点,也可以传带 points 字段的表
  • 常用 optstensor_from_image() 基本一致,额外常见字段有 content_widthcontent_heightborder_type
  • 适合 OCR 识别前的单框拉正与张量化

coreml.tensor_from_quads(mat, quads[, opts]) / coreml.multi_array_from_quads(mat, quads[, opts])

批量张量, 错误信息 = coreml.tensor_from_quads(mat, {
{
points = quad1,
content_width = 96,
content_height = 32,
},
{
points = quad2,
content_width = 80,
content_height = 32,
},
}, {
width = 96,
height = 32,
resize_mode = "top_left_letterbox",
border_type = "replicate",
})

用于批量裁剪多个四边形并自动拼成 batch 张量。

  • 需要先 require("image.cv")
  • quads 必须是非空数组;每项可以带 points
  • 每项里的 content_widthcontent_height 会覆盖全局 opts 里的同名字段
  • 返回值会按结果 rank 自动走 stack()concat() 拼成 batch,适合 OCR 多框批处理

coreml.multi_array_from_ort_tensor(tensor[, data_type])

多维数组对象, 错误信息 = coreml.multi_array_from_ort_tensor(ORT张量[, "float32"])

用于把 onnxruntime.tensor 原生拷贝成 MLMultiArray

  • 这个函数默认不存在;只有执行过 require("onnxruntime") 后才会被注入到内置 coreml 模块中
  • 转换过程走 native 层拷贝,不经过 Lua table
  • string tensor 不能转换成 MLMultiArray

类型判断与别名

coreml.is_multi_array(value) / coreml.is_tensor(value)

是否多维数组 = coreml.is_multi_array(需要判断的值)

用于判断一个值是否为 coreml_multi_array_objectis_tensor() 是同义别名。

模块级辅助函数

基础张量辅助

  • coreml.concat(arrays, axis)
  • coreml.stack(arrays, axis)
  • coreml.gather(array, dim, indices)
  • coreml.take(array, indices[, dim])
  • coreml.gather_rows(array, indices)
  • coreml.clamp(array, min, max)
  • coreml.sigmoid(array)
  • coreml.exp(array)
  • coreml.where(condition, x, y)
  • coreml.matmul(lhs, rhs)

说明:

  • take() 默认沿第 1 维取值
  • gather_rows()take(array, indices, 1) 的便捷别名
  • where() 支持标量与 MLMultiArray 混用,并按广播规则生成结果
  • matmul() 当前支持 rank-1 / rank-2 输入组合

几何与检测辅助

  • coreml.nms(boxes, scores[, opts])
  • coreml.box_points(rotated_boxes)
  • coreml.xywh_to_xyxy(boxes)
  • coreml.xyxy_to_xywh(boxes)
  • coreml.rotated_iou(lhs, rhs)
  • coreml.rotated_nms(boxes, scores[, opts])

说明:

  • nms()boxes 必须是 [N, 4]scores 必须是 [N][N, C]
  • rotated_nms()boxes 必须是 [N, 5];当前 scores 使用 Lua 数字数组
  • 两者返回的都是保存 1-based 索引的 MLMultiArray

解码与 record 辅助

  • coreml.create_decoder(schema)
  • coreml.decode_yolo(output[, opts])
  • coreml.decode_yolo_obb(output[, opts])
  • coreml.decode_matrix_candidates(output, schema[, opts])
  • coreml.decode_dense_detection(output, opts)
  • coreml.records_from_boxes(boxes, scores, class_ids[, keep_indices])
  • coreml.obb_records_from_rows(rows, scores, class_ids[, angles[, keep_indices[, opts]]])
  • coreml.points_to_records(points[, opts])

说明:

  • create_decoder() 返回 decoder 对象,支持 :decode():task():schema()
  • decode_dense_detection() 返回 { boxes, scores, labels },当输入是 batch 时返回 batch 结果数组
  • decode_dense_detection()opts.strides 是必填项,且必须是非空正整数数组
  • decode_dense_detection() 还要求 decode_widthdecode_height,且当前只支持 box_encoding = "grid_center_log_wh"
  • records_from_boxes()obb_records_from_rows()points_to_records() 会把张量结果整理成更适合 Lua 使用的 record table

掩码、关键点与跟踪辅助

  • coreml.threshold_masks(masks, threshold)
  • coreml.crop_masks_by_boxes(masks, boxes)
  • coreml.resize_masks(masks, width, height[, opts])
  • coreml.mask_iou(lhs_mask, rhs_mask)
  • coreml.mask_to_polygon(mask[, opts])
  • coreml.proto_masks(proto, coeffs, boxes, image_width, image_height[, opts])
  • coreml.project_masks(proto, coeffs, boxes, image_width, image_height[, opts])
  • coreml.db_postprocess(score_map[, opts])
  • coreml.tracker([opts])
  • coreml.reshape_keypoints(points[, keypoint_count[, keypoint_dim|opts]])
  • coreml.scale_boxes(boxes, transform)
  • coreml.clip_boxes(boxes, clip_width, clip_height)
  • coreml.scale_points(points, transform[, opts])
  • coreml.scale_keypoints(points, transform[, opts])
  • coreml.clip_keypoints(points, clip_width, clip_height[, opts])
  • coreml.ctc_greedy_decode(logits[, opts])
  • coreml.sample_logits(logits[, opts])

说明:

  • project_masks()proto_masks() 的别名
  • mask_iou() 用于直接计算两张 mask 的交并比
  • mask_iou() 还支持第三个参数 opts,可传 compare_size = true,或显式传 width / height 作为对齐后的比较尺寸
  • db_postprocess() 适合 DB / DBNet 一类文本检测后处理;输入支持 [H, W][C, H, W][N, C, H, W]
  • db_postprocess() 返回检测数组,每项都带 scorepointsboxmeta / image_meta 可直接复用图像张量化返回的元信息
  • tracker() 返回跟踪器对象,支持 :update():reset():state():close()
  • ctc_greedy_decode() 输入支持 [T, C][N, T, C]
  • ctc_greedy_decode() 支持 blank_indexmerge_repeatedapply_softmaxreturn_probabilitiescharset
  • ctc_greedy_decode() 一定会返回 indices;只有传了 charset 才会带 text;只有启用 apply_softmaxreturn_probabilities 才会带 confidence;只有启用 return_probabilities 才会额外带 probabilitiesprobability_confidence
  • sample_logits() 支持 argmaxtemperaturetop_ktop_pmin_pseed
  • sample_logits() 对 1D logits 返回单个 1-based 索引;对 batched logits 返回索引 MLMultiArray

对象基础方法

基础查询

  • array:shape()
  • array:data_type()
  • array:count()
  • array:strides()
  • array:to_table()
  • array:to_cv_mat([opts])

说明:

  • data_type() 返回 "int32""float32""float16""double"
  • to_cv_mat() 需要先 require("image.cv")

ORT 桥接

  • array:to_ort_tensor([data_type])

这个方法默认不存在;只有执行过 require("onnxruntime") 后才会被注入到 coreml_multi_array_object

类型与形状变换

  • array:astype(data_type)
  • array:clone()
  • array:reshape(shape)
  • array:transpose(axes)
  • array:slice(dim, start, stop[, step])
  • array:select(dim, index)
  • array:squeeze([dim])
  • array:unsqueeze(dim)
  • array:flatten([start_dim[, end_dim]])

说明:

  • reshape()transpose()squeeze()unsqueeze()flatten() 默认返回 view,不复制底层数据
  • reshape() / flatten() 对非连续布局会报错;这时可先 clone()
  • slice()select() 返回新的连续张量,不是 view
  • slice() / select() / gather() / take() 的索引语义都与 ONNX 页保持 1-based 一致

数值与索引方法

  • array:gather(dim, indices)
  • array:take(indices[, dim])
  • array:l2_norm()
  • array:dot(other)
  • array:max([axis])
  • array:min([axis])
  • array:add(other)
  • array:sub(other)
  • array:mul(other)
  • array:div(other)
  • array:clamp(min, max)
  • array:sigmoid()
  • array:exp()
  • array:matmul(other)
  • array:scale(number)

说明:

  • add/sub/mul/div 支持标量和有限 broadcasting
  • sigmoid()exp()matmul() 的结果会提升到浮点输出

归约、排序与选择

  • array:sum([axis])
  • array:mean([axis])
  • array:softmax([axis])
  • array:normalize([axis])
  • array:argmax([axis])
  • array:topk(k[, axis])
  • array:sort([axis[, descending]])

说明:

  • argmax() 不传轴时返回整个数组最大值的 1-based 线性索引
  • argmax(axis) 返回保存索引的 MLMultiArray
  • topk() 返回 { values = 张量, indices = 张量 }
  • sort() 返回排序后的新 MLMultiArray不会 额外返回索引表

几何与后处理对象方法

  • array:clip_boxes(clip_width, clip_height)
  • array:xywh_to_xyxy()
  • array:xyxy_to_xywh()
  • array:reshape_keypoints([keypoint_count[, keypoint_dim|opts]])
  • array:scale_points(transform[, opts])
  • array:clip_keypoints(clip_width, clip_height[, opts])

这些方法与同名模块级函数共享同一套底层实现,只是把当前数组作为第一个参数传入。

使用建议

  • 对新的通用 CoreML 接口来说,MLMultiArray 是默认的一等数据类型,不建议过早转换为 Lua 表
  • 大多数批量运算应尽量在张量对象上完成,只有在调试、小数据输出或兼容旧代码时再调用 to_table()
  • 图像预处理规则应通过 tensor_from_image() 的参数显式指定,避免把某个模型的预处理硬编码到通用流程中
  • 如果你需要一份独立副本,或希望把非连续布局整理成连续张量,请显式调用 clone()

示例

local arr = assert(coreml.tensor({
shape = {2, 3},
data_type = "float32",
}))

local filled = assert(coreml.tensor_from_table({
{1, 2, 3},
{4, 5, 6},
}, {
shape = {2, 3},
data_type = "float32",
}))

local merged = assert(coreml.concat({filled, filled}, 1))
print(coreml.is_tensor(merged))
print(merged:shape())