• 转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
    

    说明精度满足!!

  • 相关阅读:
    ORM开发之解析lambda实现完整查询(附测试例子)
    ORM开发之解析lambda实现group查询(附测试例子)
    ORM之殇,我们需要什么样的ORM框架?
    公开封尘已久的即时通讯源码
    javascript中的this与函数讲解
    javascript中的操作符详解1
    javascript中的继承与深度拷贝
    javascript之Object.defineProperty的奥妙
    javascript之活灵活现的Array
    jquery.Callbacks的实现
  • 原文地址:https://www.cnblogs.com/yanghailin/p/13669046.html
Copyright © 2020-2023  润新知