Verilog设计CNN卷积核以及激活函数

上一篇文章解决了MATLAB在训练CNN网络时遇到的问题,现在要将网络搬到FPGA中去实现,这篇文章主要介绍该网络在FPGA中的实现方式,供大家学习,后续也会将该项目开源出来。但是该项目只设计了卷积核以及激活函数,因为在后续开发的过程中发现,使用传统的CNN网络在综合时会消耗很多资源,因此后续会考虑更换更加轻量级的Mobilenet V2网络。卷积神经网络(Convolutional Neural Network, CNN)是深度学习中的一种经典模型,特别适用于处理图像、语音和视频等数据。

上一篇文章解决了MATLAB在训练CNN网络时遇到的问题,现在要将网络搬到FPGA中去实现,这篇文章主要介绍该网络在FPGA中的实现方式,供大家学习,后续也会将该项目开源出来。

但是该项目只设计了卷积核以及激活函数,因为在后续开发的过程中发现,使用传统的CNN网络在综合时会消耗很多资源,因此后续会考虑更换更加轻量级的Mobilenet V2网络。


一、CNN模块介绍

卷积神经网络(Convolutional Neural Network, CNN)是深度学习中的一种经典模型,特别适用于处理图像、语音和视频等数据。CNN通过模拟生物视觉系统的工作原理来提取数据中的特征,在计算机视觉和图像识别领域取得了显著的成功。

在本项目中完成了CNN模块中的两个部分,卷积层以及激活函数层:

卷积层 (Convolutional Layer)

卷积层是CNN的核心。其主要作用是从输入数据中提取局部特征。卷积操作通过一个小的滤波器(或称卷积核)与输入数据进行滑动窗口式的计算,得到一个特征图。每个卷积核可以学习到不同的特征(例如边缘、纹理、形状等)。通过多层卷积,网络能够学习到从低级到高级的特征。

激活函数层 (Activation Layer)

卷积层的输出通常会经过一个激活函数(如ReLU、Sigmoid、Tanh等),以引入非线性因素,使网络能够学习和表示更加复杂的特征。ReLU(Rectified Linear Unit)是最常用的激活函数,它通过将负值设置为零,保留正值,有助于加速训练并避免梯度消失问题。


二、基础模块介绍

万丈高楼平地起,在设计过程中需要很多基础的运算模块,比如浮点数的加减运算模块

2.1 浮点数相加减

2.1.1 浮点数是什么

浮点数是与定点数相对的概念,计算机中的定点数约定小数点的位置不变,即人为约定俗成地规定了一个数小数点的位置。例如定点纯整数约定了小数点在数值位的最后。定点纯小数约定了数值位的最高位在小数点后面。

由于计算机字长的限制,当需要表示的数据有很大的数值范围时,他们不能直接用定点小数或者定点整数表示

在本项目中使用浮点数进行操作,能够最大程度的提高精度,提高卷积操作的效果。

2.1.2 单精度浮点数的形式

IEEE 754规定单精度浮点数的真值一般表示为

单精度浮点数编码格式由三个字段构成:

数符s为1位,表示浮点数的正负
尾数编码f为23位(采用原码表示)
阶码编码e为8位(含1位阶符,采用移码表示,偏移量127)

2.1.3 单精度浮点数的相加的verilog代码

假设有两个浮点数:

对阶:尾数右移,小阶对大阶,阶码小的尾数右移,阶码+1

尾数加减法运算:使用补码运算,减法也采用补码加法实现

规格化:尾数加减法运算后,结果可能是非规格化数。如果结果的真值M不满足:1 / 2 ≤ M < 1 ,则是非规格化数需要规格化处理。

代码如下:

always @ (floatA or floatB) begin
	exponentA = floatA[30:23];
	exponentB = floatB[30:23];
	fractionA = {1'b1,floatA[22:0]};
	fractionB = {1'b1,floatB[22:0]}; 
	
	exponent = exponentA;

	if (floatA == 0) begin						//处理0现象
		sum = floatB;
	end else if (floatB == 0) begin
		sum = floatA;
	end else if (floatA[30:0] == floatB[30:0] && floatA[31]^floatB[31]==1'b1) begin // 刚好相反
		sum=0;
	end else begin
        // 指数
		if (exponentB > exponentA) begin // 比较指数
			shiftAmount = exponentB - exponentA; // 计算指数差
			fractionA = fractionA >> (shiftAmount); // 还原有效值
			exponent = exponentB; // 大的是指数
		end else if (exponentA > exponentB) begin 
			shiftAmount = exponentA - exponentB;
			fractionB = fractionB >> (shiftAmount);
			exponent = exponentA;
		end

        // 根据符号处理有效位数
		if (floatA[31] == floatB[31]) begin //same sign
			{cout,fraction} = fractionA + fractionB;
			if (cout == 1'b1) begin
				{cout,fraction} = {cout,fraction} >> 1;
				exponent = exponent + 1;
			end
			sign = floatA[31];
		end else begin //different signs
			if (floatA[31] == 1'b1) begin
				{cout,fraction} = fractionB - fractionA;
			end else begin
				{cout,fraction} = fractionA - fractionB;
			end
			sign = cout;
			if (cout == 1'b1) begin
				fraction = -fraction;
			end
            // 处理有效位
			if (fraction [23] == 0) begin
				if (fraction[22] == 1'b1) begin
					fraction = fraction << 1;
					exponent = exponent - 1;
				end else if (fraction[21] == 1'b1) begin
					fraction = fraction << 2;
					exponent = exponent - 2;
                    ...
				end else if (fraction[0] == 1'b1) begin
					fraction = fraction << 23;
					exponent = exponent - 23;
				end
			end
		end
		mantissa = fraction[22:0];
		sum = {sign,exponent,mantissa};			
	end
end

endmodule

这边简单分析一下代码逻辑,首先是对特殊情况进行处理,然后进行指数对其A如果两个浮点数的指数不同,较小的指数需要通过移位对齐。移位的数目是两个指数之间的差值。如果 eB > eA  ,则 fA 需要右移 eB - eA 位,反之亦然。最后进行尾数的规范化,如果加法结果的尾数的最高位(即第 23 位)为 0(意味着结果不是规范化的),则需要对尾数进行左移操作,并相应地调整指,使其符合规范化格式。

2.2 浮点数相乘

浮点乘法的运算过程可以分为以下几个步骤,具体分析如下:

求乘积的阶码

乘法运算中,结果的阶码 Ez​ 是两个乘数阶码之和,即:Ez​=Ex​+Ey​。其中,Ex​ 和 Ey​ 分别是乘数 x 和 y 的阶码部分。如果 Ez​ 超出了浮点数表示范围(根据规格化范围决定),则会出现溢出。

求乘积的尾数

乘法的核心是尾数部分的相乘。由于浮点数是规范化的,乘法时直接计算尾数的乘积:Mz​=Mx​×My​,其中,Mx​ 和 My​ 分别是乘数 x 和 y 的尾数部分。尾数部分可能会有进位或溢出。

规格化乘积的尾数

由于乘法中尾数的积可能大于等于 1,尾数通常需要右移一次。如果尾数大于 1,需要右规,并且在右移的过程中,可以使用舍入算法来确保结果的精度。常见的舍入算法包括四舍五入向零舍入,或向最近偶数舍入等。

左规(左移):如果尾数的最高有效位(即最左边的非零位)后面还有有效位(即尾数部分有进位),则需要左移尾数以满足规范化要求。

<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值