將 NumPy 陣列傳遞給模型
| 欄位 | 值 |
|---|---|
| 類別 | 模型與推論 |
| 難度 | 中級 |
| 預估閱讀時間 | 10-15 minutes |
| 標籤 | numpy, pytorch, tensor, io |
如果您正在將 Neat 整合到現有的推論堆疊中,這就是您需要處理的互通介面:如何將主機資料轉換為 Neat Tensor,以及如何將 Neat Tensor 再次轉換為主機資料。一開始就正確處理,可以避免常見的整合錯誤——錯誤的佈局、靜默的資料類型轉換、兩個世界之間意外的別名。
這也是兩個語言差異最大的地方。Python 使用者來自 NumPy/PyTorch;C++ 使用者來自 OpenCV。轉換的概念是相 同的,但 API 名稱和類型不同,因此以下針對不同語言的說明非常重要。到最後,您將會將主機資料轉換為 Neat 張量,檢查其有效載荷而不進行複製,並產生一個受擁有權管理的副本,該副本可以安全地保留,即使原始緩衝區不再存在。
操作指南
將主機資料封裝為張量
第一步將您已經擁有的資料轉換為 Neat Tensor。您明確標記圖像佈局(RGB),以便執行階段正確地解釋位元組,而不是進行推測。copy=True(或 C++ 中的 CPU 記憶體選擇)決定張量是否擁有其位元組或引用原始資料——明確的擁有權是安全的預設選項,因為原始緩衝區可能會更改或釋放。
C++: simaai::neat::from_cv_mat(mat, ImageSpec::PixelFormat::RGB, TensorMemory::CPU) 將 cv::Mat 封裝到由 CPU 支援的張量中。
Python: pyneat.Tensor.from_numpy(arr, copy=True, image_format=pyneat.PixelFormat.RGB) 將 HWC uint8 NumPy 陣列封裝起來。
// from_cv_mat converts a cv::Mat into a CPU-backed Neat Tensor.
simaai::neat::Tensor tensor = simaai::neat::from_cv_mat(
rgb, simaai::neat::ImageSpec::PixelFormat::RGB, simaai::neat::TensorMemory::CPU);
檢查有效載荷
一旦資料成為張量,您就可以讀取它。這是互通介面的單向轉換:在將任何資料傳遞到後續處理之前,確認形狀和位元組是否在轉換過程中保留下來。
C++: tensor.map_read() 傳回一個 Mapping,它公開了一個原始 data 指標和 size_bytes。這是一個張量儲存空間的視圖——沒有複製——這就是為什麼示例可以直接對前幾個位元組進行檢查和驗證。
Python: tensor.to_numpy(copy=True) 從張量中產生一個 NumPy 陣列;示例列印其 .shape,以確認 HWC 佈局在單向轉換中保持完整。
// map_read yields a Mapping with a raw pointer and size in bytes.
simaai::neat::Mapping mapped = tensor.map_read();
擁有副本
最後,產生與原始來源緩衝區完全分離的資料——即使在輸入消失後,也可以安全地保留。這是您傳遞給 長期使用的消費者的副本。
C++: tensor.clone() 複製到新的、由 CPU 擁有的儲存空間中,與其來源的 cv::Mat 無關。
**Python:**透過 PyTorch 呈現相同的概念:pyneat.Tensor.from_torch(t, copy=True, ...) 和 tensor.to_torch(copy=True) 透過一個擁有的 PyTorch 張量進行來回轉換。(如果未安裝 torch,則會優雅地跳過。)
// clone() copies into CPU-owned storage, detached from the cv::Mat buffer.
simaai::neat::Tensor owned = tensor.clone();
if (owned.dense_bytes_tight() == 0U)
throw std::runtime_error("cloned tensor is empty");