当前位置: 首页 > news >正文

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

混合精度训练原理之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 structdef 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_strbig_value32 = np.array([1.125], np.float32)
big_value16 = big_value32.astype(np.float16)  # 转换为float16print(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_float16print(f"float32 + float16: {result1.asnumpy()[0]:.23f}",result1.dtype)result2 += small_tensor_float16print(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中观察:

在这里插入图片描述

相关文章:

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

混合精度训练原理之float16和float32数据之间的互相转换 本篇文章参考:全网最全-混合精度训练原理 上述文章已经讲解的比较详细,本文只是从数值角度分析: 1. float32转入float16的精度误差 2. 在深度学习的混精度训练当中,当参数…...

网络协议--ICMP:Internet控制报文协议

6.1 引言 ICMP经常被认为是IP层的一个组成部分。它传递差错报文以及其他需要注意的信息。ICMP报文通常被IP层或更高层协议(TCP或UDP)使用。一些ICMP报文把差错报文返回给用户进程。 ICMP报文是在IP数据报内部被传输的,如图6-1所示。 ICMP…...

《红蓝攻防对抗实战》三.内网探测协议出网之HTTP/HTTPS协议探测出网

目录 一. 在 Windows 操作系统中探测 HTTP/HTTPS 出网 1. Bitsadmin 命令 2.Certuil 命令 2.Linux系统探测HTTP/HTTPS出网 1.Curl命令 2.Wget命令 对目标服务器探测 HTTP/HTTPS 是否出网时,要根据目标系统类型执行命令,不同类型的操作系统使用的探…...

【Win11】系统重装教程(最新最详细)

目录 一.简介 二.用U盘制作PE系统 三、安装系统 软件:Windows 11版本:21H2语言:简体中文大小:5.14G安装环境:PE系统,至少7代处理器硬件要求:CPU2.0GHz 内存4G(或更高)下载通道①丨…...

如何构建一个外卖微信小程序

随着外卖行业的不断发展,越来越多的商家开始关注外卖微信小程序的开发。微信小程序具有使用方便、快速上线、用户覆盖广等优势,成为了商家们的首选。 那么,如何快速开发一个外卖微信小程序呢?下面就让我们来看看吧! 首…...

小知识(5) el-table行样式失效问题

一、实现效果 子级呈现不同颜色去区分 二、最初代码 tips: 我这里使用的vue3 elementplus <el-table :row-class-name"tableRowClassName" >... </el-table>function tableRowClassName({ row, rowIndex }) {if (row.children.length 0) {return …...

【Docker】Docker数据的存储

默认情况下&#xff0c;在运行中的容器里创建的文件&#xff0c;被保存在一个可写的容器层里&#xff0c;如果容器被删除了&#xff0c;则对应的数据也随之删除了。 这个可写的容器层是和特定的容器绑定的&#xff0c;也就是这些数据无法方便的和其它容器共享。 Docker主要提…...

hive字段关键字问题处理

最近在xxl_job部署shell调度任务时,发现在编写Hql时&#xff0c;对一些使用关键字命名的字段无法解析&#xff0c;按开发规范&#xff0c;字段命名不应该有关键字,但是数据来源是第三方,无法修改,需要通过flume对从kafka的数据到hdfs上&#xff0c;数据是json格式,所以需要对关…...

指定顺序输出

系列文章目录 进阶的卡莎C++_睡觉觉觉得的博客-CSDN博客数1的个数_睡觉觉觉得的博客-CSDN博客双精度浮点数的输入输出_睡觉觉觉得的博客-CSDN博客足球联赛积分_睡觉觉觉得的博客-CSDN博客大减价(一级)_睡觉觉觉得的博客-CSDN博客小写字母的判断_睡觉觉觉得的博客-CSDN博客纸币(…...

(Java)中的数据类型和变量

文章目录 一、字面常量二、数据类型三、变量1.变量的概念2.语法的格式3.整型变量4.长整型变量5.短整型变量6.字节型变量 四、浮点型变量1.双精度浮点数2.单精度浮点数 五、字符型常量六、布尔型变量七、类型转换1.自动类型转换&#xff08;隐式&#xff09;2.强制类型转换(显式…...

SHELL脚本编程基础,bilibili王晓春老师课程个人笔记(写比较简单,仅供参考)

文章目录 一、第一天&#xff08;Shell脚本编程基础&#xff09;作者视频ppt部分作者视频操作编写一个hello.sh可执行文件使hello.sh可以到处运行没有执行权限的执行方式下载httpd&#xff08;web服务器&#xff09;curl字符界面浏览器 命令列表凌乱笔记 作业重点&#xff1a; …...

VS code运行vue项目

要在VS Code中启动Vue项目&#xff0c;您可以按照以下步骤进行操作&#xff1a; 1.打开VS Code&#xff0c;并确保已安装Vue.js插件&#xff08;如Vetur&#xff09;。 2.在VS Code的侧边栏中&#xff0c;选择您的Vue项目文件夹&#xff0c;或者使用菜单中的“文件”->“打…...

matlab中narginchk函数用法及其举例

matlab中narginchk函数用法及其举例 narginchk在编写子函数程序时候&#xff0c;在验证输入参数数目方面具有重要作用&#xff0c;本博文讲一讲该函数的用法。 一、narginchk功能 narginchk的作用是验证输入参数数目。 二、语法 narginchk(minArgs,maxArgs)narginchk(minA…...

k8s集群镜像下载加gradana监控加elk日志收集加devops加秒杀项目

展示 1.配套资料2.devops 3.elk日志收集 4.grafana监控 5.dashboard![在这里插入图片描述](https://img-blog.csdnimg.cn/bf294f9fd98e4c038858a6bf5c34dbdc.png 目的 学习k8s来来回回折腾很久了&#xff0c;光搭个环境就能折腾几天。这次工作需要终于静下心来好好学习了一…...

waf绕过

1.市场Waf分类 硬件Waf&#xff1a;绿盟、安恒、启明、知道创宇等 需要选择模式 透明模式 反向代理分为反向代理&#xff08;代理模式&#xff09;与反向代理&#xff08;牵引模式&#xff09; 反向代理又分为两种模式&#xff0c;反向代理…...

在 MyBatis-Plus 中,如果你想通过其他字段进行修改操作,可以使用条件构造器(Wrapper)来指定修改的条件。

在 MyBatis-Plus 中&#xff0c;如果你想通过其他字段进行修改操作&#xff0c;可以使用条件构造器&#xff08;Wrapper&#xff09;来指定修改的条件。 对不起&#xff0c;我在之前的回答中犯了一个错误。在条件构造器中&#xff0c;eq 方法的第一个参数应该是数据库表中的列…...

Python Opencv实践 - 入门使用Tesseract识别图片中的文字

做车牌识别项目前试一试tesseract识别中文。tesseract的安装使用请参考&#xff1a; Python OCR工具pytesseract详解 - 知乎pytesseract是基于Python的OCR工具&#xff0c; 底层使用的是Google的Tesseract-OCR 引擎&#xff0c;支持识别图片中的文字&#xff0c;支持jpeg, png…...

TCP通信实战案例-即时通信

即时通信是什么含义&#xff0c;要实现怎么样的设计&#xff1f; 即时通信&#xff0c;是指一个客户端的消息发出去&#xff0c;其他客户端可以接收到。 即时通信需要进行端口转发的设计思想。 服务端需要把在线的Socket管道存储起来。 一旦收到一个消息要推送给其他管道。…...

【数据结构初阶】算法的时间复杂度和空间复杂度

算法的时间复杂度和空间复杂度 1.算法效率1.1 如何衡量一个算法的好坏1.2 算法的复杂度 2.时间复杂度2.1 时间复杂度的概念2.2 大O的渐进表示法2.3常见时间复杂度计算举例 3.空间复杂度4. 常见复杂度对比 1.算法效率 1.1 如何衡量一个算法的好坏 如何衡量一个算法的好坏呢&am…...

git log 命令详解

测试仓库 asdf 常用参数 查询指定目录 git -C /Users/yanlp/workspace/asdf log 限制显示提交数量 git log -n 3 限制提交人|邮箱 git log --authorEdwin Kofler | git log --authoredwinkofler.dev 限制一个月内的提交git log --since1.month.ago | git log --since2023-0…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...