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);
网友评论