二值神经网络(BNN)

1.简单介绍

  二值神经网络不是一种新的网络模型,实际上它是一种极致的量化方法——将神经网络的权重和激活量化为1bit。随着神经网络的发展,神经网络的性能越来越高,但是同时,模型的大小也越来越大。对于资源有限,功耗又有要求的边沿设备,多数神经网络模型不适合进行部署,这限制了深度学习的发展。因此出现了许多模型压缩的方法,比如知识蒸馏、剪枝、量化等等。
  二值神经网络(BNN)的前身可以追溯到BWN,他只是将神经网络的权值进行二值量化,激活还是浮点的形式,实现了不错的性能。真正意义的二值神经网络(BNN)提出是在2016年Bengio大神的论文,第一次将神经网络的权值和激活同时量化为{-1,+1}。

2.二值神经网络

量化方法
  Bengio的论文中提出使用符号函数(sign)进行二值量化,如下图所示。后续的研究都是依次为基础进行的优化。使用符号函数进行二值量化的叫做确定型量化,还有一种二值化方法是随机型量化,但是不利于硬件实现,故一般不采用。
在这里插入图片描述
STE
  符号函数的梯度处处为0,因此在反向传播中不能作为损失函数,采用直通估计(STE)的方法可以避免这个问题。STE的定义如下:
在这里插入图片描述
  理论上,二值神经网络可以实现32倍内存存储的减少和提高58倍的推理速度。同时,典型的卷积乘加运算可以简化为XNOR+POPCOUNT的运算,对硬件十分友好。如下图所示:
在这里插入图片描述

3.BNN优化方法

  BNN的优点十分明显,但是它的缺点也同样突出——精度远远低于全精度网络。因此针对BNN精度急剧下降的问题,出现了一系列的优化方法,这里简要介绍几种经典方法,如下表:
在这里插入图片描述

  • XNOR-Net:XNOR-Net使用一个比例因子缩小实值与二值之间的误差。
  • IR-Net:二值化之前对激活进行分布重塑。二值神经网络对分布十分敏感。 SI-BNN:将二值量化为{0,+1},提高了网络的表现能力。
  • ReActNet:使用自适应的量化函数,使二值神经网络的每层可以自适应的学习输入的分布。
  • RBNN:添加了一个旋转矩阵,缩小了实值与二值之间的固有角偏差,从而减小量化误差。
  • AdaBin:通过将每层激活和权值量化到最优的二值集的方法减小量化误差,核心思想还是分布近似。
### 关于神经网络 (BNN) 的模型结构 神经网络(Binary Neural Network, BNN)是一种特殊的深度学习模型,其中权重和激活函数仅限于+1和-1两个。这种极端的量化方式显著减少了存储需求和计算复杂度,使得BNN非常适合移动设备和其他资源受限环境下的部署。 #### 神经网络的基本架构特点 典型的神经网络由多个化的卷积层组成,这些层之间通常会穿插有批量归一化(Batch Normalization)操作和线性整流单元(Binary ReLU)[^2]。具体来说: - **输入层**:接收原始图像数据或其他类型的特征向量。 - **化处理**:在网络内部,除了第一个全连接层外,所有的权重都被转换成±1的形式;同样地,除最后一层之外的所有中间表示也被映射到这两个离散数上[^3]。 - **特殊组件**: - 对某些改进版本如ReActNet,在传统MobileNet V1的基础上进行了调整,替换了原有的深度可分离卷积(deepwise separable convolutions),转而采用标准形式的一维/维卷积,并引入了跳跃连接(shortcut connections)[^4]。 - 另一种先进的设计方案MeliusNet,则进一步优化了整体性能表现,使其能够在ImageNet分类任务上的准确性接近甚至超越非化的轻量级模型——例如MobileNet系列。 为了帮助理解具体的构建细节,下面给出一个简化版的神经网络架构示意代码片段: ```python import torch.nn as nn class BinaryConvLayer(nn.Module): def __init__(self, in_channels, out_channels, kernel_size=3): super().__init__() self.conv = nn.Conv2d(in_channels, out_channels, kernel_size) def forward(self, x): # 假设这里实现了某种化机制 binary_weight = binarize(self.conv.weight) output = F.conv2d(x, weight=binary_weight, bias=self.conv.bias, stride=self.conv.stride, padding=self.conv.padding) return output def create_binary_network(): layers = [] current_channels = input_channels for channels in channel_sizes: layer = BinaryConvLayer(current_channels, channels) bn_layer = nn.BatchNorm2d(channels) relu_layer = nn.ReLU() layers.extend([layer, bn_layer, relu_layer]) current_channels = channels model = nn.Sequential(*layers) return model ``` 此段伪代码展示了如何定义一个简单的卷积模块及其组合形成完整的网络实例过程。需要注意的是,“binarize”函数代表了一个理想化的变换逻辑,实际实现时可能涉及更多复杂的数学运算和技术考量。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值