趋近智
通过精确极大似然估计优化归一化 (normalization)流的参数 (parameter),使模型能够生成合成数据。利用流模型生成数据依赖于训练过程在数学上的精确逆运算。训练过程涉及将数据通过前向变换来计算精确密度,而生成过程则需要反转这一流程。
为了生成一个新的数据点 ,我们首先从已知的基分布 中抽取一个样本 。这通常是一个标准正态分布。
接着,我们将该样本通过已学习到的变换 的逆变换。
由于归一化流中的函数是严格可逆的,每个生成的点 都能完美地映射回特定的隐表征 。这种结构确保了在映射过程中不会丢失任何信息。
反转前向变换以从基分布生成数据的操作序列。
在堆叠多个流层时,逆向传递必须严格反转操作顺序。如果前向传递按 的顺序应用变换,那么逆向传递必须按 的顺序应用。
在 PyTorch 中实现这一点需要反向遍历存储的层。每一层都必须定义其自身的数学逆函数。
import torch
import torch.nn as nn
class NormalizingFlow(nn.Module):
def __init__(self, layers):
super().__init__()
# ModuleList 持有各个流变换组件
self.layers = nn.ModuleList(layers)
def forward(self, x):
# 用于密度估计(训练)
log_det_jacobians = torch.zeros(x.shape[0], device=x.device)
for layer in self.layers:
x, ldj = layer.forward(x)
log_det_jacobians += ldj
return x, log_det_jacobians
def inverse(self, z):
# 用于采样(生成)
x = z
log_det_jacobians = torch.zeros(z.shape[0], device=z.device)
# 逆向传递时反向遍历
for layer in reversed(self.layers):
x, ldj = layer.inverse(x)
log_det_jacobians += ldj
return x, log_det_jacobians
要执行采样流程,只需实例化一个随机噪声张量并将其传递给逆方法即可。
def generate_samples(flow_model, num_samples, latent_dim, device="cpu"):
flow_model.eval()
with torch.no_grad():
# 从基分布中抽取样本
z = torch.randn(num_samples, latent_dim, device=device)
# 映射到数据分布
generated_data, _ = flow_model.inverse(z)
return generated_data
不同的流架构在处理逆向传递时的效率各不相同。在设计系统时,架构的选择决定了模型是否适用于实时生成。
在掩码自回归 (autoregressive)流(MAF)等自回归模型中,前向传递是高度并行化的。这使得密度估计和训练速度很快。然而,逆向传递需要顺序生成特征。使用 MAF 生成图像或音频等高维数据会非常缓慢,因为每个像素或波形步骤都依赖于前一个步骤的计算结果。
相反,逆自回归流(IAF)专为快速生成而设计。它的逆向传递是并行化的,而前向密度估计则变为顺序执行且速度较慢。
RealNVP 等耦合架构提供了一种平衡的方法。由于仿射耦合层拆分了输入维度并应用简单的逐元素操作,其前向和逆向传递都可以并行操作。这一特性使得耦合模型在生成大量数据时效率很高,同时训练速度也很快。
从生成模型中生成样本时,一种常见的实用技巧是温度缩放。与其直接从标准正态分布中采样,不如将采样的隐变量乘以一个标量参数 (parameter) ,其中 。
降低温度会使初始样本更集中在基分布的均值附近,避开了低概率的尾部区域。在实践中,这通常会使生成的数据看起来更真实,伪影更少。代价是生成结果的多样性会有所降低。
如果训练好的流模型在推理 (inference)过程中生成了噪点较多或偏离分布的样本,将温度降低到 0.8 或 0.7 是标准的排查解决步骤。
def generate_with_temperature(flow_model, num_samples, latent_dim, temperature=0.8, device="cpu"):
flow_model.eval()
with torch.no_grad():
# 对基分布样本应用温度缩放
epsilon = torch.randn(num_samples, latent_dim, device=device)
z = epsilon * temperature
generated_data, _ = flow_model.inverse(z)
return generated_data
通过控制采样温度,可以根据具体的应用需求,在生成样本的保真度和多样性之间取得平衡。
这部分内容有帮助吗?
© 2026 ApX Machine LearningAI伦理与透明度•