(QAT)DOREFA-NET:低比特在线量化训练方法

Paper name

DOREFA-NET: TRAINING LOW BITWIDTH CONVOLUTIONAL NEURAL NETWORKS WITH LOW BITWIDTH GRADIENTS

Paper Reading Note

URL: https://arxiv.org/pdf/1606.06160.pdf

TL;DR

  • 提供了低比特权重、特征、梯度的在线量化训练方案
  • 量化位宽的重要性排序为:梯度>特征>权重,所以实验中的配比建议为 1w4f6g(1bit权重,4bit特征,6bit梯度),配比的关系对应于 DoReFa 的论文名
  • 首个成功在低于 8bit 梯度下得到较高精度的在线量化训练方案
  • SVHN 和 ImageNet 数据集上基于 AlexNet 的实验结果证明精度可以与浮点模型相比

Introduction

  • 之前的量化方法对于梯度的量化位宽没有低于 8bit 的(最少是 10bit,BNN 和 XNOR-Net 都是全精度梯度训练,导致大部分训练时间消耗在反传环节),这里提出一种能在低于 8bit 位宽梯度下的训练方案
  • 这种梯度低比特量化的方案后面可能能支持在 FPGA、ASIC 上的低功耗训练
  • 量化位宽的重要性排序为:梯度>特征>权重,配比的关系对应于 DoReFa 的论文名(1-bit weights, 1-bit activations and 2-bit gradients can lead to 93% accuracy on SVHN dataset)

Dataset/Algorithm/Model/Experiment Detail

实现方式

1. STRAIGHT-THROUGH ESTIMATOR(STE,直通滤波器)
  • STE是对不可微分算子在计算反向传播梯度时的近似方法,比如量化操作不可微(量化函数一般是阶梯函数,处处的梯度为0),STE就假装量化没有发生,将梯度直接前传
  • 比如对于伯努利采样函数, c是目标函数,伯努利分布不可微, ∂ ( c ) ∂ ( p ) \frac{\partial(c)}{\partial(p)} (p)(c) 没有很好的定义,因此不能使用链式规则直接从正向过程构造反向过程,因为 p p p q q q 是期望相等的,所以使用能够被正常定义的 ∂ ( c ) ∂ ( q ) \frac{\partial(c)}{\partial(q)} (q)(c) 来近似 ∂ ( c ) ∂ ( p ) \frac{\partial(c)}{\partial(p)} (p)(c)
    在这里插入图片描述
  • 又比如对于如下量化函数,将 [0, 1] 之间的全精度数量化到 [0,1] 之间的 k-bit 量化数,注意前传的量化函数不唯一,可以是不同的量化形式
    在这里插入图片描述
  • STE 的问题:
  1. loss curve会波动
  2. 由于量化函数实际上和y=x这条直线并不一致,而我们用后者的梯度来代替前者,这就会导致梯度的不匹配
2. 权重量化
  • 对于 1bit 权重情况下量化方法如下,其中的scaling factor: E ( ∣ r i ∣ ) E(|r_{i}|) E(ri) 代表该层的权重绝对值的整体期望 ,这个 scaling factor 的作用是增加权重的取值范围;与 XNOR-Net 量化方法的区别是 XNOR-Net 中的 E ( ∣ r i ∣ ) E(|r_{i}|) E(ri) 代表的是该层权重的每个 channel 的绝对值的期望,但是这里使用逐 channel 的 scaling factor 会导致计算在反向传播过程中,当计算梯度和权重之间的卷积时无法利用位卷积核
    在这里插入图片描述

  • 对于k-bit(k>1)的权重量化
    在这里插入图片描述

    • 其中 q u a n t i z e k quantize_{k} quantizek 为量化函数,将 [0, 1] 之间的全精度浮点数聚类到 [0, 1] 区间的定点数,即将 [0, 1] 的浮点数聚类到 [0, 1] 中的 2 k 2^{k} 2k 个等距分割点上
      在这里插入图片描述
  • 权重量化源码

      def uniform_quantize(k):
        class qfn(torch.autograd.Function):
      
          @staticmethod
          def forward(ctx, input):
            if k == 32:
              out = input
            elif k == 1:
              out = torch.sign(input)
            else:
              n = float(2 ** k - 1)
              out = torch.round(input * n) / n
            return out
      
          @staticmethod
          def backward(ctx, grad_output):
            # STE (do nothing in backward)
            grad_input = grad_output.clone()
            return grad_input
      
        return qfn().apply
      
      
      class weight_quantize_fn(nn.Module):
        def __init__(self, w_bit):
          super(weight_quantize_fn, self).__init__()
          assert w_bit <= 8 or w_bit == 32
          self.w_bit = w_bit
          self.uniform_q = uniform_quantize(k=w_bit)
      
        def forward(self, x):
          if self.w_bit == 32:
            weight_q = x
          elif self.w_bit == 1:
            E = torch.mean(torch.abs(x)).detach()
            weight_q = self.uniform_q(x / E) * E
          else:
            weight = torch.tanh(x)
            max_w = torch.max(torch.abs(weight)).detach()
            weight = weight / 2 / max_w + 0.5
            weight_q = max_w * (2 * self.uniform_q(weight) - 1)
          return weight_q
    
3. 特征量化
  • 特征是简单的直接量化处理
    在这里插入图片描述
4. 梯度量化
  • 梯度量化方法

    在这里插入图片描述
    梯度对于量化更为敏感,所以前人的低比特梯度量化一般不 work,为了进一步补偿梯度量化引入的潜在偏差,这里加上随机均匀噪声从而增加鲁棒性,噪声的量级和量化误差类似:
    在这里插入图片描述

  • 一般板端部署模型时不需要在板端进行训练,所以一般都是使用全精度的梯度在服务器端进行模型训练,然后在板端部署,避免梯度量化产生的掉点

5. 整体算法流程

在这里插入图片描述

  • 需要注意的是这些低比特的层之间会有高比特精度的 affine 层连接,从而节省了 conv 层等高功耗层的计算量
6. 不同层的量化位宽处理
  • 第一层因为量化掉点明显并且第一层的 channel 数一般较少,所以一般第一层权重不量化,仅做特征量化
  • 最后一层考虑到输出 channel 或者 fc 节点数较少,不量化的影响较小,为了保证精度一般最后一层的权重和特征都不做量化

实验结果

  • 可以看出在梯度的位宽有保证的情况下相比对浮点模型的掉点较少
    在这里插入图片描述
    在这里插入图片描述

Thoughts

  • 低比特量化的经典作品,梯度量化对于板端训练的意义重大
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Yolov5 QAT(Quantization-Aware Training)是一种量化感知训练的技术,用于将深度学习模型量化精度表示,以减少模型的存储空间和计算需求,同时保持模型在推理阶段的准确性。在Yolov5中,QAT可以应用于训练过程中,以便更好地适应量化后的推理。 量化感知训练的基本思想是在训练过程中模拟量化操作,并通过添加训练过程中的损失来约束模型的量化行为。具体而言,在QAT中,模型的权重和激活值被表示为比特位数(如8位)的定点数,而不是传统的浮点数。这样做可以大幅减少模型所需的存储和计算资源。 量化感知训练可以通过以下步骤来实现: 1. 定义量化策略:确定权重和激活值的量化位数,以及量化时采用的量化方法(如线性量化或对称量化)。 2. 量化仿真:在训练过程中,在权重和激活值上应用量化操作,将它们转换为比特位数的定点数。这可以通过将浮点数四舍五入到最接近的定点数来实现。 3. 计算量化损失:在模型的前向传播过程中,通过添加量化损失来约束量化后的模型与原始浮点模型之间的差异。量化损失可以使用各种度量方法来计算,如均方根误差(RMSE)或KL散度。 4. 反向传播和参数更新:通过反向传播计算梯度并更新模型的参数,以最小化总体损失,包括量化损失和传统的分类或回归损失。 通过这些步骤,量化感知训练可以使模型在推理阶段保持较高的准确性,并显著减少模型的存储和计算需求。这对于在资源有限的设备上部署深度学习模型非常有用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值