是阅读论文《Neural Belief Propagation Auto-Encoder for Linear Block Code Design》需要的前置知识。
主要参考:https://www.zhangzhenhu.com/probability_model/8.消元法.html
在一般有向概率图下,观测到某节点集A的状态,求某节点B的状态的分布,基本做法是:
- 求P(B, A),也就是边缘概率分布
- 边缘概率分布的求法是对联合概率分布求积分,把其他变量全部积掉。由于概率图的“马尔可夫性”(也就是只依赖相连的节点),因此最终可以转变为一系列积分的乘积
- 注意不应该把A积掉。不过换种形式就可以了:假设 xi 是变量,而 xˉi 是观测值,定义 δ(xi,xˉi)=(xi==xˉi)?1:0 表示变量 xi 是否为观测值。乘上这一项就可以用求和了,其作用相当于提取。
- 求P(B|A),只要除以P(A),P(A) 可以由 P(B, A) 将B积掉得到
对于无向图,也就是用“势函数”和“归一化因子”代替了概率,做法同理。
该方法叫做“消元法”。问题是计算太复杂。如果要计算节点集合C的状态分布,则每个都要从头开始计算,效率极低。但是很多运算都是重复的。因此需要找一种方法“复用”。这个方法就是树结构下的“加和乘积算法(sum-product algorithm)”,又称为置信传播(belief propagation)算法。(在树形结构上是精确的,在环上是近似的,但实际效果也还不错)
基本思想是:对于某个节点,先收集了各个邻居的信息,如果是上游的节点需要计算概率,就把自己下游的信息向上传递;如果是下游的节点需要,则把自己的上游信息向下传递。也就是不需要再深入积分了,已经预计算了。
这里用“传递”其实不对,因为当每个节点都收集了全部的信息时,直接拿来用就是了。
换个数学一些的表述:节点x的邻居节点集合为N(x),如果 y∈N(x) 需要计算,则需要把信息 messageN(x)∖y 传递给 y。y接收了这个信息就存下来了(这是传播过程),如果真的要计算y的概率,直接拿来用(推理时)。
传递的“消息”就是这棵树某个末端的边缘概率。传递的顺序为:如果某节点x就差邻居y的信息没收到了,则把其他节点的信息汇总发给y。
下面引入“因子图”的概念。用无向图解释。无向图里势函数是定义在最大团上的,比如三个变量节点构成的团是一个三角形相互依赖。这就不是树形了,解决方法是引入“因子节点”,也就是将三角转换为星形,中心为“因子节点”。因子节点的邻居构成团。
“(广义)星三角变换”后就可以是树了。此时同类节点之间没有边,邻居都是异类。下面具体给出传递的消息是什么:
举个例子#
graph TD;
x1((变量$$x_1$$))
x2((变量$$x_2$$))
x3((变量$$x_3$$))
x4((变量$$x_4$$))
f123["因子$$\phi_{123}$$"]
f32["因子$$\phi_{34}$$"]
因子$$\phi_1$$ --- x1 --- f123 --- x2 --- 因子$$\phi_2$$
f123 --- x3 --- f32 --- x4
假设现在已经知道了 x4 和 x2 的观测量 o4 和 o2,求 x1 的概率。先用基本的消元法:
p(x1,x2=o2,x4=o4)=Z1x2,x3,x4∑ϕ1(x1)ϕ2(x2)δ(x2,o2)ϕ34(x3,x4)δ(x4,o4)ϕ123(x1,x2,x3)=Zϕ1(x1)x3∑(x4∑ϕ34(x3,x4)δ(x4,o4))(x2∑ϕ2(x2)δ(x2,o2)ϕ123(x1,x2,x3))
消元法最终公式就是这样,比较复杂。下面写成消息的形式:
x1 接收来自 ϕ123 的消息,根据定义,需要先得到 x3 和 x2 传递给 ϕ123 的消息:
uϕ34→x3(x3)=x4∑ϕ34(x3,x4)δ(x4,o4)vx2→ϕ123(x2)=uϕ2→x2(x2)=ϕ2(x2)δ(x2,o2)
于是,因子 ϕ123 传给 x1 的消息为:
uϕ123→x1(x1)=x2,x3∑ϕ123(x1,x2,x3)vx2→ϕ123(x2)uϕ34→x3(x3)
发现和消元法求和内容一致。于是得到边缘概率分布:
p(x1,o2,o4)=Zϕ1(x1)uϕ123→x1(x1)
最终:
p(x1=e1∣x2=o2,x4=o4)=p(o2,o4)p(e1,o2,o4)=x1∑p(x1,o2,o4)p(e1,o2,o4)=x1∑ϕ1(x1)uϕ123→x1(x1)ϕ1(e1)uϕ123→x1(e1)
对数似然比(LLR)消息#
在LDPC解码中,信念传播的输入是电压这种实际采样的连续值,输出是判决后的二值,这个过程中进行了一些纠错。通常内部需要多次迭代,每次迭代后检查Hx,如果是0就完成,如果不是代表还可以继续纠错,继续迭代。直到最大迭代次数,如果还不是0,说明猜不出了,只能报错,通过重传等机制弥补。
为什么LDPC需要迭代?因为有环。完美树形结构不需要迭代
首先变量是二值的。然后定义LLR类型的消息:
L(uij)=lnuji(xi=1)uji(xi=0)
表示对 xi 取值的建议。
理想情况下线性分组码解码时:Hx=0,里面进行的是模2加法,也就是选几个比特进行异或,结果是0。因子节点就是定义了这样一个规则:如果因子节点的邻居的异或为0,则势函数为1;否则为0。
uji(xi=0) 的意思是:若 xi=0,那么校验方程j成立(相连比特异或为0)的概率。L(uij) 给出了完全不知道 xi 实际取值情况下,为了满足校验方程时,对 xi 的建议,符号代表数值,绝对值代表建议的强烈程度。xi 有实际值L(也是对数似然比),和建议一致(同号)那非常完美,可以确定取值。如果和建议相悖,看加起来的符号。如果拉不回来,那么Hx大概也会不为0,说明这种情况已经超过了纠错上限。
对于节点向因子传递的消息:
vij(xi)=k∈N(i)∖j∏uki(xi)L(vij)=k∈N(i)∖j∑L(uki)
对于因子向节点传递消息:
uji(xi)=xN(j)∖i∑ϕ(xN(j))k∈N(j)∖i∏vkj(xk)uji(xi=0)=xN(j)∖i∑ϕ(xN(j)∖i,0)k∈N(j)∖i∏vkj(xk)uji(xi=1)=xN(j)∖i∑ϕ(xN(j)∖i,1)k∈N(j)∖i∏vkj(xk)
设 S=⨁k∈N(j)∖ixk 为除 i 以外所有邻居的异或和。
- 当 xi=0 时,为了满足总异或和为 0,必须要求 S=0。
- 当 xi=1 时,同上,要求 S=1。
- 此时 ϕ(xN(j)∖i,xi)=1
因此,求和公式可以具体写为(为了简洁,省略下标 kj,用 vk(xk) 表示):
uji(0)=∑xN∖i:⨁xk=0∏kvk(xk)
uji(1)=∑xN∖i:⨁xk=1∏kvk(xk)
构造“和”与“差”。这是推导中最关键的一步。我们不直接算 u(0) 和 u(1),而是算它们的和与差。
-
两者之和(所有情况的总和)
uji(0)+uji(1)=∑all x∏kvk(xk)
由于求和是对所有可能的组合,乘积可以拆开:
uji(0)+uji(1)=∏k(vk(0)+vk(1))
-
两者之差(利用符号 trick)
考虑这样一个乘积:∏k(vk(0)−vk(1))。
当我们把这个乘积展开时,每一项都是从括号里选一个数相乘。
- 如果我们选了 vk(0),符号是正的。
- 如果我们选了 vk(1),符号是负的。
对于任意一种组合 x,如果其中包含偶数个 1(即 ⨁xk=0),那么负号出现了偶数次,结果为正。
如果包含奇数个 1(即 ⨁xk=1),那么负号出现了奇数次,结果为负。
所以,这个乘积展开后正好等于“偶校验项之和”减去“奇校验项之和”:
uji(0)−uji(1)=∏k(vk(0)−vk(1))
3. 引入 LLR 和 tanh#
现在我们要计算 L(uji)=lnuji(1)uji(0)。
利用上面的和与差,我们可以构造出比值。
首先,观察单个变量 k 的项:
令 Lk=lnvk(1)vk(0),则 vk(1)vk(0)=eLk。
我们来看 vk(0)+vk(1)vk(0)−vk(1) 等于什么:
vk(0)+vk(1)vk(0)−vk(1)=vk(1)vk(0)+1vk(1)vk(0)−1=eLk+1eLk−1
根据双曲函数公式,这正是 tanh(Lk/2):
tanh(2Lk)=eLk+1eLk−1
4. 综合推导#
现在回到 L(uji)。
我们计算 uji(0)+uji(1)uji(0)−uji(1):
uji(0)+uji(1)uji(0)−uji(1)=∏k(vk(0)+vk(1))∏k(vk(0)−vk(1))=∏k(vk(0)+vk(1)vk(0)−vk(1))
代入刚才的 tanh 结论:
uji(0)+uji(1)uji(0)−uji(1)=∏ktanh(2Lk)
另一方面,对于输出端,令 Lout=L(uji),同样有:
uji(0)+uji(1)uji(0)−uji(1)=uji(1)uji(0)+1uji(1)uji(0)−1=eLout+1eLout−1=tanh(2Lout)
5. 最终结果#
联立上面两式:
tanh(2Lout)=∏k∈N(j)∖itanh(2Lk)
两边同时取反双曲正切 artanh(即 tanh−1),并乘以 2:
L(uji)=2⋅artanh(∏k∈N(j)∖itanh(2L(vkj)))
这就是论文中 Check Node 更新公式的完整由来。