用 C 写一个卷积神经网络

用 C 写一个卷积神经网络

深度学习领域最近发展很快,前一段时间读transformer论文《Attention Is All You Need》时,被一些神经网络和深度学习的概念搞得云里雾里,其实也根本没读懂。发现深度学习和传统的软件开发工程领域的差别挺大,光读论文可能不是一条很好了解深度学习的路径。所以我换了一个思路,从开源的项目入手,当时我研究了一段时间ggml项目代码(https://github.com/ggerganov/ggml) , 但实际的难度还是太过陡峭,主要的困难来源于数学推导和神经网络本身的特殊性。为了更全面的了解深度学习领域,最后我选择从基础的系统知识和书籍入手, 在阅读《Neural Networks and Deep Learning》这本书时,正好书中是通过设计一个手写识别程序来讲解神经网络,书中的例子是用python实现的,其中用了不少机器学习库,屏蔽了很多细节。于是萌生了自己用C写一个手写识别程序想法。

要用C不依赖第三方库写一个神经网络,需要从数学推导、网络模型和工程实现三个方面着手。项目本身没有什么价值,只是个人学习神经网络一个小玩具。
代码地址:https://github.com/yuanrongxi/simple-neural-network.git

神经网络涉及到的数学主要是线性代数和微积分求导,神经网络中的计算大部分是通过矩阵来完成的,首先需要弄明白标量、向量、张量等概念,掌握基本的矩阵运算,例如:空间转置、加减乘除、点积、reshape等,线性代数推荐看《Linear Algebra an Its Applications》,了解基本的向量空间和运算即可,如果想更直观可以看https://github.com/kf-liu/The-Art-of-Linear-Algebra-zh-CN/blob/main/The-Art-of-Linear-Algebra-zh-CN.pdf。积分求导主要是针对神经网络的反向传播,因为在神经网络推导时会用各种激活函数、softmax、卷积、pooling max、norm、flatten等数据操作,反向传播的过程的梯度下降算法需要对这些操作进行反向求导,所以需要清楚各个函数求导过程和代价函数概念,求导更详细的可以看B站上的《跟着李沐学AI》。

网络模型涉及到神经元和感知机的概念,通过编排神经元和激活函数构建网络分层,这个《Neural Networks and Deep Learning》中讲的比较清楚。网络模型可以理解成一堆weight(权重)/bais(偏置)加一堆的y = w.x+b的函数,但它分为正向传播(feedforward)和反向传播(backprop),正向传播就是推理,反向传播就是求权重和偏置参数。因为反向传播过程是一个利用梯度下降求导的过程,理解起来会有些困难,https://builtin.com/machine-learning/backpropagation-neural-network 对反向传播总结的非常好,通俗易懂。最后CNN模型选择参照了YanLeCun的LeNet(图-1),保留第一个卷积层,去掉了中间的卷积层。

LeNet

工程实现方面参照了NumPy的思路,将涉及到矩阵运算、激活函数、反向求导等做成一个独立的矩阵运算模块,这样做的好处是可以对专门的运算做优化,后面也方便加入GPU和CUDA做尝试。其次设计了一个run state机制,因为神经网络在推理和训练时,会有很多的中间数据,这些数据有些是临时的,有些是反向传播依赖的。为了避免频繁内存分配,在创建NN时将所有用到的对象统一分配,中间数据的矩阵flatten也是零拷贝。关于CPU并行计算上,采用了openmp进行简单的矩阵并行处理,加快训练速度,所以在矩阵运算代码中用了大量的数组下标寻址,没有使用更快的指针,后面CPU上可以尝试SSSE3/simd128采用多线程分任务优化。最后神经网络是难于调试的,往往逻辑流程运行正确,但训练出来的结果不达预期,和传统的系统工程差别大。在实现中采用了对所有数学代码进行单元测试,并逐一对照相对应的pytorch运行结果,确保数学上正确,这样做大大减轻了神经网络的调试难度。值得一提的是程序设计后期借助了cursor AI代码工具,效率是前期的4~5倍左右。

来看一下程序的效果,采用的是MNIST的数据集,6万张训练图片和1万张测试图片,训练和测试30轮,多层感知机网络的识别准确度在95%左右,CNN网络的准确度在98%左右。执行时间CNN是多层感知机的20倍左右。
在这里插入图片描述
整个程序的开发设计断断续续用了4个周末的时间,实现难度一般,过程有些简单的认识:

  1. 之所以Python成为深度学习界的标准开发语言,是因为它有很多强大的库和平台,像NumPy、Pytorch、Keras等,写一个神经网络可能只需几十行代码,简单高效,其他语言无可匹及。业界正在研究基于Python语言的编译技术,这可能是未来重要的方向之一。

  2. 深度学习与传统软件工程差别大,传统软件工程是建立的逻辑学层面的工程体系,只要逻辑性强从事软件开发不是难事,所以行业内人员参差不齐。AI和深度学习领域有自己独立的知识体系,而且更多是要依靠数学推导和模型设计,工程实现也更偏CPU/GPU相关的编程,逻辑在其中起的作用有限,AI这个领域不太可能出现从培训机构出来就业的人员。传统软降工程也走到一个阶段了,软件工程的需求正在从传统的工程领域快速迁移到深度学习领域。

  3. 深度学习的计算分为推理和训练,随着网络模型的发展计算将越来越重。训练的计算量会因为成本越来越高会出现更高效的芯片和分布式计算网络。而推理计算由于安全和场景需要,可能会越来越终端化,而且推理的计算量未来是训练计算量的万倍甚至更多,会催生出新的工程领域,例如ggml。

  4. AI发展很快,很多面向程序员的工具,像github copilot、cursor等,生成的代码未必可直接使用,但能够加快从概念到代码的过程,合理使用AI工具可以更快的进入陌生领域。

科技正在大力向前,它已不再朝我而来,我唯一能做的是调整自己的位置来跟上它的步伐。

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

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

相关文章

智能优化算法应用:基于入侵杂草算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于入侵杂草算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于入侵杂草算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.入侵杂草算法4.实验参数设定5.算法结果6.…

【FPGA】Verilog:BCD 加法器的实现 | BCD 运算 | Single-level 16 bit 超前进位加法器 | 2-level 16-bit 超前进位加法器

0x00 BCD 运算 在 BCD 中,使用4位值作为操作数,但由于只表示 0 到 9 的数字,因此只使用 0000 到 1001 的二进制数,而不使用 1010 到 1111 的二进制数(dont care)。 因此,不能使用常规的 2complement 运算来计算,需要额外的处理:如果 4 位二进制数的运算结果在 1010 …

quickapp_快应用_快应用与h5交互

快应用与h5交互 h5跳转到快应用[1] 判断当前环境是否支持组件跳转快应用[2] h5跳转到快应用(1)deeplink方式进行跳转(推荐)(2)h5点击组件(接收参数存在问题)(3)url配置跳转(官方不推荐) 问题-浏览器问题 web组件h5页面嵌入快应用快应用发送消息到h5页面h5页面接收快应用发送的消…

网络攻击(一)--安全渗透简介

1. 安全渗透概述 目标 了解渗透测试的基本概念了解渗透测试从业人员的注意事项 1.1. 写在前面的话 在了解渗透测试之前,我们先看看,信息安全相关的法律是怎么样的 中华人民共和国网络安全法 《中华人民共和国网络安全法》由全国人民代表大会常务委员会…

Linux--操作系统

1. 常见的操作系统 Windowsmac OSLinuxiOSAndroid 2. 操作系统的定义 操作系统直接运行在计算机上的系统软件, 它是控制硬件和支持软件运行的计算机程序。 3. 操作系统的作用 向下控制硬件向上支持软件的运行,具有承上启下的作用。 4.总结 操作系统…

ansible中的角色

1.理解roles在企业中的定位及写法 查看创建目录结构 ansible - galaxy list 指定新的位置 vim ansible.cfg roles_path ~/.ansible/roles 建立项目 cd roles/ ansible-galaxy init vsftpd tree vsftpd/ 编辑任务执行(顺序)文件 vim vsftpd/tas…

Qt开发 之 Qt5各版本情况分析

文章目录 1、简介2、Qt5 版本归纳3、下载地址3.1、典型版本3.1.1、Qt5.0.03.1.2、Qt5.9.93.1.3、Qt5.12.12 3.2、当前Qt5最新版本 1、简介 Qt6 出生刚刚好一年的时间,已经出到6.6版本,带来了许多的新特性和改进。今天刚刚好抽空总结下陪伴 我工作这么长…

第三届iEnglish全国ETP大赛16强落位 诠释教育游戏价值

10日,与北方骤降的温度形成鲜明对比,以“玩转英语,用iEnglish”为主题的国内首个教育游戏活动第三届iEnglish全国ETP(English Through Pictures)大赛总决赛小组赛热火朝天的进行。随着“云帆沧海队”搭上末班车,本届活动16强全部产生,接下来的三个周末他们将向年度总冠军发起最…

Linux(20):软件安装:原始码与 Tarball

开放源码的软件安装与升级 在Windows系统上面的软件都是一模一样的,【无法修改该软件的源代码】,因此,万一想要增加或者减少该软件的某些功能时,无能为力。。。 Linux 上面的软件几乎都是经过 GPL 的授权,所以每个软件…

数据结构之选择排序

目录 直接选择排序 选择排序的时间复杂度 堆排序 向上调整算法 向下调整算法 向上调整算法建立堆 向下调整算法建立堆 堆排序整体代码 堆排序的时间复杂度 直接选择排序 在之前讲插入排序时,我们讲了这样的一个应用场景,我们在斗地主摸牌时&…

银行数据分析进阶篇:银行外呼业务数据分析与客户精准营销优化研究

上次和大家分享了“信用卡全生命周期分析”的案例,不少朋友都有正向的反馈,今天继续和大家分享我之前看到的银行数据分析的案例,这个案例结构清晰,内容详细,相信朋友们能很快掌握! 01 需求痛点 我们先来了…

计算机网络:应用层(一)

我最近开了几个专栏,诚信互三! > |||《算法专栏》::刷题教程来自网站《代码随想录》。||| > |||《C专栏》::记录我学习C的经历,看完你一定会有收获。||| > |||《Linux专栏》&#xff1…

LLM之RAG理论(一)| CoN:腾讯提出笔记链(CHAIN-OF-NOTE)来提高检索增强模型(RAG)的透明度

论文地址:https://arxiv.org/pdf/2311.09210.pdf 检索增强语言模型(RALM)已成为自然语言处理中一种强大的新范式。通过将大型预训练语言模型与外部知识检索相结合,RALM可以减少事实错误和幻觉,同时注入最新知识。然而&…

【Spring教程17】Spring框架实战:实例详解解读AOP通知类型的使用

欢迎大家回到《Java教程之Spring30天快速入门》,本教程所有示例均基于Maven实现,如果您对Maven还很陌生,请移步本人的博文《如何在windows11下安装Maven并配置以及 IDEA配置Maven环境》,本文的上一篇为《AOP配置管理中AOP切入点表…

现代雷达车载应用——第2章 汽车雷达系统原理 2.2节

经典著作,值得一读,英文原版下载链接【免费】ModernRadarforAutomotiveApplications资源-CSDN文库。 2.2 汽车雷达架构 从顶层来看,基本的汽车雷达由发射器,接收器和天线组成。图2.2给出了一种简化的单通道连续波雷达结构[2]。这…

[湖湘杯 2021 final]MultistaeAgency

文章目录 题目是给了源码,我们先来看web的main.go package mainimport ("bytes""crypto/md5""encoding/json""fmt""io""io/ioutil""log""math/rand""net/http""o…

存储成本降71%,怪兽充电历史库迁移OceanBase

怪兽充电作为共享充电宝第一股,业务增长迅速,以至于业务架构不停地增加组件。在验证 OceanBase 可以简化架构并带来更大的业务价值后,首次尝试在历史库中使用 OceanBase 替代 MySQL,存储成本降低 71%。本文为怪兽充电运维架构部王…

odoo自定义提示性校验

背景: 在odoo16的原生的代码里,可以给按钮添加一个 confirm属性,从而达到 提示性校验的效果。 问题: 这个属性加了之后一定会弹出提示性校验的对话框,于是如何根据我们的实际业务,从后端返回提示性信息,…

ubuntu 20.04.6 server 服务器 下载与安装(配置静态IP)

下载地址:https://releases.ubuntu.com/20.04.6/ubuntu-20.04.6-live-server-amd64.iso 第一步: 准备U盘,使用软碟通将下载好的镜像写入到U盘中 软碟通网址:https://www.cn.ultraiso.net/xiazai.html 点击:文件 ->…

matlab 最小二乘拟合空间直线(方法三)

目录 一、算法原理1、算法过程2、参考文献二、代码实现三、结果展示四、相关链接博客长期更新,GPT与爬虫自重,你也未必能爬到最新版本。 一、算法原理 1、算法过程 空间直线的点向式方程为: