python - 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} ]
解决方案
推荐阅读
- javascript - 正确格式化/解析不同的日期格式
- php - 删除自定义 postype 基础 slug 并使用自定义分类 + 帖子标题或只是帖子标题为永久链接添加前缀
- php - 在不使用 javascript 和 jquery 的情况下,在 php 中使用分页的多个复选框
- java - Android XML解析错误:只允许一个根元素
- javascript - 获取属于 JavaScript/Node js 中部分 ID 的数组对象的计数
- git - Jenkinsfile,获取PR中所有修改过的文件
- jquery - jquery控制的多级html菜单
- ironpython - 是否可以使用 IronPython 的 scapy 脚本?
- apache-flink - Flink 中的动态 SQL 查询
- java - 如何等待从 GUI 输入回到主界面?