Перейти до основного вмісту

Налаштування параметрів моделі

ПолеЗначення
КатегоріяМоделі та інференс
СкладністьПочатковий
Орієнтовний час читання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>.

tutorials/005_configure_model_options/configure_model_options.cpp
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.

tutorials/005_configure_model_options/configure_model_options.cpp
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; ми виводимо конкретну форму.

tutorials/005_configure_model_options/configure_model_options.cpp
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=.

tutorials/005_configure_model_options/configure_model_options.cpp
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()Примусово активує повний режим детального виводу інформації для всіх тем.

Для налаштування черги/пропускної здатності під час виконання, див. Налаштування пропускної здатності та глибини черги.

Повний початковий код​

Показати повні програми
tutorials/005_configure_model_options/configure_model_options.cpp
// 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;
}
}

Джерело​