【Paper Reading】Deep Learning with Limited Numerical Precision

【Paper Reading】Deep Learning with Limited Numerical Precision

2015 《computer science》
IBM Suyog Gupta

背景

深度学习技术的成功很大程度上取决于底层硬件平台的快速执行能力,使用大量标记数据对复杂网络进行监督训练。在以往的模型的训练中,训练的过程都是采用高精度的浮点数进行模型的训练,对硬件的存储和计算资源要求很高。本文想探求使用有精度限制的定点数对模型进行训练,研究有精度限制的数据表示和计算在神经网络训练中对模型性能的影响。首先,定点计算单元通常比浮点引擎更快,消耗的硬件资源和能量也少得多。在给定的面积和功耗预算中,更小的逻辑单元的定点算术电路将允许实例化更多这样的单位。其次,低精度的数据表示减少了内存占用,使较大的模型能够适应给定的内存容量,累积起来,这可以极大地改进数据级并行性。

方法

文章的方法比较简单,在定点数中,用[QI、QF]来表示,QI对应整数、QF对应小数,整数位的数量(IL)加上小数位的数量(FL)用来表示该数字的总位数WL。本文用<IL、FL>表示,IL (FL)对应的是整数(小数)部分的长度IL(FL). ϵ表示给定的定点数格式能够表示的最小正数,表示的范围为[-2(IL-1),2(IL-1)-2^(-FL)], ϵ为2^(-FL)。
数据在量化(从高精度浮点数到低精度定点数)的过程中,有两种舍入的方式,一个是临近取舍,一个是随机取舍。
在这里插入图片描述
临近取舍采用的是四舍五入的方法,在[x]和[x]+ϵ之间的数据,靠近哪个就量化为哪个,随机取舍的方法是,在[x]和[x]+ϵ之间的数据,取[x]或[x]+ϵ是一个概率分布,这样的一个好处是量化后的概率分布的期望还是原来的高精度浮点数x。
由于从高精度浮点数向低精度定点数量化的过程中,数据的表示范围会变小,数据会溢出,所以需要用最小值或最大值代替溢出的无法用低精度顶点数表示的数。
在这里插入图片描述
取舍的这一部分的代码如下:

FL = 8  # 小数部分位数
IL = 16-FL  # 整数部分位数
round = False  # False 是最近邻取舍,True 是随机取舍
MIN = -(1 << (IL - 1))
MAX = -MIN - 2 ** (-FL)
#量化范围是[  -2^(IL-1)~2^(IL-1)-2^(-IF)  ]
def float_to_fixed(x):

    global MIN, MAX, FL
    #print(FL)
    if x <= MIN: return MIN
    if x >= MAX: return MAX
    sig = 1
    if x < 0:
        sig = -1
        x = -x
    q = int(x)
    x -= q
    e = 1
    for i in range(FL):
        x *= 2
        e /= 2
        if x >= 1:
            x -= 1
            q += e

    if round:  # 随机舍入
        r = random()  # 产生0-1的随机数
        if r < x:
            q += e
    else:  # 邻近舍入
        if x >= 0.5:
            q += e
    q *= sig
    if q <= MIN: return MIN
    if q >= MAX: return MAX
    return q

实验

为了展示在深度神经网络训练中采用有限精度数据表示的效果的研究结果,文章考虑了全连接深度神经网络和卷积神经网络(CNN),并给出了MNIST和CIFAR10的结果。
在这里插入图片描述
图像显示,在全连接网络中,MNIST数据集上,随机舍入在FL为8、10、14中,训练和测试的误差都与全精度浮点数的结果差不多。
在这里插入图片描述
图像显示,在卷积神经网络LeNet-5中,MNIST数据集上,随机舍入在FL为12、14,训练和测试的误差都与全精度浮点数的结果差不多,而临近舍入的误差要大得多,且训练无法收敛。
在这里插入图片描述
图像显示,在卷积神经网络LeNet-5中,CIFAR-10数据集上,临近舍入在FL为14时,训练无法收敛。随机舍入在FL为14时,训练和测试的误差都与全精度浮点数的结果差不多,在FL为12时,精度略有损失。
在博客[1]中,作者有对该论文的实现,结果和论文差不多。

结论

本文应该是最早的关于神经网络量化的文章,是在训练过程中,对数据进行量化,用低精度定点数代替高精度浮点数来计算,可以显著地提高能源效率和计算吞吐量,但这同时可能会影响神经网络的性能。对于低精度定点计算,传统的舍入方案失败,在深度神经网络训练过程中采用随机舍入,其结果与32位浮点计算结果基本一致。文章还为随机舍入的方案,专门设计了一个硬件实现的架构。
这篇文章写的时间为2015年,正式深度学习刚兴起的时候,这个时候的网络模型比较简单,网络的层数不深,分类任务中,分类的类别也不是很多。导致网络对数据的精度要求可能没有那么高,所以在训练中,在MNIST和CIFAR-10数据集上的效果还可以。但当在更深的网络或更复杂的任务,可能效果就会差很多了。
这篇文章给模型在推理中的量化提供了一个想法,可以采用这种随机舍入的方案进行模型的推理中的量化。

参考资料

[1] 对论文 Deep Learning with Limited Numerical Precision 的理解与结论的验证https://blog.csdn.net/qq_41832757/article/details/102741855

### Deeplearning4j (DL4J) Java 深度学习库 使用教程 #### 一、概述 Deeplearning4j(简称 DL4J)是一个专为Java和Scala开发者设计的开源深度学习库,适用于基于Java虚拟机(JVM)的应用程序。该工具集由多个子项目组成,共同满足不同场景下的需求[^3]。 #### 二、安装指南 为了顺利使用DL4J,在开始之前需完成必要的准备工作: - **环境准备** - 安装最新版本的JDK(建议8及以上),因为DL4J依赖于较新的Java特性。 - 配置好Maven或Gradle作为项目的构建管理工具,以便更方便地引入所需的依赖项。 - **添加依赖** 对于采用Maven构建系统的项目而言,可在`pom.xml`文件内加入如下配置来获取核心模块及其他常用扩展包: ```xml <dependencies> <!-- Core library --> <dependency> <groupId>org.deeplearning4j</groupId> <artifactId>deeplearning4j-core</artifactId> <version>${dl4j.version}</version> </dependency> <!-- Additional components as needed, e.g., ND4J for numerical computing --> <dependency> <groupId>org.nd4j</groupId> <artifactId>nd4j-native-platform</artifactId> <version>${nd4j.version}</version> </dependency> </dependencies> ``` 上述代码片段展示了如何通过Maven声明对DL4J及其底层计算引擎ND4J的支持[^1]。 #### 三、快速入门实例 下面给出一段简单的例子,演示怎样定义一个多层感知器并执行基本训练过程: ```java import org.deeplearning4j.nn.multilayer.MultiLayerNetwork; import org.deeplearning4j.optimize.listeners.ScoreIterationListener; import org.nd4j.linalg.dataset.api.iterator.DataSetIterator; import org.nd4j.linalg.factory.Nd4j; public class SimpleDl4jExample { public static void main(String[] args){ // 构建网络结构... MultiLayerNetwork model = new MultiLayerNetwork(conf); model.init(); model.setListeners(new ScoreIterationListener(10)); //每迭代十次打印一次得分 DataSetIterator trainingData; //= ... 获取训练数据的方式取决于具体应用场景... int numEpochs = 10; for(int i=0;i<numEpochs;i++){ while(trainingData.hasNext()){ model.fit(trainingData.next()); } trainingData.reset(); //重置iterator以备下一轮epoch循环读取 } System.out.println("Training complete."); } } ``` 此段代码创建了一个多层神经网络,并对其进行了初始化设置监听器用于监控损失函数变化情况,接着加载了训练样本集合并对它们实施多次遍历更新权重直至达到预定轮数结束整个流程[^2]。 #### 四、深入探索资源推荐 随着实践水平逐步提高,可进一步查阅官方文档深入了解各个功能细节以及最佳实践经验分享等内容。此外还有活跃的技术交流平台可供参考学习他人经验教训,比如GitHub Issues页面、Stack Overflow标签区等地方都聚集了不少热心人士愿意解答疑问[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值