小白如何快速入门计算机视觉?

去年 11 月的时候,给自己了一个目标,希望在未来的 3个月时间里,写满100篇关于从零入门AI视觉的算法、代码文字。

历经 3 个月,终于在今天 100 篇文章写完了,代码也全部调试完成,上传到 github 上开源给大家,有想要学习或入门 AI 的可以看看,地址:https://github.com/dongtuoc/cv_learning_resnet50

项目介绍

本项目在做什么

本项目旨在完成对 AI 的计算机视觉的入门学习,并且在 Intel CPU 上完成以 resnet50 为基础的神经网络的全部手写,以及性能优化。

首先通过对一些经典的传统计算机视觉算法进行实操,理解计算机视觉的含义;随后以 resnet50 神经网络为例子,系统的讲解一个 AI 模型的基础算法原理和相关背景知识。

最后通过本仓库中的代码实战,从零手写 resnet50 神经网络,完成任意一张图片的识别,以及神经网络模型的性能优化

  • 传统计算机视觉部分,会有灰度图、RGB、均值/高斯滤波器、利用 Canny 算子对图像进行边缘检测、利用大津算法对图像进行分割等小的实操项目。

  • AI 部分会有一个手写数字识别项目(Mnist) 作为引子,来理解一个 AI 模型的训练和推理过程。

  • AI 原理部分,会详细阐述和解析 resnet50 中用到的算法和背景知识。

  • 实战部分用 python/C++ 两种语言完成 resnet50 模型的从零手写。

    • 其中 resnet50 的所有核心算法和网络结构(包括Conv2d、AvgPool、MaxPool、fc、Relu、残差结构) 全部手写,不借用任何第三方库。
    • 由于是自己手写的算法和模型结构,因此会有很大的自由度进行性能优化,性能优化是本项目最后进行的部分,会迭代多个版本,一步步将模型的性能调到比较不错的效果。
  • 实战部分在完成手写算法的基础上,除了要保证网络精度可用(也就是任意给一张图片,经过预处理之后,Top1/Top5 可以正确的预测出图片) 之外,还会关注性能优化部分,这一点后面会有介绍。

为什么要全部手写核心算法

目前网上有很多教程,在教你手搭神经网络的时候,基本都是基于 torch 的 nn 模块或其他模块,用 nn.conv2d 就完成了卷积计算。

对于想深究算法和学习算法的同学,或者一些初学者而言,即使按照教程将神经网络搭建出来了,或这将图片推理出来了,依旧是云里雾里,不知其原理,始终浮于表面,心里学的也不踏实,这一点我在多年前初学的时候感受尤为明显。

事实上,nn.conv2d 是将 conv2d 的算法实现给封装起来了,我们看不到它的实现机制,很难学到里面的实现细节,跟别提如何在此基础上进行性能优化了(虽然该接口已经被优化过)。

于是便有了这个项目。

最初仅仅是想自己动手完成一个简单的 resnet50 的模型的手写。

随后有一些小伙伴联系我希望跟着学习,于是开始系统的写文章,结果越写越多,索性做了一个小册,通过小册的写作,激励我不断的维护和更新这个项目,截止到现在,还在不断的更新代码,为代码写注释,写相关的文章。

所以,你可以看到,本项目的代码部分是大家都可以下载学习的,但是仓库配套的 100 多篇文章是付费的。

该项目中的代码从2023年4月开始编写,2023年11月做成小册,陆续调试了很多次,所有代码都是我手动编写而成。

目前项目中所有代码已经完全跑通,精度也很OK,性能经过 5 个版本的迭代,也基本达到了不错的效果。

你可以学到什么

通过本项目,你可以一窥传统计算机视觉的经典算法,理解传统计算机视觉和基于深度学习的计算机视觉算法的联系和区别,深入理解 resnet50 中用到的所有算法原型、算法背景原理、resent50 的思想、resnet50 的网络结构、以及常见的神经网络优化方法。

你可以参考项目中的代码,真正运行一个 resnet50 神经网络,完成一张或多张图片的推理。

在项目的 new_version_with_notes 目录下是带有注释的版本,代码中关键的地方我会给出文字详解。

如果你把项目代码和配套的文章都阅读一遍,完全实操一遍,我觉得入门 AI 视觉并不是难事,同时关于 resnet50 这个经典模型,即使你是一个小白,完全实操一遍之后也可以出师了。

项目所涉及文章

该项目搭配有 100+ 篇背景知识、原理解析和代码实操相关的介绍文章, 花费了巨大的精力写成。

有两种办法可以阅读到这些文章:

  1. 在这里(如果跳转不了就右键,复制连接地址到浏览器打开)订阅。

  2. 在这里订阅。

仓库结构

  • 0_gray 为灰度图相关代码
  • 1_RGB 为灰度图与 RGB 转换相关代码
  • 2_mean_blur 为均值滤波相关代码
  • 3_gussian_blur 为高斯滤波相关代码
  • 4_canny 为 canny 算法相关,用来完成图片的边缘检测
  • 5_dajin 为大津算法相关,用来完成图片的分割
  • 6_minst 为一个经典的手写数字识别 AI 模型(神经网络),可以在笔记本(CPU)上进行模型的训练和推理
  • practice 为以 resnet50 为基础的模型算法手写、模型搭建和相关的主目录,也是本项目从零手写 resnet50 的主要目录,这里面又包含了:
    • model 目录:与开源模型相关的文件,包括模型参数的下载,参数的解析等。
    • pics 目录: 使用模型识别一张图片时,存放图片的目录
    • python 目录:利用 python 语言手写的 resnet50 项目
    • cpp 目录:利用 c++ 语言手写的 resnet50 项目。

其中,python 目录和 cpp 目录互相独立。

在 cpp 目录中,分别存在 1st 到 6th 6个目录,为性能优化的迭代目录,6 个目录相互独立,可以独立运行任意目录中的代码,对比查看在迭代过程中,由于代码的优化带来的性能提升效果。

  • new_version_with_notes 目录: 这是本仓库的一个新版本,包含上述所有代码,里面的目录结构复刻了上述结构。区别在于给代码添加了注释,并且优化了一些细节。建议第一次使用的同学直接使用 new_version_with_notes 目录下的代码。

我是如何实现从零手写 resnet50 的

实现思路

模型获取

使用 torchvision 从已经预训练好的模型中,将 resnet50 每一层的权值保存到仓库中,所保存的权值文件会在后续被加载进来,参与卷积、全连接、BN层的计算。

这里多说一些,在实际工业项目的模型部署中,神经网络的权值也是作为独立的数据被加载到GPU/CPU中完成计算的。

而很多实际模型的性能瓶颈会是在权值加载部分。为什么呢?我分析有几个原因:

  • 受限于芯片内存的限制。导致无法将神经网络的所有权值全部一次加载,而多次加载带来的副作用便是会带来多余的IO操作,内存越小此问题越严重。

  • 受限于芯片带宽的限制。在模型参数量日益增大的今天,GB 级别的带宽越来越显得吃力,而且在很多时候,IO 和计算无法真正在芯片上完全流水起来,尤其是在堆算力的时候,IO 就被凸显出来了。

  • 在 model 目录下,运行以下脚本,即可将参数保存到 model/resnet50_weight 中。

    $ python3 resnet50_parser.py

代码实现

在保存完权值后,利用 python / C++ 语言,分别实现 Conv2d, BatchNorm, Relu, AvgPool, MaxPool, FullyConnect(MatMul) 等核心函数。

按照 resent50的网络结构, 将以上算法搭起来。

  • 模型文件参考 model/resnet50.onnx.png 和 model/resnet50_structure.txt
  • 手工搭建 resnet50 的网络结构参考 我手工搭建的模型, Python 版本
推理

代码实现完成后,意味着模型运行需要的基础算法和参数已经就位,下面读取一张本地图片,进行推理。

  • 读取一只猫的图片,参考获取图片

读取完图片,开始推理,正确推理出来是一只猫,本项目第一阶段目标(准确性验证)即完成。

优化

在基本功能实现完成后,开始着手进行性能优化。

性能优化属于神经网络中的一大重点,下面单分一章节来说明。

性能优化

python 版本

这部分是 python 版本的性能优化,先看下本仓库如何使用 python 代码。

怎么用 python 版本
  1. resnet50 的核心算法和手搭网络是用基础的 python 语法写的,有些十分基础的操作调用 numpy 库。
  2. 导入图片调用的 pillow 库,导入图片这种逻辑不属于从零手写 resnet50 核心算法的范畴,我也没时间去写类似的逻辑,直接用 pillow 库。
  3. 安装依赖,主要是上面两个库的依赖(国内清华源比较快,可自己按需来选择),在 python 目录下,执行:

不使用清华源

$ pip3 install -r requirements.txt

使用清华源:

$ pip3 install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

  1. 推理
  • 在 python 目录下,运行以下命令,完成推理,你可以修改 my_infer.py 中的获取图片的逻辑,将图片替换成你自己的图片,看能否正确的识别出来。

    $ python3 my_infer.py

由于 Python 版本也基本没有调用三方库,以 python 的语法来写卷积循环,其性能绝对差到惨不忍睹,实测发现用 python 版本推理一张图片十分缓慢,主要是循环太多(但是为了展示算法的内部实现)。

python 版本的一点优化

利用 np.dot(内积运算)代替卷积的乘累加循环。

  • 优化 python 版本的算法实现:优化版本

python 不调用三方库的话,很多优化点无法去做(比如指令集不好控制、内存不好控制),下面还是重点优化C++版本。

C++ 版本

这部分是 C++ 版本的性能优化,先看下本仓库如何使用 c++ 代码。

怎么用 c++ 版本

本仓库的 C++ 代码已经合入了几次优化提交,每次都是在前一次优化的基础上做的进一步优化,优化记录可以通过 cpp 目录下的文件名很方便的看出来。

  • cpp/1st_origin 目录下存放的是第一版的 C++ 代码
  • cpp/2nd_avx2 目录下存放的是第二版的 C++ 代码,启用了 avx2 指令集的优化,以及 -Ofast 编译选项
  • cpp/3rd_preload 目录下存放的是第三版的 C++ 代码,利用类似内存池的方式,增加了权值提前加载的逻辑,仍保留了每一层结果输入输出的动态 malloc 过程。
  • cpp/4th_no_malloc 目录下存放是第四版优化的 c++ 代码,删除了所有动态内存申请的操作,大幅提高性能。
  • cpp/5th_codegen 目录下存放是第五版优化的 c++ 代码,利用 CodeGen 和 jit 编译技术生成核心计算逻辑。
  • cpp/6th_mul_thread 目录下存放是第六版优化的 c++ 代码,利用多线程优化卷积的运算,大幅提升性能。
编译

每个版本的目录下文件是独立的,不存在依赖,如果你想看两个版本间的代码改动,可以使用源码比较工具来查看。

每个版本的目录下文件的编译过程是相同的。 如果你只有 windows 环境而没有 linux 环境,可以查看不用虚拟机,10 分钟快速在 windows 下安装 linux 系统这里快速安装一个linux系统,如果你购买了付费文章,会有更加详细的安装指导。

如果你有 linux 环境,并且对 linux 操作很熟悉,请直接往下看:

  • C++ 版本编译依赖 opencv 库,用来进行图片的导入,功能与 python 版本的 pillow 类似,linux 环境下,执行以下命令安装 opencv 库:

    $ sudo apt-get install libopencv-dev python3-opencv libopencv-contrib-dev

  • cpp 目录下,运行 compile.sh 即可完成编译。

    $ bash ./compile.sh

编译完成后,在当前目录下,生成名为 resnet 的可执行文件,直接执行该文件,会对仓库中保存的图片进行推理,并显示结果。

$ ./resnet

初始版本一

目录为 cpp/1st_origin。

第一版没有考虑性能问题,仅仅是按照想法完成了功能,可想而知性能惨不忍睹,此版本性能数据:

Average Latency :16923 ms

Average Throughput:0.059 fps

性能数据和电脑性能有关,你可跑下试试,看看打印出来的 Lantency 是多少。

优化版本二

目录为cpp/2nd_avx2。

第二版在第一版的基础上,将卷积算法中的乘累加的循环运算,利用向量指令集做了并行化加速,采用的向量指令集为 avx2,你可以通过以下命令查看你的 CPU 是否支持 avx2 指令集。

$ cat /proc/cpuinfo

在显示的信息中如果存在 avx2 便是支持该指令集。

此版本性能数据:

Average Latency : 4973 ms

Average Throughput :0.201 fps

优化版本三

目录为cpp/3rd_preload 。

第三版在第二版的基础上,消除了运算推理过程中针对权值参数动态 malloc 的过程,改为在推理之前,利用 std::map 管理一个类内存池的结构,推理之前将所有的权值参数全部加载进来,这一步优化在实际模型部署中是有现实意义的。

模型参数的提前加载可以最大限度的减轻系统的IO压力,减少时延。

此版本性能数据:

Average Latency:862 ms

Average Throughput:1.159 fps

优化版本四

目录为cpp/4th_no_malloc 。

第四版在第三版的基础上,消除了运算推理过程中所有动态内存申请,以及与字符串相关的操作。

此版本性能数据:

Average Latency:742 ms

Average Throughput:1.347 fps

优化版本五

目录为cpp/5th_codegen 。

第五版在第四版的基础上,利用 CodeGen 技术生成核心计算逻辑,利用 jit 编译完成编译过程。

此版本性能数据:

Average Latency:781 ms

Average Throughput:1.281 fps

优化版本六

目录为cpp/6th_mul_thread。

第六版在第五版的基础上,利用多线程来优化了卷积计算,对 co 维度进行了线程间的独立拆分,用满 CPU 线程数。

此版本性能数据:

Average Latency:297 ms

Average Throughput:3.363 fps

经过 6 个版本的优化,推理延时从 16923 ms 优化至 297 ms, 提升了近 60 倍的性能。推理一张图片已经感觉不到卡顿,算是不错的效果。

整体仓库依赖

  1. 保存权值的依赖
  • cd 到 model 目录,安装解析模型相关的依赖库。

    $ pip3 install -r requirements.txt -i pypi.tuna.tsinghua.edu.cn/simple

  1. python 推理依赖
  • cd 到 python 目录,安装推理 resnet50 需要的依赖库,主要是 numpy 还有 Pillow 库,用来导入图片。

    $ pip3 install -r requirements.txt -i pypi.tuna.tsinghua.edu.cn/simple

其他 Contact me

  • 本项目所有代码和相关文章,均为个人原创,未经同意,请勿随意转载至任何平台,更不可用于商业目的,我已委托相关维权人士对原创文章和代码进行监督。

  • 如果你有其他相关事宜,欢迎和我交流。

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

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

相关文章

旧物回收小程序开发:环保与科技的创新结合

随着科技的飞速发展,我们的日常生活越来越离不开手机应用程序。而在环保日益成为社会焦点的今天,如何将科技与环保相结合,成为了一个值得深思的问题。今天,我们将探讨旧物回收小程序的开发,它如何助力环保,…

【重要公告】BSV区块链上线TypeScript SDK,未来将支持更多开发语言

​​发表时间:2024年2月21日 BSV区块链协会宣布上线JavaScript和TypeScript SDK(即“标准开发工具包”)。TypeScript SDK旨在为开发者提供新版统一核心代码库,以便利开发者在BSV区块链上开发能够任意扩容的应用程序。新上线的SDK替…

SpringBoot集成自然语言处理hanlp工具包

HanLP是一系列模型与算法组成的NLP工具包&#xff0c;目标是普及自然语言处理在生产环境中的应用。 下载与配置 <dependency><groupId>com.hankcs</groupId><artifactId>hanlp</artifactId><version>portable-1.8.4</version> <…

掌握Python操作Word:从基础到高级全覆盖

掌握Python操作Word&#xff1a;从基础到高级全覆盖 引言Python操作Word的基础文档的创建与打开文档的基本操作 创建和打开Word文档创建新的Word文档打开现有文档读取文档内容修改现有文档 编辑文档内容添加和编辑文本设置格式插入标题 处理文档结构操作段落列表的处理表格的操…

深入理解 Vuex:从基础到应用场景

前言 在之前的文章中&#xff0c;我们已经对 Vue.js 有了一定的了解。今天我们要对Vue官方的状态共享管理器Vuex进行详细讲解&#xff0c;将其基本吃透&#xff0c;目标是面对大多数业务需求&#xff1b; 一、介绍 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用…

『操作系统OS笔记』MAC(m1芯片)电脑安装FFmpeg

MAC(m1芯片)电脑安装FFmpeg mac电脑安装ffmpeg两种方法 文章目录 1. brew安装FFmpeg2. 官网下载FFmpeg压缩包3. 使用FFmpeg将音频和视频合并 1. brew安装FFmpeg brew install ffmpeg # 需要等比较久的时间&#xff0c;安装很多东西&#xff0c;安装过程中如果遇到报错对应解决…

MES数据采集设备

在智能制造日益盛行的今天&#xff0c;MES&#xff08;制造执行系统&#xff09;作为连接计划与生产现场的关键环节&#xff0c;其重要性不言而喻。而MES数据采集设备则是MES系统的核心组件&#xff0c;负责实时、准确地获取生产现场的各种数据&#xff0c;为企业的生产决策提供…

信息系统项目管理师--范围管理

项⽬范围管理 产品范围&#xff1a;指某项产品、服务或成果所具有的特征和功能。产品范围的完成情况是根据产品需求来衡量的。“需求”是指根据特定协议或其他强制性规范&#xff0c;产品、服务或成果 必须具备的条件或能⼒。 项⽬范围&#xff1a;包括产品范围&#xff0c;是为…

bat转exe

新建bat2exe.bat文件 ;echo off ;Title Converting batch scripts to file.exe with iexpress ;Mode 75,3 & color 0A ;Rem Original Script https://github.com/npocmaka/batch.scripts/edit/master/hybrids/iexpress/bat2exeIEXP.bat ;echo( ;if "%~1" equ &q…

探索HTTP/2

文章目录 http/1.1http/2疑惑 探索1. 连接前言2. 帧结构2.1 帧类型 Type 3. 帧详情3.1 SETTINGS 帧3.2 WINDOW_UPDATE 帧3.3 PRIORITY 帧3.4 HEADERS 帧3.5 DATA 帧3.6 PING3.7 GOAWAY 帧3.8 RST_STREAM 帧3.9 PUSH_PROMISE 帧3.10 CONTINUATION 帧 你对http2了解多少&#xff…

git的基本概念和用法

Git是一个版本控制系统&#xff0c;它可以跟踪代码的变化并记录每个修改的历史。以下是Git的基本概念和使用方式&#xff1a; 仓库&#xff08;Repository&#xff09;&#xff1a;Git仓库是存储代码和历史记录的地方。它可以是本地仓库&#xff08;在本地电脑上&#xff09;或…

基于 EfficientNetV2 实现判别MNIST 手写模型分类

pytorch深度学习项目实战100例 的学习记录 我的环境&#xff1a; 白票大王&#xff1a; google colab 用其他的话&#xff0c;其实实现也行&#xff0c;但是让小白来重环境来开始安装的话&#xff0c;浪费时间 论文速读 EfficientNetV2是由 Google Research&#xff0c;Br…

移动端开发之uni-app开发规范说明

移动端开发之uni-app开发规范说明 文章目录 移动端开发之uni-app开发规范说明1. 工程结构2. 注释(必须)1. vue头文件注释2. 代码注释 1. 工程结构 一个uni-app工程&#xff0c;默认包含如下目录及文件&#xff1a; ┌─uniCloud 云空间目录&#xff0c;阿里云为…

华为配置智能升级功能升级设备示例

配置智能升级功能升级设备示例 组网图形 图1 配置智能升级功能组网图 背景信息组网需求配置思路前提条件操作步骤操作结果 背景信息 为了方便用户及时了解设备主流运行版本&#xff0c;快速完成升级修复&#xff0c;华为设备支持自动下载、自助升级功能。用户在设备Web网管…

【HTML】HTML基础7.2(有序列表)

目录 标签 效果 注意 标签 <ol> <li>列表内容</li> <li>列表内容</li> <li>列表内容</li> <li>列表内容</li> 。。。。。。 </ol> 效果 代码 <ol><li>银河护卫队 10000000000</li><l…

C++ LRU缓存

题目&#xff1a; //构建双向链表的节点结构&#xff08;要有两个构造函数&#xff09; struct Node{int key, val;Node* pre;Node* next;Node():key(0), val(0), pre(nullptr), next(nullptr) {}Node(int _key, int _val): key(_key), val(_val), pre(nullptr), next(nullpt…

windows无界鼠标,多机共享一套键鼠

原因 当前使用一台笔记本和一个台式机。用起来很麻烦。想要找到共享键鼠的方案。找到了无界鼠标这个软件。 安装 在两台电脑上都安装powertoy应用。 https://github.com/microsoft/PowerToys csdn下载 安装完成后找到无界鼠标打开 配置 多台电脑配置相同的key,刷新识别设…

Unity3d调用C++ dll中的函数

一、生成dll 1.新建dll工程 2. 不用管dllmain.cpp&#xff0c;添加自定义Helper.h和Helper.cpp 3.添加要在外部调用的方法 //头文件 #define DLLEXPORT extern "C" __declspec(dllexport) DLLEXPORT int _stdcall Addition(int x, int y); DLLEXPORT int _stdcal…

LeetCode每日一题只 快乐数

目录 题目介绍&#xff1a; 算法原理&#xff1a; 鸽巢原理&#xff1a; 如何找到环里元素&#xff1a; 代码实现&#xff1a; 题目介绍&#xff1a; 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 算法原理&#xff1a; 我先简单举两个例子&#xff…

python界面开发 - OptionMenu菜单

文章目录 1. python图形界面开发1.1. Python图形界面开发——Tkinter1.2. Python图形界面开发——PyQt1.3. Python图形界面开发——wxPython1.4. Python图形界面开发—— PyGTK&#xff1a;基于GTK1.5. Python图形界面开发—— Kivy1.6. Python图形界面开发——可视化工具1.7. …