📚 一、整篇论文的总结 📚
💡 引言:这篇论文提出了一种新的生成模型框架——生成对抗网络(GANs)。GANs由两个部分组成:一个生成器和一个判别器。生成器的目标是生成尽可能真实的数据,以欺骗判别器,而判别器的目标是尽可能准确地区分真实数据和生成的数据。这种设置形成了一个对抗的游戏,通过这个游戏,生成器可以学习生成更真实的数据。
📈 相关工作:作者讨论了GANs与其他生成模型的关系,包括深度信念网络(DBNs)、深度玻尔兹曼机(DBMs)、生成随机场(GRFs)、自动编码器等。作者指出,与这些模型相比,GANs的优势在于其训练过程更直接,不需要马尔可夫链或者推断网络。
🎯 生成对抗网络:作者详细介绍了GANs的理论基础和模型结构。在GANs中,生成器和判别器都是由神经网络实现的。生成器接收一个随机噪声z,通过神经网络转化为假数据。判别器接收真实数据和假数据,通过神经网络输出数据为真的概率。生成器和判别器的训练过程是一个对抗的过程,通过这个过程,生成器可以学习生成更真实的数据。
📊 实验:作者进行了一系列实验来验证GANs的性能。实验结果显示,GANs能够生成高质量的样本,并且在一些任务上超过了其他生成模型。
👏 结论:作者总结了GANs的优点,包括训练过程直接、无需马尔可夫链、无需推断网络等。同时,作者也指出GANs的一些挑战,包括训练过程的稳定性问题、模式崩溃问题等。
二、常见面试题
-
使用tanh作为生成器最后一层的激活函数,而不是sigmoid:tanh是双曲正切函数,其函数值在-1和1之间,输出范围更广,相比于sigmoid函数(其函数值在0和1之间),tanh函数在接近0的地方变化更加敏感,能够更好地处理输入的细微变化。此外,tanh函数的输出是以0为中心的,这意味着它的输出是负的和正的,这有助于模型的训练,因为它可以更好地处理负的输入值。😄
-
使用正态分布(高斯分布)对潜在空间中的点进行采样,而不用均匀分布:正态分布是一种常见的概率分布,它的形状是一个钟形曲线,也被称为高斯分布。在GAN中,我们通常使用正态分布对潜在空间中的点进行采样,因为正态分布能够更好地捕捉到数据的复杂性,而均匀分布可能会忽略数据中的某些特性。📝
-
引入随机性以提高稳健性:在训练GAN时,由于GAN是一个动态平衡的过程,所以可能会以各种方式“卡住”。为了防止这种情况,我们在训练过程中引入随机性。这种随机性可以通过两种方式引入:一种是在判别器中使用dropout,另一种是向判别器的标签添加随机噪声。这种随机性有助于增加模型的稳健性,使其能够更好地处理各种各样的输入数据。😄
-
避免稀疏的梯度:在深度学习中,稀疏性通常是我们需要的属性,但在GAN中并非如此。有两件事情可能导致梯度稀疏:最大池化运算和ReLU激活。为了避免这种情况,我们推荐使用步进卷积代替最大池化来进行下采样,还推荐使用LeakyReLU层来代替ReLU激活。LeakyReLU和ReLU类似,但它允许较小的负数激活值,从而放宽了稀疏性限制。ReLU函数是一个分段线性函数,它在正数部分是线性的,但在负数部分的值为0,这意味着ReLU函数在负数部分的梯度为0,这可能导致梯度稀疏。而LeakyReLU函数在负数部分不再是0,而是一个较小的负斜率,这意味着LeakyReLU函数在负数部分的梯度不再为0,从而可以缓解梯度稀疏的问题。😄
-
避免棋盘状伪影:在生成的图像中,经常会见到棋盘状伪影,这是由生成器中像素空间的不均匀覆盖导致的。为了解决这个问题,每当在生成器和判别器中都使用步进的 Conv2DTranpose 或 Conv2D 时,使用的内核大小要能够被步幅大小整除。这样可以确保在每个步进操作后,像素空间都能被均匀地覆盖,从而避免出现棋盘状伪影。📝
-
输入规范化到(-1,1)之间,最后一层的激活函数使用tanh(BEGAN除外):这是因为tanh函数的输出范围是(-1,1),这可以使得生成器的输出与输入数据的范围一致,有助于模型的训练。
-
使用wassertein GAN的损失函数:Wasserstein GAN(WGAN)的损失函数可以提供更稳定的训练过程,并且能够更好地处理模式崩溃问题。
-
如果有标签数据的话,尽量使用标签,也有人提出使用反转标签效果很好,另外使用标签平滑,单边标签平滑或者双边标签平滑:这些都是为了提高模型的鲁棒性和泛化能力。
-
使用mini-batch norm, 如果不用batch norm 可以使用instance norm 或者weight norm:这些都是归一化技术,可以加速模型的训练,提高模型的性能。
-
避免使用RELU和pooling层,减少稀疏梯度的可能性,可以使用leakrelu激活函数:ReLU激活函数和pooling层可能会导致梯度稀疏,影响模型的训练。LeakyReLU激活函数可以避免这个问题。
-
优化器尽量选择ADAM,学习率不要设置太大,初始1e-4可以参考,另外可以随着训练进行不断缩小学习率:ADAM优化器在处理非凸优化问题时表现出色,而GAN就是一个非凸优化问题。适当的学习率设置和调整策略可以加速模型的收敛。
-
给D的网络层增加高斯噪声,相当于是一种正则化:这可以提高模型的鲁棒性,防止模型过拟合。
-
模式崩溃(Mode Collapse):在训练过程中,生成器可能会学习到一种模式,使得它总是生成相同或相似的样本,而忽略了数据的其他模式。这种现象被称为模式崩溃。这是因为在GAN的训练过程中,生成器和判别器是在进行一种零和博弈,生成器的目标是尽可能地欺骗判别器,而判别器的目标是尽可能地区分出真实样本和生成样本。当生成器找到一种能够欺骗判别器的有效方式后,它可能会一直使用这种方式生成样本,导致生成的样本缺乏多样性。
-
训练不稳定:GAN的训练过程通常非常不稳定,很难找到一个合适的平衡点。这是因为生成器和判别器的训练是交替进行的,而且两者的训练速度往往不同步。如果判别器训练得太快,生成器可能会难以跟上;反之,如果生成器训练得太快,判别器可能会难以区分真实样本和生成样本。这种不稳定性使得GAN的训练过程需要非常细致的调参。
-
无法保证生成样本的质量:尽管GAN可以生成非常逼真的样本,但是它无法保证生成样本的质量。这是因为GAN的训练目标是最小化生成样本和真实样本之间的分布差异,而不是最大化生成样本的质量。因此,即使GAN的训练过程收敛,也无法保证生成的样本具有高质量。
三、实现GAN的步骤 & 代码
步骤1:实现GAN中的生成器
生成对抗网络(GAN)的生成器部分是一个神经网络,其目标是生成尽可能真实的数据。以下是实现步骤:
-
定义网络结构:生成器通常是一个反卷积网络(deconvolutional network),也称为上采样网络(upsampling network)。它接收一个随机噪声向量作为输入,然后通过一系列的反卷积层将其转化为具有相同维度的数据。
-
初始化参数:初始化网络的权重和偏置。通常使用小的随机值进行初始化。
-
前向传播:将噪声向量输入到网络中,通过激活函数和反卷积操作生成数据。
-
生成数据:生成器的输出是生成的数据,这些数据将被送入判别器进行评估。
步骤2:实现GAN中的判别器
判别器是GAN的另一部分,它是一个二分类器,其目标是区分生成的数据和真实数据。以下是实现步骤:
-
定义网络结构:判别器通常是一个卷积神经网络(CNN)。它接收生成的数据或真实数据作为输入,然后通过一系列的卷积层将其转化为一个概率输出。
-
初始化参数:初始化网络的权重和偏置。通常使用小的随机值进行初始化。
-
前向传播:将数据输入到网络中,通过激活函数和卷积操作得到一个概率输出。
-
分类数据:判别器的输出是一个概率,表示输入数据来自真实数据的概率。
步骤3:实现GAN
-
训练判别器:首先,使用真实数据和生成的数据训练判别器。优化目标是最大化判别器正确分类真实数据和生成数据的概率。
-
训练生成器:然后,使用判别器的反馈训练生成器。优化目标是最大化判别器错误分类生成数据的概率。
-
迭代训练:重复上述两步,直到生成器生成的数据能够欺骗判别器,即判别器无法区分生成的数据和真实数据。
# 导入必要的库
import torch
import torch.nn as nn
# 定义生成器
class Generator(nn.Module):
def __init__(self):
super(Generator, self).__init__()
# 定义网络结构
def forward(self, input):
# 定义前向传播
return output
# 定义判别器
class Discriminator(nn.Module):
def __init__(self):
super(Discriminator, self).__init__()
# 定义网络结构
def forward(self, input):
# 定义前向传播
return output
# 定义损失函数和优化器
criterion = nn.BCELoss() # 二元交叉熵损失函数
optimizerD = torch.optim.Adam(D.parameters(), lr=0.0002)
optimizerG = torch.optim.Adam(G.parameters(), lr=0.0002)
# 步骤5:训练GAN
for epoch in range(num_epochs):
for i, data in enumerate(dataloader, 0):
# 1. 更新判别器:最大化 log(D(x)) + log(1 - D(G(z)))
# 2. 更新生成器:最大化 log(D(G(z)))
# 假设我们有一个批量的真实数据real_data和一个批量的噪声z
real_data = ...
z = ...
# 步骤1:更新判别器
## 首先,我们通过生成器生成一批假数据
fake_data = G(z)
## 然后,我们计算判别器在真实数据和假数据上的预测
D_real = D(real_data)
D_fake = D(fake_data)
## 接着,我们计算判别器的损失。这里我们使用二元交叉熵损失函数,目标是让判别器尽可能地把真实数据分类为1,把假数据分类为0
lossD_real = criterion(D_real, torch.ones_like(D_real))
lossD_fake = criterion(D_fake, torch.zeros_like(D_fake))
lossD = lossD_real + lossD_fake
## 最后,我们使用反向传播和优化器来更新判别器的参数
lossD.backward()
optimizerD.step()
# 步骤2:更新生成器
## 首先,我们生成一批新的假数据
fake_data = G(z)
## 然后,我们计算判别器在这批假数据上的预测
D_fake = D(fake_data)
## 接着,我们计算生成器的损失。这里我们的目标是让生成器生成的假数据尽可能地被判别器分类为1
lossG = criterion(D_fake, torch.ones_like(D_fake))
## 最后,我们使用反向传播和优化器来更新生成器的参数
lossG.backward()
optimizerG.step()
四、十个问题 & 回答
-
Q1 论文试图解决什么问题? 😄
这篇论文提出了一种新的生成模型架构——生成对抗网络(GAN)。这种架构试图解决如何更好地训练生成模型的问题,特别是在数据分布可能非常复杂的情况下。 -
Q2 这是否是一个新的问题? 📝
训练生成模型并不是一个新问题,但是GAN提出了一种全新的方法来解决这个问题。在GAN之前,人们通常使用方法如变分自编码器(VAEs)或者马尔可夫链蒙特卡洛(MCMC)方法来训练生成模型,但这些方法都有各自的局限性。 -
Q3 这篇文章要验证一个什么科学假设? 😄
这篇文章的主要科学假设是,通过同时训练两个模型——一个生成器和一个判别器,我们可以更好地训练生成模型。生成器的目标是生成尽可能真实的数据,以欺骗判别器,而判别器的目标是区分真实数据和生成器生成的数据。 -
Q4 有哪些相关研究?如何归类?谁是这一课题在领域内值得关注的研究员? 📝
在GAN之前,人们通常使用方法如变分自编码器(VAEs)或者马尔可夫链蒙特卡洛(MCMC)方法来训练生成模型。这些方法可以被归类为生成模型的研究。在这个领域内,Ian Goodfellow是一个值得关注的研究员,他是GAN的首席发明者。 -
Q5 论文中提到的解决方案之关键是什么? 😄
论文中提到的解决方案的关键是生成对抗网络(GAN)的架构。在这个架构中,一个生成器网络试图生成尽可能真实的数据,以欺骗一个判别器网络,而判别器网络则试图区分真实数据和生成器生成的数据。 -
Q6 论文中的实验是如何设计的? 📝
论文中的实验主要是在多个数据集上训练GAN,并与其他生成模型方法进行比较。实验结果显示,GAN能够生成的数据质量超过了其他方法。 -
Q7 用于定量评估的数据集是什么?代码有没有开源? 😄
论文中使用了多个数据集进行评估,包括MNIST、Toronto Face Database(TFD)和CIFAR-10。至于代码,原始的GAN论文并没有提供开源代码,但是现在有许多开源的GAN实现可以在网上找到。 -
Q8 论文中的实验及结果有没有很好地支持需要验证的科学假设? 📝
论文中的实验结果很好地支持了其科学假设。实验结果显示,GAN能够生成的数据质量超过了其他方法,这支持了其假设,即通过同时训练一个生成器和一个判别器,我们可以更好地训练生成模型。 -
Q9 这篇论文到底有什么贡献? 😄
这篇论文的主要贡献是提出了生成对抗网络(GAN)这一全新的生成模型架构。这种架构为训练生成模型提供了一种新的方法,特别是在数据分布可能非常复杂的情况下。 -
Q10 下一步呢?有什么工作可以继续深入? 📝
在GAN之后,有许多工作可以继续深入。例如,可以研究如何改进GAN的稳定性,因为GAN的训练通常被认为是不稳定的。此外,还可以研究如何使用GAN生成更复杂的数据类型,如文本或音频。还有一些工作是关于如何理解和解释GAN的,因为尽管GAN能够生成高质量的数据,但是它们的内部工作方式通常是不透明的。
五、每页摘要
第1页摘要 📄
1️⃣ 这篇论文提出了一种新的框架,用于通过对抗过程估计生成模型。在这个过程中,我们同时训练两个模型:一个生成模型G,用于捕获数据分布;一个判别模型D,用于估计样本来自训练数据而非G的概率。G的训练过程是最大化D犯错误的概率。这个框架对应于一个极小极大两人博弈。
2️⃣ 在任意函数G和D的空间中,存在一个唯一的解,其中G恢复了训练数据分布,而D在任何地方都等于1/2。在G和D由多层感知器定义的情况下,整个系统可以通过反向传播进行训练。在训练或生成样本过程中,无需任何马尔可夫链或展开的近似推理网络。
1️⃣ 深度学习的承诺是发现丰富的、层次化的模型,这些模型代表了在人工智能应用中遇到的数据类型的概率分布,如自然图像、包含语音的音频波形和自然语言语料库中的符号。
2️⃣ 到目前为止,深度学习最引人注目的成功涉及到判别模型,通常是那些将高维、丰富的感官输入映射到类标签的模型。这些引人注目的成功主要基于反向传播和dropout算法,使用分段线性单元,这些单元具有特别良好的梯度行为。
3️⃣ 深度生成模型的影响力较小,这是由于在最大似然估计和相关策略中出现的许多难以近似的概率计算,以及在生成上下文中利用分段线性单元的优势的困难。
4️⃣ 在提出的对抗网络框架中,生成模型与一个对手进行对抗:一个判别模型,学习确定样本是来自模型分布还是数据分布。生成模型可以被认为类似于一个伪造者团队,试图制造假货币并在不被检测的情况下使用,而判别模型类似于警察,试图检测假货币。这场比赛中的竞争驱使两队改进他们
第2页摘要 📄
1️⃣ 本框架可以产生许多种模型和优化算法的特定训练算法。在本文中,我们探讨了当生成模型通过多层感知器传递随机噪声生成样本,判别模型也是多层感知器的特殊情况。我们将这种特殊情况称为对抗网络。在这种情况下,我们可以仅使用非常成功的反向传播和dropout算法训练两种模型,并仅使用前向传播从生成模型中采样。不需要任何近似推理或马尔可夫链。
2️⃣ 直到最近,大部分关于深度生成模型的工作都集中在提供概率分布函数的参数规范的模型上。然后,可以通过最大化对数似然来训练模型。在这类模型中,可能最成功的是深度Boltzmann机。这类模型通常具有难以处理的似然函数,因此需要对似然梯度进行许多近似。这些困难促使了“生成机器”的发展——这些模型不明确表示似然,但能够生成来自所需分布的样本。生成随机网络是一个可以通过精确的反向传播而不是Boltzmann机所需的许多近似来训练的生成机器的例子。这项工作通过消除在生成随机网络中使用的马尔可夫链,扩展了生成机器的概念。
3️⃣ 我们的工作通过使用观察到的反向传播导数通过生成过程,我们在开发这项工作时并不知道Kingma和Welling以及Rezende等人已经开发出了更通用的随机反向传播规则,允许人们通过具有有限方差的高斯分布进行反向传播,并向协方差参数以及均值进行反向传播。这些反向传播规则可以允许人们学习生成器的条件方差,我们在这项工作中将其视为超参数。Kingma和Welling以及Rezende等人使用随机反向传播来训练变分自编码器(VAEs)。像生成对抗网络一样,变分自编码器将一个可微分的生成器网络与第二个神经网络配对。与生成对抗网络不同,VAE中的第二个网络是一个识别模型,执行近似推理。GANs需要通过可见单元进行微分,因此不能模拟离散数据,而VAEs需要通过隐藏单元进行微分,因此不能有离散的潜在变量。其他类似VAE的方法存在,
第3页摘要 📄
1️⃣ 生成对抗网络(GANs)的框架可以产生许多种模型和优化算法的特定训练算法。在这篇论文中,我们探讨了当生成模型通过多层感知器传递随机噪声生成样本,判别模型也是多层感知器的特殊情况。我们将这种特殊情况称为对抗网络。在这种情况下,我们可以仅使用非常成功的反向传播和dropout算法训练两种模型,并仅使用前向传播从生成模型中采样。不需要任何近似推理或马尔可夫链。
2️⃣ 直到最近,大部分关于深度生成模型的工作都集中在提供概率分布函数的参数规范的模型上。然后,可以通过最大化对数似然来训练模型。在这类模型中,可能最成功的是深度Boltzmann机。这类模型通常具有难以处理的似然函数,因此需要对似然梯度进行许多近似。这些困难促使了“生成机器”的发展——这些模型不明确表示似然,但能够生成来自所需分布的样本。生成随机网络是一个可以通过精确的反向传播而不是Boltzmann机所需的许多近似来训练的生成机器的例子。这项工作通过消除在生成随机网络中使用的马尔可夫链,扩展了生成机器的概念。
3️⃣ 我们的工作通过使用观察到的反向传播导数通过生成过程,我们在开发这项工作时并不知道Kingma和Welling以及Rezende等人已经开发出了更通用的随机反向传播规则,允许人们通过具有有限方差的高斯分布进行反向传播,并向协方差参数以及均值进行反向传播。这些反向传播规则可以允许人们学习生成器的条件方差,我们在这项工作中将其视为超参数。Kingma和Welling以及Rezende等人使用随机反向传播来训练变分自编码器(VAEs)。像生成对抗网络一样,变分自编码器将一个可微分的生成器网络与第二个神经网络配对。与生成对抗网络不同,VAE中的第二个网络是一个识别模型,执行近似推理。GANs需要通过可见单元进行微分,因此不能模拟离散数据,而VAEs需要通过隐藏单元进行微分,因此不能有离散的潜在变
第4页摘要 📄
1️⃣ 生成对抗网络的训练过程可以通过图1进行可视化。在这个过程中,判别分布(D,蓝色虚线)被同时更新,以便在数据生成分布(黑色点线)的样本和生成分布(绿色实线)的样本之间进行区分。在算法的内部循环中,D被训练以区分数据样本,收敛到D*(x) = pdata(x) / (pdata(x) + pg(x))。在对G进行更新后,D的梯度引导G(z)流向更可能被分类为数据的区域。
2️⃣ 在经过多步训练后,如果G和D具有足够的容量,他们将达到一个点,即pg = pdata,此时他们都无法改进。判别器无法区分这两个分布,即D(x) = 1/2。
3️⃣ 算法1描述了使用小批量随机梯度下降训练生成对抗网络的过程。在我们的实验中,我们使用了k = 1,这是最便宜的选项。
4️⃣ 基于梯度的更新可以使用任何标准的基于梯度的学习规则。在我们的实验中,我们使用了动量。
5️⃣ 本节首先考虑了给定生成器G的最优判别器D。对于固定的G,最优的判别器D是 D ∗ ( G ( x ) ) = p d a t a ( x ) / ( p d a t a ( x ) + p g ( x ) ) D*(G(x)) = pdata(x) / (pdata(x) + pg(x)) D∗(G(x))=pdata(x)/(pdata(x)+pg(x))。
第5页摘要 📝
1️⃣ 论文提供了对判别器D的训练标准的证明,这个标准是在给定任何生成器G的情况下,最大化量V(G;D)。这个量可以被解释为最大化对条件概率P(Y=y|x)的估计的对数似然,其中Y表示x是否来自pdata(y=1)或pg(y=0)。
2️⃣ 论文提出了一个全局最小虚拟训练标准C(G)的定理,该定理仅在pg=pdata时实现。在这一点上,C(G)达到了值-log 4。
3️⃣ 论文提出了一个命题,如果G和D有足够的容量,并且在算法1的每一步中,允许判别器在给定G的情况下达到其最优,并且pg被更新以改善标准 E x ∼ p d a t a [ l o g D G ( x ) ] + E x ∼ p g [ l o g ( 1 − D G ( x ) ) ] Ex∼pdata[logD^G(x)] +Ex∼pg[log(1-D^G(x))] Ex∼pdata[logDG(x)]+Ex∼pg[log(1−DG(x))],那么pg会收敛到pdata。
4️⃣ 但是,实际上,对抗网络通过函数G(z; θg)表示pg分布的有限家族,并优化θg而不是pg本身,所以这些证明并不适用。尽管如此,多层感知器在实践中的优秀性能表明,尽管缺乏理论保证,它们仍然是一个合理的模型。
🔑 关键洞见:这一页的内容主要是关于GAN的理论分析,包括对判别器的训练标准的证明,全局最小虚拟训练标准的定理,以及在给定一定条件下,生成器的分布pg会收敛到真实数据分布pdata的命题。这些理论分析为GAN的训练提供了理论支持,但在实际应用中,由于优化的是参数θg而不是pg本身,这些证明并不直接适用。尽管如此,多层感知器在实践中的优秀性能表明,它们仍然是一个合理的模型。
第6页摘要
-
实验结果:GANs在多个数据集上进行了训练,包括MNIST、多伦多人脸数据库(TFD)和CIFAR-10。生成器网络使用了ReLU和Sigmoid激活函数的混合,而判别器网络使用了Maxout激活函数。在训练判别器网络时,应用了Dropout。虽然理论框架允许在生成器的中间层使用Dropout和其他噪声,但是在这里,噪声只作为输入应用于生成器网络的最底层。
-
概率估计:通过对生成器G产生的样本拟合高斯Parzen窗口,来估计测试集数据在pg下的概率,并报告在此分布下的对数似然。高斯的参数通过在验证集上进行交叉验证获得。这种方法的估计似然具有较高的方差,且在高维空间中表现不佳,但它是目前最好的方法。这促使了对如何评估这种模型的进一步研究。
-
优点和缺点:新的框架相对于之前的建模框架具有优点和缺点。主要的缺点是没有pg(x)的显式表示,以及在训练过程中D和G必须保持良好的同步。优点是不需要马尔可夫链,只使用反向传播来获取梯度,学习过程中不需要推理,可以将各种函数纳入模型中。
-
结论和未来工作:这个框架允许许多直接的扩展。
第7页摘要
-
模型样本的可视化:图2展示了从模型中抽取的样本。最右边的列显示了邻近样本的最近训练样本,以证明模型没有记忆训练集。这些样本是公平的随机抽取,而不是精选的。与大多数其他深度生成模型的可视化不同,这些图像显示了模型分布的实际样本,而不是给定隐藏单元样本的条件均值。此外,这些样本是不相关的,因为抽样过程不依赖于马尔可夫链混合。
-
模型的扩展:这个框架允许许多直接的扩展。例如,可以通过向G和D添加c作为输入,得到条件生成模型p(x|c)。可以通过训练一个辅助网络来预测给定x的z,实现学习近似推理。可以通过训练一系列共享参数的条件模型,来近似地模拟所有条件p(xS|x~S),其中S是x的索引的子集。可以使用对抗网络来实现确定性MP-DBM的随机扩展。在有限的标记数据可用时,来自判别器或推理网络的特征可以改善分类器的性能,实现半监督学习。通过设计更好的方法来协调G和D,或在训练过程中确定更好的z的抽样分布,可以大大提高训练效率。
第8页摘要
- 生成模型的挑战:表2总结了深度生成模型的各种操作中不同方法遇到的困难。这些操作包括训练、推理、抽样、评估p(x)和模型设计。对于GANs,训练中的挑战在于同步判别器和生成器,推理和抽样没有困难,评估p(x)可以通过Parzen密度估计进行近似,模型设计理论上可以允许任何可微函数。