Libtorch C++ 和 pytorch 的不同输出

Ark*_*i99 5 c++ jit pytorch libtorch

我在 pytorch 和 libtorch 中使用相同的跟踪模型,但得到不同的输出。

\n

Python代码:

\n
import cv2\nimport numpy as np \nimport torch\nimport torchvision\nfrom torchvision import transforms as trans\n\n\n# device for pytorch\ndevice = torch.device(\'cuda:0\')\n\ntorch.set_default_tensor_type(\'torch.cuda.FloatTensor\')\n\nmodel = torch.jit.load("traced_facelearner_model_new.pt")\nmodel.eval()\n\n# read the example image used for tracing\nimage=cv2.imread("videos/example.jpg")\n\ntest_transform = trans.Compose([\n        trans.ToTensor(),\n        trans.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])\n    ])       \n\nresized_image = cv2.resize(image, (112, 112))\n\ntens = test_transform(resized_image).to(device).unsqueeze(0)\noutput = model(tens)\nprint(output)\n
Run Code Online (Sandbox Code Playgroud)\n

C++代码:

\n
#include <iostream>\n#include <algorithm> \n#include <opencv2/opencv.hpp>\n#include <torch/script.h>\n\n\nint main()\n{\n    try\n    {\n        torch::jit::script::Module model = torch::jit::load("traced_facelearner_model_new.pt");\n        model.to(torch::kCUDA);\n        model.eval();\n\n        cv::Mat visibleFrame = cv::imread("example.jpg");\n\n        cv::resize(visibleFrame, visibleFrame, cv::Size(112, 112));\n        at::Tensor tensor_image = torch::from_blob(visibleFrame.data, { 1, visibleFrame.rows, \n                                                    visibleFrame.cols, 3 }, at::kByte);\n        tensor_image = tensor_image.permute({ 0, 3, 1, 2 });\n        tensor_image = tensor_image.to(at::kFloat);\n\n        tensor_image[0][0] = tensor_image[0][0].sub(0.5).div(0.5);\n        tensor_image[0][1] = tensor_image[0][1].sub(0.5).div(0.5);\n        tensor_image[0][2] = tensor_image[0][2].sub(0.5).div(0.5);\n\n        tensor_image = tensor_image.to(torch::kCUDA);\n        std::vector<torch::jit::IValue> input;\n        input.emplace_back(tensor_image);\n        // Execute the model and turn its output into a tensor.\n        auto output = model.forward(input).toTensor();\n        output = output.to(torch::kCPU);\n        std::cout << "Embds: " << output << std::endl;\n\n        std::cout << "Done!\\n";\n    }\n    catch (std::exception e)\n    {\n        std::cout << "exception" << e.what() << std::endl;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

该模型给出了(1x512)输出张量的大小,如下所示。

\n

Python输出

\n
tensor([[-1.6270e+00, -7.8417e-02, -3.4403e-01, -1.5171e+00, -1.3259e+00,\n\n-1.1877e+00, -2.0234e-01, -1.0677e+00, 8.8365e-01, 7.2514e-01,\n\n2.3642e+00, -1.4473e+00, -1.6696e+00, -1.2191e+00, 6.7770e-01,\n\n...\n\n-7.1650e-01, 1.7661e-01]], device=\xe2\x80\x98cuda:0\xe2\x80\x99,\ngrad_fn=)\n
Run Code Online (Sandbox Code Playgroud)\n

C++ 输出

\n
Embds: Columns 1 to 8 -84.6285 -14.7203 17.7419 47.0915 31.8170 57.6813 3.6089 -38.0543\n\n\nColumns 9 to 16 3.3444 -95.5730 90.3788 -10.8355 2.8831 -14.3861 0.8706 -60.7844\n\n...\n\nColumns 505 to 512 36.8830 -31.1061 51.6818 8.2866 1.7214 -2.9263 -37.4330 48.5854\n\n[ CPUFloatType{1,512} ]\n
Run Code Online (Sandbox Code Playgroud)\n

使用

\n
    \n
  • 火炬1.6.0
  • \n
  • 自由火炬 1.6.0
  • \n
  • 视觉工作室2019
  • \n
  • Windows 10
  • \n
  • 库达10.1
  • \n
\n

Rik*_*ika 6

在最终标准化之前,您需要将输入缩放到 0-1 范围,然后继续正在进行的标准化。转换为浮点型,然后除以 255 应该可以得到结果。这是我写的片段,可能有一些语法错误,应该是可见的。
尝试这个 :

#include <iostream>
#include <algorithm> 
#include <opencv2/opencv.hpp>
#include <torch/script.h>


int main()
{
    try
    {
        torch::jit::script::Module model = torch::jit::load("traced_facelearner_model_new.pt");
        model.to(torch::kCUDA);
        
        cv::Mat visibleFrame = cv::imread("example.jpg");

        cv::resize(visibleFrame, visibleFrame, cv::Size(112, 112));
        at::Tensor tensor_image = torch::from_blob(visibleFrame.data, {  visibleFrame.rows, 
                                                    visibleFrame.cols, 3 }, at::kByte);
        
        tensor_image = tensor_image.to(at::kFloat).div(255).unsqueeze(0);
        tensor_image = tensor_image.permute({ 0, 3, 1, 2 });
        ensor_image.sub_(0.5).div_(0.5);

        tensor_image = tensor_image.to(torch::kCUDA);
        // Execute the model and turn its output into a tensor.
        auto output = model.forward({tensor_image}).toTensor();
        output = output.cpu();
        std::cout << "Embds: " << output << std::endl;

        std::cout << "Done!\n";
    }
    catch (std::exception e)
    {
        std::cout << "exception" << e.what() << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

我无法访问运行此程序的系统,因此如果您遇到以下任何评论。

  • @Arki99,这是 pytorchs ToTensor 的默认设置。当你在 Pytorch 转换中执行“ToTensor()”时,它只是将输入图像重新缩放到 0-1 的范围。因此,为了获得相同的行为,您需要在 libtorch 中执行相同的操作。 (2认同)