MNN模型结构解读–反序列化为文本格式
MNN是阿里开源的端侧深度学习框架,支持Tensorflow、Caffe、ONNX、tflite主流模型文件格式,通过Convert模块将已经训练好的网络模型转为MNN定义的模型格式,官方已经支持Netron工具可视化MNN模型,由于MNN的模型结构定义使用了flatbuffers库,因此可以通过flatbuffers的接口将.mnn格式的文件解析为文本格式。
flatbuffers是谷歌开源的序列化结构化库,相比protobuf库性能更好更加轻量,只需包含include文件夹即可编译,两者序列化的结果都是二进制格式,不方便阅读,protobuf提供了text_format类将二进制的message转化为文本。而flatbuffers为了解析文本格式就需要包含flatbuffers/src下的code_generators.cpp、idl_gen_text.cpp、idl_parser.cpp、util.cpp等4个源文件,头文件需要另外包含flatbuffers/idl.h和flatbuffers/util.h,下面以MNN模型mobilenet-v1为例。
#include <fstream>
#include <iostream>
#include <string>
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
int main() {
std::ifstream infile;
infile.open("mobilenet-v1-1.0.mnn", std::ios::binary | std::ios::in);
infile.seekg(0, std::ios::end);
int length = infile.tellg();
infile.seekg(0, std::ios::beg);
char* buffer_pointer = new char[length];
infile.read(buffer_pointer, length);
infile.close();
std::string BasicOptimizer_text;
std::string CaffeOp_text;
std::string GpuLibrary_text;
std::string MNN_text;
std::string Tensor_text;
std::string TensorflowOp_text;
std::string TFQuantizeOp_text;
std::string Type_text;
std::string UserDefine_text;
flatbuffers::LoadFile("BasicOptimizer.fbs",false, &BasicOptimizer_text);
flatbuffers::LoadFile("CaffeOp.fbs",false, &CaffeOp_text);
flatbuffers::LoadFile("GpuLibrary.fbs",false, &GpuLibrary_text);
flatbuffers::LoadFile("MNN.fbs",false, &MNN_text);
flatbuffers::LoadFile("Tensor.fbs",false, &Tensor_text);
flatbuffers::LoadFile("TensorflowOp.fbs",false, &TensorflowOp_text);
flatbuffers::LoadFile("TFQuantizeOp.fbs",false, &TFQuantizeOp_text);
flatbuffers::LoadFile("Type.fbs",false, &Type_text);
flatbuffers::LoadFile("UserDefine.fbs",false, &UserDefine_text);
flatbuffers::Parser parser;
parser.Parse(Type_text.c_str(), nullptr, "Type.fbs") &&
parser.Parse(Tensor_text.c_str(), nullptr, "Tensor.fbs") &&
parser.Parse(UserDefine_text.c_str(), nullptr, "UserDefine.fbs") &&
parser.Parse(CaffeOp_text.c_str(), nullptr, "CaffeOp.fbs") &&
parser.Parse(TensorflowOp_text.c_str(), nullptr, "TensorflowOp.fbs") &&
parser.Parse(GpuLibrary_text.c_str(), nullptr, "GpuLibrary.fbs") &&
parser.Parse(TFQuantizeOp_text.c_str(), nullptr, "TFQuantizeOp.fbs") &&
parser.Parse(MNN_text.c_str(), nullptr, "MNN.fbs") &&
parser.Parse(BasicOptimizer_text.c_str(), nullptr, "BasicOptimizer.fbs");
std::string output_text;
flatbuffers::GenerateText(parser, buffer_pointer, &output_text);
std::ofstream os;
os.open("mobilenet-v1.txt");
os<<output_text;
os.close();
}
编译命令
g++ parsermnntotext.cpp ../src/code_generators.cpp ../src/idl_gen_text.cpp ../src/idl_parser.cpp ../src/util.cpp -I ../include/ -o mnntotext