gpt4 book ai didi

c++ - 与 Python 相比,在 Pytorch C++ API 中无法获得相似的 DL 预测结果

转载 作者:行者123 更新时间:2023-12-01 14:23:25 26 4
gpt4 key购买 nike

我已经使用 unet 架构训练了一个深度学习模型,以便在 python 和 pytorch 中分割核。我想加载这个预训练模型并用 C++ 进行预测。为此,我获得了跟踪文件(扩展名为 pt)。然后,我运行了这段代码:

#include <iostream>

#include <torch/script.h> // One-stop header.

#include <iostream>
#include <memory>

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


using namespace cv;


int main(int argc, const char* argv[]) {


Mat image;
image = imread("C:/Users/Sercan/PycharmProjects/samplepyTorch/test_2.png", CV_LOAD_IMAGE_COLOR);

std::shared_ptr<torch::jit::script::Module> module = torch::jit::load("C:/Users/Sercan/PycharmProjects/samplepyTorch/epistroma_unet_best_model_trace.pt");
module->to(torch::kCUDA);


std::vector<int64_t> sizes = { 1, 3, image.rows, image.cols };
torch::TensorOptions options(torch::ScalarType::Byte);
torch::Tensor tensor_image = torch::from_blob(image.data, torch::IntList(sizes), options);
tensor_image = tensor_image.toType(torch::kFloat);
auto result = module->forward({ tensor_image.to(at::kCUDA) }).toTensor();


result = result.squeeze().cpu();
result = at::sigmoid(result);

cv::Mat img_out(image.rows, image.cols, CV_32F, result.data<float>());

cv::imwrite("img_out.png", img_out);

}

图片输出(第一张图片:测试图片,第二张图片:Python预测结果,第三张图片:C++预测结果):

enter image description here

如您所见,C++ 预测输出与 Python 预测输出不同。您能否提供解决此问题的解决方案?

最佳答案

尽管这个问题很老,但它可能对某些人有用。此答案基于 pytorch 1.5.0发布(以及 C++ 前端的第一个稳定版本),情况可能与以前的版本略有不同(尽管 1.4.0 + 可以使用相同的 IIRC)。

PyTorch C++ 前端代码

  • 无需显式创建torch::TensorOptions如果只想在 torch::from_blob 中指定类型,则对象.检查Configuring Properties of Tensor在 PyTorch 笔记中,这将进一步清除它。基本上,您可以使用 torch::ScalarType::Byte .
  • 这个类型相当于torch::kUInt8在 IMO 文档中更容易找到
  • 无需创建std::vector对象保持形状为 torch::from_blob它的第二个参数类型为 IntArrayRef ,这是一个 typedef 对于 ArrayRef<int64_t> (参见 ArrayRef documentation)。反过来,这个类有多个重载的构造函数,其中一个需要 std::initializer_list 。 (这正是你的 { 1, 3, image.rows, image.cols } )

考虑到所有这些,您可以创建 tensor_image像这样在一行中(添加 auto 因为返回的类型是 IMO 显而易见的,并且 const 因为它不会随着类型在同一行中的更改而进一步修改):

const auto tensor_image =
torch::from_blob(image.data, {1, 3, image.rows, image.cols},
torch::kUInt8)
.toType(torch::kFloat);

实际错误

OpenCV 在 BGR 中加载图像(蓝-绿-红)格式,而 PyTorch 通常使用 RGB (在 torchvision 中说 Python )。解决方案是置换您的 image所以颜色匹配。

包括上面的变化,整个代码变成:

const auto tensor_image =
torch::from_blob(image.data, {1, 3, image.rows, image.cols},
torch::kUInt8)
.toType(torch::kFloat)
.permute(0, 3, 2, 1);

现在您的预测应该没问题了。也许获得 tensor > 0 会有所帮助而不是 sigmoid因为它可能是二进制分类,本身不需要此操作。

其他 PyTorch 相关的东西

不需要使用at (ATen - 如文档、基础张量和数学运算库中所述,所有其他内容都建立在该库上) namespace 不再为 torch::命名空间重定向到它。

更清晰、更少混淆的选项是:

  • torch::kCUDA而不是 at::kCUDA
  • torch::sigmoid而不是 at::sigmoid

还有 .data<T>已弃用 .data_ptr<T>

总而言之,您很少需要使用与 torch:: 不同的命名空间它是子命名空间。

关于c++ - 与 Python 相比,在 Pytorch C++ API 中无法获得相似的 DL 预测结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55531432/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com