首页 > 其他分享 >基于神经网络的手写数字识别及其ZYNQ实现

基于神经网络的手写数字识别及其ZYNQ实现

时间:2024-08-05 16:24:18浏览次数:9  
标签:仿真 FPGA py Vivado 神经网络 ZYNQ Anaconda 手写

        基于MNIST数据集的手写数字识别是神经网络(Neural Network)的经典应用。

       本文将讨论一种名为“ZYNET”的全连接神经网络框架,它可以自动生成针对FPGA的硬件实现架构。我们以手写数字识别为例,在ZYNQ平台上对该架构进行验证。本章包括以下几个部分:

1环境配置

2下载工程文件

3训练神经网络

4 FPGA实现

5 FPGA仿真

6 ZYNQ开发板验证

1环境配置安装Anaconda

         Anaconda是一个功能强大的Python开发环境,主要用于科学计算、数据分析和机器学习等领域。它包含了各种用于数学计算、数据绘图的扩展包,并提供了交互式的开发工具(Jupyter Notebook)。

       我们需要下载并安装Anaconda,通过它我们可以非常方便地安装各种深度学习框架,如知名的TensorFlow、PyTorch,以及本文中所使用的ZYNET。

首先进入Anaconda官网(https://www.anaconda.com/download),找到对应操作系统的Anaconda安装包进行下载。

图 1 点击跳过注册,进入下载界面

图 2 下载Windows版本

图 3 下载完成后双击安装包进行安装

Anaconda安装过程如下图所示:


图 4 Anaconda安装完成

安装ZYNET 

         在系统的“开始”菜单中找到“Anaconda3 (64-bit)”并展开,在“Anaconda Prompt”上右击,选择“以管理员身份运行”。

图 5 以管理员身份运行Anaconda Promp

在弹出的命令窗口中,输入指令“python --version”,查看当前Python的版本:

图 6 在命令窗输入指令查看python版本

接下来输入指令“pip install zynet”,安装“基于ZYNQ的神经网络库”,此过程需要保持联网:

图 7 安装zynet

2 下载工程文件

        在作者vipinkmenon的GitHub主页下载配套的工程文件,网址vipinkmenon (Vipin K) · GitHub,工程名为neuralNetwork:

图 8 vipinkmenon的GitHub主页

图 9 下载neuralNetwork工程文件

将下载的工程文件压缩包解压出来,路径中不要包含中文或者特殊字符:

图 10 解压工程文件

在解压后的工程目录中,打开并查看“Tut-6”文件夹中的内容:

图 11 解压后的工程目录

       将“Tut-6”文件夹中的全部内容拷贝到一个新建的文件夹中,文件夹的名称由英文字母和下划线组成,如“DaLei_FPGA”:

图 12 拷贝Tut-6文件夹中的内容

3 训练神经网络

使用Notepad++打开上图中名为“trainNN.py”的文件:

图 13 trainNN.py中的网络结构

       在代码的第6行,修改网络的结构为“net = network2.Network([784, 30, 20, 10])”,然后保存,如下图所示:

 图14 修改后的网络结构 

      在Anaconda Prompt窗口通过cd指令将目录切换至刚刚新建的文件夹,我这里的目录为“F:\task\ZYNQ_NN\DaLei_FPGA”:

图 15 切换Anaconda Prompt窗口的工作目录

输入指令“python trainNN.py”,对修改后的网络进行训练:

图 16 训练修改后的神经网络

     网络的训练将迭代30次,该迭代次数是由图 14中trainNN.py文件的第9行——“net.SGD(training_data, 30, 10, 0.1”中的第一个数字所指定的。

在前面几次迭代过程中,神经网络的准确率将不断提高,如下图所示:

图 17 神经网络的训练过程

神经网络训练结束之后,可以看到最终的准确率,我这里是96.47%:

图 18 训练过程迭代30次结束

 在训练结束后,网络的“权重”和“偏置”数据会输出到名为“WeigntsAndBiases.txt”文件中:

图 19 网络的权重和偏置信息

       需要注意的是,在上面的训练过程中,神经网络所采用的激活函数为ReLu。接下来,我们将使用Sigmod作为激活函数,重新进行网络的训练。

       使用Notepad++打开上图中名为“network2.py”的文件,代码的第326行用于指定网络所使用的激活函数,而第331行是它的反函数。我们需要注释掉代码的329行和334行,同时取消对328行和333行的注释,即使用Sigmoid代替Relu作为激活函数。

图 20 修改前,使用ReLu激活函数

按照下图箭头所指示的位置进行修改,设置激活函数的输出为Sigmoid,并保存:

图 21 修改后,使用Sigmoid激活函数

接下来,在Anaconda Prompt窗口再次输入指令“python trainNN.py”,重新对网络进行训练:

图 22 重新进行训练

激活函数选择Sigmoid后重新训练,迭代30次之后网络的准确度为96.75%

图 23 激活函数设置为Sigmoid的网络训练结果

在重新训练之后,网络相应的权重和偏置文件也会更新:

图 24 网络重新训练后,权重和偏置文件会更新

 4 FPGA实现 

拷贝neuralNetwork-master\Tut-8目录中的“mnistZyNet.py”文件至当前文件夹(DaLei_FPGA):

图 25 拷贝mnistZyNet.py

使用Notepad++查看mnistZyNet.py文件:

图 26 ZyNet模型

       上图红色方框中描述的网络结构与图 14 修改后的网络结构相同。需要注意的是,在硬件实现的过程中,网络的最后一层没有使用常见的“softmax”,而是替换成了“hardmax”,如代码中的第11行所示。该模块通过比较各个分类结果的评分大小,输出评分最高的类别,从而避免在FPGA中实现softmax的复杂运算。

       在代码第20行,红色箭头所指示的dataWidth用于指定输入数据的位宽,由整数部分和小数部分组成,其中整数部分的位宽由inputIntSize所指定(包含符号位)。

在Anaconda Prompt窗口输入指令“python mnistZyNet.py”,执行该文件:

图 27 执行mnistZyNet,生成FPGA实现代码

      以上指令会生成神经网络所对应的FPGA实现代码,同时解析图 24中的权重和偏置文件WeigntsAndBiases.txt,生成后缀为.mif的ROM初始化文件。

       在解析网络权重的过程中,窗口中会打印出权重数据整数部分所对应的bit位宽,即上图中第一个红色箭头所指的数字4。该数字被用来设置图 26中第20行的变量weightIntSize。

       上面的指令同样会创建一个Vivado工程,在工程中完成整个神经网络的硬件实现架构。该过程需要在系统变量中添加Vivado的路径,否则会打印信息:‘Vivado’不是内部或外部命令, 也不是可运行的程序

在系统变量中添加Vivado的过程如下图所示:

图 28 在系统变量中添加Vivado

       环境变量添加完成后,重启Anaconda Prompt,并将目录切换至“DaLei_FPGA”,最后重新执行指令“python mnistZyNet.py”。

       接下来Vivado会启动,并创建相应的工程,在该工程中完成神经网络的RTL实现、封装IP核并创建Block Design,如下图所示:

图 29 创建Vivado工程

        工程创建完毕后Vivado会自动退出,然后在当前文件夹中会新增一个名为“myProject1”的工程文件夹。同时还新增了一个名为“src”的文件夹,其中包含了神经网络的HDL代码、mif文件以及tb文件

图 30 自动创建的Vivado工程

在名为“myProject1”的文件夹中双击打开后缀为.xpr的Vivado工程:

图 31 打开Vivado工程

        在打开的Vivado工程中可以看到顶层模块是一个名为“zyNet”的神经网络,下面例化了三个名为Layer_1、Layer_2、Layer_3的全连接网络层,以及一个名为maxFinder的“hardmax”层:

图 32 创建的Vivado工程

在上面的Vivado工程中还包含了一个名为“myBlock2”的设计,双击打开后如下图所示:

图 33 基于ZYNQ的Block Design

       图中是一个基于ZYNQ平台的Block Design,除了前面所实现的zyNet神经网络,还添加了一个AXI DMA。ZYNQ的PS端可以通过DMA输出大小为28*28的MNIST手写数据集,zyNet神经网络在识别结束后输出中断信号,通知PS端从AXI-Lite接口读取手写数字的识别结果。

ZYNET最终实现的神经网络模块如下图所示:

图 34 最终实现的神经网络模块

       在zyNet模块中,AXI-Lite接口(s_axi)除了用来读取最终的识别结果,还可以用来动态配置神经网络的权重和偏置。这样就可以在网络重新训练之后,通过PS端非常方便地更新网络的权重和偏置,而不需要重新编译硬件(生成bitstream)。前提是在mnistZyNet.py文件的第14行中(图 26),需要将pretrained='Yes'修改为pretrained='No',否则权重信息将以mif文件的形式存储在PL中的ROM里,无法通过PS进行动态配置。

5 FPGA仿真

      在Vivado左侧的导航栏里点击“Run Simulation”,然后选择“Run Behavioral Simulation”,如下图所示:

图 35 运行仿真

仿真运行后在控制台会提示警告信息,无法读取名为“test_data_0000.txt”的文件:

图 36 仿真过程中的警告信息

       上面的警告信息是由于仿真过程需要将MNIST数据集中的测试数据作为输入,因此需要生成测试数据。首先在Vivado中结束当前的仿真过程,然后拷贝neuralNetwork-master\Tut-8目录中的“genTestData.py”文件至当前文件夹(DaLei_FPGA):

图 37 拷贝genTestData.py

       由于DaLei_FPGA文件夹中已经存在相同名称的文件,因此在弹出的对话框中选择“替换目标中的文件”,最后在Notepad++中打开genTestData.py:

图 38 用于生成测试数据的脚本genTestData.py

       代码的第3行指定了输出测试数据的路径,即Vivado工程的仿真目录。红色箭头所标注的位置指示出测试数据的bit位宽,包含整数部分和小数部分,其中整数部分的位宽由IntSize指定(包含符号位)。测试数据通过解压名为“mnist.pkl.gz”的压缩包获得,即MNIST数据集。

       在Anaconda Prompt窗口中输入指令“python genTestData.py”,等待指令运行结束后,会在指定的路径中生成一万个测试数据,编号从“test_data_0000.txt”一直到“test_data_9999.txt”。

图 39 生成仿真过程使用的测试数据

       按照图 35中的操作过程重新运行仿真,在SIMULATION界面中,点击工具栏中的“Run All”按钮,如下图所示:

图 40 Vivado仿真界面选择Run All

       仿真过程会对MNIST数据集中的100个测试用例进行识别,并统计FPGA神经网络的识别准确率,每个测试用例的识别结果和期望结果均打印在控制台中:

图 41 仿真过程中打印的识别结果和准确率

        上图中红色箭头指示出FPGA神经网络在仿真过程中的识别准确率为99%,这是针对前一百个测试用例的统计结果。如果需要修改仿真过程中测试用例的数目,可以结束仿真过程,然后在Simulation Sources中双击打开top_sim.v,在代码的第24行修改名为MaxTestSamples的变量:

图 42 指定仿真过程中测试数据的数目

6 ZYNQ开发板验证

在“征服者”ZYNQ开发板上搭建测试环境:

图 43 在征服者ZYNQ开发板上验证

       使用OV5640摄像头采集图像,对手写数字进行识别,并将识别的结果打印在HDMI显示器的左上角。验证结果如下图所示:

图 44 ZYNET手写数字识别结果

最后给出整个设计完整的Block Design架构图:

图 45 在ZYNQ上实现手写数字识别Block Design设计

       该设计的视频讲解会在b站【第二期——ZYNQ图像处理】课程中更新,大家有兴趣可以关注磊哥的b站账号(大磊FPGA)。

标签:仿真,FPGA,py,Vivado,神经网络,ZYNQ,Anaconda,手写
From: https://blog.csdn.net/sunshine_atk/article/details/140923471

相关文章

  • 【高录用!Fellow 主讲!SPIE独立出版 | 往届均已EI检索】第四届先进算法与神经网络国际学
    第四届先进算法与神经网络国际学术会议(AANN2024)由中国石油大学(华东)及山东省可信人工智能生态数据开放创新应用实验室联合主办,会议将于2024年8月9-11日在中国·青岛召开。AANN2024将围绕“先进算法与神经网络”的最新研究领域,为来自国内外高等院校、科学研究所、企事业......
  • 卷积神经网络 - 基本卷积函数的变体篇
    序言在深度学习和卷积神经网络(CNN\text{CNN}CNN)的广阔领域中,基本卷积函数是构建网络结构的基础,它们通过滑动窗口的方式对输入数据进行特征提取。然而,随着应用场景和数据......
  • Pytorch笔记|小土堆|P16-22|神经网络基本骨架、卷积层、池化层、非线性激活层、归一化
    torch.nnContainers是神经网络骨架,含6个类,最常用的是Module——BaseclassforallNNmodulesModule所有神经网络模型(子类)都必须继承Module(父类),Module相当于给所有的神经网络提供了模板,但可进行修改官方示例:importtorch.nnasnnimporttorch.nn.functionalasFclass......
  • 翻译: 可视化深度学习神经网络一
    这是一个随意书写的28*28像素、分辨率很低的数字3但你的大脑一看见就能轻松辨识出来,我想要你好好欣赏这点人脑能够毫无障碍地辨识是非常厉害的我的意思是,这个、这个、还有这个,都能被识别为3即使前后图像的图形组成有很大差异当你看到这张3在眼中所激发的感光细......
  • 神经网络训练(二):基于残差连接的图片分类网络(进阶篇②)
    目录日常·唠嗑3基于ResNet18的优化3.1初步构思3.1.1数据预处理3.1.2批量大小3.1.3参数初始化3.1.4optimizer3.1.5学习速率3.2hyper-parameter测试3.2.1批量大小日常·唠嗑       昨天写完了神经网络训练(二):基于残差连接的图片分类......
  • 【MATLAB源码】机器视觉与图像识别技术(7)续---BP神经网络
    系列文章目录在最后面,各位同仁感兴趣可以看看!BP神经网络第一节、BP网络定义第二节、BP网络结构及其特点第三节、信息传播方式信息的正向传播:实质是计算网络的输出误差的反向传播:实质是学习过程第四节、BP网络的算法流程图及设计第五节、BP网络的局限与不足第八节、BP网络......
  • 深入探索EPSA:提升卷积神经网络性能的新式注意力模块
     原论文地址:https://arxiv.org/abs/2105.14447摘要摘要部分提出了一种新的注意力模块——金字塔分割注意力(PSA)模块,该模块通过替代ResNet瓶颈块中的3x3卷积,显著提升了模型性能。PSA模块能够作为即插即用组件,增强网络的多尺度表征能力,使EPSANet在多个计算机视觉任务上超越了......
  • 基于深度学习的适应硬件的神经网络
    基于深度学习的适应硬件的神经网络设计旨在最大限度地利用特定硬件平台的计算和存储能力,提高模型的执行效率和性能。这些硬件包括图形处理单元(GPU)、张量处理单元(TPU)、现场可编程门阵列(FPGA)和专用集成电路(ASIC)。以下是关于适应硬件的神经网络的详细介绍:1.背景和动机硬件异构......
  • PyTorch 训练自定义功能齐全的神经网络模型的详细教程
    在前面的文章中,老牛同学介绍了不少大语言模型的部署、推理和微调,也通过大模型演示了我们的日常的工作需求场景。我们通过大语言模型,实实在在的感受到了它强大的功能,同时也从中受益颇多。今天,老牛同学想和大家一起来训练一个自定义的、但是功能齐全的简单的神经网络模型。这个模型......
  • 从零手写实现 nginx,为什么不能有 java 版本的 nginx?(已完结,共 35 讲)
    前言大家好,我是老马。很高兴遇到你。作为一个java开发者,工作中一直在使用nginx。却发现一直停留在使用层面,无法深入理解。有一天我在想,为什么不能有一个java版本的nginx呢?一者是理解nginx的设计灵魂,再者java开发者用java语言的服务器不是更加自然吗。于是......