目录
Tensorflow/Mxnet模型转ncnn
我采用的是先将模型转为onnx,再用onnxsim简化去除胶水op,再转ncnn。
ps:这里的tf指的是1.x版本并不是2.x版本。关于tf2.x版本看这里:nihui大佬https://zhuanlan.zhihu.com/p/152535430
nihui大佬文章也提到了ncnn支持的是pytorch转的onxx而非其他的。我这里tf转onnx没有出错,并且可以正常进行推理。但是使用onnxsim出错了,这个目前我还不知道原因,没有解决。
1.Pb模型转ncnn
1.1Pb转onnx
pb模型转onnx:
python -m tf2onnx.convert\
--input model_name.pb\
--inputs input_name:0\
--outputs output_name:0\
--output model_name.onnx\
--verbose
ps:这里我采用的是pb文件转onnx,当然也有其他方式,这里我没有用到不去阐述。
转为onnx,当然要进行check啦。
import onnx
import onnxruntime
onnx_model = onnx.load("path of model.onnx ")
onnx.checker.check_model(onnx_model)
# print(onnx.helper.printable_graph(onnx_model.graph))
session = onnxruntime.InferenceSession("path of model.onnx ")
inp = session.get_inputs()[0].name
out = session.get_outputs()[0].name
# print(inp)
# print(out)
graph = onnx.helper.printable_graph(onnx_model.graph)
# print(graph)
input = onnx_model.graph.input
output = onnx_model.graph.output
# print(input, output)
检查无误后可以用onnxruntime进行推理,推理中得到输入,输出是最为重要的。加载玩模型后,输入模型需要的输入,得到输出后做自己想要的操作。比如我的模型是人脸识别的一个模型,我得到正确的输入后,将输入给模型后,得到输出(人脸的128维特征),进行后续的特征比对,进行人脸认证。
先定义一个加载模型的函数,return我需要的输入和输出以及一个session。
def load_onnx_mobilefacennet():
session = onnxruntime.InferenceSession("model.onnx")
input_name = session.get_inputs()[0].name
output_name = session.get_outputs()[0].name
return session, input_name, output_name
得到输入和输出后,将处理过的正确的输入传入进行就可得到输出。
emb_arrays = session.run([output_name], {input_name: input_images})
最后,进行特征比对。
if dict[0][1] > VERIFICATION_THRESHOLD:
name = dict[0][0]
probs.append(dict[0][1])
info_name.append(name)
else:
probs.append(dict[0][1])
info_name.append("unknown")
1.2onnx进行简化
使用onnxsim进行简化
python -m onnxsim model.onnx model-sim.onnx
简化后进行转ncnn。我是在这里出错了。。具体原因我还没有找到。
1.3onnx转ncnn
使用之前我们提到的,以及编译好的ncnn,在tools/onnx2ncnn中
onnx2ncnn model-sim.onnx model.param model.bin
到此我们转换完了。
2.Mxnet转ncnn
前面的步骤和上文提到的都一样。
在用onnxruntime推理时候要注意,之前我们pb是whc的,但是mxnet模型是chw的,所以进行推理时候我们要将图片转为chw。
import onnx
import onnxruntime
import cv2
import numpy as np
image_path = 'image.jpg'
onnx_file = "model.onnx"
img = cv2.imread(image_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img=(img-127.5)
img=img*0.0078125
img = np.transpose(img, (2, 0, 1)) # HWC->CHW
ort_session = onnxruntime.InferenceSession(onnx_file)
input_name = ort_session.get_inputs()[0].name # 'data'
outputs = ort_session.get_outputs()[0].name # 'fc1'
input_blob = np.expand_dims(img, axis=0).astype(np.float32) # NCHW
out = ort_session.run([outputs], input_feed={input_name: input_blob})
print(out[0])
另外在推理时候会遇到一些错误,我们直接修改onnx模型中一些结构:具体详见https://zhuanlan.zhihu.com/p/165294876
至此,我们就得到了我们需要的.param和.bin文件
后续我们就可以使用ncnn进行模型部署。下一篇会写用ncnn加载这两个文件内进行推理。