美文网首页MNN源码阅读
MNN源码阅读--Tensor数据结构解析和运行示例

MNN源码阅读--Tensor数据结构解析和运行示例

作者: 夏津Sirius | 来源:发表于2020-10-15 09:34 被阅读0次

    tensor就是容纳推理框架中间数据的一个数据结构,常用的有关函数如下:

    1.新建一个Tensor:

     Tensor* create<float>(const std::vector<int>& shape, void* data = NULL, DimensionType dimType = TENSORFLOW) 
    

    这其中第一个参数是tensor的维度信息,第二个参数是是否指定数据指针,第三个参数是数据在内存中的排布信息,如果是CAFFE证明是NCHW类型,如果是TENSORFLOW证明是NHWC类型,默认的类型是TENSORFLOW类型,这里经常会有一些坑,比如最终想要得到一个131024*1024的数据时候,如果没有指定是CAFFE类型的数据排布,而是使用默认的情况(TENSORFLOW),读出来的数据channel维度就在最后。

    2.基本的方法

    得到各种维度和长度:

    
    int width();
    
    int height();
    
    int channel();
    
    int batch();
    
    

    得到shape向量和数据总数:

    
    std::vector<int> shape();
    
    int elementSize();
    

    得到数据指针:

    template <typename T>
    
        T* host() const {
    
            return (T*)mBuffer.host;
    
        }
    

    3.和Interpreter有关的Tensor操作

    Interpreter就是一个MNN的从模型得到的一个网络,有关Interpreter的tenosr操作,肯定就是涉及到输入的tesnor和输出的tensor的设置,由于可能在不同的设备上运行,因此可能有内存拷贝的操作。

    获取Interpreter的输入tensor:

    
    Tensor*  Interpreter::getSessionInput(const Session* session, const char* name)
    
    

    获取Interpreter的输出tensor:

    
    Tensor* Interpreter::getSessionOutput(const Session* session, const char* name)
    
    

    将host的tensor数据拷贝给Interpreter的tensor

    
    bool copyFromHostTensor(const Tensor* hostTensor);
    
    

    将Interpreter的tensor数据拷贝给host tensor

    
    bool copyToHostTensor(Tensor* hostTensor) const;
    
    

    一个简单的端到端MNN例子:

    
    //读取模型
    
    I = std::shared_ptr<MNN::Interpreter>(MNN::Interpreter::createFromFile("resnet.mnn"));
    
    //配置会话
    
    auto type = MNN_FORWARD_CPU;$
    
    config.type = type;$
    
    config.numThread = 16;$
    
    config.backupType = type;$
    
    backendConfig.precision = MNN::BackendConfig::Precision_Low;$
    
    config.backendConfig = &backendConfig;$
    
    //创建seesion
    
    S = I->createSession(config);$
    
    //获取输入输出tensor
    
    inTensor = I->getSessionInput(S, NULL);$
    
    outTensor = I->getSessionOutput(S, NULL);$
    
    //创建输入的host tensor,读取图片,并且赋值给inHostTensor
    
    MNN::Tensor* inHostTensor = MNN::Tensor::create <float>(inTensor->shape()), NULL, MNN::Tensor::CAFFE);
    
    cv::Mat image = cv::imread("11.jpg");
    
    for(int i = 0; i < inHostTensor->elementSize(); i++) {
    
        inHostTensor->host<float>()[i] = image.data[i];
    
    }
    
    //拷贝给Interpreter的输入inTensor,注意这里拷贝之前和之后的tensor并不是完全一致,有时网络的inTensor的总体数据量会大于hostTesnor的,
    
    //比如hostTensor要是1,3,512,512,那么inTensor就是1,4,512,512,为了方便于计算,把3变成了4,同理outTensor也一样,当拷贝回host后才是正常的数据
    
    //多余的位置一般用0补
    
    inTensor->copyFromHostTensor(inHostTensor);
    
    //运行网络
    
    I->runSession(S);
    
    //创建输出host tensor,拷贝回host的tensor
    
    MNN::Tensor* outHostTensor = MNN::Tensor::create <float>(outTensor->shape(), NULL, MNN::Tensor::CAFFE);
    
    outTensor->copyToHostTensor(outHostTensor);
    
    

    相关文章

      网友评论

        本文标题:MNN源码阅读--Tensor数据结构解析和运行示例

        本文链接:https://www.haomeiwen.com/subject/eqcgpktx.html