卷 IV · 通CH 14深度 14/24

把十分之一的比特翻掉

前十三章假设比特能完好送到。现实不是这样:线会串扰,无线会衰落,内存会被宇宙射线打中。卷 IV 的问题只有一个——在一条会说谎的线上,怎么说出不会错的话。

★ 真信道C = 1 − H(p)最坏的是 p = 0.5

▷ 先猜一下

一条线路会随机翻掉一些比特。哪种情况下这条线最没用(每次使用能传的信息最少)?

A 翻位率 10%B 翻位率 50%C 翻位率 90%D 翻位率 100%(每一位都翻)

最简单的噪声模型

把现实中所有的噪声源——热噪声、串扰、衰落、宇宙射线——统统抽象成一件事:

◆ 二元对称信道(BSC)

你发一个比特。它有 p 的概率被翻成相反的,有 1−p 的概率原样通过。每一位独立。

        1−p
   0 ─────────▶ 0
     ╲   p    ╱
      ╲──────╱
      ╱──────╲
     ╱   p    ╲
   1 ─────────▶ 1
        1−p

「对称」指的是 0 翻成 1 和 1 翻成 0 的概率一样。这个模型简单得离谱,但它抓住了本质,而且香农所有的核心结论都能在它身上讲清楚。

先看一眼它有多难受:

p 拖到 0.1,看那五个字母被打成了什么样。40 个比特里翻掉 4 个,「HELLO」就已经面目全非了。

那么这条线还能传多少

直觉可能会说:「翻掉 10%,那大概还剩 90% 吧。」

不对,而且差得挺远。正确答案是:

C = 1 − H(p)                【二元对称信道的容量】

p = 0.1  →  C = 1 − 0.469 = 【0.531 比特 / 每次使用】

只剩 53%,不是 90%。为什么?

◆ 那个 H(p) 是被谁吃掉的

收方拿到一个比特。这个比特里包含两件事:

  1. 发方到底发的是 0 还是 1;
  2. 这一位到底翻没翻。

第二件事本身就是一个随机变量,它的熵是 H(p) = 0.469 比特。这部分不确定性占掉了收到的比特里的一份,而它对你毫无用处——它是关于噪声的信息,不是关于消息的信息。

于是留给消息的只剩 1 − H(p) = 0.531

用互信息的语言写(第 19 章会正式定义):

C = max I(X; Y) = H(Y) − H(Y|X) = 1 − H(p)

# H(Y)   收到的那一位有多少不确定性       最多 1 比特
# H(Y|X) 已知发的是什么,收到的还有多少不确定  = H(p),纯噪声
# 相减 = 收到的东西里,真正来自发送方的那部分

最坏的不是「全翻」

现在回到开头那个问题。把 demo 里的 p 一路拖到 1,看看容量:

p = 0.0   C = 1.000     # 完美信道
p = 0.1   C = 0.531
p = 0.2   C = 0.278
p = 0.3   C = 0.119
p = 0.5   C = 0.000     ← 【最坏】
p = 0.7   C = 0.119
p = 0.9   C = 0.531
p = 1.0   C = 1.000     ← 又满了!
◆ p = 1 的信道和完美信道一样好

「每一位都翻」是完全可预测的。收方把收到的全部取反,就得到了原文,一个错都没有。

坏的不是噪声大,是噪声不可预测。

而最不可预测的地方在正中间:p = 0.5。这时收到的比特和发出的比特统计独立——你收到一个 1,发的是 0 还是 1 的概率各半。这条线传的信息量是 0,你不如自己在家抛硬币。

这个观察在工程上有真实的用处:

▸ 在现实里:把「已知的坏」变成「不坏」
  • 差分信号(LVDS、USB、以太网、HDMI)。用两根线传一对反相的信号,接收端取差值。共模干扰同时打在两根线上,一相减就消掉了。这是「可预测的噪声不算噪声」的物理版。
  • 回声消除。你的手机通话里,扬声器的声音会被自己的麦克风收进去。但那个声音是已知的(就是你刚播出去的),所以可以精确地减掉。
  • DRAM 的行锤(Rowhammer)和纠错。某些位翻转有规律(同一行反复访问导致邻行翻位),一旦规律被识别,就能被针对性地防御。
  • 反过来的用法:加密。好的密文必须让攻击者觉得每一位都是 p = 0.5——「和随机不可区分」就是「容量为 0」的另一种说法。密码学的很多安全定义,翻译过来就是「攻击者能获得的互信息可忽略」。
✗ 这个直觉是错的
翻位率 10%,那就有 10% 的数据坏了,剩下 90% 是好的。 两个问题。第一,你不知道是哪 10% 坏了——如果知道,那就是「擦除信道」,容量是 0.9,比 BSC 高得多。第二,损失不是线性的:10% 的翻位吃掉了 47% 的容量。

「知道哪里错了」这件事本身值很多比特,这是一个反复出现的主题:

擦除信道(知道哪位丢了)    C = 1 − p     p=0.1 → 0.900
二元对称信道(不知道哪位错) C = 1 − H(p)  p=0.1 → 0.531

# 同样丢 10%,「知道丢在哪」比「不知道」多传 69% 的信息。

这就是为什么网络协议里校验和如此重要:它把「悄悄出错」(BSC,很难对付)变成「明确丢包」(擦除信道,好对付得多)。TCP 的重传机制建立在这个转换上。一个坏包被丢掉,比一个坏包被当成好包用,代价小得多。

∑ 为什么容量公式里要取 max

容量的正式定义是 C = maxp(x) I(X;Y)——在所有可能的输入分布上取最大值。

为什么要取 max?因为容量是信道的性质,不该取决于你怎么用它。如果你只发 0 不发 1,那你一个比特都没传,但这是你的问题,不是信道的问题。所以容量定义为「最会用的人能达到的极限」。

对二元对称信道,最优输入分布恰好是均匀的(0 和 1 各一半)——这有直观理由:信道是对称的,所以没有理由偏爱任何一个输入符号。

这也给出一个实用推论:要跑满一条信道,你发出去的比特流必须看起来像随机的。而一段没压缩的文本远远不是随机的。所以「先压缩再传输」不只是省流量,它是跑满信道容量的前提。

这件事有个名字,叫信源–信道分离定理:先把信源压到熵(第 5–9 章),再对压完的比特做纠错编码(第 15–17 章),这两步分开做,和联合优化一样好。这条定理是现代通信系统架构分层的理论依据——它解释了为什么「压缩」和「纠错」在每一个系统里都是两个独立的模块。

(要补一句边界:分离定理在点对点、无限长码块的理想条件下成立。在多用户、有时延约束的现实场景里,联合设计有时确实更好。但作为工程架构的默认选择,分离几乎总是对的。

◇ 结账
B:翻位率 50%

如果你选了 D,那是最自然的直觉——「全错了当然最糟」。但全错是完全可预测的,取个反就完事了。

这一题真正想让你换掉的观念是:噪声的危害不在幅度,在不可预测性。一个稳定偏差 100 度的温度计,你减掉 100 就能用;一个随机偏差 ±1 度的温度计,你什么都做不了。

C = 1 − H(p) 这个式子里那个 H(p),量的正是「噪声本身有多难猜」。

这一章的一句话

一条会翻位的线,每次使用能可靠带走 1 − H(p) 比特。被吃掉的那部分不是「坏掉的数据」,是「这一位到底翻没翻」这个问题本身占掉的——所以最坏的信道不是全翻,是翻一半。

下一章:既然线会出错,那就多说几遍呗。这个直觉几乎每个人都有,而它在算术上非常昂贵。我们会算清它到底多贵——要把错误率压到十亿分之一,重复码需要重复 35 次,码率掉到 0.029。而香农说你本来可以跑 0.531。