当前位置: 首页 > news >正文

闲庭信步使用SV搭建图像测试平台:第三十一课——基于神经网络的手写数字识别

  (本系列只需要modelsim即可完成数字图像的处理,每个工程都搭建了全自动化的仿真环境,只需要双击文件就可以完成整个的仿真,大大降低了初学者的门槛!!!!如需要该系列的工程文件请关注知识星球:成工fpga,关注即送200GB学习资料,链接已置顶!)

本篇系列教程内容的最后一课,当然按照成工的习惯,还会有一篇结篇语,用来总结过去,展望未来。

最后一篇的内容,那我们就来实现一下大家比较感兴趣的神经网络,用神经网络来实现手写数字的识别,具体的原理成工就不讲了,大家可以关注一下B站上开源骚客的基于ZYNQ实现CNN手写数字识别。成工没有做模型的训练,直接用训练好的参数来实现CNN的模型。

一采用的CNN模型如下所示,各层的含义和数据量大家可以自行理解一下。成工想说的是,神经网络并不是多难,都是很成熟的,但是运算量很大,就是一直在进行乘加运算。比如Conv层有30个5x5的卷积核,而我们前面讲的插值,均值,增强,sobel等算子也不过都是1个3x3的算子,就算扩展到5x5,一个神经网络的Conv层的运算量至少增大30倍,因为Conv层的参数都是无规律的小数,并不像前面可以进行一些巧算。

手写数字都是28x28像素的,经过Conv层后去掉了两圈0(由于是模板是5x5,如果是3x3那就是去掉一圈零),图像大小变成了24x24,但是由于有30个卷积核,所以Conv层计算完毕后图像的大小是24x24x30。

激活Pelu层不改变图像节点数据的尺寸,激活函数很多,这个使用最简单的,数据小于0那就取0,大于0的数据不变。

Pooling层尺寸是2x2,步进是2,经过Pooling层后图像数据的大小是12x12x30=4320。

第一个全连接层Affine输出100个节点数据,也就是说Pooling层的4320个节点数据都要和这100个节点分别连接进行乘加运算,所以光参数量是需要4320*100=432000个。如果说Conv层的计算已经有些大了,全列举层的计算就是非常夸张了。不过这才是一个简单的手写数字识别的训练好的模型,现在动不动亿万参数的大模型,需要成百上千张GPU卡训练几个月,花费都在百万,千万甚至上亿级别的。

第二个全连接层Affine输出10个节点数据,那就是把上一层的100个节点和当前的10个节点全连接,需要的参数是100*10=1000个,这个计算量还可以。为什么最终是10个节点数据?因为数字是0-9共10个,所以10个输出就足够了。如果是识别猫的模型,输出两个节点就可以了,一个表示是猫,另一个表示不是猫。

成工写了CNN相关的功能模块,单独放在了img_cnn_pkt的包中,主要包括set_image_param,conv_2d,relu,pool_conv,full_connect,pool_full,predit_out,normalize等几个task。也不复杂,主要是要考虑数字的扩展和缩放,因为参数都是先放大后取的整数位。

网上有相关的数据集和测试集,这个成工也放在工程里面了,不过是jpg格式的,需要手动转换成bmp格式。

img文件夹多了一个文件夹,中src放置测试图片,dst存放结果的图片,parameter存放参数文件,show_img存放了0-9十张数字图片,当CNN识别的结果是几就将对应的图片存储到dst文件夹。

如下是参数文件夹下的文件,可见是全连接的w1参数最多。

如下是show_img文件夹下的图片。

仿真文件tb_image_sim如下,首先设置参数,从参数文件中读取相关的参数。因为图片都是黑白的,也就是RGB三通道数据都相同,所以直接取一个通道的数据进行CNN即可。101行是把图像上下翻转,因为模型训练是是采用的图片从左上到右下进行输入,而我们处理的bmp图片是从左下到右上进行输入,所以要先翻转。然后进行CNN的各步操作,最后得出预测的数据。109-110行保存了卷积和激活后的30张24x24的中间数据,可以很直接的看一下中间的结果。最后的113-118行就是实现了根据预测的数据将show_img文件夹下面的图片保存到dst文件夹。

假如我们对src文件夹下的test_590_3.bmp这种图片进行识别。

我们双击sim文件夹下的top_tb.bat文件,完成系统的自动化仿真。

仿真完毕后,可以看到modelsim有如下的打印信息,也就是说识别出来了数字3。

再看看img文件夹下的dst文件夹,除了将数字3的图片保存到改文件夹,还生成了卷积后的30张中间结果的图片。

当然模型的识别准确率也不是100%,比如模型就会把src中的test_18_3.bmp图片上的数据识别成8,当然准确率不是本文的重点,重点是模型的实现过程。

http://www.lryc.cn/news/580317.html

相关文章:

  • Ubuntu基础(监控重启和查找程序)
  • 模块三:现代C++工程实践(4篇)第一篇《C++模块化开发:从Header-only到CMake模块化》
  • Redis的编译安装
  • LabVIEW电阻率测试
  • LinkedList剖析
  • Kafka消息积压全面解决方案:从应急处理到系统优化
  • idea的使用小技巧,个人向
  • 类图+案例+代码详解:软件设计模式----适配器模式
  • 【电赛培训】运算放大器、滤波器
  • 使用 C++/OpenCV 和 MFCC 构建双重认证智能门禁系统
  • 堆的简单介绍
  • 智链万物:人工智能驱动的产业智能化革命
  • 使用 C++/Faiss 加速海量 MFCC 特征的相似性搜索
  • Python(28)Python循环语句指南:从语法糖到CPython字节码的底层探秘
  • 解决el-select数据类型相同但是显示数字的问题
  • 【Project】基于kafka的高可用分布式日志监控与告警系统
  • C#扩展方法全解析:给现有类型插上翅膀的魔法
  • CMake基础:条件判断详解
  • 探索 Ubuntu 上 MongoDB 的安装过程
  • [Cyclone] 哈希算法 | SIMD优化哈希计算 | 大数运算 (Int类)
  • 【大模型】到底什么是Function Calling和MCP,以及和ReAct推理的关系是什么?
  • 若 VSCode 添加到文件夹内右键菜单中显示
  • 03_性能优化:让软件呼吸更顺畅
  • ABB焊接机器人智能节气仪
  • App爬虫工具篇-appium配置
  • AWS WebRTC:通过shell分析viewer端日志文件
  • 查看linux中steam游戏的兼容性
  • 权电阻网络DAC实现电压输出型数模转换Multisim电路仿真——硬件工程师笔记
  • C++构造和折构函数详解,超详细!
  • Linux基本命令篇 —— uname命令