当前位置: 首页 > news >正文

PixelCNN介绍:VQ-VAE的前一步探索

一、自回归图像建模:PixelCNN 的基本思想

图像本质上是一个高维数据,比如一张 32×3232 \times 3232×32 的彩色图像有 32×32×3=307232 \times 32 \times 3 = 307232×32×3=3072 个像素值。直接对这么高维的空间建模非常困难。PixelCNN 采用 自回归(autoregressive)建模 的方式,将联合概率分解为一系列条件概率的乘积:

p(x)=∏i=1H×Wp(xi∣x1,x2,…,xi−1) p(\mathbf{x}) = \prod_{i=1}^{H \times W} p(x_i \mid x_1, x_2, \dots, x_{i-1}) p(x)=i=1H×Wp(xix1,x2,,xi1)

其中:

  • x\mathbf{x}x 是整张图像展平后的像素向量
  • xix_ixi 是第 iii 个像素(按从左到右、从上到下的顺序)
  • 每个像素的出现概率依赖于它之前的所有像素

这个分解方式类似于语言模型中预测下一个词,只不过这里是预测下一个像素。

例如,在生成第 $ i $ 个像素时,模型只能看到它的“左上区域”——也就是所有已经生成的像素(上方所有行 + 当前行左侧像素),不能看到右边或下边的“未来像素”。


二、掩码卷积(Masked Convolution):防止信息泄露

为了实现上述约束,PixelCNN 使用了 掩码卷积(masked convolution)。普通的卷积操作是中心对称的,会同时看到周围所有方向的信息,这在自回归生成中是不允许的。

1. 掩码设计

假设使用 $3 \times3 $ 的卷积核,我们定义一个二值掩码矩阵 MMM,使得卷积核只能“看到”当前位置之前的像素:

M=[111110000] M = \begin{bmatrix} 1 & 1 & 1 \\ 1 & 1 & 0 \\ 0 & 0 & 0 \\ \end{bmatrix} M=110110100

这个掩码表示:

  • 第一行全部可见(上方像素)
  • 第二行只有左边和中间可见(当前行左侧像素)
  • 第三行全不可见(下方像素,属于未来)

然后,在卷积层初始化时,将卷积核权重与这个掩码相乘:

Wmasked=W⊙M W_{\text{masked}} = W \odot M Wmasked=WM

这样,卷积操作就天然屏蔽了未来的像素信息。

2. 多层堆叠与感受野扩展

单层掩码卷积的感受野有限(如 3×33 \times 33×3),但通过多层堆叠,后续层可以逐步扩大感受野。经过 LLL 层后,最终层可以覆盖整个左上区域,实现全局依赖建模。


三、像素级概率建模:输出分布而非具体值

PixelCNN 不直接输出像素值,而是为每个像素输出一个离散的概率分布。以灰度图为例,每个像素取值范围是 {0,1,…,255}\{0, 1, \dots, 255\}{0,1,,255},模型输出一个 256 维的 softmax 分布:

p(xi=k∣x<i)=exp⁡(fk(x<i))∑j=0255exp⁡(fj(x<i)) p(x_i = k \mid \mathbf{x}_{<i}) = \frac{\exp(f_k(\mathbf{x}_{<i}))}{\sum_{j=0}^{255} \exp(f_j(\mathbf{x}_{<i}))} p(xi=kx<i)=j=0255exp(fj(x<i))exp(fk(x<i))

其中 fk(⋅)f_k(\cdot)fk() 是神经网络(PixelCNN)的第 kkk 个输出通道,表示第 iii 个像素取值为 kkk 的未归一化得分(logit)。

对于彩色图像(RGB),通常采用 逻辑混合分布(Mixture of Logistic Distributions) 或逐通道建模。一种常见做法是将三个通道分开预测:

p(x)=∏ip(ri,gi,bi∣x<i)=∏ip(ri∣x<i)⋅p(gi∣ri,x<i)⋅p(bi∣ri,gi,x<i) p(\mathbf{x}) = \prod_{i} p(r_i, g_i, b_i \mid \mathbf{x}_{<i}) = \prod_{i} p(r_i \mid \mathbf{x}_{<i}) \cdot p(g_i \mid r_i, \mathbf{x}_{<i}) \cdot p(b_i \mid r_i, g_i, \mathbf{x}_{<i}) p(x)=ip(ri,gi,bix<i)=ip(rix<i)p(giri,x<i)p(biri,gi,x<i)

即先预测红色通道,再基于红色预测绿色,再基于前两者预测蓝色,进一步增强依赖性。


四、训练目标:最大化对数似然

PixelCNN 的训练目标是最小化负对数似然(Negative Log-Likelihood),等价于最大化数据出现的概率:

L=−Ex∼data[log⁡p(x)]=−E[∑i=1Nlog⁡p(xi∣x<i)] \mathcal{L} = -\mathbb{E}_{\mathbf{x} \sim \text{data}} \left[ \log p(\mathbf{x}) \right] = -\mathbb{E} \left[ \sum_{i=1}^{N} \log p(x_i \mid \mathbf{x}_{<i}) \right] L=Exdata[logp(x)]=E[i=1Nlogp(xix<i)]

在训练时,输入整张图像,网络对每个位置输出一个概率分布,然后计算交叉熵损失。由于所有操作都是可导的(除了最后的采样),可以通过反向传播优化模型参数。


五、生成过程:逐像素采样

训练完成后,就可以进行图像生成。过程如下:

  1. 初始化一张全空图像(例如全零)
  2. 从左上角开始,逐个位置进行预测:
    • 将已生成的部分输入 PixelCNN
    • 得到当前位置的像素分布 p(xi∣x<i)p(x_i \mid \mathbf{x}_{<i})p(xix<i)
    • 从中采样一个像素值(例如按概率随机抽取,或取最可能的值)
    • 填入图像
  3. 重复直到所有像素生成完毕

这个过程是顺序的、不可并行的,所以生成速度较慢,但能保证每一步都符合整体分布。


六、与 VQ-VAE 结合:采样离散编码序列

在 VQ-VAE 的框架中,PixelCNN 并不直接生成原始图像,而是作用于 离散的隐编码图

回忆一下 VQ-VAE 的流程:

  1. 编码器将图像 xxx 映射为连续向量 ze(x)z_e(x)ze(x)
  2. 通过最近邻查找,得到离散索引 k=arg⁡min⁡j∥ze(x)−ej∥k = \arg\min_j \|z_e(x) - e_j\|k=argminjze(x)ej,其中 eje_jej 是 codebook 向量
  3. 所有索引组成一个“小图像” zq\mathbf{z}_qzq,大小远小于原图(如 32×3232 \times 3232×32 而非 256×256256 \times 256256×256

此时,我们可以把 zq\mathbf{z}_qzq 看作一个“低分辨率语义图”,每个位置的值是一个离散的 codebook 索引(比如从 0 到 511)。

于是,PixelCNN 的任务变成了:

学习这个离散编码图的分布 p(zq)=∏ip(zq,i∣zq,<i)p(\mathbf{z}_q) = \prod_i p(z_{q,i} \mid \mathbf{z}_{q,<i})p(zq)=ip(zq,izq,<i)

训练完成后,我们就可以:

  1. 用 PixelCNN 采样出一个全新的 zq\mathbf{z}_qzq
  2. 将每个索引查表得到对应的嵌入向量 eke_kek
  3. 输入解码器,生成完整图像

这就实现了“从无到有”的图像生成。


七、数学总结:完整流程公式化

设原始图像为 xxx,VQ-VAE 的编码过程为:

ze=Encoder(x),ki=arg⁡min⁡j∥ze(i)−ej∥2,zq(i)=eki z_e = \text{Encoder}(x), \quad k_i = \arg\min_j \|z_e^{(i)} - e_j\|^2, \quad z_q^{(i)} = e_{k_i} ze=Encoder(x),ki=argjminze(i)ej2,zq(i)=eki

PixelCNN 建模隐编码图 k={k1,k2,…,kN}\mathbf{k} = \{k_1, k_2, \dots, k_N\}k={k1,k2,,kN} 的分布:

p(k)=∏i=1Np(ki∣k<i;θ) p(\mathbf{k}) = \prod_{i=1}^N p(k_i \mid \mathbf{k}_{<i}; \theta) p(k)=i=1Np(kik<i;θ)

其中 θ\thetaθ 是 PixelCNN 的参数。

训练目标:

Lpixelcnn=−E[∑i=1Nlog⁡p(ki∣k<i)] \mathcal{L}_{\text{pixelcnn}} = -\mathbb{E} \left[ \sum_{i=1}^N \log p(k_i \mid \mathbf{k}_{<i}) \right] Lpixelcnn=E[i=1Nlogp(kik<i)]

生成时,逐个采样:

ki∼p(ki∣k<i) k_i \sim p(k_i \mid \mathbf{k}_{<i}) kip(kik<i)

最后通过解码器生成图像:

x^=Decoder(ek1,ek2,…,ekN) \hat{x} = \text{Decoder}(e_{k_1}, e_{k_2}, \dots, e_{k_N}) x^=Decoder(ek1,ek2,,ekN)


八、改进与变体

原始 PixelCNN 有一些局限,后续出现了多个改进版本:

  • PixelRNN:使用 RNN 结构建模长距离依赖,效果更好但更慢
  • PixelCNN++:引入了更灵活的输出分布(混合逻辑分布)、上下文敏感的掩码、残差连接等,提升生成质量
  • Conditional PixelCNN:加入类别标签或其他条件,实现可控生成
  • Stacked PixelCNN:多尺度生成,先生成低频结构,再生成细节

总结

PixelCNN 的核心是:

  • 将图像生成转化为逐像素预测问题
  • 使用掩码卷积确保不泄露未来信息
  • 输出离散概率分布,通过最大化似然进行训练
  • 生成时逐像素采样,构建完整图像
  • 与 VQ-VAE 结合时,用于在离散隐空间中采样合理的编码序列,从而实现高质量图像生成

虽然生成速度慢,但它为后来的自回归生成模型(如 Image Transformer、DALL-E、VQ-GAN)奠定了基础。特别是它与 VQ-VAE 的结合,展示了“先压缩,再生成”这一强大范式,直接影响了 Stable Diffusion 等现代生成模型的设计思路。

http://www.dtcms.com/a/309488.html

相关文章:

  • 2025年Python Web框架之争:Django、Flask还是FastAPI,谁将主宰未来?
  • JsHook入门
  • 什么是爬虫协议?
  • 如何优雅删除Docker镜像和容器(保姆级别)
  • 热能小车cad【12张】三维图+设计说明书
  • 机械学习中的一些优化算法(以逻辑回归实现案例来讲解)
  • 【Flutter3.8x】flutter从入门到实战基础教程(五):Material Icons图标的使用
  • 燃气营商环境测评:以用户反馈推动服务升级​(第三方市场调查)
  • 逻辑回归----银行贷款模型优化
  • 嵌入式教学的云端革命:高精度仿真如何重塑倒车雷达实验与工程教育——深圳航天科技创新研究院赋能新一代虚实融合实训平台
  • IIS 让asp.net core 项目一直运行
  • Linux文件系统理解2
  • OpenGL Camera
  • 【03】海康MVS V4.3.0 ——安装教程、查看示例、库、头文件、开发指南
  • vue项目预览pdf隐藏工具栏和侧边栏
  • YOLOv8/YOLOv11 C++ OpenCV DNN推理
  • 人机协作!智慧环卫如何实现按需清扫?
  • 【支持Ubuntu22】Ambari3.0.0+Bigtop3.2.0——Step7—Mariadb初始化
  • 链接脚本中. = ALIGN(4);的作用?
  • C++ --- stack和queue的使用以及简单实现
  • 高级11-Java日志管理:使用Log4j与SLF4J
  • 【Electron】打包后图标不变问题,图标问题
  • 支持selenium的chrome driver更新到138.0.7204.183
  • uv 常用指令
  • GitLab Docker Compose 迁移后 Redis 权限问题排查与解决
  • 计算机网络:点分十进制如何转化为32位4字节二进制表现形式
  • 在Centos7中安装gitlab
  • elementui中rules的validator 用法
  • 3ds Max V-Ray渲染崩溃?8招告别卡顿冻结
  • 建造者模式及优化