TensorFlow深度学习实战(34)——TensorFlow Probability
TensorFlow深度学习实战(34)——TensorFlow Probability
- 0. 前言
- 1. TensorFlow Probability
- 2. TensorFlow Probability 分布
- 3. 使用 TFP 分布
- 3.1 抛硬币示例
- 3.2 正态分布
- 小结
- 系列链接
0. 前言
TensorFlow Probability
(TFP
) 是基于 TensorFlow
的库,专为概率推理和统计建模设计。它提供了丰富的工具,支持概率分布、统计推断、贝叶斯建模、马尔可夫链蒙特卡洛、变分推断等一系列功能,旨在帮助研究人员构建复杂的概率模型,并进行高效的推断与学习。
1. TensorFlow Probability
TensorFlow Probability
(TFP
) 是 TensorFlow
生态系统的一部分,是一个用于开发概率模型的库,可以用于进行概率推理和统计分析。TFP
构建在 TensorFlow
之上,并提供相同的计算优势。
在 TFP
底层,有 TensorFlow
支持的所有数值运算,特别是 LinearOperator
类(属于 tf.linalg
),它包含可以用于矩阵执行的所有方法,而无需实际生成矩阵,提供了高效的无矩阵运算。TFP
包含大量概率分布及其相关的统计计算,还具有 tfp.bijectors
,提供了大量的变换分布。
Bijectors
封装了概率密度的变量变换。也就是说,当一个变量从空间 A
转换到空间 B
时,需要一种方法来映射这些变量的概率分布,Bijectors
提供了实现这些变换所需的所有工具。
TensorFlow Probability
还提供了 JointDistribution
,用于绘制联合样本并计算联合对数密度(对数概率密度函数)。标准的 TFP
分布作用于张量,但 JointDistribution
作用于张量的结构。tfp.layers
提供了可以用于扩展标准 TensorFlow
层并为其添加不确定性的神经网络层。最后,TFP
提供了大量的概率推理工具。在本节中,我们将逐步介绍这些函数和类。
首先使用 pip
安装 TensorFlow Probability
:
$ pip install tensorflow-probability
接下来,通过简单的示例来了解如何使用 TFP
,首先进行导入:
import matplotlib.pyplot as plt
import tensorflow_probability as tfp
import functools, inspect, sys
import seaborn as sns
探索 tfp.distributions
中的不同分布类:
tfd = tfp.distributions
distribution_class = tfp.distributions.Distribution
distributions = [name for name, obj in inspect.getmembers(tfd)if inspect.isclass(obj) and issubclass(obj, distribution_class)]print(distributions)
输出结果如下所示:
可以看到,TFP
提供了丰富的分布类型。接下来,使用正态分布:
normal = tfd.Normal(loc=0., scale=1.)
使用以上代码将得到一个均值为 0
、标准差为 1
的正态分布。可以使用 sample
方法生成符合该分布的随机样本:
def plot_normal(N):samples = normal.sample(N)sns.histplot(samples)plt.title(f"Normal Distribution with zero mean, and 1 std. dev {N} samples")plt.show()for n in [100, 1000, 10000]:plot_normal(n)
可以看到随着 N
的增加,图像呈现出正态分布特征:
接下来,我们将探索 TFP
中的不同分布。
2. TensorFlow Probability 分布
在 TensorFlow Probability
(TFP
) 中,每个分布都包含与之相关的形状 (shape
)、批大小 (batch size
) 和事件大小 (event size
)。形状是样本大小,表示独立且同分布的抽样或观测。以正态分布为例:
import matplotlib.pyplot as plt
import tensorflow_probability as tfp
import seaborn as sns
import tensorflow as tftfd = tfp.distributionsnormal = tfd.Normal(loc=0., scale=1.)
以上代码定义了一个均值为 0
、标准差为 1
的正态分布。使用 sample
函数时,将从这个分布中随机抽样。观察打印出的对象 normal
的 batch_shape
和 event_shape
属性:
print(normal)
输出如下所示:
tfp.distributions.Normal("Normal", batch_shape=[], event_shape=[], dtype=float32)
尝试定义另一个正态分布对象,但 loc
和 scale
使用列表作为参数:
normal_2 = tfd.Normal(loc=[0., 0.], scale=[1., 3.])
print(normal_2)
输出如所示:
tfp.distributions.Normal("Normal", batch_shape=[2], event_shape=[], dtype=float32)
观察 batch_shape
的变化。可以看到,如果从中采样一个样本,将从两个正态分布中抽取,一个均值为 0
、标准差为 1
,另一个均值为 0
、标准差为 3
。因此,批大小 batch_shape
决定了同一分布类型的抽样数量,这两个正态分布是独立的,因此是同一分布类型的批次。
我们可以创建相同类型分布的批次,但不能创建包含不同类型分布的混合批次,比如同时包含一个正态分布和高斯分布。
如果我们需要一个依赖于两个变量的正态分布,每个变量具有不同的均值,可以通过 MultivariateNormalDiag
实现,这会影响事件大小 event_shape
,即从该分布中单次抽样或观测的原子形状:
normal_3 = tfd.MultivariateNormalDiag(loc = [[1.0, 0.3]])
print(normal_3)
# tfp.distributions.MultivariateNormalDiag("MultivariateNormalDiag", batch_shape=[1], event_shape=[2], dtype=float32)
可以看到在输出中,event_shape
已经发生了改变。
3. 使用 TFP 分布
TensorFlow Probability
(TFP
) 提供了多种函数在分布实例化后执行各种操作。我们已经介绍了正态 (Normal
) 分布和抽样方法 sample
。还学习了如何使用 TFP
创建单变量分布、多变量分布或独立分布。TFP
提供了许多方法与创建的分布进行交互。包括:
sample(n)
:从分布中抽样n
个样本(观测值)prob(value)
:返回离散值 (value
) 的概率或连续值 (value
) 的概率密度log_prob(values)
:返回值 (values
) 的对数概率或对数似然mean()
:返回分布的均值stddev()
:返回分布的标准差
3.1 抛硬币示例
接下来,使用 TFP
提供的函数描述数据。以抛硬币为例,如果我们抛一枚硬币,只有两种可能——要么是正面,要么是反面,这种只有两个离散值的分布称为伯努利分布。考虑以下不同的场景:
场景 1
一枚标准硬币,正面出现的概率为 0.5
,反面出现的概率为 0.5
。
创建此分布:
coin_flip = tfd.Bernoulli(probs=0.5, dtype=tf.int32)
获取样本:
coin_flip_data = coin_flip.sample(2000)
可视化样本:
plt.hist(coin_flip_data)
plt.show()
由于是标准硬币,可以看到具有相等数量的正面和反面,正面和反面的概率都是 0.5
:
print(coin_flip.prob(0))
# tf.Tensor(0.5, shape=(), dtype=float32)
场景 2
一枚偏向正面的硬币,正面的概率为 0.8
,反面的概率为 0.2
。
创建此分布:
bias_coin_flip = tfd.Bernoulli(probs=0.8, dtype=tf.int32)
获取样本:
bias_coin_flip_data = bias_coin_flip.sample(2000)
可视化样本:
plt.hist(bias_coin_flip_data)
plt.show()
可以看到,正面的数量明显多于反面,反面的概率不再是 0.5
,而是接近 0.2
:
print(bias_coin_flip.prob(0))
# tf.Tensor(0.2, shape=(), dtype=float32)
场景 3
两枚硬币,其中一个偏向正面的概率为 0.8
,另一个偏向正面的概率为 0.6
。
两枚独立的硬币偏向正面的概率分别为 0.8
和 0.6
,创建此分布:
two_bias_coins_flip = tfd.Bernoulli(probs=[0.8, 0.6], dtype=tf.int32)
获取样本:
two_bias_coins_flip_data = two_bias_coins_flip.sample(2000)
可视化样本:
plt.hist(two_bias_coins_flip_data[:,0], alpha=0.8, label='Coin 1')
plt.hist(two_bias_coins_flip_data[:,1], alpha=0.5, label='Coin 2')
plt.legend(loc='center')
plt.show()
蓝色的条形图对应硬币 1
,橙色的条形图对应硬币 2
。图中的棕色部分是两个硬币结果重叠的区域。可以看到,对于硬币 1
,正面的数量远多于硬币 2
。
3.2 正态分布
在伯努利分布中,数据只有两个可能的离散值,例如正面和反面,好和坏,垃圾邮件和正常邮件,等等。但在日常生活中,大量数据具有连续范围,因此正态分布非常常见。
正态分布的概率密度函数可以表示为:
f(x;μ,σ)=1σ2πexp(−12(x−μσ)2)f(x;\mu,\sigma)=\frac 1{\sigma\sqrt{2\pi}}exp(-\frac12(\frac{x-\mu}{\sigma})^2) f(x;μ,σ)=σ2π1exp(−21(σx−μ)2)
其中 μ\muμ 是分布的均值,σ\sigmaσ 是标准差。在 TFP
中,参数 loc
代表均值,参数 scale
代表标准差。接下来,为了说明如何使用正态分布,使用某一个地点特定季节的天气数据。
3.2.1 单变量正态分布
假设天气仅依赖于温度,通过收集多年的夏季温度样本,可以得到一个良好的数据表示,得到一个单变量正态分布。
基于天气数据,六月的平均温度为 35
摄氏度,标准差为 4
摄氏度,据此创建正态分布:
temperature = tfd.Normal(loc=35, scale = 4)
获取样本数据:
temperature_data = temperature.sample(1000)
可视化数据:
sns.displot(temperature_data, kde= True)
plt.show()
验证样本数据的均值和标准差,可以通过以下方法获得分布的均值和标准差:
print(temperature.mean())
# tf.Tensor(35.0, shape=(), dtype=float32)
print(temperature.stddev())
# tf.Tensor(4.0, shape=(), dtype=float32)
使用样本数据,可以通过以下方法获得均值和标准差进行验证:
print(tf.math.reduce_mean(temperature_data))
# tf.Tensor(35.103275, shape=(), dtype=float32)
print(tf.math.reduce_std(temperature_data))
# tf.Tensor(4.061728, shape=(), dtype=float32)
可以看到,样本数据具有相同的均值和标准差。
3.2.2 多变量分布
假设,天气依赖两个变量,温度和湿度,这种类型的数据分布(多变量分布)可以使用 TFP
中的 MultivariateNormalDiag
分布类定义:
weather = tfd.MultivariateNormalDiag(loc = [35, 56], scale_diag=[4, 15])
weather_data = weather.sample(1000)plt.scatter(weather_data[:, 0], weather_data[:, 1], color='blue', alpha=0.4)
plt.xlabel("Temperature Degree Celsius")
plt.ylabel("Humidity %")
plt.show()
使用 TFP
生成的具有两个变量(温度和湿度)的多变量正态分布如下:
使用 TFP
中的不同分布和双射,可以生成遵循与真实数据相同的联合分布的合成数据,用于训练模型。
小结
TensorFlow Probability
(TFP
) 是一个强大且灵活的工具集,适用于构建和推理复杂的概率模型,特别适用于结合机器学习和统计建模的任务。无论是经典的概率模型,还是现代的深度学习与贝叶斯推断结合的任务,TFP
都能提供高效且易于集成的解决方案。
系列链接
TensorFlow深度学习实战(1)——神经网络与模型训练过程详解
TensorFlow深度学习实战(2)——使用TensorFlow构建神经网络
TensorFlow深度学习实战(3)——深度学习中常用激活函数详解
TensorFlow深度学习实战(4)——正则化技术详解
TensorFlow深度学习实战(5)——神经网络性能优化技术详解
TensorFlow深度学习实战(6)——回归分析详解
TensorFlow深度学习实战(7)——分类任务详解
TensorFlow深度学习实战(8)——卷积神经网络
TensorFlow深度学习实战(9)——构建VGG模型实现图像分类
TensorFlow深度学习实战(10)——迁移学习详解
TensorFlow深度学习实战(11)——风格迁移详解
TensorFlow深度学习实战(12)——词嵌入技术详解
TensorFlow深度学习实战(13)——神经嵌入详解
TensorFlow深度学习实战(14)——循环神经网络详解
TensorFlow深度学习实战(15)——编码器-解码器架构
TensorFlow深度学习实战(16)——注意力机制详解
TensorFlow深度学习实战(17)——主成分分析详解
TensorFlow深度学习实战(18)——K-means 聚类详解
TensorFlow深度学习实战(19)——受限玻尔兹曼机
TensorFlow深度学习实战(20)——自组织映射详解
TensorFlow深度学习实战(21)——Transformer架构详解与实现
TensorFlow深度学习实战(22)——从零开始实现Transformer机器翻译
TensorFlow深度学习实战(23)——自编码器详解与实现
TensorFlow深度学习实战(24)——卷积自编码器详解与实现
TensorFlow深度学习实战(25)——变分自编码器详解与实现
TensorFlow深度学习实战(26)——生成对抗网络详解与实现
TensorFlow深度学习实战(27)——CycleGAN详解与实现
TensorFlow深度学习实战(28)——扩散模型(Diffusion Model)
TensorFlow深度学习实战(29)——自监督学习(Self-Supervised Learning)
TensorFlow深度学习实战(30)——强化学习(Reinforcement learning,RL)
TensorFlow深度学习实战(31)——强化学习仿真库Gymnasium
TensorFlow深度学习实战(32)——深度Q网络(Deep Q-Network,DQN)
TensorFlow深度学习实战(33)——深度确定性策略梯度