MNN
MNN
- 1. 编译
- 2. 模型转换与推理
- 3. CPP API
- 4. 参考文献
1. 编译
编译 MNN 很简单,但如果编译模型转换工具 MNNConvert 就需要安装 protobuf,而 protobuf 依赖 zlib。
2. 模型转换与推理
以推理一个简单的函数拟合模型为例。
1. 使用 Pytorch 保存 onnx
net = Net()
net.load_state_dict(torch.load('parameters.pth'))
input = torch.randn(1, 1, 2, 2)
input_names = ['input'] # 给输入节点取名
output_names = ['output'] # 给输出节点取名
torch.onnx.export(net, input, "example.onnx", verbose=True, input_names=input_names, output_names=output_names)# 下面是torch.onnx.export的输出:
graph(%input : Float(1, 1, 2, 2),%net.0.weight : Float(1, 1, 2, 2),%net.0.bias : Float(1)):%output : Float(1, 1, 1, 1) = onnx::Conv[dilations=[1, 1], group=1, kernel_shape=[2, 2], pads=[0, 0, 0, 0], strides=[1, 1]](%input, %net.0.weight, %net.0.bias) # D:\anaconda3\envs\torch\lib\site-packages\torch\nn\modules\conv.py:349:0return (%output)
net 加载训练好的参数 onnx 模型也会有训练好的参数。第 4、5 行给输入输出结点取名,在第 6 行这两个参数可以省略。但这两个参数在把 mnn 从 NC4HW4 转换到 NCHW 时有用,详情在参考 2 和参考 3。
2. 使用 MNN 转换 onnx 到 mnn
如果编译源码时设置了 -DMNN_BUILD_CONVERTER=true 编译了 MNNConvert 可以使用下面的命令:
MNNConvert -f ONNX --modelFile example.onnx --MNNModel example.mnn --bizCode biz
如果没有编译 MNNConvert,可以使用 Python 的 MNN 包转换:
pip install MNN
python -m MNN.tools.mnnconvert -f ONNX --modelFile example.onnx --MNNModel example.mnn --bizCode biz
3. 推理
#include <iostream>
#include "MNN/Interpreter.hpp"int main() {// 1.创建解释器。std::string model_path = "../example.mnn";std::shared_ptr<MNN::Interpreter> net;net = std::unique_ptr<MNN::Interpreter>(MNN::Interpreter::createFromFile(model_path.c_str()));// 2.后端。MNN::BackendConfig backendConfig;backendConfig.precision = MNN::BackendConfig::Precision_High;backendConfig.power = MNN::BackendConfig::Power_High;backendConfig.memory = MNN::BackendConfig::Memory_Normal;// 3.配置。MNN::ScheduleConfig config;config.numThread = 1;config.type = static_cast<MNNForwardType>(MNN_FORWARD_CPU);config.backendConfig = &backendConfig;// 4.会话。MNN::Session* session = net->createSession(config);net->releaseModel();// 5.获取输入输出节点。MNN::Tensor* input_placeholder = net->getSessionInput(session, nullptr);MNN::Tensor* output_placeholder = net->getSessionOutput(session, nullptr);for (int x : input_placeholder->shape())std::cout << x << " "; std::cout << std::endl;for (int x : output_placeholder->shape())std::cout << x << " "; std::cout << std::endl;// 6.准备数据。MNN::Tensor* data = MNN::Tensor::create<float>(input_placeholder->shape(), NULL, MNN::Tensor::CAFFE);for (int i = 1; i < 5; i++)data->host<float>()[i - 1] = i * 10;// 7.输入。input_placeholder->copyFromHostTensor(data);// 8.运行。net->runSession(session);// 9.输入输出。input_placeholder->print();output_placeholder->print();
}
CMakelists.txt 的内容:
cmake_minimum_required(VERSION 3.2)
project(mnn)include_directories(D:\\software\\MNN\\include)
link_directories(D:\\software\\MNN\\build)
add_executable(tmnn mnn.cpp)
target_link_libraries(tmnn MNN)
3. CPP API
// 复制a到b并输出b。
MNN::Tensor* a = ...
MNN::Tensor b(a, a->getDimensionType());
a->copyToHostTensor(&b);
b.print();
4. 参考文献
- 语雀 MNN 文档
- mnn 格式转换 1
- mnn 格式转换 2
MNN
MNN
- 1. 编译
- 2. 模型转换与推理
- 3. CPP API
- 4. 参考文献
1. 编译
编译 MNN 很简单,但如果编译模型转换工具 MNNConvert 就需要安装 protobuf,而 protobuf 依赖 zlib。
2. 模型转换与推理
以推理一个简单的函数拟合模型为例。
1. 使用 Pytorch 保存 onnx
net = Net()
net.load_state_dict(torch.load('parameters.pth'))
input = torch.randn(1, 1, 2, 2)
input_names = ['input'] # 给输入节点取名
output_names = ['output'] # 给输出节点取名
torch.onnx.export(net, input, "example.onnx", verbose=True, input_names=input_names, output_names=output_names)# 下面是torch.onnx.export的输出:
graph(%input : Float(1, 1, 2, 2),%net.0.weight : Float(1, 1, 2, 2),%net.0.bias : Float(1)):%output : Float(1, 1, 1, 1) = onnx::Conv[dilations=[1, 1], group=1, kernel_shape=[2, 2], pads=[0, 0, 0, 0], strides=[1, 1]](%input, %net.0.weight, %net.0.bias) # D:\anaconda3\envs\torch\lib\site-packages\torch\nn\modules\conv.py:349:0return (%output)
net 加载训练好的参数 onnx 模型也会有训练好的参数。第 4、5 行给输入输出结点取名,在第 6 行这两个参数可以省略。但这两个参数在把 mnn 从 NC4HW4 转换到 NCHW 时有用,详情在参考 2 和参考 3。
2. 使用 MNN 转换 onnx 到 mnn
如果编译源码时设置了 -DMNN_BUILD_CONVERTER=true 编译了 MNNConvert 可以使用下面的命令:
MNNConvert -f ONNX --modelFile example.onnx --MNNModel example.mnn --bizCode biz
如果没有编译 MNNConvert,可以使用 Python 的 MNN 包转换:
pip install MNN
python -m MNN.tools.mnnconvert -f ONNX --modelFile example.onnx --MNNModel example.mnn --bizCode biz
3. 推理
#include <iostream>
#include "MNN/Interpreter.hpp"int main() {// 1.创建解释器。std::string model_path = "../example.mnn";std::shared_ptr<MNN::Interpreter> net;net = std::unique_ptr<MNN::Interpreter>(MNN::Interpreter::createFromFile(model_path.c_str()));// 2.后端。MNN::BackendConfig backendConfig;backendConfig.precision = MNN::BackendConfig::Precision_High;backendConfig.power = MNN::BackendConfig::Power_High;backendConfig.memory = MNN::BackendConfig::Memory_Normal;// 3.配置。MNN::ScheduleConfig config;config.numThread = 1;config.type = static_cast<MNNForwardType>(MNN_FORWARD_CPU);config.backendConfig = &backendConfig;// 4.会话。MNN::Session* session = net->createSession(config);net->releaseModel();// 5.获取输入输出节点。MNN::Tensor* input_placeholder = net->getSessionInput(session, nullptr);MNN::Tensor* output_placeholder = net->getSessionOutput(session, nullptr);for (int x : input_placeholder->shape())std::cout << x << " "; std::cout << std::endl;for (int x : output_placeholder->shape())std::cout << x << " "; std::cout << std::endl;// 6.准备数据。MNN::Tensor* data = MNN::Tensor::create<float>(input_placeholder->shape(), NULL, MNN::Tensor::CAFFE);for (int i = 1; i < 5; i++)data->host<float>()[i - 1] = i * 10;// 7.输入。input_placeholder->copyFromHostTensor(data);// 8.运行。net->runSession(session);// 9.输入输出。input_placeholder->print();output_placeholder->print();
}
CMakelists.txt 的内容:
cmake_minimum_required(VERSION 3.2)
project(mnn)include_directories(D:\\software\\MNN\\include)
link_directories(D:\\software\\MNN\\build)
add_executable(tmnn mnn.cpp)
target_link_libraries(tmnn MNN)
3. CPP API
// 复制a到b并输出b。
MNN::Tensor* a = ...
MNN::Tensor b(a, a->getDimensionType());
a->copyToHostTensor(&b);
b.print();
4. 参考文献
- 语雀 MNN 文档
- mnn 格式转换 1
- mnn 格式转换 2