1 BNN Net
BNN(“二值化神经网络”),即Bengio于2016年发表的文章:《Binarized Neural Networks: Training Neural Networks with Weights and Activations Constrained to +1 or −1》。通过“二值化”操作,使模型的参数占用更小的存储空间(内存消耗理论上减少为原来的1/32倍,从float32到1bit);同时利用位操作来代替网络中的乘加运算,大大降低了运算时间。
“二值化”是一种1位的量化,其数据只有两个可能的值,即-1(0)或+1,使用“二值化”操作进行压缩后,网络中的权重和激活都可以用1位表示,而不会占用太多内存。此外,通过二值化,网络可以使用轻量级的XNOR位运算代替繁重的浮点乘加运算,相比于“非二值化”的网络,将大量的数学运算变成了位操作,这样就节省了大量的空间和前向传播的时间,使神经网络的应用门槛变得更低。
由于深度模型具有多层结构和数百万个参数,因此深层CNN具有很强的学习能力,通常具有令人满意的性能。例如,VGG-16网络包含大约1.4亿个32位浮点参数,对于ImageNet数据集上的图像分类任务,可以达到92.7%的Top-5测试准确率。整个网络需要占用500M字节以上的存储空间,并再一次推理过程中执行 1.6x1010次浮点算术运算。这使得深层的卷积神经网络严重依赖于GPU等高性能硬件,而在实际应用中,通常只有计算资源有限的设备可用,如移动电话和嵌入式设备。以基于FPGA的嵌入式设备为例,通常该类设备只有数千个计算单元,远远不能处理常见深度模型中的数百万次浮点运算,复杂的模型与有限的计算资源之间存在着严重的矛盾。
尽管目前涌现了大量用于深度学习的专用硬件,这些硬件提供了高效的矢量运算操作以实现正向推理中的快速卷积,但繁重的计算和存储仍然不可避免地限制了深度卷积神经网络的实际应用。因此出现了大量的网络压缩的相关研究。
在现有的网络压缩技术中,基于量化的技术是一种很有潜力且十分高效的解决方案,与浮点模型相比,量化模型可以通过以非常低的精度表示网络权重来压缩、加速原始网络。沿此方向,最极端的量化是二值化。
BNN研究对象是前馈网络。
前馈模型(卷积可以看成是一种特殊的全连接)可以用如下公式表示:
其中,xk为第k层的输入,Wk为第k层的权值矩阵,σ(⋅)为非线性激活函数。 对于二值化权值和激活,首先,我们定义取符号操作:
在 BNN中,网络权值为 +1 或 -1,即可以用 1bit 表示,这一点与 BinaryConnect 相同。更进一步,BinaryNet 使用了输出为二值的激活函数,即:
这样,除了第一层的输入为浮点数或多位定点数外,其他各层的输入都为 1 bit。项目中对此处做了改进,在精度允许的情况下,将第一层同样做二值化处理。
1.1 网络结构
(1)含有三层卷积层,7.2节中使用的为该网络,网络结构如下所示:
其中输入层为77,三个卷积层输出通道分别为16,23和2,激活层为Hardtanh。
(2)含有五层卷积层,该节使用的为此网络,网络结构如下所示:
其中输入层为2828,五个卷积岑输出通道分别为4、8、16、32、2,激活层为Hardtanh。
1.2 实验目的
在口罩判定的分类任务中验证BNN网络的性能。
1.3 实验环境
操作系统:Ubuntu18.04
其他:AI004, Python 3.6.8,PyTorch 1.1.0,GTX 1080ti
数据集:CelebA,RMFD
1.4 实验步骤
Step 0:打开终端,进入项目根目录
$ cd BinaryNet.pytorch
项目结构如下所示:
Step 1:输入命令开始训练
$ python main_mask_prune_v1.py
训练过程如下图所示:
训练结束后,权重自动保存在ckp文件目录下,如下图所示:
Step 2:预测图片
$ python predict_prune_v1.py
结果如下图所示:
预测结果自动保存在work/result目录下,如图所示:
Step 3:输出FM文件
输出满足硬件需求的FM数据文件
$ python input_fm.py
在当前目录下会生成input.fm.bin文件,该文件直接供硬件使用。
2 单元阵列
2.1 实验目的
基于Anlogic FPGA PA1芯片完成一个低比特DNN算法实现设计,该设计用到的LUT单元阵列容量不低于100k逻辑单元。
2.2 实验环境
(1)生成Verilog文件:
操作系统:Ubuntu18.04
其他:AI004, Python 3.6.8,PyTorch 1.1.0,GTX 1080ti
数据集:CelebA,RMFD
使用网络:BNN Net
(2)生成位流文件:
操作系统::Win10(64位),
工具:TD,iverilog,GTKWave
2.3 实验步骤
(1)结合BNN Net生成Verilog文件
BNN Net详述见7.5.4节,这里采用了三层卷积的网络结构。其中其中输入层为14*14,共四层卷积层,卷积层数分别为8、16、23、2,激活层为Hardtanh。
Step0:进入项目根目录,并查看项目结构
$ cd /AIHOME/bwu/workspace_temp/project/BinaryNet.pytorch2
项目结构如下所示:
Step1:训练网络
$ cd train
$ python main_mask_14.py
训练过程如图所示:
训练结束后,权重自动保存在ckp/ckp-14文件目录下,如图所示:
Step2:推断
$ cd …/
$ python predict.py
过程如下图所示:
预测结果自动保存在work/result目录下,如下图所示:
Step3:生成Verilog文件,输出数据网表
为满足硬件仿真调试需求,需要将训练后的权重文件以及卷积后的特征图逐层解析,并且映射成测试网表,形成硬件描述语言。流程图如下:
其中,对每一层的参数以及特征图变量的映射规则如下:
P0000代表当前层输入特征,P后面的四个变量从左至右分别代表层名,坐标x,坐标y,通道c。
W00000代表当前层的权重参数,W后的五个变量从左至右分别代表层名,输出batch,坐标x,坐标y,输入通道c。
c00000代表一个卷积单元的计算结果,,每个卷积单元为9*9大小,即分别有9个权重和9个特征点乘累加,c后的五个变量从左至右分别代表层名,输入通道c,坐标x,坐标y,输出batch。
C0000代表卷积单元计算结果的通道和,即下一层第一个batch的最终结果,C后的四个变量从左至右分别代表层名,坐标x,坐标y,输入通道c。
A0000代表经过激活后的结果,A后的四个变量从左至右分别代表层名,坐标x,坐标y,输入通道c。
提取网络每层的权重文件及特征图文件
$ cd extract
$ python extract_14.py
输出结果如下所示:
每层的权重参数和特征图数据分别保存在当前目录新产生的extract_out/param_14和extract_out/fm_14文件下。
加载权重及特征图文件,生成硬件描述语言文件,输出卷积过程的数据网表。
$ cd …/dump_net_list
$ python test_unit_layer_all4.py
生成的test_unit_layer14.v文件存放在当前目录新产生的test_unit文件夹下。
经过简单修改后即可用于实现低比特DNN算法实现,修改后的源文件为BNN.v
(2)通过Verilog文件实现低比特DNN算法
Step1:新建工程(TD)
>>> 双击打开TD软件
>>> 选择“Project” , “New Project”
此时会弹出新项目对话框。
>>> 指定所创建项目的存储路径并输入项目名称(英文),例如DNN_TEST
>>> 选择“Device Family” ==> PA1。
>>> 选择“Device Name” ==> PA1L120SFG676C。
>>> 选择“OK”。
。。。。。。
2.4 实验结果
Step0:资源使用情况分析
>>>在Console中写TCL语句:report_area -file *.area,可以在打印的log中查看slice的信息,利用率为98.03%如下图:
本芯片每一个slice可配置成1个独立lut6,业界所说的lut逻辑单元一般以lut4为标准,PA1芯片的lut6电路等效1.8个标准lut4电路。本设计等效于125051个逻辑单元,已超过100k的逻辑单元用量,达到实验目标。
Step1:仿真结果分析
在上述具体仿真实验步骤中已经可以看到仿真的波形,可以看到P_data_valid有效(高有效)的时候,P_data_0的数值是0,P_data_1的数值是1,此口罩识别网络最后是根据最后得到的这两个数值来判断图片的人是否戴口罩的,当第二个数值为1第一个数值是0那么此人就是戴口罩的,反之就是未戴口罩(按照训练数据集的标注中这两个数值只有可能是0和1或者1和0)。因为本设计是将一个戴口罩的图片(如下图)转成网络专用的feature map然后当成初始数据放入本设计中的,所以最后的结果可以证明是正确的。