生成模型与概率分布基础
生成模型与概率分布基础
- 0. 前言
- 1. 概率基础
- 1.1 概率分布
- 1.2 预测置信度
- 1.3 像素的联合概率
- 2. 基于概率模型生成人脸图像
- 2.1 平均面孔
- 2.2 条件概率
- 2.3 概率生成模型
- 2.4 参数化建模
0. 前言
概率分布是机器学习的基础,在生成模型中尤为重要。在本节中,我们首先了解什么是概率,以及如何在不使用任何神经网络或复杂算法的情况下使用它来生成人脸图像。仅借助基本数学和 NumPy
代码,学习如何创建概率生成模型。
1. 概率基础
在任何机器学习文献中都不可能忽略术语“概率”,它在不同的上下文中可能具有不同的含义,因此可能会造成混淆。概率通常在数学方程式中用 ppp 表示,在学术论文、教程和博客中随处可见。尽管这是一个似乎易于理解的概念,但根据上下文可能有多种不同的定义和解释。在本节中,将在以下情况下探讨概率的使用:
- 分布
- 置信度
1.1 概率分布
假设要训练一个神经网络对猫和狗的图像进行分类,并且数据集中包含 600
张狗的图像和 400
张猫的图像。在将数据馈送到神经网络之前,需要先对数据进行打散。否则,如果在一小批 (batch
) 数据中仅看到具有相同标签的图像,则网络将变得懒惰,并预测所有图像都具有相同的标签,而无需费力地学习并区分它们。如果我们随机采样数据集,则概率可以写为:
pdata(dot) = 0.6
pdata(cat) = 0.4
这里的概率指的是数据分布 (data distribution
)。在此示例中,这是指猫和狗图像数量与数据集中图像总数的比率。这里的概率是静态的,并且对于给定的数据集不会改变。
在训练一个深度神经网络时,数据集通常太大而无法馈入网络,因此网络训练一个 epoch
需要将数据集划分成多个小批次。如果对数据集进行了很好的混洗,则小批量数据的采样分布 (sampling distribution
) 将与数据分布的采样分布相似。如果数据集不平衡,其中某些类别的图像比另一个类别的图像多,则神经网络可能会偏向于预测图像数量更多的类别,这是过拟合 (overfitting
) 的一种形式。因此,可以以不同的方式对数据进行采样,以赋予数量的类更多的权重。如果要在采样时平衡类别数量,则采样概率如下:
psample(dog) = 0.5
psample(cat) = 0.5
概率分布 (
probability distribution
) p(x)p(x)p(x) 是数据点 xxx 出现的概率。机器学习中使用两种常见的分布。均匀分布 (Uniform distribution
) 是每个数据点都有相同的发生机会;这就是通常所说的在不指定分布类型的情况下随机抽样的含义。高斯分布 (gaussian distribution
) 是另一种常用的分布,也称其为正态分布。概率在中心(均值)处达到峰值,并在两侧逐渐减小。高斯分布具有良好的数学特性。
1.2 预测置信度
经过迭代,模型终于完成了训练,接下来用图像测试模型。该模型输出以下概率:
p(dog) = 0.6
p(cat) = 0.4
在这里,概率不再是指分布;而是相反,其表示对预测有多自信,或者换句话说,对输出有多大的信心,而不再是通过计算出现次数来量化的东西。如果完全确定某物是狗,则 p(dog)=1.0p(dog) = 1.0p(dog)=1.0、p(cat)=0.0p(cat) = 0.0p(cat)=0.0。这称为贝叶斯概率 (Bayesian probability
)。
传统的统计方法将概率视为事件发生的机会,例如,小球具有某种颜色的机会。在更广泛的统计学领域中,关于频数法或贝叶斯法哪一个更好的争论很大,但是,贝叶斯方法在深度学习和工程学中可能更重要。它已被用于开发许多重要的算法,包括利用卡尔曼滤波 (
Kalman filtering
) 跟踪火箭的轨迹。在计算火箭轨迹的投影时,卡尔曼滤波器使用来自全球定位系统 (global positioning system
,GPS
) 和速度传感器 (speed sensor
) 的信息。两组数据都很嘈杂,但是GPS
数据最初不太可靠(意味着可信度较低),因此在计算中此数据的权重较小。可以将概率视为置信度得分而不是频率。贝叶斯概率最近还用于搜索深度神经网络的超参数。
现在,已经阐明了普通机器学习中常用的两种主要概率类型:分布概率和置信度。在接下来的描述中,将假设概率意味着概率分布,而不是置信度。接下来,将研究在图像生成中起着非常重要作用的分布——像素分布。
1.3 像素的联合概率
查看以下图片——分辨它们是狗还是猫?分类器如何生成置信度分数?
这些是狗还是猫的照片?答案是显而易见的。查看图片时,我们会意识到第一张图片是猫,第二张图片是狗。我们从整体上看到了图片,但这不是计算机所看到的,电脑看到的是像素。
像素是数字图像中最小的空间单位,它代表一种颜色。最常用的配色方案是 8
位 RGB
,其中一个像素由三个通道组成,分别称为 R
(红色),G
(绿色) 和 B
(蓝色)。它们的值范围从 0
到 255
(最高强度为 255
)。例如,黑色像素的值为 [0, 0, 0]
,而白色像素的值为 [255, 255, 255]
。
描述图像像素分布的最简单方法是通过计算强度等级从 0
到 255
的像素数;可以通过绘制直方图将其可视化。尽管这可以为我们提供一些信息——例如,天空的图像可能有很多蓝色像素,所以直方图可以可靠地告诉我们有关此的某些信息——直方图不能告诉我们像素之间的相互关系。换句话说,直方图不包含空间信息,即一个蓝色像素与另一个蓝色像素的距离。
取代定义代表整个图像 xxx 的 p(x)p(x)p(x) 可以将 xxx 定义为 x1,x2,x3,…,xnx_1, x_2, x_3, …, x_nx1,x2,x3,…,xn,可以将 p(x)p(x)p(x) 定义为像素 p(x1,x2,x3,…,xn)p(x_1, x_2, x_3, …, x_n)p(x1,x2,x3,…,xn) 的联合概率,其中 nnn 是像素数。
使用以下图像来说明联合概率的含义。以下是三张 2 x 2
像素的图像,其中包含二进制值,其中 0
是黑色,1
是白色:
首先通过计算白色 x1x_1x1 的数量并将其除以图像总数来计算 p(x1=white)p(x_1 = white)p(x1=white)。然后,对 x2x_2x2 进行相同的操作,如下所示:
p(x1=white)=2/3p(x2=white)=0/3p(x_1 = white) = 2/3 \\ p(x_2 = white) = 0/3 p(x1=white)=2/3p(x2=white)=0/3
我们称 p(x1)p(x_1)p(x1) 和 p(x2)p(x_2)p(x2) 彼此独立,因为我们可以分别计算它们。如果我们计算 x1x_1x1 和 x2x_2x2 均为黑色的联合概率,则会得到以下结果:
p(x1=black,x2=black)=0/3p(x_1=black, x_2=black) = 0/3 p(x1=black,x2=black)=0/3
然后,可以计算出这两个像素的完整联合概率,如下所示:
p(x1=black,x2=white)=0/3p(x1=white,x2=black)=3/3p(x1=white,x2=white)=0/3p(x_1=black, x_2=white) = 0/3 \\ p(x_1=white, x_2=black) = 3/3 \\ p(x_1=white, x_2=white) = 0/3 p(x1=black,x2=white)=0/3p(x1=white,x2=black)=3/3p(x1=white,x2=white)=0/3
我们需要执行 16
次相同的步骤来计算 p(x1,x2,x3,x4)p(x_1, x_2, x_3, x_4)p(x1,x2,x3,x4) 的完整联合概率。现在,我们可以完全描述像素分布,并使用它来计算边缘分布,如 p(x1,x2,x3)p(x_1, x_2, x_3)p(x1,x2,x3) 或 p(x1)p(x_1)p(x1)。但是,对于每个像素具有 256 x 256 x 256 = 16777216
种可能性的 RGB
值,联合分布所需的计算呈指数增长。这是深层神经网络可以发挥作用的地方。可以训练神经网络以学习像素数据分布 PdataP_{data}Pdata。因此,神经网络也可以视为概率模型 PmodelP_{model}Pmodel。
我们可以使用 XXX 表示数据集,xxx 表示从数据集采样的图像,xix_ixi 表示像素。图像生成的目的是生成具有类似于 p(X)p(X)p(X) 的像素分布 p(x)p(x)p(x) 的图像。例如,桔子的图像数据集将很有可能出现大量彼此相邻分布在一个圆圈中的橙色像素。因此,在生成图像之前,我们将首先根据实际数据 pdata(X)p_{data}(X)pdata(X) 建立概率模型 pmodel(x)p_{model}(x)pmodel(x)。之后,我们通过 pmodel(x)p_{model}(x)pmodel(x) 绘制样本来生成图像。
2. 基于概率模型生成人脸图像
在本节中,将学习如何通过从概率模型中采样(甚至不使用神经网络)来生成图像。
2.1 平均面孔
使用香港中文大学创建的大规模 CelebFaces Attributes
(CelebA
) 数据集。可以使用 tensorflow_datasets
模块直接下载此文件:
ds_train, ds_info = tfds.load('celeb_a', split='test',
shuffle_files=False, with_info=True)
fig = tfds.show_examples(ds_train, ds_info)
使用 tfds.show_examples() API
预览图像的一些示例样本:
正如在图中看到的那样,每个图像中都有一张名人面孔。每张图片都是独一无二的,具有不同的性别,姿势,表情和发型。接下来,利用图像的概率分布来帮助我们创建新面孔。我们将使用最简单的统计方法——均值,即图像中的平均像素。更具体地说,我们将平均每个图像的xi来计算新图像的xi。为了加快处理速度,我们仅使用该数据集中的 2000
个样本,如下所示:
sample_size = 2000
ds_train = ds_train.batch(sample_size)
features = next(iter(ds_train.take(1)))
sample_images = features['image']
new_image = np.mean(sample_images, axis=0)
plt.imshow(new_image.astype(np.uint8))
事实证明,平均图像相当连贯:
2.2 条件概率
CelebA
数据集的每个图像都用如下面部特征标记:
我们将使用这些属性来生成新图像。假设我们要生成一个男性形象。我们该怎么做?我们仅使用将 Male
属性设置为 true
的图像,而不是计算每个图像的概率:
p(x∣y)p(x | y) p(x∣y)
表示在 yyy 的条件下 xxx 的概率。这称为条件概率 (conditional probability
)。在我们的示例中,yyy 是面部属性。当我们以 Male
属性为条件时,该变量不再是随机概率;而是每个样本都将具有“男性”属性,我们可以确定每个面孔都属于一个男人。下图显示了使用其他属性以及 Male
属性生成的新平均脸,例如 Male+Eyeglasses
和 Male+Eyeglasses+Mustache+Smiling
。随着条件的增加,样本数量会减少,并且平均图像也会变得嘈杂:
可以通过使用不同的属性来生成新面孔,但是并非每种组合都能产生令人满意的结果。以下是一些具有不同属性的女性面孔。最右边的图像是一个有趣的图像。使用了 Female
,Smiling
,Eyeglasses
和 Pointy_Nose
的属性,事实证明,具有这些属性的人往往也有波浪形的头发,但是本示例中未显式的包含此属性。可视化是有用的工具,可提供对数据集的有效认知:
也可以在生成图像时尝试使用中位数,而不是使用均值,这可能会产生更清晰的图像。只需将 np.mean()
替换为 np.median()
。
2.3 概率生成模型
我们希望通过图像生成算法实现三个主要目标:
- 生成看起来像给定数据集中的图像
- 生成多样性的图像
- 控制正在生成的图像
通过简单地获取图像中像素的均值,演示了如何实现目标 1
和 3
。但是,缺点在于,在每个条件下只能生成一张图像。对于一种算法,从数百或数千个训练图像中仅生成一个图像,这确实不是很有效。
下图显示了数据集中某一图片的一个颜色通道的分布。图表上的 x
标记是中位数。当我们使用数据的均值或中位数时,我们总是在采样同一点,因此结果没有变化。有没有一种方法可以生成多个不同的面孔?是的,可以尝试通过从整个像素分布中采样来增加生成的图像变化:
我们可以首先通过计算每个像素的联合概率来创建概率模型 pmodelp_{model}pmodel。但是由于样本空间巨大,因此实现起来在计算上是昂贵的。我们将直接从数据集中绘制像素样本。为了在新图像中创建 x0x_0x0 像素,我们通过运行以下代码从数据集中所有图像的 x0x_0x0 像素中随机采样:
for i in range(h):for j in range(w):rand_int = np.random.randint(0, sample_images.shape[0])new_image[i,j] = sample_images[rand_int,i,j]
使用随机采样生成图像,尽管图像之间存在一些差异,但它们之间并没有太大差异,我们的目标是能够生成各种面孔。而且,与使用均值时相比,图像明显更嘈杂。其原因是像素分布彼此独立。
例如,对于嘴唇上的给定像素,我们可以合理地期望颜色是粉红色或红色,相邻像素也一样。但是,由于我们是从与人脸位置和姿势不同的图像中独立采样的,因此这会导致像素之间出现颜色不连续性,最终产生以下嘈杂的结果:
为什么平均脸比随机采样看起来更平滑?首先,这是因为像素之间的均值距离较小。想象一下一个随机采样场景,其中一个像素采样接近
0
,下一个像素采样接近255
。这些像素的平均值可能位于中间的某个位置,因此它们之间的差异会更小。另一方面,图片背景中的像素往往具有均匀的分布;例如,它们全都可能是蓝天,白墙,绿叶等的一部分。由于它们在色谱中相当均匀地分布,因此平均值约为[127, 127, 127]
,恰好是灰色。
2.4 参数化建模
我们刚刚做的就是使用像素直方图作为 pmodelp_{model}pmodel,但是这里有一些缺点。首先,由于样本空间大,因此样本分布中并非每种可能的颜色都存在。结果,生成的图像将永远不会包含数据集中不存在的颜色。例如,我们希望能够生成完整的肤色,而不是仅生成数据集中存在的一种特殊的棕色阴影。如果尝试使用条件生成面部,则会发现并非每种条件的每种都是可行的。例如,对于 Mustache + Sideburns + Heavy_Makeup + Wavy_Hair
,根本就没有满足这些条件的样品。
其次,样本空间随着我们增加数据集的大小或图像分辨率而增加。这可以通过使用参数化模型来解决。下图显示了 1000
个随机生成的数字的直方图:
我们可以使用概率密度函数 (Probability Density Function
, PDF
) (图中的红线)在数据上拟合高斯模型。高斯分布的PDF公式如下:
f(x)=1σ2πe−12(x−μσ)2f(x)=\frac 1{\sigma\sqrt{2\pi}}e^{-\frac 12(\frac {x-\mu}\sigma)^2} f(x)=σ2π1e−21(σx−μ)2
其中,μμμ 是平均值,而 σ\sigmaσ 是标准差。我们可以看到 PDF
覆盖了直方图间隙,这意味着我们可以为样本空间的每个数字生成一个概率。这个高斯模型只有两个参数——均值和标准差。
现在可以将 1000
个数字压缩为两个参数,并且我们可以使用该模型绘制所需的任意数量的样本。当然,图像是复杂的,无法通过简单模型(例如高斯模型)或实际上任何数学模型来描述。这就是神经网络发挥作用的地方。