編碼長度、範圍與精度的矛盾#

  • 若給定編碼的長度,其所能表示的不同信息的數量是有限的
  • 例如 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 次就能試出結果

作者在做博士論文時的親身經歷:一個機器學習算法在某個階段發散,一些參數變得非常大,而另一些參數變得非常小。大數字和小數字相加減時,小數字總是被忽略掉,等於白加。後來他先把大的參數做粗調,再做精調,兼顧了溫出和精度的問題才得到解決。

要點#

  • 在編碼長度(二進制位數)一定的情況下,編碼能表示的不同信息的數量是有限的
  • 信息的動態範圍和精度就是一對矛盾,我們不可能既要動態範圍大,還要求精度高
  • 根據不同的應用平衡二者的關係,是信息編碼的藝術