一、浮点表示的背景
数据类型的选择决定了所需的计算资源的数量,从而影响模型的速度和效率。在深度学习应用中,平衡精度和计算性能成为一项至关重要的练习,因为更高的精度通常意味着更大的计算需求。
在各种数据类型中,浮点数主要用于深度学习,因为它们能够以高精度表示各种值。通常,浮点数使用n位来存储数值。这些n位进一步分为三个不同的组成部分:
- 符号:符号位指示数字的正数或负数。它使用一位,其中 0 表示正数,1 表示负数。
- 指数:指数是一段位,表示基数(在二进制表示中通常为 2)的幂。指数也可以是正数或负数,允许数字表示非常大或非常小的值。
- 有效数/尾数:剩余位用于存储有效数,也称为尾数。这代表数字的有效数字。数字的精度在很大程度上取决于有效数字的长度。
这种设计允许浮点数以不同的精度级别覆盖广泛的值。用于这种表示的公式是:
( − 1 ) sign × base exponent × significand \color{red}{(-1)^{\text{sign}} \times \text{base}^{\text{exponent}} \times \text{significand}} (−1)sign×baseexponent×significand
为了更好地理解这一点,让我们深入研究深度学习中一些最常用的数据类型:float32 (FP32)、float16 (FP16) 和 bfloat16 (BF16):
- FP32:使用 32 位来表示数字:一位表示符号,八位表示指数,其余 23 位表示有效数。虽然 FP32 提供高精度,但其缺点是计算量和内存占用量较高。
- FP16:使用 16 位来存储数字:一位用于符号,五位用于指数,十位用于有效数。尽管这使其内存效率更高并加速计算,但范围和精度的降低可能会导致数值不稳定,从而可能影响模型的准确性。
- BF16:也是一种 16 位格式,但其中一位用于符号,八位用于指数,七位用于有效数。与 FP16 相比,BF16 扩大了可表示范围,从而降低了下溢和上溢风险。尽管由于有效位数较少而导致精度降低,但 BF16 通常不会显着影响模型性能,并且对于深度学习任务来说是一个有用的折衷方案。
二、IEEE754制32位浮点数转换为十进制
首先了解一下IEEE754制32位浮点数的存储方式
一个由IEEE745制的32位浮点数由三部分组成
组成部分 | 位数 | 含义 |
---|---|---|
符号位 | 1位 | 0为正,1为负 |
指数位 | 2~9位 | 类比十进制的科学计数法,此处以2为底,指数位为幂。注意还需要加上127的偏移量 |
尾数位 | 10~32位 | 省略了1. 实际为1.(尾数位),类似小数的二进制写法 |
核心逻辑:
I E E E 制浮点数 ⇒ 浮点数的二进制表示 ⇒ 浮点数的十进制表示 IEEE制浮点数⇒浮点数的二进制表示⇒浮点数的十进制表示 IEEE制浮点数⇒浮点数的二进制表示⇒浮点数的十进制表示
我们用例子来帮助理解,
1、例一
我们有一个用IEEE754二进制表示的32位浮点数:
0 1000 0000 1001 0010 0001 1111 1011 011
求它所代表的十进制浮点数是多少?
第一步:
符号位为
0
⇛
正数
0⇛正数
0⇛正数
第二步:
尾数部分: 1.1001 0010 0001 1111 1011 011
如果结尾处是多个0,则将多余的0舍去
第三步:
指数位:
(
10000000
)
2
=
(
128
)
10
(10000000)_2=(128)_{10}
(10000000)2=(128)10
减去偏移量:128+(-127)=1
第四步:组合:
根据
(
−
1
)
sign
×
base
exponent
×
significand
\color{red}{(-1)^{\text{sign}} \times \text{base}^{\text{exponent}} \times \text{significand}}
(−1)sign×baseexponent×significand,计算得:
( − 1 ) 0 × 2 1 × 1. 10010010000111111011011 = 11.0010010000111111011011 (-1)^0\times 2^1 \times 1.\color{#F784EB}{1001 0010 0001 1111 1011 011}\color{black}{=11.001 0010 0001 1111 1011 011} (−1)0×21×1.10010010000111111011011=11.0010010000111111011011
至此已将IEEE制浮点转换为浮点数的二进制表示
最后再将 11.0010 0100 0011 1111 0110 11 11.0010\quad0100\quad0011\quad1111\quad0110\quad11 11.0010010000111111011011 转换为十进制:
1 × 2 1 2 + 1 × 2 0 1 + 0 × 2 − 1 0 + 0 × 2 − 2 0 + 1 × 2 − 3 0.125 + 0 × 2 − 4 0.0625 + 0 × 2 − 5 0 + 1 × 2 − 6 0.015625 + 0 × 2 − 7 0 + 0 × 2 − 8 0 + 0 × 2 − 9 0 + 0 × 2 − 10 0 + 1 × 2 − 11 0.00048828125 + 1 × 2 − 12 0.000244140625 + 1 × 2 − 13 0.0001220703125 + 1 × 2 − 14 0.00006103515625 + 1 × 2 − 15 0.000030517578125 + 1 × 2 − 16 0.0000152587890625 + 0 × 2 − 17 0 + 1 × 2 − 18 0.000003814697265625 + 1 × 2 − 19 0.0000019073486328125 + 0 × 2 − 20 0 + 1 × 2 − 21 + 1 × 2 − 22 = 3.1415927410125732 \begin{aligned} 1×2^1&\quad\quad2\\ +1×2^0&\quad\quad1\\\\ +0×2^{-1}&\quad\quad0\\ +0×2^{-2}&\quad\quad0\\ +1×2^{-3}&\quad\quad0.125\\ +0×2^{-4}&\quad\quad0.0625\\\\ +0×2^{-5}&\quad\quad0\\ +1×2^{-6}&\quad\quad0.015625\\ +0×2^{-7}&\quad\quad0\\ +0×2^{-8}&\quad\quad0\\\\ +0×2^{-9}&\quad\quad0\\ +0×2^{-10}&\quad\quad0\\ +1×2^{-11}&\quad\quad0.00048828125\\ +1×2^{-12}&\quad\quad0.000244140625\\\\ +1×2^{-13}&\quad\quad0.0001220703125\\ +1×2^{-14}&\quad\quad0.00006103515625\\ +1×2^{-15}&\quad\quad0.000030517578125\\ +1×2^{-16}&\quad\quad0.0000152587890625\\\\ +0×2^{-17}&\quad\quad0 \\ +1×2^{-18}&\quad\quad 0.000003814697265625 \\ +1×2^{-19}&\quad\quad0.0000019073486328125 \\ +0×2^{-20}&\quad\quad 0\\ +1×2^{-21}&\quad\quad \\ +1×2^{-22}&\quad\quad \\ =&\quad\quad3.1415927410125732 \end{aligned} 1×21+1×20+0×2−1+0×2−2+1×2−3+0×2−4+0×2−5+1×2−6+0×2−7+0×2−8+0×2−9+0×2−10+1×2−11+1×2−12+1×2−13+1×2−14+1×2−15+1×2−16+0×2−17+1×2−18+1×2−19+0×2−20+1×2−21+1×2−22=21000.1250.062500.01562500000.000488281250.0002441406250.00012207031250.000061035156250.0000305175781250.000015258789062500.0000038146972656250.000001907348632812503.1415927410125732
2、例二
我们有一个用IEEE754二进制表示的32位浮点数:
0 1000 0011 0100 1000 0000 0000 0000 000
求它所代表的十进制浮点数是多少?
第一步:
符号位为
0
⇛
正数
0⇛正数
0⇛正数
第二步:
尾数部分: 1.0100 1000 0000 0000 0000 000
将多余0舍去得
1.0100 1
第三步:
指数位:
(
10000011
)
2
=
(
131
)
10
(1000 0011)_2=(131)_{10}
(10000011)2=(131)10
减去偏移量:131+(-127)=4
第四步:组合:
1.01001 × 2 4 = 10100.1 1.01001\times2^4=10100.1 1.01001×24=10100.1
至此已将IEEE制浮点转换为浮点数的二进制表示
最后再将 10100.1 10100.1 10100.1 转换为十进制:
1 × 2 4 16 + 0 × 2 3 0 + 1 × 2 2 4 + 0 × 2 1 0 + 0 × 2 0 0 + 1 × 2 − 1 0.5 = 20.5 \begin{aligned} 1\times 2 ^ { 4 }&\quad\quad 16 \\ +0 \times 2 ^ { 3 }&\quad\quad 0 \\ +1 \times 2 ^ { 2 }&\quad\quad 4 \\ +0 \times 2 ^ { 1 }&\quad\quad 0 \\ +0 \times 2 ^ { 0 }&\quad\quad 0 \\ +1 \times 2 ^ { - 1 }&\quad\quad 0.5 \\ =&\quad\quad20.5 \end{aligned} 1×24+0×23+1×22+0×21+0×20+1×2−1=1604000.520.5