手把手教学在windows系统上将pytorch模型转为onnx,再转为ncnn的全过程

news2024/11/20 13:31:51

前言

最近呢,在忙一个项目,需要将pytorch训练的模型部署在移动端。然后遇到也遇到了一些坑,简单的记录一下整个过程,转换的模型就使用经典的分类网络模型mobilenet_v2。

将pytorch模型转换为onnx模型

环境准备

这个步骤比较简单,只需要安装pytorch即可,笔者这里使用的是pytorch 1.9.1的版本,直接用pip 安装即可

转换步骤

pytorch转为onnx的代码网上很多,也比较简单,就是需要注意几点:1)模型导入的时候,是需要导入模型的网络结构和模型的参数,有的pytorch模型只保存了模型参数,还需要导入模型的网络结构;2)pytorch转为onnx的时候需要输入onnx模型的输入尺寸,有的模型是固定尺寸输入,有的是不固定,这个需要注意区分

转换代码如下,供参考:

import os
import sys
import torch
import torchvision

def export_onnx():

    onnx_model_name = "mobilenet.onnx"

    print("Loading Model")
    model = torchvision.models.mobilenet_v2(pretrained=True)
    model.eval() # Put in inference mode
    
    # Create dummy input
    dummy_input = torch.randn(1, 3, 224, 224)

    # Export as ONNX
    print(f"Exporting as ONNX: {onnx_model_name}")
    torch.onnx._export(
        model,
        dummy_input,
        onnx_model_name, # Output name
        opset_version=13, # ONNX Opset Version
        export_params=True, # Store the trained parameters in the model file
        do_constant_folding=True, # Execute constant folding for optimization
        input_names = ['input'],   # the model's input names 
        # output_names = ['pred_logits', 'pred_points'], # the model's output names (see forward in the architecture)
        output_names = ['pred_logits'], # the model's output names (see forward in the architecture)
        # dynamic_axes={
        #     # Input is an image [batch_size, channels, width, height]
        #     # all of it can be variable so we need to add it in dynamic_axes
        #     'input': {
        #         0: 'batch_size',
        #         1: 'channels',
        #         2: 'width',
        #         3: 'height'
        #     }, 
        #     'pred_logits': [0, 1, 2]
        # } 
    )



if __name__ == '__main__':

    export_onnx()

像笔者这种使用torchvision加载模型的方式,脚本会自动从torchvision库上下载模型保存在本地,本地的保存路径是C:\Users\用户名.cache\torch\hub\checkpoints

将onnx模型转为ncnn

环境搭建

需要编译安装的软件包括:vs2019/2017、 cmake、opencv(可选)、protobuf 3.11.2、VulkanSDK 1.2.148.0(可选)、ncnn。

这里除了opencv和VulkanSDK ,其他的软件都的必装的。opencv是图像处理库,如果需要在windows系统上运行转好的ncnn的模型,一般都需要用到opencv做一些图像读写操作,或者是前处理之类的。VulkanSDK是gpu加速的一个sdk库,可以根据自己的电脑环境选装。

因为笔者的环境之前就已经安装了vs2019和cmake,所以这里就不详细讲述这两个软件的安装,vs2019和cmake的安装,网上也有很多教程可以参考。vs2019整体是在线安装,比较简单,基本上就是一直点下一步就可以了。cmake可以在这个官网下载最新的版本,然后本地解压一下,再配置一下环境,能够在命令行输入cmake,就能有如下的效果即代表环境配置成功:
在这里插入图片描述

编译安装protobuf 3.11.2

Protobuf是一种平台无关、语言无关、可扩展且轻便高效的序列化数据结构的协议,可以用于网络通信和数据存储。
从该地址下载protobuf3.11.2的压缩包,解压后放在之前新建的文件中,然后在开始菜单找到Visual Studio 2019=>x64 Native Tools Command Prompt for VS 2019右击,点击更多,以管理员身份运行,输入以下命令编译protobuf3.4.0:

cd <protobuf-root-dir>
mkdir build-vs2019
cd build-vs2019
cmake -A x64 -DCMAKE_INSTALL_PREFIX=%cd%/install -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_MSVC_STATIC_RUNTIME=OFF ../cmake
cmake --build . --config Release -j 2
cmake --build . --config Release --target install

其中protobuf-root-dir是你的protobuf解压的路径。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
基本上安装好的库目录就是这样的

编译安装ncnn

编译安装ncnn,首先也是从官网下载稳定的版本,就是带有版本号的版本,笔者这里下载的是ncnn-20230223-full-source这个版本。下载压缩包后,解压,然后和编译protobuf一样,在开始菜单找到Visual Studio 2019=>x64 Native Tools Command Prompt for VS 2019右击,点击更多,以管理员身份运行,输入以下命令编译:

cd <ncnn-root-dir>
mkdir -p build-vs2019
cd build-vs2019
cmake -A x64 -DCMAKE_INSTALL_PREFIX=%cd%/install -DProtobuf_INCLUDE_DIR=<protobuf-root-dir>/build/install/include -DProtobuf_LIBRARIES=<protobuf-root-dir>/build/install/lib/libprotobuf.lib -DProtobuf_PROTOC_EXECUTABLE=<protobuf-root-dir>/build/install/bin/protoc.exe ..
cmake --build . --config Release -j 8
cmake --build . --config Release --target install

这里需要说明的是ncnn-root-dir是本地ncnn-20230223-full-source安装包解压后的路径,protobuf-root-dir是本地protobuf安装包路径。另外,protobuf-root-dir后面的build也需要换成编译protobuf文件夹名字,比如上一步中,我们使用的文件夹名字是build-vs2019,那就要换成这个名字,对应起来就行了。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
到这里,基本上ncnn就成功编译完成了。另外需要注意的是,如果有的小伙伴没有能够成功编译,出现了报错的情况,一定一定要仔细检查第一个cmake命令行,是否出现了一些错误。笔者在第一次编译安装ncnn时候,在最后一步的cmake中出现了如下的错误:
请添加图片描述
错位中提示"file cannot create directory", 当时debug这个错误了一两个小时,在网上也没有搜到对应的错误以及解决方案,甚至一度以为是权限不够导致的这个错误,后来才发现在第一步命令行中

cmake -A x64 -DCMAKE_INSTALL_PREFIX=%cd%/install -DProtobuf_INCLUDE_DIR=<protobuf-root-dir>/build/install/include -DProtobuf_LIBRARIES=<protobuf-root-dir>/build/install/lib/libprotobuf.lib -DProtobuf_PROTOC_EXECUTABLE=<protobuf-root-dir>/build/install/bin/protoc.exe ..

配置的protobuf-root-dir的路径不对,-DProtobuf_INCLUDE_DIR和 DProtobuf_LIBRARIES之间缺少了空格,而且运行该命令后,也明显提示错误,比如说是找不到libprotobuf.lib,或者protoc.exe,但是没有仔细查看命令行的错误,导致在第三步中报错,还找错了解决问题的方向。

另外需要提醒一点的是,如果在编译过程中出现了错误,建议是删掉build目录后,重新新建这个目录,再进行编译,否则容易重复出现上一次的错误,这是因为有cmakecache的原因。

转换步骤

进入到上一步中编译好的ncnn-20230223-full-source/build/文件夹,这里就是安装好的ncnn目录,大致是这样的
在这里插入图片描述
然后进入到build\tools\onnx\Release目录下,打开cmd命令行,输入如下命令:

onnx2ncnn.exe mobilenet.onnx mobilenet.bin mobilenet.param

就可以在当前目录生成两个ncnn格式的模型。

另外,由于ncnn支持的算子是有限的,所以很多时候会在转模型的时候报错,比如本次实验使用的mv2,居然也报错,有Shape not supported yet!
Unknown data type 0
在这里插入图片描述
真是一次失败的尝试!!

后记

其实呢,在费劲巴拉的把整个ncnn所有的依赖库编译安装成功,才得到了算子不支持的结果,真是很扫兴。后来笔者在ncnn官网发现,其实有编译好的ncnn库,完全可以不用自己辛苦去编译,直接下载就好了。比如笔者下载的是windows vs2019环境编译的版本
在这里插入图片描述
下载解压之后,打开ncnn-20230223-windows-vs2019\x64\bin,就可以看到有onnx2ncnn.exe这个工具
在这里插入图片描述
同样尝试将mv2的onnx模型转为ncnn试试,也得到了同样的错误
在这里插入图片描述

最后的最后,如果你连ncnn编译好的库都不愿意下载,也可以完全可以完成onnx转ncnn模型,你只需要打开这位大佬的创建一键转换网页,上传onnx模型,编译在线转换为ncnn模型

参考

ncnn | Windows(VS2019)编译
how to build
win10下pytorch转ncnn手把手教程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/418672.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

U+平台和华为软开平台怎么拉取远程项目作为新项目

这是根据聊天记录改的帖子&#xff0c;这样应该算得上是一篇技术博客了吧&#xff0c;又完成一个指标【狗头】 用idea作为开发工具 首先连接校园网&#xff0c;然后进入U网址http://10.5.1.21:30080/student/group 从这进去 修改https密码&#xff0c;选择修改&#xff0c;不…

Ubuntu20.04 安装QGIS

qgis的git&#xff1a; GitHub - qgis/QGIS: QGIS is a free, open source, cross platform (lin/win/mac) geographical information system (GIS) qgis的官网:Welcome to the QGIS project! qgis插件包下载地址&#xff1a;https://plugins.qgis.org/plugins/ 1.Prerequisi…

前 K 个高频元素(力扣刷题代码随想录刷题)

给你一个整数数组 nums 和一个整数 k &#xff0c;请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 思路&#xff1a; 要统计元素出现频率对频率排序找出前K个高频元素首先统计元素出现的频率&#xff0c;这一类的问题可以使用map来进行统计。 然后是对频率…

商汤科技推出“日日新SenseNova”,大模型体系赋能人工智能新未来

2023年4月10日&#xff0c;商汤科技SenseTime技术交流日活动在上海举行&#xff0c;分享了以“大模型大算力”推进AGI&#xff08;通用人工智能&#xff09;发展的战略布局&#xff0c;并公布了商汤在该战略下的“日日新SenseNova”大模型体系。 公开信息显示&#xff0c;商汤科…

使用Python突破某网游游戏JS加密限制,进行逆向解密,实现自动登录

兄弟们天天看基础看腻了吧 今天来分享一下如何使用Python突破某网游游戏JS加密限制&#xff0c;进行逆向解密&#xff0c;实现自动登录。 逆向目标 目标&#xff1a;某 7 网游登录主页&#xff1a;aHR0cHM6Ly93d3cuMzcuY29tLw接口&#xff1a;aHR0cHM6Ly9teS4zNy5jb20vYXBpL…

面试了上百位性能测试后,我发现了一个令人不安的事实...

在企业中负责技术招聘的同学&#xff0c;肯定都有一个苦恼&#xff0c;那就是招一个合适的测试太难了&#xff01;若要问起招哪种类型的测试最难时&#xff0c;相信很多人都会说出“性能测试”这个答案。 每当发布一个性能测试岗位&#xff0c;不一会就能收到上百份简历&#…

商会协会入会资源需求活动小程序开发

商会协会入会资源需求活动小程序开发 功能列表&#xff1a; 用户注册&#xff1a;用户可以通过小程序注册账号并加入商会协会。会员管理&#xff1a;可以管理会员的基本信息&#xff0c;包括个人信息、公司信息、会员资格等级等。同时&#xff0c;管理者可以根据会员等级制定…

JavaSE抽象类和接口

文章目录JavaSE抽象类和接口一、抽象类1、抽象类概念2、抽象类特性二、接口1、接口概念2、接口特性3、多接口4、接口之间的继承5、常用接口使用6、抽象类和接口的区别三、Object类JavaSE抽象类和接口 一、抽象类 1、抽象类概念 一个类中没有包含足够的信息来描绘一个具体的对…

最长公共子序列(动态规划)

Time Limit: 1 Sec Memory Limit: 128 Mb Description 求两个序列的最每组测试样例都为一行&#xff0c;两组字符串&#xff0c;每组不超过1000&#xff0c;用空格隔开。求最长公共子序列&#xff0c;都为小写字母。Input 每组测试样例都为一行&#xff0c;两组字符…

PHP快速入门03-面向对象编程

文章目录前言面向对象编程关于PHP的面向对象编程类的默认方法和属性面向对象编程示例总结前言 本文已收录于PHP全栈系列专栏&#xff1a;PHP快速入门与实战 面向对象编程 关于PHP的面向对象编程 PHP的面向对象编程&#xff08;Object-Oriented Programming&#xff0c;OOP…

OK-3399-C ADB烧录

ADB烧写 一、OK3399用户资料工具目录附带了ADB工具的资料包路径&#xff1a; 二、将其解压在C:\User目录 三、将设备通过type-c线download口与电脑相连接&#xff0c;打开命令行&#xff0c;进入解压的目录&#xff0c;查看adb是否安装成功&#xff1a; 四、安装成功后&#x…

gpt4all保姆级使用教程! 不用联网! 本地就能跑的GPT

原文&#xff1a;gpt4all保姆级使用教程! 不用联网! 本地就能跑的GPT 什么是gpt4all gpt4all是在大量干净数据上训练的一个开源聊天机器人的生态系统。它不用科学上网&#xff01;甚至可以不联网&#xff01;本地就能用&#xff0c;像这样↓&#xff1a; 如何使用&#xff…

【针对项目在线OJ系统的测试】:Junit+Selenium

目录 一、背景介绍&#xff1a; 二、导入的依赖&#xff1a; 三、测试模块1&#xff1a;index页面的测试 测试点1&#xff1a;测试"我的OJ系统这4个字是否存在" 测试点2&#xff1a;测试"题目列表"这4个字是否存在 测试点3&#xff1a;测试"编号…

设计模式(十二)之装饰器模式

文章目录什么是装饰器模式例子&#xff1a;总结什么是装饰器模式 现在有一块蛋糕&#xff0c;涂上奶油就变成了奶油蛋糕&#xff0c;如果加上草莓就是草莓奶油蛋糕&#xff0c;再加上蜡烛就变成了生日蛋糕。 程序中的对象与蛋糕十分相似。将对象类比成蛋糕&#xff0c;不断的加…

Faster-RCNN代码解读6:主要文件解读-中

Faster-RCNN代码解读6&#xff1a;主要文件解读-中 前言 ​ 因为最近打算尝试一下Faster-RCNN的复现&#xff0c;不要多想&#xff0c;我还没有厉害到可以一个人复现所有代码。所以&#xff0c;是参考别人的代码&#xff0c;进行自己的解读。 ​ 代码来自于B站的UP主&#xff…

Qt音视频开发36-超时检测和自动重连的设计

一、前言 如果网络环境正常设备正常&#xff0c;视频监控系统一般都是按照正常运行下去&#xff0c;不会出现什么问题&#xff0c;但是实际情况会很不同&#xff0c;奇奇怪怪七七八八的问题都会出现&#xff0c;就比如网络出了问题都有很多情况&#xff08;交换机故障、网线故…

TensorFlow 1.x 深度学习秘籍:11~14

原文&#xff1a;TensorFlow 1.x Deep Learning Cookbook 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 深度学习 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 不要担心自己的形象&#xff0c;只关心如…

持续集成——通过docker命令安装Jenkins

一、持续集成体系介绍 1、核心价值&#xff1a; 集成自动化测试&#xff0c;减少重复劳动 尽早发现和解决缺陷,减少风险 形成有机整体&#xff0c;明确阶段交付物 2、常见集成方案 a、阶段化 为不同的构建测试套件建立不同的CI循环周期 单元测试运行时间短&#xff0c;反馈…

测试基础篇

目录软件测试的生命周期测试用例设计如何描述一个bug如何创建一个Bug案例Bug的级别Bug的生命周期测试人员和开发人员产生争执了怎么办&#xff1f;软件测试的生命周期 软件测试的生命周期&#xff1a;需求分析→测试计划→测试设计、软件开发→测试执行→测试评估 软件测试&a…

AXI DMA

PG021 AXI DMA&#xff1a;AXI Direct Memory Access AXI DMA为内存和AXI4-Stream外设之间提供了高带宽的直接内存访问&#xff0c;其可选的S/G功能可以将CPU从数据搬运任务中解放出来。 AXI DMA通过AXI4-LITE接口对寄存器做一些配置和获取 MM2S&#xff1a;MemoryMap to St…