数字IC实践项目(3)—卷积神经网络加速器(开源项目)
基于FPGA的卷积神经网络算法加速
- 基于FPGA实现神经网络加速器是一种常见的硬件加速器设计方法。它利用FPGA的可编程性和并行计算能力,通过定制化的硬件结构来加速神经网络的训练和推理过程。
- 为了实现神经网络加速器,需要设计一个特定的硬件架构,能够有效地实现神经网络中的各种操作,如卷积、池化、全连接等。这个过程通常需要先对神经网络进行分析和优化,选择适合于FPGA实现的算法和数据结构。
- 与传统的CPU和GPU相比,基于FPGA的神经网络加速器具有更高的灵活性和低延迟。同时,由于FPGA的可重构性,可以根据需要重新配置硬件结构,满足不同的应用需求。
- 基于FPGA实现神经网络加速器可以提高神经网络的运行效率和处理速度,是一种非常具有潜力的硬件加速器设计方法。但是,由于硬件设计和优化的复杂性,需要具备一定的硬件设计和编程经验才能有效地实现神经网络加速
项目难度:⭐⭐⭐
项目推荐度:⭐⭐⭐
项目推荐天数:1~3天
项目简介和学习目的
该项目是一个简单的卷积神经网络硬件化实现, 没有构建对应的神经网络算法,也并没有完成下板综合测试;
其中,卷积和池化模块的构建方法可以用来实现具体的神经网络架构。
项目实践环境:
FPGA开发环境:
前仿: Modelsim SE-64 2019.2
综合: Quartus (Quartus Prime 17.1) Standard Edition
数字IC开发环境:
前仿: VCS 2016
综合:DC 2016
项目学习目的:
(1)熟练掌握项目中各文件的工程管理;
(2)熟悉Verilog HDL仿真、FPGA综合工具以及了解数字IC设计工具及流程;
(3)学习卷积神经网络的基本结构和基础原理;
(4)学习卷积、池化和激活模块的实现方法;
(5)熟练掌握Verilog语法和验证方法;
(6)熟练掌握Modelsim、VCS等开发工具。
卷积神经网络简介
卷积神经网络(Convolutional Neural Network,CNN)是一种常用的深度学习神经网络模型,其特点是可以对输入数据进行有效的卷积操作,并且具有良好的特征提取和分类能力。
相比于传统的全连接神经网络,在处理图像、语音等具有空间结构的数据时,卷积神经网络具有更好的效果。它通过卷积层、池化层、激活函数等组件构成,可以有效地从输入数据中提取出有意义的特征,并将其映射到输出层进行分类或回归。
- 卷积层是卷积神经网络的核心组建,它通过一系列的滤波器(也称为卷积核)来逐步提取出输入数据的特征信息。
- 池化层则用于减少数据的维度,并增强特征的平移不变性。
- 激活函数则用于引入非线性因素,使得整个网络更加灵活和鲁棒。
在训练过程中,卷积神经网络通常使用反向传播算法来更新权重参数,以最小化损失函数。由于深度学习网络通常需要大量的训练数据和计算资源,因此在实际应用中,常常需要借助GPU、TPU等硬件加速器来提高训练和推理效率。
卷积神经网络是一种非常有效的深度学习模型,在图像、语音、视频处理等领域广泛应用。它通过卷积、池化等操作,可以从输入数据中提取出有意义的特征,并且具有良好的分类和回归能力。
经典卷积神经网络:https://ieeexplore.ieee.org/document/517077
卷积操作:
图像卷积操作是卷积神经网络中的核心操作之一,其主要作用是从图像中提取有意义的特征信息。其原理和过程如下:
定义滤波器(卷积核):滤波器是一个小矩阵,其元素代表了卷积操作中的权重参数。滤波器的大小通常为奇数,例如 3 x 3、5 x 5 等。
将滤波器移动到输入图像上的每个位置:在每个位置上,将滤波器对应位置的元素与输入图像对应位置的像素值相乘并求和,得到输出图像上该位置的像素值。
遍历整张输入图像:重复上述操作,直到遍历整张输入图像,得到输出图像。
这个过程可以描述为一个二维离散卷积运算,公式为:
y
(
i
,
j
)
=
∑
0
M
−
1
m
∑
0
N
−
1
n
⋅
x
(
i
+
m
,
j
+
n
)
⋅
h
(
m
,
n
)
y(i,j)=\sum_{0}^{M-1}{m}\sum_{0}^{N-1}{n}\cdot x(i+m,j+n)\cdot h(m,n)
y(i,j)=0∑M−1m0∑N−1n⋅x(i+m,j+n)⋅h(m,n)
其中,
x
x
x 表示输入图像,
(
i
,
j
)
(i,j)
(i,j) 表示输出图像上的位置,
h
h
h 表示滤波器,
M
M
M 和
N
N
N 分别为滤波器的高度和宽度,
y
y
y 表示输出图像上的像素值。
需要注意的是,卷积操作可以增强图像的特征表现力。例如,在识别人脸的任务中,一个水平和垂直的边缘滤波器可以检测出眉毛和眼睛上的边缘信息,而斜向的边缘滤波器可以检测到鼻子和嘴巴边缘信息。
图像卷积操作是卷积神经网络中的核心操作之一,通过滤波器与输入图像的逐像素点乘和相加得到输出图像,并且可以提取出图像的有意义特征,从而实现对图像的有效处理。
池化操作:
最大池化:
平均池化:
池化操作是卷积神经网络中的一种用于降低特征图维度和空间
其主要目的是减少数据的维度,并增强特征的平移不变性。其原理和过程如下:
定义池化窗口大小:池化窗口是一个小矩阵,通常为 2 x 2 或 3 x 3 大小。它沿着输入特征图上的行和列移动,并在每个位置上执行池化操作。
池化操作:在每个池化窗口内,将其中所有元素取平均值(平均池化)或最大值(最大池化),得到输出特征图上该位置的像素值。
遍历整张输入特征图:重复上述操作,直到遍历整张输入特征图,得到输出特征图。
最大池化操作表示取池化窗口内的最大值,而平均池化则是取平均值。
需要注意的是,池化操作可以减少特征图的大小,并且增强特征的平移不变性和局部不变性。例如,在图像分类任务中,池化操作可以将输入图像中的一些平移和旋转变化所带来的影响降低,从而增强模型的鲁棒性。
总之,池化操作是卷积神经网络中的一种核心操作,通过在池化窗口内进行统计运算,得到输出特征图上的像素值。它可以减少特征图的大小,并增强特
激活操作:
(1)Sigmoid函数
(2)Tanh/双曲正切激活函数
(3)ReLU激活函数
(4)Leaky ReLU激活函数
神经网络激活函数是指位于神经网络中每个节点的非线性函数,其作用是将节点的输出转换为非线性形式。激活函数的运算过程如下:
神经网络中的每个节点都包含一个权重向量
w
w
w 和一个偏置量
b
b
b,输入向量
x
x
x 通过这些参数与该节点相连。
将上述直接输出的结果传递给激活函数 f f f,得到最终的节点输出 y = f ( w T x + b ) y=f(w^Tx+b) y=f(wTx+b)。
神经网络的后续节点则使用前一层节点的输出作为自己的输入,如此循环进行,直到最终输出层产生预测结果。
激活函数的非线性特性使神经网络具有了更强的表达能力和学习能力,因为线性变换无法表达复杂的非线性关系。常见的激活函数有以下几种:
- Sigmoid 函数: f ( z ) = 1 1 + e − z f(z)=\frac{1}{1+e^{-z}} f(z)=1+e−z1,将输入映射到 0-1 之间,常用于二分类问题。
- Tanh 函数: f ( z ) = e z − e − z e z + e − z f(z)=\frac{e^{z}-e^{-z}}{e^{z}+e^{-z}} f(z)=ez+e−zez−e−z,将输入映射到 -1~1 之间,比Sigmoid 函数具有更广的有效区域。
- ReLU 函数: f ( z ) = max ( 0 , z ) f(z)=\max(0,z) f(z)=max(0,z),将输入映射为非负值,常用于深度神经网络中,因其能够有效减少梯度消失现象。
- Leaky ReLU 函数:
f
(
z
)
=
{
z
z
≥
0
0.01
z
z
<
0
f(z)=\begin{cases}z & z\geq 0\\0.01z & z<0\end{cases}
f(z)={z0.01zz≥0z<0,在 ReLU 函数的基础上,将负数部分乘以一个小的斜率系数,以避免 ReLU 函数的神经元死亡问题。
神经网络激活函数通过对节点输出进行非线性变换,使神经网络具有了更强的表达和学习能力,并且不同的激活函数可以适应不同的任务场景。
完整项目框图
完整项目说明:
是一个集成卷积、池化和激活函数的神经网络加速器架构,代码层次清晰,完成功能验证。
卷积模块
模块图:
使用9个MAC模块完成乘法和累加,并串联起来。加法器和乘法器位宽均按照最大位设计,即满足3*3卷积计算总和后需要的位宽。
工作原理:
gif图源于thedatabus.io网站。
较好展示了卷积模块的工作流程。
MAC链会将上次计算的结果依次传递给下阶段的MAC模块,等待输入数据完成计算后,整个模块也就完成了卷积操作。
备注:
卷积验证采用的数据,卷积核、输入和卷积计算结果如下。
仿真波形:
当conv_vld有效时对应的输出结果为258,294,402和438。
符合上述软件计算结果。每个周期输出一个卷积结果。
池化模块
模块图:
工作原理:
池化模块支持最大池化和平均池化。
最大池化模块包含一个比较器、最大值寄存器、移位寄存器以及控制逻辑。
平均池化模块工作时,会先经过加法器完成累加,而后完成平均计算。
仿真波形:
在顶层模块中使用平均池化,池化前44,池化后22。
激活模块
模块图:
工作原理:
激活模块包含了Relu和Tanh两种激活函数,可供选择,为了节省资源,可以选择使用Relu激活函数,Relu函数本质是一个比较器,大于0保持,小于0则为0。
Tanh激活模块采用了查找表的方式,这是实现非线性激活中相对较节省资源的操作方式。
仿真波形:
Relu激活函数,正数保持原值,复数输出为0。
VCS仿真&DC综合结果
VCS仿真结果
DC综合结果
dc_shell -topo
面积报告:
功耗报告:
layout window (standard cell):
由于部分模块没有clk对应的物理端口,这里只单独列举卷积模块的layout。
Bug&Debug
值得注意的地方是,整个开源项目侧重于卷积、池化以及激活等模块的电路设计,并没有完成一个实际 的神经网络搭建。不过整个项目采用结构化设计,层次分明,也完成了功能验证。
注意:
个人觉得,整个开源项目中最出彩的部分在于卷积模块的设计,MAC链加上移位寄存器,对于时序要求较高的设计可以采用类似的设计完成。
总结
卷积神经网络是机器学习中广泛使用的一种深度学习模型。由于模型的复杂性和计算量,通常需要较长的训练时间和大量的计算资源。为了提高卷积神经网络的训练和应用速度,人们提出了卷积神经网络加速器的硬件实现。
- 卷积模块是卷积神经网络中最常用的模块,它通过卷积核对输入数据进行卷积运算,生成新的特征图。对于卷积模块的加速,可以通过并行化和局部缓存等优化手段来减少计算时间。
- 池化模块是卷积神经网络中的另一个重要模块,它用于减小特征图的空间维度,同时保留特征的重要性。池化操作通常使用最大值或均值池化方法,而池化模块的加速可以通过使用特定的硬件来实现。
- 激活模块是卷积神经网络中的非线性函数,用于增强模型的非线性表示能力。常见的激活函数包括ReLU、sigmoid和tanh等。激活模块可以通过使用特定的硬件电路实现,从而加速模型的推断速度。
卷积神经网络加速器的硬件实现对于提高模型的应用速度至关重要,并且对卷积、池化和激活模块进行硬件优化可以有效地提高模型的计算性能。
项目地址
https://github.com/thedatabusdotio/fpga-ml-accelerator
参考链接
[1] https://cs231n.github.io/convolutional-networks/#conv
[2] https://ieeexplore.ieee.org/document/517077
[3]https://www.freesion.com/article/5936434427/
[4]https://mp.weixin.qq.com/s?__biz=MzIwNDY0MjYzOA==&mid=2247501777&idx=1&sn=e9fa3839e90a62de478e101201a8a6ad&chksm=973f87f0a0480ee6e7abe75803a7ae3ff6e83b382f716b0d7614cac265c8f0b262a379ec3aa5&scene=27