深度学习模型部署

1.模型应用场景

我只在PC电脑和嵌入式板卡上部署

2.部署环境

包括原生态darknet,原生态caffe,tensorflow,onnx,opencv,trt等环境

3.选择方式

        之前是在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

4.TF2转onnx

        参考官网教程就好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.

等这几天看看有什么解决办法

你可能感兴趣的:(人工智能,深度学习)