PixelRNN 是一种生成模型,将深度学习与自回归的条件概率建模相结合,专注于逐像素地生成图像。它通过学习像素之间的条件依赖关系,将每个像素的生成视为基于前面已生成像素的条件分布采样的结果。具体而言,PixelRNN 对输入图像 $x$ 的像素序列进行建模,将联合概率分布 $p(x)$ 分解为多个条件分布 $p(x_i | x_1, x_2, \ldots, x_{i-1})$,以此逐步生成完整图像。这种方法直接在像素空间内进行建模,不依赖于潜在变量表示,从而有效捕捉图像中复杂的空间相关性。
逐行扫描: 回忆一下老式电视的工作原理,屏幕上的图像是通过电子束逐行扫描生成的。
从屏幕的左上角开始,电子束一行一行地绘制像素,每一行从左到右依次填充,直到整个画面被完整显示。
每个像素的色彩和亮度都可以依据之前绘制的像素进行调整,以保证整个画面流畅且一致。
逐行扫描正是 PixelRNN 模型的核心思想,即对图像中尚未生成的像素进行条件预测,条件依赖于已生成的部分。随着“已完成像素”逐渐扩展到整张图,PixelRNN 就像在解一个谜题,逐像素递归生成出一幅完整的图像。
假设有一个图像 $x$(可以视为像素矩阵),PixelRNN 的思路是自回归地对图像像素的联合概率分布 $p(x)$ 进行建模。所谓自回归,指的是将一个多维的(如二维图像)或序列的联合分布拆解为一连串的条件分布:
$$ p(x) = \prod_{t} p\bigl(x[t] \mid x[1], x[2], \ldots, x[t-1]\bigr), $$
其中 $x[t]$ 表示第 $t$ 个像素(或序列项)。当我们对第 $t$ 个像素进行采样时,会依据已经采样好的前 $t-1$ 个像素来预测它的分布。注意,在实际实现中,$x[t]$ 的预测是基于之前 $t-1$ 个像素的聚合隐表示 $h[t]$。
这是一种朴素的设计,任意一个像素的取值可以被看作依赖于它前面的已经生成的像素,而不依赖之后的像素(当然能取决于 先后 是如何定义的)。因此,我们只需要学习如何利用前面已经生成的像素来预测当前像素的条件分布,而不是直接对整个图像的联合分布进行建模。相比直接处理高维联合分布,这种逐步分解的方法大幅降低了建模的复杂性。
将图像看做从上到下、从左到右的一维序列:
$$ (x[1], x[2], \dots, x[w], x[w+1], x[w+2], \dots, x[H\times W]) $$
使用一个 RNN(如 LSTM)对该序列依次处理,输出对下一个像素分布的参数估计。例如:
$$ h[t] = \text{LSTM}(h[t-1], x[t]), \quad p(x[t] \mid x[1],\ldots,x[t-1]) = f_\theta(h[t]) $$
其中 $h[t]$ 是 RNN 的隐状态,$f_\theta(\cdot)$ 是一个可能输出像素分布(例如多分类 softmax来输出 0 - 255)的函数。
可能你会问,为什么我们可以通过 $f_\theta(h[t])$ 来预测 $p(x[t] \mid x[1],\ldots,x[t-1])$,即使 $h[t]$ 并不完全等同于完整的历史序列 $x[1],\ldots,x[t-1]$?
举个简单的例子,设函数 $v=g(u) = u + 1 \quad u \in \mathbb{Z}$。在这种情况下, $p(x∣u)$ 和 $p(x∣v)$ 是相同的.
因为 $v$ 是通过对 $u$ 的平移变换得到的,即 $v = u + 1$,这一变换不会改变条件分布 $p(x ∣ u)$ 的形式。换言之,变量的线性平移不会影响其与其他变量之间的条件依赖关系。因此,对于任意给定的 $x$ 和相应的 $u$ 与 $v$,我们有以下关系成立:
$$ p(x ∣ u = 1) = p(x ∣ v = 2), \, p(x ∣ u = 2) = p(x ∣ v = 3), \dots $$
这表明 $p(x ∣ u)$ 和 $p(x ∣ v)$ 在数值和形式上是一致的。
**注意:**在数学上,下面的两个概率表达式可能而不是总是等价,
$$ p\bigl(x[t] \mid x[1], x[2], \ldots, x[t-1]\bigr) $$
$$ \small
p\bigl(x[t] \mid h[t]\bigr) \\h[t] = \text{LSTM}(h[t-1], x[t])
$$