1.准备部署文件
需要准备的部署文件包括头文件(.h), mace库文件(.),转化后的模型(.a),这里以resnet18v1-opt.onnx模型为例
1.1. 优化onnx模型
# Optimize your model
$python MACE_ROOT/tools/onnx_optimizer.py resnet18v1.onnx resnet18v1-opt.onnx
1.2. 准备部署文件(.yml)
可以参考官方的例子:https://mace.readthedocs.io/en/latest/user_guide/basic_usage.html
TensorFlow,Caffe,ONNX这三个模型的部署文件有点差别,根据自己的平台修改。下面是我的文件内容
library_name: resnet18v1
target_abis: [arm64-v8a]
model_graph_format: code
model_data_format: code
models:
resnet18v1:
platform: onnx
model_file_path: /MACE/mace-models/onnx-models/resnet18v1-opt.onnx
model_sha256_checksum: 96e3b832f63db6a9647b63c9a6f7561a75a74463b15e13a3e2a7d48b774242ef
subgraphs:
- input_tensors: data
output_tensors: resnetv15_dense0_fwd
input_shapes: 1,224,224,3
output_shapes: 1,1,1,1000
backend: pytorch
runtime: cpu+gpu
limit_opencl_kernel_time: 0
nnlib_graph_mode: 0
obfuscate: 1
注意这几个参数:
model_graph_format
model_data_format
input_tensors
output_tensors
input_shapes
output_shapes
这几个参数可以使用Netron可视化工具读出
1.3. 使用MACE转换工具来转换模型
$python tools/converter.py convert --config=/MACE/mace-models/onnx-models/onnx-resnet18v1.yml
生成的文件结构如下所示:
builds
├── include
│ └── mace
│ └── public
│ ├── mace_engine_factory.h
│ └── resnet18v1.h
└── model
└── arm64-v8a
└── resnet18v1.a
1.4. 拷贝转换后的文件到Android工项目
- 在examples下的android模板工程中的macelibrary/src/main/cpp 文件夹下
-- 新建include/mace/public 文件夹
-- 新建lib 文件夹
-- 新建model 文件夹
- 复制mace.h和刚才生成的 mace_engine_factory.h 和 resnet18v1.h 三个文件
builds/include/mace/public/mace.h 拷贝到 macelibrary/src/main/cpp/include/mace/public builds/resnet18v1/include/mace/public/mace_engine_factory.h 拷贝到 macelibrary/src/main/cpp/include/mace/public builds/resnet18v1/include/mace/public/resnet18v1.h 拷贝到 macelibrary/src/main/cpp/include/mace/public
- 复制模型文件
builds/resnet18v1/model/arm64-v8a/resnet18v1.a 拷贝到 macelibrary/src/main/cpp/model/arm64-v8a
- 复制mace库文件
builds/lib/arm64-v8a/ 下所有文件夹 拷贝到 macelibrary/src/main/cpp/lib/arm64-v8a/ 目录下
2.导入Android项目
打开AndroidStudio导入项目
2.1. 修改 CMakeLists.txt 文件
在macelibrary/CMakeLists.txt 文件中找到
set(mobilenet_lib ${CMAKE_SOURCE_DIR}/src/main/cpp/model/arm64-v8a/mobilenet.a)
改为:
set(mobilenet_lib ${CMAKE_SOURCE_DIR}/src/main/cpp/model/arm64-v8a/resnet18v1.a)
2.2. 修改 .cc 文件
在 macelibrary/src/main/cpp/image_classify.cc 文件找到代码
struct MaceContext {
std::shared_ptr<mace::GPUContext> gpu_context;
std::shared_ptr<mace::MaceEngine> engine;
std::string model_name;
mace::DeviceType device_type = mace::DeviceType::CPU;
std::map<std::string, ModelInfo> model_infos = {
{"mobilenet_v1", {"input", "MobilenetV1/Predictions/Reshape_1",
{1, 224, 224, 3}, {1, 1001}}},
{"mobilenet_v2", {"input", "MobilenetV2/Predictions/Reshape_1",
{1, 224, 224, 3}, {1, 1001}}},
{"mobilenet_v1_quant", {"input", "MobilenetV1/Predictions/Softmax:0",
{1, 224, 224, 3}, {1, 1001}}},
{"mobilenet_v2_quant", {"input", "output",
{1, 224, 224, 3}, {1, 1001}}}
};
}
并添加代码:
{"resnet18v1", {"data", "resnetv15_dense0_fwd", {1, 224, 224, 3}, {1, 1001}}}
这个文件要和自己的部署文件对得上
2.3. 修改初始文件
- 在com.xiaomi.mace.demo.result下的InitData.java文件,添加自己的模型名称
public static final String[] MODELS = new String[]{"onnx_mobilenet-v2_1_0", "mobilenet_v2", "mobilenet_v1_quant", "mobilenet_v2_quant"};
修改
public InitData() {
model = MODELS[0];
}
里面的model = MODELS[0]; 这个对应(a)中的索引顺序,并将其作为默认模型
3. 编译Android项目
以上修改完成,直接编译android项目就可以生成 .apk文件。