转libtorch验证精度小程序
pytorch端和libtorch端转的每一步都需要验证精度,一般情况下,就debug看看两天的tensor值最开始的或者结尾一不一样,一般相差10的-4就没有问题,实在不行就根据形状随机的写下标,写几个看看值是否差不多。下面具体说明:
法1:就是debug
pycharm界面可以看到tensor的值,但是也只能看到前几个,libtorch端debug看不到具体的值,就需要打印,比如下图:
看到形状是[1,1,176,232],并且可以看到刚开始的数值,
然后在libtorch端
out_cnn_feature.print(); //可以打印形状
print(out_cnn_feature[0][0][0][0]);
print(out_cnn_feature[0][0][0][1]);
一般用这种就可以。
法2:就是都打印出来
pytorch端:
torch.set_printoptions(profile="full") ##设置全打印,要不然会只打印部分
print()
print(cnn_feature)
libtorch端就是std::cout<<
std::cout<<out_cnn_feature<<std::endl;
今天的问题就是出现在这里,由于tensor很多,四维的, [1, 64, 176, 232]]
我都打印出来了,但是查看两边的末尾居然数值不一样,我陷入了迷茫,怎么会不一样的呢,
pytorch端打印出来的:这里只挑选了末尾
.....
0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00,
0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00,
0.0000e+00, 1.8241e-02, 3.7855e-02, 5.1648e-02, 6.9472e-02,
7.5886e-02, 6.2488e-02, 5.3092e-02, 4.9214e-02, 3.2424e-02,
0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00,
0.0000e+00, 2.2409e-02, 5.9125e-02, 7.3034e-02, 7.8709e-02,
8.1365e-02, 6.6245e-02, 3.3653e-02, 3.5107e-03, 0.0000e+00,
0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00,
0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00, 0.0000e+00,
0.0000e+00, 0.0000e+00, 1.6959e-02, 8.4786e-02, 7.6052e-02,
6.0393e-03, 1.5005e-01]]]], device='cuda:0')
torch.Size([1, 64, 176, 232])
libtorch端打印出来的:
...
Columns 226 to 232 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000
0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.1690
0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.4958
0.2146 0.3086 0.4865 0.7304 0.6248 0.3952 0.8936
0.6491 0.9671 1.3239 1.6022 1.3248 0.9135 1.2821
0.4172 0.7862 1.1826 1.5443 1.4480 0.9591 1.3625
0.0000 0.1353 0.4472 0.7860 0.8949 0.5023 1.0074
0.0000 0.0000 0.0000 0.1277 0.2543 0.0000 0.5729
0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.3276
0.0000 0.0468 0.0638 0.0376 0.0368 0.0000 0.3606
0.1234 0.2253 0.3690 0.4342 0.3223 0.0145 0.4935
0.0497 0.1805 0.4058 0.6071 0.5131 0.1477 0.6037
0.0000 0.0692 0.2938 0.6034 0.5530 0.2219 0.6972
...
1.1562 1.6830 2.2225 2.3272 1.7687 1.0226 1.6562
1.4114 1.9929 2.5320 2.6342 2.0122 1.1713 1.7332
1.5383 2.1320 2.6493 2.7903 2.2010 1.3044 1.7876
1.4056 1.9831 2.5459 2.7430 2.2532 1.3688 1.7918
1.1810 1.6469 2.2447 2.5814 2.1879 1.3891 1.7717
1.0624 1.3491 1.9263 2.3603 2.0877 1.3708 1.7344
1.0898 1.1901 1.6129 2.0556 1.9314 1.2830 1.6365
0.9879 1.0583 1.3138 1.6865 1.6553 1.0959 1.4531
0.7448 0.8707 1.0215 1.2570 1.2761 0.8424 1.1714
0.1721 0.3478 0.5670 0.7771 0.8533 0.5682 0.8848
0.0000 0.0000 0.1971 0.4777 0.5936 0.4074 0.6883
0.3786 0.4729 0.6606 0.7925 0.7622 0.5115 0.6819
1.0491 1.1145 1.1849 1.1411 0.9475 0.6323 0.7749
0.4496 0.5070 0.5284 0.4641 0.2916 0.1936 0.5501
0.0000 0.0000 0.0170 0.0848 0.0761 0.0060 0.1500
[ Variable[CUDAType]{1,64,176,232} ]
对比最后几个可以看到,pytorch最后几位还是一样的,可以出现了很多0,而libtorch没有很多0,
然后,用法1:
先用libtorch端下标打印:
print(out_cnn_feature[0][63][175][231]);
print(out_cnn_feature[0][63][175][226]);
print(out_cnn_feature[0][63][175][225]);
print(out_cnn_feature[0][63][175][224]);
print(out_cnn_feature[0][63][175][223]);
print(out_cnn_feature[0][63][175][222]);
print(out_cnn_feature[0][63][175][221]);
print(out_cnn_feature[0][63][175][220]);
print(out_cnn_feature[0][63][175][219]);
print(out_cnn_feature[0][63][175][218]);
print(out_cnn_feature[0][63][175][217]);
print(out_cnn_feature[0][63][175][216]);
print(out_cnn_feature[0][63][175][215]);
输出如下:
0.150047
[ Variable[CUDAType]{} ]0
[ Variable[CUDAType]{} ]0
[ Variable[CUDAType]{} ]0
[ Variable[CUDAType]{} ]0
[ Variable[CUDAType]{} ]0
[ Variable[CUDAType]{} ]0
[ Variable[CUDAType]{} ]0
[ Variable[CUDAType]{} ]0
[ Variable[CUDAType]{} ]0
[ Variable[CUDAType]{} ]0
[ Variable[CUDAType]{} ]0
[ Variable[CUDAType]{} ]0
居然是0,但是显示就不是!!!
呃呃呃,可能是排版问题导致的把,其实是一致的。
pytorch端打印输出:
print(cnn_feature[0][63][175][231])
print(cnn_feature[0][63][175][226])
print(cnn_feature[0][63][175][225])
print(cnn_feature[0][63][175][224])
print(cnn_feature[0][63][175][223])
print(cnn_feature[0][63][175][222])
print(cnn_feature[0][63][175][221])
print(cnn_feature[0][63][175][220])
print(cnn_feature[0][63][175][219])
print(cnn_feature[0][63][175][218])
print(cnn_feature[0][63][175][217])
print(cnn_feature[0][63][175][216])
print(cnn_feature[0][63][175][215])
torch.Size([1, 64, 176, 232])
tensor(0.1500, device='cuda:0')
tensor(0., device='cuda:0')
tensor(0., device='cuda:0')
tensor(0., device='cuda:0')
tensor(0., device='cuda:0')
tensor(0., device='cuda:0')
tensor(0., device='cuda:0')
tensor(0., device='cuda:0')
tensor(0., device='cuda:0')
tensor(0., device='cuda:0')
tensor(0., device='cuda:0')
tensor(0., device='cuda:0')
tensor(0., device='cuda:0')
法3:写代码把两边的tensor保存本地,在用numpy读取做差,看差值是多少
对于大的tensor,只看部分其实是不放心的,于是写代码来验证:
pytorch端保存tensor到本地txt
def save_tensor(tensor_in,path_save):
tensor_in = tensor_in.contiguous().view(-1,1)
np_tensor = tensor_in.cpu().numpy()
# np_tensor = np_tensor.view()
np.savetxt(path_save,np_tensor,fmt='%.12e')
libtorch端:
bool save_tensor_txt(torch::Tensor tensor_in_,string path_txt)
{
#include "fstream"
ofstream outfile(path_txt);
torch::Tensor tensor_in = tensor_in_.clone();
tensor_in = tensor_in.view({-1,1});
tensor_in = tensor_in.to(torch::kCPU);
auto result_data = tensor_in.accessor<float, 2>();
for(int i=0;i<result_data.size(0);i++)
{
float val = result_data[i][0];
// std::cout<<"val="<<val<<std::endl;
outfile<<val<<std::endl;
}
return true;
}
python端做差验证
import numpy as np
path_pytorch_txt = "/data_1/everyday/0914/cnnfeature_pytorch.txt"
path_libtorch_txt = "/data_1/everyday/0914/cnnfeature_libtorch.txt"
pytorch_tensor = np.loadtxt(path_pytorch_txt)
libtorch_tensor = np.loadtxt(path_libtorch_txt)
diff = pytorch_tensor - libtorch_tensor
max_ = np.max(np.abs(diff))
print("max=",max_)
输出如下:
max= 1.5639420000379545e-05
说明精度满足!!
好记性不如烂键盘---点滴、积累、进步!