Налаштування параметрів моделі
| Поле | Значення |
|---|---|
| Категорія | Моделі та інференс |
| Складність | Початковий |
| Орієнтовний час читання | 5 minutes |
| Мітки | model-options, configuration, contracts |
Розділ 001 завантажує модель із розумними параметрами за замовчуванням. Для реальних моделей — особливо моделей виявлення, таких як YOLOv8 — вам потрібно вказати їхні параметри: у якому піксельному форматі та розмірі надходять вхідні дані, як їх слід нормалізувати та як необроблені вихідні дані мережі перетворюються на відфільтровані рамки. ModelOptions об’єднує все це в єдину структуру, яку ви заповнюєте перед створенням моделі.
У цьому розділі налаштовується модель YOLOv8 від початку до кінця, а потім перевіряються параметри, які середовище виконання отримало на основі цих налаштувань. В результаті ви налаштуєте параметри вхідних даних, попередньої обробки та постоброб ки, зчитаєте отримані input_specs()/output_specs()/metadata і пропустите один детермінований кадр через налаштовану модель.
Покроковий огляд
Вкажіть вхідні дані та параметри попередньої обробки
Перший блок описує, як виглядає кадр і як його підготувати для мережі. format (BGR у цьому випадку) і обмеження input_max_width/height/depth визначають вхідні параметри, які перевіряються середовищем виконання, і встановлюють розміри буферів. Поля нормалізації містять середнє значення та стандартне відхилення для кожного каналу, з якими було навчено модель, тому необроблені пікселі масштабуються до діапазону, який очікує мережа.
Поля розташовані в opt.preprocess.*: kind = InputKind::Image, color_convert.input_format = PreprocessColorFormat::BGR і normalize.enable = AutoFlag::On, причому mean/stddev є std::array<float, 3>.
opt.preprocess.kind = simaai::neat::InputKind::Image;
opt.preprocess.color_convert.input_format = simaai::neat::PreprocessColorFormat::BGR;
opt.preprocess.input_max_width = 640;
opt.preprocess.input_max_height = 640;
opt.preprocess.input_max_depth = 3;
opt.preprocess.normalize.enable = simaai::neat::AutoFlag::On;
opt.preprocess.normalize.mean = std::array<float, 3>{0.485f, 0.456f, 0.406f};
opt.preprocess.normalize.stddev = std::array<float, 3>{0.229f, 0.224f, 0.225f};
Оголосіть постобробку
Другий блок формує вихідні дані детектора. decode_type вибирає шлях декодування прямокутників YOLOv8, а score_threshold, nms_iou_threshold та top_k фільтрують необроблені результати виявлення, відкидаючи прямокутники з низькою вп евненістю, об’єднуючи перекривні прямокутники та обмежуючи кількість тих, що залишаються. boxdecode_original_width/boxdecode_original_height надають декодеру геометрію вихідного кадру, необхідну для відображення нормалізованих координат назад у пікселі, а name_suffix стабілізує згенеровані імена етапів, щоб граф конвеєра залишався читабельним під час об’єднання з іншими.
decode_type = BoxDecodeType::YoloV8; поля геометрії: boxdecode_original_width/boxdecode_original_height.
opt.decode_type = simaai::neat::BoxDecodeType::YoloV8;
opt.score_threshold = 0.55f;
opt.nms_iou_threshold = 0.45f;
opt.top_k = 100;
opt.boxdecode_original_width = 640;
opt.boxdecode_original_height = 640;
opt.name_suffix = "_chapter";
Завантаження та перевірка отриманого контракту
Створення Model із цими параметрами дозвол яє застосувати контракт до архіву. Потім ми зчитуємо його: input_specs() та output_specs() відображають узгоджені обмеження тензора, а metadata() надає доступ до контракту у форматі «ключ/значення», що зберігається в архіві. Перевірка цих даних після завантаження підтверджує, що середовище виконання прийняло ваші параметри, і показує конкретні розміри, з якими ви будете працювати.
Специфікації є значеннями TensorConstraint; ми виводимо конкретну форму.
simaai::neat::Model model(model_path, opt);
print_spec("input_specs[0]", model.input_specs().front());
print_spec("output_specs[0]", model.output_specs().front());
std::cout << "metadata_keys=" << model.metadata().size() << "\n";
Відтворити один кадр
Зрештою, ми синтезуємо один. 640×640 Кадр BGR, який обробляється налаштованою моделлю, підтверджує, що весь процес виконується від початку до кінця, і виводить кількість отриманих результатів.
Кадр — це cv::Mat; run() повертає TensorList чий size() ми друкуємо як outputs=.
cv::Mat bgr(640, 640, CV_8UC3, cv::Scalar(10, 20, 30));
if (!bgr.isContinuous())
bgr = bgr.clone();
auto out = model.run(std::vector<cv::Mat>{bgr}, /*timeout_ms=*/2000);
if (out.empty())
throw std::runtime_error("model produced no outputs");
std::cout << "outputs=" << out.size() << "\n";
Запуск
Запустіть програму, і ви повинні побачити остаточні форми специфікацій, кількість метаданих і загальну кількість результатів. Запустіть команди Python і C++ (попередньо скомпільовані) з Neat встановити в кореневу директорію **(директорію, яка містить) share/ і lib/); виконайте команди збірки з вихідного коду з кореневої директорії репозиторію.
C++ (prebuilt):
./lib/sima-neat/tutorials/tutorial_005_configure_model_options \
--model /tmp/yolo_v8s.tar.gz
C++ (build from source):
./build.sh --target tutorial_005_configure_model_options
./build/tutorials-standalone/tutorial_005_configure_model_options \
--model /tmp/yolo_v8s.tar.gz
Очікуваний результат (форма та кількість ключових точок залежать від архіву моделі; збірка C++ виводить детальні специфікації та outputs=, збірка Python виводить форми та output_count=):
input_specs[0]: shape=[640,640,3]
output_specs[0]: shape=[]
metadata_keys=8
outputs=1
[OK] 005_configure_model_options
Щоб інтегрувати вихідний код C++ з цієї глави у власний проєкт за допомогою спеціального файлу CMakeLists.txt (додаткова тека не потрібна), див. розділ Як запускати навчальні матеріали на головній сторінці.
На практиці
Попередньо встановлені рівні деталізації виводу
Управління повідомленнями під час збірки/виконання фреймворку здійснюється за допомогою VerboseOptions у GraphOptions, Model::Options та Model::RouteOptions.
Поточний режим за замовчуванням для розробки: VerboseOptions::debug_all(). Явно викликайте production() або quiet(), коли потрібно зменшити обсяг виведеної інформації.
| Попередньо встановлений режим | Призначення |
|---|---|
VerboseOptions::quiet() | Пригнічує вивід інформації про прогрес і деталі фреймворку. |
VerboseOptions::production() | Показує лише прогрес на етапі виконання. |
VerboseOptions::debug_plugins() | Зберігає зручний інтерфейс для користувача у виробничому середовищі, але також відображає інформацію про плагіни та теми GStreamer. |
VerboseOptions::debug_all() | Примусово активує повний режим детального виводу інформації для всіх тем. |
Для налаштування черги/пропускної здатності під час виконання, див. Налаштування пропускної здатності та глибини черги.
Повний початковий код
Показати повні програми
// Model::Options chapter: configure input/preproc/boxdecode via Options, inspect specs.
//
// Usage:
// tutorial_005_configure_model_options --model /path/to/yolo_v8s.tar.gz
#include "neat.h"
#include <opencv2/core.hpp>
#include <array>
#include <iostream>
#include <stdexcept>
#include <string>
namespace {
bool get_arg(int argc, char** argv, const std::string& key, std::string& out) {
for (int i = 1; i + 1 < argc; ++i) {
if (key == argv[i]) {
out = argv[i + 1];
return true;
}
}
return false;
}
void print_spec(const char* label, const simaai::neat::TensorConstraint& spec) {
std::cout << label << ": shape=[";
for (std::size_t i = 0; i < spec.shape.size(); ++i) {
std::cout << (i ? "," : "") << spec.shape[i];
}
std::cout << "]\n";
}
} // namespace
int main(int argc, char** argv) {
try {
std::string model_path;
if (!get_arg(argc, argv, "--model", model_path)) {
std::cerr << "Usage: tutorial_005_configure_model_options --model <path>\n";
return 1;
}
// Model::Options groups input caps, preproc, and box-decode into one struct.
simaai::neat::Model::Options opt;
opt.preprocess.kind = simaai::neat::InputKind::Image;
opt.preprocess.color_convert.input_format = simaai::neat::PreprocessColorFormat::BGR;
opt.preprocess.input_max_width = 640;
opt.preprocess.input_max_height = 640;
opt.preprocess.input_max_depth = 3;
opt.preprocess.normalize.enable = simaai::neat::AutoFlag::On;
opt.preprocess.normalize.mean = std::array<float, 3>{0.485f, 0.456f, 0.406f};
opt.preprocess.normalize.stddev = std::array<float, 3>{0.229f, 0.224f, 0.225f};
opt.decode_type = simaai::neat::BoxDecodeType::YoloV8;
opt.score_threshold = 0.55f;
opt.nms_iou_threshold = 0.45f;
opt.top_k = 100;
opt.boxdecode_original_width = 640;
opt.boxdecode_original_height = 640;
opt.name_suffix = "_chapter";
// CORE LOGIC
simaai::neat::Model model(model_path, opt);
print_spec("input_specs[0]", model.input_specs().front());
print_spec("output_specs[0]", model.output_specs().front());
std::cout << "metadata_keys=" << model.metadata().size() << "\n";
cv::Mat bgr(640, 640, CV_8UC3, cv::Scalar(10, 20, 30));
if (!bgr.isContinuous())
bgr = bgr.clone();
auto out = model.run(std::vector<cv::Mat>{bgr}, /*timeout_ms=*/2000);
if (out.empty())
throw std::runtime_error("model produced no outputs");
std::cout << "outputs=" << out.size() << "\n";
std::cout << "[OK] 005_configure_model_options\n";
return 0;
} catch (const std::exception& e) {
std::cerr << "[FAIL] " << e.what() << "\n";
return 1;
}
}