从信息熵到模型量化

今天做模型量化的时候想了解下背后的原理,然后发现又用到了KL散度,在模型量化中用它去评估量化前后的精度损失,同时也看到了老朋友交叉熵,整理一番之后又有了新的收获。

交叉熵与KL散度

  • 问题:KL散度和交叉熵是什么关系?为什么之前深度学习分类问题中使用交叉熵而不是KL散度作为loss函数??

  • 信息论里的熵是什么

    • 熵(Entropy)最早由热力学引入,而信息论中的熵指的是随机变量的不确定性
    • 信息论认为百分百概率发生的事件信息量为0,概率越低的事件信息量越大,所以可以用事件发生概率的倒数取对数来量化一个事件的信息量
    • 因为信息量只描述了事件的一个结果,所以信息熵就是信息量的期望:
      在这里插入图片描述

  • 从KL散度到交叉熵

    • KL散度,也叫KL距离,一般被用于计算两个分布之间的不同。虽然可以叫KL距离,但不具备距离的对称性,在距离上的对称性指的是A到B的距离等于B到A的距离。

    • KL散度的数学定义:对于离散事件我们可以定义事件A和B的差别
      在这里插入图片描述

      • 如果Pa=Pb,即两个事件分布完全相同,那么KL散度等于0
      • 可以发现减号左边的就是事件A的熵
      • 如果颠倒顺序,求B||A的散度,那么就需要使用B的熵,所以KL散度来计算两个分布A与B的时候是不是对称的。
    • KL散度 = 交叉熵 - 熵

      • 事实上交叉熵和KL散度的公式非常相近,其实就是KL散度的后半部分,A和B的交叉熵 = A与B的KL散度 - A的熵:
        在这里插入图片描述

      • 其中,A的信息熵为:
        在这里插入图片描述

      • 所以,A和B的交叉熵为:
        在这里插入图片描述

      • 观察公式发现:如果S(A)是一个常量,那么KL散度和交叉熵在特定条件下等价


  • 为什么交叉熵可以作为loss函数(信息熵的角度)

    • 机器学习的过程就是希望在训练数据上模型学到的分布和真实数据的分布越接近越好,但我们没有真实数据的分布,只能使用训练数据的分布替代真实数据的分布。所以机器学习训练就是最小化这两个分布之间差距的过程,因此可以使用KL散度来度量。
    • 根据前面的公式结论,训练数据的分布A是给定的,那么求A||B的散度等价于求交叉熵H(A,B),当交叉熵最低时(等于训练数据分布的熵),我们学到了“最好的模型”。既然等价,那么我们优先选择更简单的公式,因此选择交叉熵。

  • 交叉熵的另一种思路(最大似然估计的角度)

    • 现在有一个真实分布为 P(x) 的随机变量,我们对它进行了N次独立同分布实验,对于每个可能的结果x观察到的次数为 N(x),那么它的似然值就可以写成
      在这里插入图片描述

    • 乘法公式把每次实验的概率乘起来,然后合并相同的项写成幂次。这是个乘积的形式,取个对数可以得到求和的形式
      在这里插入图片描述

    • 这个式子有两个缺点,第一它是个负数,第二它的数值跟样本数有关,样本越多数值越小,因此除以一下总的样本数归一化,再取个相反数,然后改用频率表示
      在这里插入图片描述

    • P代表模型输出分布,P0为训练数据观察到的频率,公式右边即模型输出分布和训练数据分布的交叉熵。因此可以看出,交叉熵最小实质上就是似然值最大。

    • 我们可以证明,在给定 P0 的情况下,使交叉熵最小的分布P一定有 P=P0,根据拉格朗日乘子法:
      在这里插入图片描述

    • 求偏导得到
      在这里插入图片描述

    • 即 P和 P0 成比例,再根据归一化条件得到 P=P0。

    • 因此模型训练时,以交叉熵作为loss函数做梯度下降就是在寻找交叉熵的最小值,就是让模型输出的分布尽量接近训练数据的分布,而训练数据的分布近似真实分布,所以交叉熵可以作为机器学习里的loss函数。

  • 小结

    • 如果从熵的角度出发,交叉熵在深度学习中和KL散度等价,因此我们使用更简单的交叉熵作为梯度下降的loss函数,知道了它的来龙去脉,这是一个更偏物理的理解(信息论)。
    • 如果从最大似然估计的角度出发,可以发现交叉熵的最小值其实是似然值最大,这是一种更偏数学的理解(概率论)。两种思路从不同角度出发,经过数学推导后最终得到一样的结果,殊途同归的美感,让人不得不感慨一个秒阿。


KL散度与量化

  • 问题:量化为什么会用到KL散度?是要解决一个什么样的问题?

  • 什么是量化以及为什么要量化

    • 量化是指将连续取值近似为有限多个离散值的过程。
    • 模型量化能有效缩减模型大小,减少内存带宽和存储空间。FP32 模型中,每个 weight 数值原本需要 32-bit 的存储空间,量化之后只需要 8-bit 即可。因此,模型的大小将直接降为将近 1/4。
    • 不仅模型大小明显降低, activation 采用 8-bit 之后也将明显减少对内存的使用,这也意味着低精度推理过程将明显减少内存的访问带宽需求,提高高速缓存命中率,尤其对于像 batch-norm, relu,elmentwise-sum 这种内存约束(memory bound)的 element-wise 算子来说,效果更为明显。
    • 模型量化后会损失一定的精度。
    • 量化过程通常有离线量化和训练量化两种,离线量化更方便,训练量化往往损失的精度更小,后续原理讨论主要为离线量化。

  • 量化的基本原理

    • 在这里插入图片描述

    • 上面是简单的max-min 映射,这是针对均匀分布的,很明显的可以知道,只要数据分布的不是很均匀,那么精度损失是很大的,因此一般采取不对称映射:
      在这里插入图片描述

    • 因此,我们的问题就转换为如何寻找最优的阀值T使得精度的损失最小

    • NVIDIA选择的是KL散度描述两个分布的差异程度,放到量化的情境里面就是量化前后两个分布的差异程度,因此问题转换为求KL散度的最小值。换句话说,用KL散度表示int8量化后的值分布跟f32的值分布之间的信息量丢失程度。

  • int8量化流程
    在这里插入图片描述

    • 宏观处理流程如下,首先准备一个校准数据集,然后对每一层:

      • 收集激活值的直方图;
      • 基于不同的阀址产生不同的量化分布;
      • 然后计算每个分布与原分布的KL散度,然后选择KL散度最小的一个,也就是量化后分布跟原分布最近的一个。
        此时就选出了一个最优阀值使得量化后的精度损失最小,再根据上图的不对称映射,对应的scale值也就出来了。至此,模型量化完成。

猜你喜欢

转载自blog.csdn.net/hechao3225/article/details/122041852
今日推荐