首页 > 解决方案 > PyTorch Python && C++ 来自共享模型的不一致结果

问题描述

我正在用 C++ 运行一个受过 Python3 训练的、torch_script 导出的 CNN。但是,我无法在测试数据上重现结果。

对于相同的数据补丁,分类器以各自语言返回的类标签是相反的。不确定 C++ 实现中是否有一些内存损坏,但我至少能够验证 Python 实现给出了正确的结果。我还要如何调试?现在,我正在尝试比较 conv 内核的权重矩阵,以验证模型在两种实现中是否一致。

检查代码中的最后几行以查看差异。

注意 - 两种语言之间的补丁统计信息是相同的,可能是内存在 C++ 中未对齐?

还有什么我可以检查的吗?

Python 导出脚本:

    cnn = CNN1()

    cnn.load_state_dict(torch.load(args.cnn))

    torch_script_nn = torch.jit.script(cnn)

    script_file_name = args.cnn.replace('.torch', '.pytorch_script')
    torch_script_nn.save(script_file_name)

    print('{} CONVERTED TO {} '.format(args.cnn, script_file_name))

Python 测试脚本

    cnn = CNN1()
    cnn.load_state_dict(torch.load(cnn_file))

    i = 100
    j = 100
    patch_size = 14
    img = np.load(f)['arr_0']
    # plt.imshow(img, cmap='gray');plt.show()

    patch = img[i: i+ patch_size, j:j+patch_size]
    print('Patch max : {}, min {}'.format(np.max(patch), np.min(patch)))

    plt.imshow(patch, cmap='gray');plt.show()
    patch = np.expand_dims(patch, axis=2)
    normalized_patch = (patch - np.min(patch)) / np.max(patch - np.min(patch))
    print('Normalized Patch max : {}, min {}'.format(np.max(normalized_patch), np.min(normalized_patch)))
    torch_stack = torch.stack([torch.Tensor(normalized_patch)])
    print(torch_stack.shape)
    res = cnn(torch_stack.permute(0, 3, 1, 2))

    print('Class label {}'.format(res))

印刷

Patch max : 16.035221099853516, min 11.432785987854004
Normalized Patch max : 1.0, min 0.0
torch.Size([1, 14, 14, 1])
tensor([[9.9995e-01, 5.4011e-05]], grad_fn=<SoftmaxBackward>)

C++ 测试

std::cout << "TESTING CNN" << std::endl;
    std::size_t i = 100;
    std::size_t j = 100;

    const cv::Rect roi(i, j, patchSize, patchSize);
    cv::Mat amplitudePatch = amplitude(roi);
    double min;
    double max;
    cv::minMaxLoc(amplitudePatch, &min, &max);
    std::cout << "Patch Max : " << max << std::endl;
    std::cout << "Patch Min " << min << std::endl;

    cv::imshow("Patch", amplitudePatch);
    cv::Mat normalizedPatch = normalizeAmplitudePatch(amplitudePatch);
    cv::imshow("NPatch", normalizedPatch);
    cv::minMaxLoc(normalizedPatch, &min, &max);
    std::cout << "Normalized Patch Max : " << max << std::endl;
    std::cout << "Normalized Patch Min " << min << std::endl;

    cv::waitKey(0); 
    auto options = torch::TensorOptions().dtype(torch::kF32);

    std::cout << 1 << " " << amplitudePatch.size().height<< " " <<
        amplitudePatch.size().width<< " " << amplitudePatch.channels() << std::endl;

    torch::Tensor patchTensor = torch::from_blob(
      amplitudePatch.data, 
      {1, amplitudePatch.size().height,
        amplitudePatch.size().width, amplitudePatch.channels()},
      options);

    std::vector<c10::IValue> inputs;
    inputs.push_back(patchTensor.permute({0, 3, 1, 2}));
    torch::Tensor result = cnn.forward(inputs).toTensor();

    std::cout << result << std::endl;

印刷

Patch Max : 16.0352
Patch Min : 11.4328
Could not initialize OpenGL for RasterGLSurface, reverting to RasterSurface.
Could not initialize OpenGL for RasterGLSurface, reverting to RasterSurface.
Normalized Patch Max : 1
Normalized Patch Min 0
1 14 14 1
 0  1
[ Variable[CPUFloatType]{1,2} ]

标签: pythonc++pytorchtorchtorchvision

解决方案


推荐阅读