我只在PC电脑和嵌入式板卡上部署
包括原生态darknet,原生态caffe,tensorflow,onnx,opencv,trt等环境
之前是在PC电脑上运行程序,经常使用的是darknet和caffe,环境部署简单,前面的文章有提到如何安装环境。
后来用opencv的dnn模块,发现非常方便,可以加载yolo,caffe,tensorflow部分模型,onnx部分模型,所以碰到一些模型优先会想到opencv来加载调用,甚至不需要做模型转换,非常方便。
现在在jetson板子上加载模型,加载的tf2.0的模型,opencv没办法直接加载,需要做模型转换,对于基础类网络结果如resnet,ssd,mobilenet,maskrcnn等可以转成tf1.0的模型,然后再用opencv加载,也很方便。但是有些模型没办法转换,比如ssd_efficient等,我是没有转换成功。jetson上直接用tf2.0的环境也可以,但是也有问题,比如加载save_model模型时间比较长,有人说是驱动版本问题,这个我没有去试,有人说重装protobuf,对我来说没有用,所以想到tf2.0=》onnx=>TRT
参考官网教程就好https://github.com/onnx/tensorflow-onnx,有一点儿需要注意的是,
--inputs-as-nchw
这个参数的设定是根据输入数据决定的,有的是nchw,有的是nhwc。
例如
python -m tf2onnx.convert --saved-model /home/wx/work/pyproject/test/fine_tuned_model/saved_model/ --output fine_model_nhwc.onnx --opset 11
onnx加载模型例子
# Preprocess and normalize the image def preprocess(img_file, w, h): input_shape = (1, 3, w, h) img = Image.open(img_file) img = img.resize((w, h), Image.BILINEAR) # convert the input data into the float32 input img_data = np.array(img) #img_data = np.transpose(img_data, [2, 0, 1]) img_data = np.expand_dims(img_data, 0) mean_vec = np.array([0.485, 0.456, 0.406]) stddev_vec = np.array([0.229, 0.224, 0.225]) norm_img_data = np.zeros(img_data.shape).astype('float32') for i in range(img_data.shape[3]): #norm_img_data[:, i, :, :] = (img_data[:, i, :, :] / 255 - mean_vec[i]) / stddev_vec[i] norm_img_data[:, :, :, i] = (img_data[:, :, :, i]) return norm_img_data.astype('uint8'), np.array(img) # %% SSD模型推理 def infer_ssd(onnx_model: str): # Run the model on the backend session = onnxruntime.InferenceSession(onnx_model, None) # get the name of the first input of the model input_name = session.get_inputs()[0].name output_name = session.get_outputs()[0].name # print(len(session.get_outputs())) print('Input Name:', input_name) print('Output Name:', output_name) # 符合https://github.com/onnx/models/tree/master/vision/object_detection_segmentation/ssd 模型的输入要求 input_data, raw_img = preprocess(img_file, 600, 600) print('输入图像大小:', input_data.shape) raw_result = session.run([], {input_name: input_data}) start = time.time() raw_result = session.run([], {input_name: input_data}) end = time.time() print('推理时间:', end - start, 's') bboxes = np.squeeze(raw_result[1]) # 200x4 labels = raw_result[2].T # 200x1 scores = raw_result[4].T # 200x1,结构已经按照得分从高到低的顺序排列 fig, ax = plt.subplots(1) ax.imshow(raw_img) LEN = np.sum(np.where(scores > 0.5, 1, 0)) for k in range(LEN): x1 = input_data.shape[2] * bboxes[k][1] y1 = input_data.shape[2] * bboxes[k][0] x2 = input_data.shape[2] * bboxes[k][3] y2 = input_data.shape[2] * bboxes[k][2] rect = patches.Rectangle((x1, y1), x2 - x1, y2 - y1, linewidth=1, edgecolor='r', fill=False) ax.add_patch(rect) plt.show()
preprocess中处理img时,看自己模型是nwhc还是ncwh。
后面再考虑onnx转trt模型。但是trt不支持一些datatype,例如UINT8.
等这几天看看有什么解决办法