• 深度学习模型部署全流程-模型部署


    往期回顾:模型训练

    前言

    在上一篇文章中详细讲述了模型训练的流程,这篇文章主要介绍模型部署的流程。模型部署通常指通过C/C++语言能够把python框架训练好的模型跑起来,毕竟C/C++运行效率更高,并且只用提供依赖库和头文件即可移植。

    模型部署全流程

    1.推理框架

    首先要找到一套成熟的推理框架,利用该框架即可完成模型量化,模型推理等功能。在这里推荐自己常用的一套框架腾讯出品的NCNN框架,当然也有很多其他的推理框架,但是部署的流程都是大同小异的!
    该框架如何编译,如何使用官方都有详细的教程!
    在这里插入图片描述

    2.onnx模型

    在模型部署之前一般会将我们训练好的模型(xxx.pth)文件转换为onnx的模型文件,onnx为一个中转模型,几乎所有的推理框架都能识别该模型文件,对onnx支持度非常高,并将其再次转换为NCNN框架能够使用的模型。
    转换代码入下

    import torch
    from flower_cls import Net
    
    model_path = "./model/9.pth"
    checkpoint = torch.load(model_path)
    
    net = Net()
    net.load_state_dict(checkpoint)
    net.eval()
    
    # 指定输入数据维度[N, C, H, W],和训练时保持一致
    img = torch.rand([1, 3, 224, 224])
    
    onnx_path = "./model/out.onnx"
    
    output = net(img)
    print(output.shape)
    
    out = torch.onnx.export(model=net,
                            args=torch.randn(1, 3, 224, 224),
                            f=onnx_path,
                            input_names=["input"],
                            output_names=["output"],
                            export_params=True,
                            verbose=False
    )
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    3.模型转换

    将onnx模型转换成NCNN框架的模型文件,该转换工具推理框架都会提供,输出的out.param和out.bin就是适用于NCNN框架的模型文件了!
    在这里插入图片描述

    4.代码实现

    通过NCNN提供的API让模型输出结果,主要步骤为:

    • 1.图像数据读入和与处理,保持和训练时一致即可
    // opencv读取输入图片
    cv::Mat img = cv::imread("1.jpg", 1);
    int w = img.cols;
    int h = img.rows;
    
    // 减均值除方差以及缩放操作
    ncnn::Mat in = ncnn::Mat::from_pixels_resize(img.data, ncnn::Mat::PIXEL_GRAY, w, h, 224, 224);
    float mean[3] = { 0.485*255, 0.456*255, 0.406*255 };
    float norm[3] = { 1/0.229/255, 1/0.224/255, 1/0.225/255 };
    in.substract_mean_normalize(mean, norm);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 2.加载模型文件,NCNN中API都定义好了,调用即可
    // 构建NCNN的net,并加载转换好的模型
    ncnn::Net net;
    net.load_param("model.param");
    net.load_model("model.bin");
    
    • 1
    • 2
    • 3
    • 4

    3.创建网络层提取器,指定具体提取哪些层的输出结果。(网络层的名称在转换onnx模型时会指定,也可以查看.param文件中的名称,从而找到正确名称,可以查看param文件解释

    // 创建网络提取器,设置网络输入,线程数,light模式等等
    ncnn::Extractor ex = net.create_extractor();
    
    ex.input("input", in);
    // 调用extract接口,完成网络推理,获得输出结果
    ncnn::Mat feat;
    ex.extract("output", feat);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.将输出转化为所需信息,例如我训练的模型会输出一个[1,1,5]的矩阵,代表5个类别的概率,找到最大值即代表该图像所对应的类别,可以看到第二类概率最高
    在这里插入图片描述

    5.完整代码

    #include 
    #include 
    #include 
    #include "ncnn/net.h"
    
    using namespace cv;
    using namespace std;
    using namespace ncnn;
    
    int main()
    {
     // opencv读取输入图片
        cv::Mat img = cv::imread("1.jpg", 1);
        int w = img.cols;
        int h = img.rows;
    
        // 减均值以及缩放操作,最后输入数据的值域为[-1,1]
        ncnn::Mat in = ncnn::Mat::from_pixels_resize(img.data, ncnn::Mat::PIXEL_GRAY, w, h, 224, 224);
        float mean[3] = { 0.485*255, 0.456*255, 0.406*255 };
        float norm[3] = { 1/0.229/255, 1/0.224/255, 1/0.225/255 };
        in.substract_mean_normalize(mean, norm);
     
     // 构建NCNN的net,并加载转换好的模型
        ncnn::Net net;
        net.load_param("model.param");
        net.load_model("model.bin");
    
     // 创建网络提取器,设置网络输入,线程数,light模式等等
        ncnn::Extractor ex = net.create_extractor();
    
        ex.input("input", in);
     // 调用extract接口,完成网络推理,获得输出结果
        ncnn::Mat feat;
        ex.extract("output", feat);
    
        cout<<"输出矩阵维度:"<<endl;
        cout<<"c:"<<feat.c<<endl;
        cout<<"h:"<<feat.h<<endl;
        cout<<"w:"<<feat.w<<endl;
        
        cout<<"各个类别的概率:"<<endl;
        cout<<feat[0]<<endl;
        cout<<feat[1]<<endl;
        cout<<feat[2]<<endl;
        cout<<feat[3]<<endl;
        cout<<feat[4]<<endl;
        
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    小结

    主要介绍了模型部署流程,其中最重要的是NCNN框架的使用,多看官方文档,多写写代码就熟悉了,其他框架也都大同小异!

    如果文章对你有用,请点个赞呗!!!

  • 相关阅读:
    图的数据结构
    React 补充
    js金额转大写以及获取url后面的参数
    VirtualBox中安装MacOS Big Sur
    微信小程序原生加vant改变日历组件开始和结束的默认文案
    应用层 - 常见协议、域名、DNS、DHCP、HTTP、form提交、正向代理反向代理、CDN
    Mysql数据库大数据量的解决方案介绍(三、Mycat中间件分片实战)
    Linux-基本指令02
    【项目】短信模块对Java枚举的使用
    Opencv基于文字检测去图片水印
  • 原文地址:https://blog.csdn.net/qq_43049432/article/details/127692386