Передавання масивів 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++) визначає, чи володіє тензор своїми байтами, чи використовує псевдонім вихідного джерела — явне володіння є безпечним варіантом за замовчуванням, коли вихідний буфер може бути змінений або звільнений.
simaai::neat::from_cv_mat(mat, ImageSpec::PixelFormat::RGB, TensorMemory::CPU) перетворює cv::Mat на тензор, що зберігається в пам’яті ЦП.
// 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);
Перевірка корисного навантаження
Після того, як дані перетворено на тензор, їх можна знову зчитати. Це друга половина процесу взаємодії: перед передачею даних далі необхідно підтвердити, чи збереглися форма та кількість байтів після перетворення.
tensor.map_read() повертає Mapping, що надає доступ до вказівника на необроблені data та size_bytes. Це представлення даних у пам’яті тензора, без копіювання, тому в прикладі можна безпосередньо обчислити контрольну суму перших байтів.
// map_read yields a Mapping with a raw pointer and size in bytes.
simaai::neat::Mapping mapped = tensor.map_read();
Отримання власної копії
Нарешті, створіть дані, які повністю відокремлені від початкового буфера джерела, і їх можна безпечно зберігати після того, як вхідні дані будуть видалені. Це копія, яку ви передаєте довготривалим споживачам.
tensor.clone() копіює дані в нову область пам’яті, що належить ЦП, незалежно від cv::Mat, з якої вони були отримані.
// 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");
Запуск
Запу стіть команди Python і C++ (попередньо зібрані) з кореневої теки встановлення Neat (теки, яка містить share/ і lib/); запустіть команди збірка з вихідного коду з кореневої теки репозиторію. Для цього розділу не потрібен архів моделі.
C++ (prebuilt):
./lib/sima-neat/tutorials/tutorial_009_pass_numpy_to_model \
--width 128 --height 96
C++ (build from source):
./build.sh --target tutorial_009_pass_numpy_to_model
./build/tutorials-standalone/tutorial_009_pass_numpy_to_model \
--width 128 --height 96
Очікуваний результат (C++):
tensor_rank=3
tensor_bytes=36864
head_checksum=4342
clone_bytes=36864
[OK] 009_pass_numpy_to_model
Очікуваний результат (Python, якщо встановлено torch):
numpy_roundtrip_shape=(96, 128, 3)
torch_roundtrip_shape=(96, 128, 3)
(Якщо torch не встановлено, під час збірки Python буде виведено torch_roundtrip_skipped=True замість рядка torch.) Щоб інтегрувати вихідний код C++ цього розділу у власний проєкт за допомогою спеціального файлу CMakeLists.txt (додаткова тека не потрібна), див. розділ Як запускати навчальні матеріали на головній сторінці.
На практиці
Поверхня взаємодії, узагальнена для швидкого довідника після завершення демонстрації циклічного обміну даними.
API перетворення
- NumPy:
pyneat.Tensor.from_numpy(array, copy=..., image_format=...)(вхідні дані);tensor.to_numpy(copy=...)(вихідні дані). - PyTorch:
pyneat.Tensor.from_torch(tensor, copy=..., image_format=...)(вхідні дані);tensor.to_torch(copy=...)(вихідні дані). - OpenCV (C++):
simaai::neat::from_cv_mat(mat, pixel_format, memory)(вхідні дані);tensor.map_read()для представлення без копіювання;tensor.clone()для створення незалежної копії.