Как извлечь ответ нейронной сети формата pytorch в c++?

Я обучил keras модель и затем сконвертировал её в pytorch используя mmdnn. Затем я попробовал использовать её в c++ коде:

#include <iostream>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <torch.h>

int main()
{
    cv::Mat image;
    image= cv::imread("test_img.png", cv::IMREAD_GRAYSCALE);   // Read the file

try
{
    torch::jit::script::Module module;
    module = torch::jit::load("my_model.pth");

    torch::IntArrayRef input_dim = std::vector<int64_t>({ 1, 2, 256, 256});

    cv::Mat input_img;
    image.convertTo(input_img, CV_32FC3, 1 / 255.0);
    torch::Tensor x = torch::from_blob(input_img.data, { 1, 2, 256, 256 }, torch::kFloat);
    torch::NoGradGuard no_grad;

    auto output = module.forward({ x });

    float* data = static_cast<float*>(output.toTensor().data_ptr());

    cv::Mat output_img = cv::Mat(256, 256, CV_32FC3, data);
    cv::imwrite("output_img.png", output_img);
}
catch (std::exception &ex)
{
    std::cout << "exception! " << ex.what() << std::endl;
}

    return 0;
}

В результате запуска получено исключение:

exception! isTensor() INTERNAL ASSERT FAILED at E:\20B\pytorch\pytorch\aten\src\ATen/core/ivalue_inl.h:112, please report a bug to PyTorch. Expected Tensor but got Tuple (toTensor at E:\20B\pytorch\pytorch\aten\src\ATen/core/ivalue_inl.h:112) (no backtrace available)

Исключение было выброшено в строке float* data = static_cast<float*>(output.toTensor().data_ptr()); при вызове функции toTensor(). Если использовать вместо неё toTuple(), то получившийся объект не имеет метода data_ptr(), который нужен мне для получения данных, содержащих ответа нейронной сети (и чтобы затем поместить их в картинку opencv для последующего её сохранения).

Как всё-таки извлечь картинку из ответа нейронной сети?


Ответы (1 шт):

Автор решения: zcorvid

В данном случае ответ нейронной сети содержит массив (tuple) блобов, поэтому для их извлечения в виде тензоров нужно использовать следующие вызовы:

torch::Tensor t0 = output.toTuple()->elements()[0].toTensor();
torch::Tensor t1 = output.toTuple()->elements()[1].toTensor();

Теперь в переменных t0 и t1 тензоры с двумя ответами нейронной сети.

→ Ссылка