2、TensorFlow Probability 基础:安装与配置、TFP 核心组件概览
好,咱们正式开始动手了。这一章我带你先把环境搭好,再快速过一遍 TFP 的四大核心组件。说白了,这就是你接下来所有贝叶斯编程的「工具箱」。我个人习惯先把工具认全,再谈怎么用,这样后面学起来会顺手很多。
2.1 安装与配置:别让环境卡住你
安装 TFP 其实很简单,但有几个坑我得提前跟你说。我曾经在一台老旧的服务器上折腾了整整一下午,最后发现是 Python 版本不兼容——嗯,这种经历一次就够了。
2.1.1 基础安装命令
我建议你直接用 pip 安装,干净利落:
# 安装 TensorFlow 和 TFP
pip install tensorflow==2.12.0
pip install tensorflow-probability==0.20.0
2.1.2 验证安装
装完之后,我习惯先跑个简单的导入测试:
import tensorflow as tf
import tensorflow_probability as tfp
print("TF version:", tf.__version__)
print("TFP version:", tfp.__version__)
# 创建一个最简单的正态分布,验证安装
normal_dist = tfp.distributions.Normal(loc=0., scale=1.)
print("采样结果:", normal_dist.sample(5))
如果能看到版本号和采样结果,恭喜你,环境搞定了。
2.1.3 避坑指南:GPU 配置
如果你要用 GPU 加速,记得检查 CUDA 和 cuDNN 的版本。我建议你直接用 tf.config.list_physical_devices('GPU') 看一眼。为什么?因为 TFP 的 MCMC 采样在 GPU 上能快好几倍,尤其是数据量大的时候。
%load_ext autoreload 和 %autoreload 2,这样修改代码后不用重启内核。做贝叶斯建模时,你会频繁调整模型结构,这个设置能省不少时间。
2.2 TFP 核心组件概览:四大金刚
TFP 的核心组件其实就四个:distributions、bijectors、mcmc、vi。我管它们叫「四大金刚」。每个组件解决一类问题,咱们一个一个看。
2.2.1 tfp.distributions:概率分布工厂
这是你用得最多的模块。说白了,它就是各种概率分布的「工厂」。你想用正态分布?伯努利分布?还是更复杂的混合分布?这里都有。
# 创建分布对象
normal = tfp.distributions.Normal(loc=0., scale=1.)
bernoulli = tfp.distributions.Bernoulli(probs=0.7)
# 基本操作
print("PDF at 0:", normal.prob(0.)) # 概率密度函数
print("LogPDF at 0:", normal.log_prob(0.)) # 对数概率密度
print("采样5个:", normal.sample(5)) # 随机采样
log_prob 求梯度。这在变分推断和梯度下降中至关重要。你想想看,如果分布不可微,很多优化算法就没法用了。
2.2.2 tfp.bijectors:分布变形金刚
Bijectors 是 TFP 里最巧妙的设计之一。它能把一个简单分布「变形」成复杂分布。我刚开始学的时候觉得这玩意儿有点抽象,后来在项目中做约束参数时才发现它有多好用。
# 用 Softplus 把实数映射到正数
softplus = tfp.bijectors.Softplus()
normal = tfp.distributions.Normal(loc=0., scale=1.)
# 构造一个正数分布
positive_normal = tfp.distributions.TransformedDistribution(
distribution=normal,
bijector=softplus
)
print("采样(都是正数):", positive_normal.sample(5))
为什么会用到这个?举个例子:你要建模一个标准差参数,它必须是正数。直接用正态分布采样可能得到负数,但用 Softplus 变换后,所有采样值都是正的。嗯,这就是 bijector 的妙处。
2.2.3 tfp.mcmc:贝叶斯推断的引擎
MCMC 是贝叶斯推断的核心引擎。TFP 提供了多种采样器,我用的最多的是 HamiltonianMonteCarlo(HMC)和 NoUTurnSampler(NUTS)。
# 一个简单的 MCMC 示例
target_log_prob_fn = lambda x: tfp.distributions.Normal(loc=0., scale=1.).log_prob(x)
hmc = tfp.mcmc.HamiltonianMonteCarlo(
target_log_prob_fn=target_log_prob_fn,
step_size=0.1,
num_leapfrog_steps=3
)
# 采样
samples, _ = tfp.mcmc.sample_chain(
num_results=1000,
current_state=0.,
kernel=hmc,
num_burnin_steps=500
)
tfp.mcmc.SimpleStepSizeAdaptation 自动调整步长,等模型稳定了再手动微调。
2.2.4 tfp.vi:变分推断的捷径
当数据量很大时,MCMC 可能跑不动。这时候变分推断(VI)就派上用场了。它用优化代替采样,速度快很多,但精度会差一些。
# 变分推断示例
# 假设我们要近似一个后验分布
surrogate_posterior = tfp.distributions.Normal(
loc=tf.Variable(0.),
scale=tf.Variable(1.)
)
# 优化 ELBO
losses = tfp.vi.fit_surrogate_posterior(
target_log_prob_fn=lambda x: tfp.distributions.Normal(loc=0., scale=1.).log_prob(x),
surrogate_posterior=surrogate_posterior,
optimizer=tf.optimizers.Adam(learning_rate=0.1),
num_steps=1000
)
2.3 张量与分布的基本操作
TFP 的分布是建立在 TensorFlow 张量之上的。这意味着你可以利用 TensorFlow 的自动微分、GPU 加速和批处理能力。
2.3.1 批处理:一次处理多个分布
# 创建一批正态分布
batch_normal = tfp.distributions.Normal(
loc=[0., 1., 2.], # 三个不同的均值
scale=[1., 0.5, 2.] # 三个不同的标准差
)
# 采样:返回形状为 (3,) 的张量
samples = batch_normal.sample()
print("批采样:", samples)
# 计算每个分布的概率
probs = batch_normal.prob([0.5, 1.5, 2.5])
print("概率值:", probs)
2.3.2 事件形状与批形状
这是初学者最容易搞混的概念。我简单解释一下:
- 批形状(Batch Shape):独立分布的个数。比如上面例子中的 3 个分布。
- 事件形状(Event Shape):每个分布采样的维度。比如多元正态分布的维度。
# 多元正态分布
mvn = tfp.distributions.MultivariateNormalDiag(
loc=[0., 0.], # 2维均值
scale_diag=[1., 1.] # 2维标准差
)
print("批形状:", mvn.batch_shape) # 空,因为没有批处理
print("事件形状:", mvn.event_shape) # [2],因为是2维分布
2.3.3 可微性:贝叶斯编程的基石
TFP 的分布操作都是可微的。这意味着你可以对 log_prob 求梯度,然后用梯度下降优化参数。这是变分推断和 HMC 的基础。
# 演示可微性
x = tf.Variable(0.5)
with tf.GradientTape() as tape:
dist = tfp.distributions.Normal(loc=0., scale=1.)
log_prob = dist.log_prob(x)
grad = tape.gradient(log_prob, x)
print("梯度:", grad) # 输出 -0.5,因为正态分布的 log_prob 对 x 的导数是 -x
嗯,到这里,TFP 的基础你已经掌握了。下一章我们会用这些工具搭建第一个完整的贝叶斯模型。记住,工具是死的,但组合方式是活的。多动手试试,你会发现 TFP 的强大之处。