zoukankan      html  css  js  c++  java
  • 转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
    

    说明精度满足!!

  • 相关阅读:
    STL之vector详解
    vim下使用YouCompleteMe实现代码提示、补全以及跳转设置
    Ceph之数据分布:CRUSH算法与一致性Hash
    ceph之crush算法示例
    Js正则Replace方法
    JS框架设计之加载器所在路径的探知一模块加载系统
    JS模块加载系统设计V1
    JS框架设计之模块加载系统
    Builder生成器(创建型模式)
    JS框架设计之主流框架的引入机制DomeReady一种子模块
  • 原文地址:https://www.cnblogs.com/yanghailin/p/13669046.html
Copyright © 2011-2022 走看看