編碼長度、範圍與精度的矛盾#
- 若給定編碼的長度,其所能表示的不同信息的數量是有限的
- 例如 16 位二進制數字最多能表示 65536 個不同數字,範圍是 0 到 6 萬多
- 如果想提高精度(例如精確到小數點後面兩位),能表示的數字範圍就縮小到 0 到 600 多
- 這就是範圍和精度的矛盾——我們不可能既要動態範圍大,還要求精度高
IEEE 754 浮點數標準#
- 為了兼顧數字的動態範圍和精度,計算機普遍採用科學記數法
- IEEE 754—2008 標準使用 64 位二進制編碼:
- 1 位表示正負號
- 11 位表示數字的動態範圍(數量級的指數)
- 52 位表示精度(浮點數)
- 這樣的設計可以表示小到 10^(-308)、大到 10^(308) 的數字
浮點數的局限#
- 64 位二進制編碼並不能表示那麼多不同的數字,中間的很多數字都被漏過了
- 在數軸上,計算機雙精度浮點數只是稀稀拉拉地占據了一些點,大部分區域並未覆蓋
- 這有別於我們日常使用的能夠表示任意精度、任意大小的科學記數法
8 位浮點數與 GPU 應用#
- 在 GPU 的一些應用場合中,用 8 位二進制數(1 字節)表示浮點數
- 如果能兼顧精度和範圍,可以表示從 ±0.0078 到 480 之間的數字
- 從 64 位降低到 8 位可以帶來:
- 節省 7/8 的存儲空間
- 提高處理速度至少一個數量級
- 大幅提高處理器性能,特別是單位能耗的計算能力
- 這就是為什麼今天很多 GPU 能做到將上千個內核集成到一芯片中
粗調與精調的藝術#
- 不僅在信息的表示上要兼顧範圍和精度,在很多計算上也是如此
- 例如機器學習的模型訓練:
- 一開始步長放得比較大,這樣能夠快速接近最後的結果
- 後來步長則要縮得比較小,以免錯過了最佳點
- 任何一個四級工程師,都需要能靈活應用粗調和精調的原則
例題 3.3:兩個玻璃球問題(AB)#
題目#
給你兩個一模一樣的玻璃球,從某一高度摔到地上一定會摔碎。恰好摔碎的高度在一層樓到 100 層樓之間。如何用最少的試驗次數,用這兩個玻璃球測試出恰好摔碎的高度?
解題思路#
- 策略一(精調):從第一層開始逐層試驗,保證成功但效率低,最壞需要 100 次
- 策略二(粗調):隨便猜一猜然後試,例如跑到 30 層一試、80 層一試,但可能兩個球都碎了也測不出結果
- 正確策略:把兩個球想成兩位數,用兩位數對 1 ~ 100 進行編碼
- 第一個球對應十位數,第二個球對應個位數
- 先拿第一個球到 10 層樓去試,每次增加 10 層
- 確定範圍後,用第二個球從該範圍底部一層一層地試
- 這樣最多保證 19 次就能試出結果
作者在做博士論文時的親身經歷:一個機器學習算法在某個階段發散,一些參數變得非常大,而另一些參數變得非常小。大數字和小數字相加減時,小數字總是被忽略掉,等於白加。後來他先把大的參數做粗調,再做精調,兼顧了溫出和精度的問題才得到解決。
要點#
- 在編碼長度(二進制位數)一定的情況下,編碼能表示的不同信息的數量是有限的
- 信息的動態範圍和精度就是一對矛盾,我們不可能既要動態範圍大,還要求精度高
- 根據不同的應用平衡二者的關係,是信息編碼的藝術