Pular para o conteúdo principal

Módulo de arrays multidimensionais do ML

MLMultiArray é o tipo de tensor mais comum no CoreML.
Esta página reúne as funções de módulo e os métodos de objeto relacionados a MLMultiArray no módulo coreml, incluindo:

  • criação de tensores
  • conversão de dados Lua / imagem / OpenCV em tensores
  • conversão entre MLMultiArray e tensores ORT
  • operações matemáticas, reduções, ordenação e concatenação usuais
  • auxiliares de pós-processamento para detecção / OBB / mask / keypoint / tracker

Se você pretende encapsular na camada Lua modelos de classificação, embedding, texto, detecção ou outros modelos CoreML genéricos, os recursos desta página são a base principal.

Este módulo só está disponível em versões posteriores a 20260319

Criação e conversão

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

objeto_array_multidimensional, mensagem_de_erro = coreml.new_multi_array({
shape = array_de_formato,
data_type = tipo_de_dado,
})

Cria um objeto MLMultiArray vazio do CoreML, adequado para uso posterior como entrada de modelo ou tensor intermediário.

  • shape é o formato desejado, por exemplo {1, 3, 224, 224}.
  • data_type aceita opcionalmente "int32", "float32", "float16" e "double"; "float64" pode ser usado como alias de "double".
  • coreml.tensor(opts) é um alias equivalente.

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

objeto_array_multidimensional, mensagem_de_erro = coreml.multi_array_from_table(tabela_de_dados, {
shape = array_de_formato,
data_type = tipo_de_dado,
})

Converte explicitamente os dados de uma tabela Lua em MLMultiArray.

  • shape deve corresponder à quantidade total de dados.
  • As regras de data_type são as mesmas de new_multi_array().
  • coreml.tensor_from_table(...) é um alias equivalente.

coreml.tensor_from_image(image[, opts])

objeto_array_multidimensional, metadados = coreml.tensor_from_image(imagem, configuração)

Converte um objeto de imagem em um tensor aceito pelo CoreML conforme uma configuração explícita.

Campos de configuração comuns:

  • width / height
  • layout: aceita somente "nchw" e "nhwc"
  • channel_order: "rgb", "bgr", "gray", "grey" ou "grayscale"
  • data_type
  • scale
  • mean
  • std
  • resize_mode: "stretch", "letterbox", "center_crop"
  • letterbox_mode: aceita "center" e "top_left"; "topleft" também é tratado como "top_left"
  • pad_color
  • interpolation: "bilinear", "nearest"
  • alpha_mode: "ignore", "white", "black", "premultiply"
  • crop = {x, y, width, height}

Observações:

  • Esta função cuida somente da tensorização de imagens orientada por uma configuração explícita; não associa implicitamente regras de pré-processamento a um modelo específico.
  • Em caso de sucesso, o segundo valor retornado é uma tabela de metadados de pré-processamento; em caso de falha, retorna nil, mensagem_de_erro.
  • Os campos comuns dos metadados incluem: src_width, src_height, crop_x, crop_y, crop_width, crop_height, dst_width, dst_height, resized_width, resized_height, scale_x, scale_y, ratio, pad_left, pad_top, pad_right, pad_bottom, resize_mode, offset_x, offset_y e letterbox_mode.

coreml.tensor_from_images(images[, opts])

tensor_do_batch, metadados_do_batch = coreml.tensor_from_images({img1, img2}, {
width = 640,
height = 640,
layout = "nchw",
})

Converte um grupo de imagens em lote para MLMultiArray.

  • As dimensões das imagens originais podem ser diferentes.
  • Desde que o shape de saída e o data_type processados sejam iguais em cada imagem, elas podem ser combinadas em um batch.
  • O segundo valor retornado é um array de metadados na mesma ordem das entradas.

coreml.image_from_tensor(tensor[, opts])

objeto_imagem, mensagem_de_erro = coreml.image_from_tensor(tensor, opts)

Restaura um tensor MLMultiArray 2D / 3D / 4D como objeto de imagem, o que é útil para depurar entradas e saídas de modelos.

Campos de configuração comuns:

  • layout
  • channel_order
  • batch_index: baseado em 1; o padrão é o primeiro batch (1)
  • scale
  • mean
  • std
  • clamp
  • value_range: "0_255" ou "0_1"

Observações:

  • São aceitos somente tensores 2D / 3D / 4D.
  • A quantidade de canais deve ser 1 ou 3.

coreml.image_to_multi_array(image[, opts])

Este é o nome da interface antiga e atualmente é apenas um alias de compatibilidade de coreml.tensor_from_image(...). Em código novo, use tensor_from_image() de maneira uniforme.

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

Converte cv.mat em MLMultiArray.

  • Primeiro é necessário executar require("image.cv").
  • Os dois nomes são aliases equivalentes.

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

objeto_array_multidimensional, mensagem_de_erro = 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",
})

Recorta em perspectiva uma região quadrilateral de cv.mat e produz diretamente um MLMultiArray.

  • Primeiro é necessário executar require("image.cv").
  • quad pode receber diretamente quatro pontos ou uma tabela com o campo points.
  • As opções comuns são basicamente as mesmas de tensor_from_image(); os campos adicionais comuns são content_width, content_height e border_type.
  • É adequado para retificar e tensorizar uma única caixa antes do reconhecimento OCR.

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

tensor_do_batch, mensagem_de_erro = 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",
})

Recorta vários quadriláteros em lote e os combina automaticamente em um tensor batch.

  • Primeiro é necessário executar require("image.cv").
  • quads deve ser um array não vazio; cada item pode conter points.
  • content_width e content_height de cada item substituem os campos de mesmo nome em opts global.
  • O retorno escolhe automaticamente stack() ou concat() conforme o rank do resultado para formar o batch, sendo adequado ao processamento em lote de várias caixas OCR.

coreml.multi_array_from_ort_tensor(tensor[, data_type])

objeto_array_multidimensional, mensagem_de_erro = coreml.multi_array_from_ort_tensor(tensor_ORT[, "float32"])

Faz uma cópia nativa de onnxruntime.tensor para MLMultiArray.

  • Esta função não existe por padrão; ela só é injetada no módulo coreml integrado depois de executar require("onnxruntime").
  • A conversão usa uma cópia na camada nativa e não passa por uma tabela Lua.
  • Tensores string não podem ser convertidos em MLMultiArray.

Verificação de tipo e aliases

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

é_array_multidimensional = coreml.is_multi_array(valor_a_verificar)

Verifica se um valor é um coreml_multi_array_object. is_tensor() é um alias equivalente.

Funções auxiliares do módulo

Auxiliares básicos de 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)

Observações:

  • take() lê, por padrão, ao longo da primeira dimensão.
  • gather_rows() é um alias conveniente de take(array, indices, 1).
  • where() permite misturar escalares e MLMultiArray e gera o resultado conforme as regras de broadcasting.
  • matmul() atualmente aceita combinações de entradas rank-1 / rank-2.

Auxiliares geométricos e de detecção

  • 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])

Observações:

  • boxes de nms() deve ser [N, 4], e scores deve ser [N] ou [N, C].
  • boxes de rotated_nms() deve ser [N, 5]; atualmente scores usa um array numérico Lua.
  • Ambos retornam um MLMultiArray contendo índices baseados em 1.

Auxiliares de decodificação e records

  • 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])

Observações:

  • create_decoder() retorna um objeto decoder com suporte a :decode(), :task() e :schema().
  • decode_dense_detection() retorna { boxes, scores, labels }; para uma entrada batch, retorna um array de resultados batch.
  • opts.strides de decode_dense_detection() é obrigatório e deve ser um array não vazio de inteiros positivos.
  • decode_dense_detection() também exige decode_width e decode_height; atualmente aceita somente box_encoding = "grid_center_log_wh".
  • records_from_boxes(), obb_records_from_rows() e points_to_records() organizam os resultados dos tensores em uma tabela de records mais adequada ao uso em Lua.

Auxiliares de máscaras, pontos-chave e rastreamento

  • 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])

Observações:

  • project_masks() é um alias de proto_masks().
  • mask_iou() calcula diretamente a interseção sobre união de duas máscaras.
  • mask_iou() também aceita um terceiro argumento opts, com compare_size = true ou width / height explícitos como dimensões alinhadas de comparação.
  • db_postprocess() é adequado ao pós-processamento de detecção de texto do tipo DB / DBNet; a entrada aceita [H, W], [C, H, W] ou [N, C, H, W].
  • db_postprocess() retorna um array de detecções, cada item com score, points e box; meta / image_meta pode reutilizar diretamente os metadados retornados pela tensorização de imagem.
  • tracker() retorna um objeto rastreador com suporte a :update(), :reset(), :state() e :close().
  • ctc_greedy_decode() aceita entradas [T, C] ou [N, T, C].
  • ctc_greedy_decode() aceita blank_index, merge_repeated, apply_softmax, return_probabilities e charset.
  • ctc_greedy_decode() sempre retorna indices; só inclui text quando charset é passado; só inclui confidence quando apply_softmax ou return_probabilities está habilitado; só inclui adicionalmente probabilities e probability_confidence quando return_probabilities está habilitado.
  • sample_logits() aceita argmax, temperature, top_k, top_p, min_p e seed.
  • Para logits 1D, sample_logits() retorna um único índice baseado em 1; para logits em batch, retorna um MLMultiArray de índices.

Métodos básicos do objeto

Consultas básicas

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

Observações:

  • data_type() retorna "int32", "float32", "float16" ou "double".
  • to_cv_mat() exige executar antes require("image.cv").

Ponte ORT

  • array:to_ort_tensor([data_type])

Este método não existe por padrão; ele só é injetado em coreml_multi_array_object depois de executar require("onnxruntime").

Conversão de tipo e formato

  • 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]])

Observações:

  • reshape(), transpose(), squeeze(), unsqueeze() e flatten() retornam uma view por padrão, sem copiar os dados subjacentes.
  • reshape() / flatten() geram erro para layouts não contíguos; nesse caso, chame clone() antes.
  • slice() e select() retornam novos tensores contíguos, não uma view.
  • A semântica de índices de slice() / select() / gather() / take() é consistente com a página do ONNX e usa base 1.

Métodos numéricos e de índice

  • 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)

Observações:

  • add/sub/mul/div aceitam escalares e broadcasting limitado.
  • Os resultados de sigmoid(), exp() e matmul() são promovidos para saída de ponto flutuante.

Redução, ordenação e seleção

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

Observações:

  • Sem um eixo, argmax() retorna o índice linear baseado em 1 do maior valor do array.
  • argmax(axis) retorna um MLMultiArray contendo os índices.
  • topk() retorna { values = tensor, indices = tensor }.
  • sort() retorna um novo MLMultiArray ordenado e não retorna uma tabela de índices adicional.

Métodos de objeto geométricos e de pós-processamento

  • 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])

Esses métodos compartilham a mesma implementação subjacente das funções de módulo homônimas; a diferença é que o array atual é passado como primeiro argumento.

Recomendações de uso

  • Para as novas interfaces CoreML genéricas, MLMultiArray é o tipo de dado de primeira classe padrão; não o converta prematuramente em tabela Lua.
  • A maioria das operações em lote deve ser feita no objeto tensor sempre que possível; chame to_table() apenas para depuração, saída de dados pequenos ou compatibilidade com código antigo.
  • As regras de pré-processamento de imagem devem ser especificadas explicitamente pelos parâmetros de tensor_from_image(), evitando codificar o pré-processamento de um modelo específico em um fluxo genérico.
  • Se precisar de uma cópia independente ou quiser transformar um layout não contíguo em tensor contíguo, chame clone() explicitamente.

Exemplo

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())