混合精度训练原理之float16和float32数据之间的互相转换

news2024/11/15 18:05:39

混合精度训练原理之float16和float32数据之间的互相转换

本篇文章参考:全网最全-混合精度训练原理

  • 上述文章已经讲解的比较详细,本文只是从数值角度分析:
    1. float32转入float16的精度误差
    2. 在深度学习的混精度训练当中,当参数值(float32)获取到计算得到的梯度值(float16)后的更新过程。

问题一:float32转入float16的精度误差

首先,我们还是回顾一下float16和float32在计算机当中的存储格式:

在这里插入图片描述
有了上述内容之后,我们通过一个实际的例子来观察,float32到float16的舍入误差:(我们使用python的numpy作为例子演示,当用到具体框架如pytorch将其转化为Tensor再进行转化是一样的)

  • 当我们创建了一个十进制数据[1.12156456132],并通过float32进行存储。
big_value32 = np.array([1.12156456132], np.float32)
print(f"big_value32:{big_value32[0]:.23f}")

//result:
big_value32:1.12156450748443603515625

不考虑计算机存储,我们使用十进制转二进制得到【1.12156456132 】的二进制表示为【1.000111110001111011011010111001110011100011010100001…】,它是一个不能在有限精度内存储的数据,根据上述float32的存储空间表示,我们知道它只能保存23位有效数字(不包含首位的1),截取后,他在计算机中的表示为【1.00011111000111101101101】(截取时查看后一位,为1时进一位,为0时不进位),故其十进制表示为【1.12156450748443603515625】(所以在存取数字时是有损失的),舍入为float16时,计算的存储表示为【1.0001111100】,表示为十进制为 【1.12109375】 ,这个时候便产生了舍入误差

问题二:在深度学习的混精度训练当中,当参数值(float32)获取到计算得到的梯度值(float16)后的更新过程。

  • 在混精度训练中,为什么一定要保存一份float32的权重副本用于和计算得出的float16数据做更新?因为如果用float16和float16做计算(加法),相对于float32,会造成精度的损失,甚至导致无法更新
  1. 我们仍然举一个例子来说明这个问题,我们考虑一个十进制的原始数据(权重),假设为【1.125】,利用float16二进制存储为【0 01111 0010000000】,float32二进制存储为【0 01111111 00100000000000000000000】。
  2. 同时考虑一个计算得出的float16梯度,假设为【0.12457275190625】,二进制float16表示为【0 01011 1111111001】。
  3. 我们使用float16的原始权重去做更新:即【0 01111 0010000000】+【0 01011 1111111001】,由于他们的指数部分不相同,我们需要将指数较小的数据的小数点向左移,以保证他们的指数部分对齐,【0 01011 1111111001】将指数部分对齐【0 01111 0010000000】后,小数点需要向左移4位,在左边补0,移位之后的结果为【0 01111 0001111111】。
  4. 将两者的有效位部分相加,即【0010000000】(0)+【0001111111】(1),括号里面表示第11位有效位数值,用于进位,根据二进制加法,我们综合符号位和指数为,得到最后结果为:【0 01111 0100000000】,转换为十进制为【1.250】。
  1. 跟上个例子一样,但我们考虑使用float32去和新计算出来的float16数据做计算,在计算过程中,float16会被转换为更高精度的float32参与计算。
  2. 二进制float16【0 01011 1111111001】转换为float32为【0 01111011 11111110010000000000000】(指数位+122,有效位数后面补0)。
  3. 进行加法计算【0 01111111 00100000000000000000000】+【0 01111011 11111110010000000000000】,算得最后结果为【0 01111111 00111111111001000000000】,转换为十进制为【1.24957275390625】。从中我们可以看到精度的损失,这也是为什么要保存权重的高精度副本用于更新。
  • 如果还有理解不到位的地方,可以配合这两个工具食用:
    • 在线IEEE浮点二进制计算器
    • 在线进制转换

附:1.更新失效例子(mindspore代码):

import numpy as np
import mindspore as ms
from mindspore import Tensor
import struct

def float_to_bin(num):
    return format(struct.unpack('!I', struct.pack('!f', num))[0], '032b')

def float16_to_bin(num):
    float16 = np.float16(num)
    int_bits = np.frombuffer(float16.tobytes(), dtype=np.uint16)[0]
    bin_str = format(int_bits, '016b')
    return bin_str


big_value32 = np.array([1.125], np.float32)
big_value16 = big_value32.astype(np.float16)  # 转换为float16

print(f"weight_float16:{big_value16[0]:.23f}")
print(f"weight_float32:{big_value32[0]:.23f}")
print(float16_to_bin(big_value16[0]))
print(float_to_bin(big_value32[0]))


small_value_float16 = np.array([0.00041999], np.float16) 

print(f"grad_float16:{small_value_float16[0]:.23f}")
print(float16_to_bin(small_value_float16[0]))
print(float_to_bin(small_value_float16[0]))


# 在MindSpore中进行计算
small_tensor_float16 = Tensor(small_value_float16, ms.float16)
big_tensor16 = Tensor(big_value16, ms.float16)
big_tensor32 = Tensor(big_value32, ms.float32)

# float32与float16相加
print(f"------epoch 0--------")
result1 = big_tensor32 + small_tensor_float16
print(f"float32 + float16: {result1.asnumpy()[0]:.23f}",result1.dtype)
result2 = big_tensor16 + small_tensor_float16
print(f"float16 + float16: {result2.asnumpy()[0]:.23f}",result2.dtype)
for i in range(100):
    print(f"------epoch {i+1}--------")
    result1 += small_tensor_float16
    print(f"float32 + float16: {result1.asnumpy()[0]:.23f}",result1.dtype)
    result2 += small_tensor_float16
    print(f"float16 + float16: {result2.asnumpy()[0]:.23f}",result2.dtype)

    
print("float32 + float16:", result1.asnumpy(),result1.dtype)
print("float16 + float16:", result2.asnumpy(),result2.dtype)

if not np.isclose(result1.asnumpy(), result2.asnumpy()):
    print("The results are different!")
else:
    print("The results are the same!")

在这里插入图片描述

2.误差累积例子:将上述small_value_float16改为0.12457275190625,即可得到问题2,例子2中观察:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1133475.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

打破总分行数据协作壁垒,DataOps在头部股份制银行的实践|案例研究

从银行开始建设数据仓库至今已近20年,当前各银行机构在数据能力建设中面临诸多困扰:如何保证数据使用时的准确性?如何让数据敏捷响应业务变化?如何让更多的业务人员使用数据? 这些问题极大影响了经营指标的达成与业务…

【Python 算法】信号处理通过陷波滤波器准确去除工频干扰

对于一个信号来说通常汇入工频噪声往往是因为交流电产生的电泳,影响了我们信号采集导致信号上存在工频干扰。 那么matlab去除工频干扰可以通过陷波滤波器实现。 通常使用scipy.signal实现信号的处理。 Scipy的信号处理模块(scipy.signal)来创…

算法通过村第十六关-滑动窗口|黄金笔记|结合堆的应用

文章目录 前言堆与滑动窗口结合的问题总结 前言 提示:不论记忆多么痛苦,它属于过去,已经逝去了,我们为什么还执着于它并让它代表我们?我们就这样,所以,我们受苦。 --丹津葩默 这个还是一个比较重…

堆(二叉树,带图详解)

一.堆 1.堆的概念 2.堆的存储方式 逻辑结构 物理结构 2.堆的插入问题 3.堆的基本实现(代码)(以小堆为例) 1.堆的初始化 2. 向上调整 3.插入结点 4. 交换函数、堆的打印 5.向下调整 6.删除根节点并调整成小根堆 7.获取堆…

Transformer详解学习

1. Transformer 原理 1.1 Transformer整体结构 Transformer的结构图,拆解开来,主要分为图上4个部分,其中最重要的就是2和3Encoder-Decoder部分,对咯,Transformer是一个基于Encoder-Decoder框架的模型。 接下来我将按照…

通过使用Cpolar内网穿透工具实现BUG管理系统的远程访问

文章目录 前言1. 本地安装配置BUG管理系统2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射本地服务 3. 测试公网远程访问4. 配置固定二级子域名4.1 保留一个二级子域名 5. 配置二级子域名6. 使用固定二级子域名远程7. 结语 前言 BUG管理软件,作为软件测试工程师的必备工具…

Kettle循环结果集中的数据并传入SQL组件【或转换】里面

简介:在尝试使用了结果集的Demo循环后,进入到生产还是有一点问题的,以下是各个组件的分解解释、遇到的问题,以及解决问题的思路,最后文章的最后会把完整的Ktr文件放出来。记得收藏点赞喔! 先来看张图~来自…

【疯狂Java】数组

1、一维数组 (1)初始化 ①静态初始化:只指定元素,不指定长度 new 类型[] {元素1,元素2,...} int[] intArr; intArr new int[] {5,6,7,8}; ②动态初始化:只指定长度,不指定元素 new 类型[数组长度] int[] princes new in…

【德哥说库系列】-PostgreSQL跨版本升级

📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】!😜&am…

【算法训练-动态规划 五】【二维DP问题】最大正方形

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【动态规划】,使用【数组】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为&…

Kafka - 深入了解Kafka基础架构:Kafka的基本概念

文章目录 Kafka的基本概念 Kafka的基本概念 我们首先了解一些Kafka的基本概念。 1)Producer :消息生产者,就是向kafka broker发消息的客户端2)Consumer :消息消费者,向kafka broker获取消息的客户端3&…

如何避免Web3诈骗,重点关注这5个安全标识提醒

从预付费电子邮件到网络钓鱼攻击,互联网充斥着各种骗局。尽管区块链内置了加密功能,但它们也遭受了相当多的恶意攻击并被获取了对帐户的访问权限。幸运的是,大多数诈骗攻击都有特定的安全标识提醒,精明的用户可以留意,…

淘宝商品详情API接口,解决滑块问题

淘宝商品详情API接口是一种用于获取淘宝商品详细信息的接口,它可以帮助开发者在自己的网站或应用程序中快速获取淘宝商品的详细信息,包括价格、图片、商品描述等。 该接口的主要作用包括: 商品信息展示:通过淘宝商品详情API接口…

网络协议--IGMP:Internet组管理协议

13.1 引言 12.4节概述了IP多播给出,并介绍了D类IP地址到以太网地址的映射方式。也简要说明了在单个物理网络中的多播过程,但当涉及多个网络并且多播数据必须通过路由器转发时,情况会复杂得多。 本章将介绍用于支持主机和路由器进行多播的In…

wkhtmltoimage/wkhtmltopdf 使用实践

1. 介绍 wkhtmltopdf/wkhtmltoimage 用于将简单的html页面转换为pdf或图片; 2.安装 downloads 2.1. mac os 下载64-bit 版本然后按照指示安装, 遇到 untrust developers 时,需要在 Settings -> Privacy 处信任下该安装包。 2.2. debian # 可用…

[AutoSar NVM] 存储架构

依AutoSAR及公开知识辛苦整理,禁止转载。 专栏 《深入浅出AutoSAR》, 全文 2900 字. 图片来源: 知乎 汽车的ECU内存中有很多不同类型的变量,这些变量包括了车辆各个系统和功能所需的数据。大部分变量在ECU掉电后就会丢失&#x…

AnkiPDF Guru软件评测:打开全新学习方式的大门

在当今信息爆炸的时代,如何高效学习和记忆成为了每个人关注的焦点。AnkiPDF Guru软件作为结合了Anki和PDF的学习利器,向我们展示了一种全新的学习方式。本文将以软件的实用性和使用场景为切入点,从专业的角度客观分析和评测该软件&#xff0c…

3.2.6:工作表的VBA操作引申

我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的劳动效率,而且可以提高数据处理的准确度。我推出的VBA系列教程共九套和一部VBA汉英手册,现在已经全部完成,希望大家利用、学习。 如果…

【毕业设计】基于SSM酒店后台管理系统

前言 🔥本系统可以选作为毕业设计,运用了现在主流的SSM框架,采用Maven来帮助我们管理依赖,所选结构非常合适大学生所学的技术,本系统结构简单,容易理解!本系统功能结构完整,非常高适…

express session JWT JSON Web Token

了解 Session 认证的局限性 Session 认证机制需要配合 cookie 才能实现。由于 Cookie 默认不支持跨域访问,所以,当涉及到前端跨域请求后端接口的时候,需要做很多额外的配置,才能实现跨域 Session 认证。 注意: 当前端…